Project

General

Profile

[logo] 
 
Home
About/Contact
Major Tools
  Dinotrace
  Verilator
  Verilog-mode
  Verilog-Perl
Other Tools
  IPC::Locker
  Parallel::Forker
  Voneline
General Info
  Papers

allow-strings-in-option-file.patch

Yves Mathieu, 10/18/2019 04:13 PM

Download (8.19 KB)

View differences:

src/V3Options.cpp
1236 1236
    fl = new FileLine(filename);
1237 1237

  
1238 1238
    // Split into argument list and process
1239
    // Note we don't respect quotes.  It seems most simulators dont.
1240
    // Woez those that expect it; we'll at least complain.
1241
    if (whole_file.find('\"') != string::npos) {
1242
        fl->v3error("Double quotes in -f files cause unspecified behavior.");
1243
    }
1239
    // Note we try to respect escaped char, double/simple quoted strings
1240
    // Other simulators dont respect a common syntax...
1241
    // We will warn user...
1244 1242

  
1245 1243
    // Strip off arguments and parse into words
1246 1244
    std::vector<string> args;
1247
    string::size_type startpos = 0;
1248
    while (startpos < whole_file.length()) {
1249
        while (isspace(whole_file[startpos])) ++startpos;
1250
        string::size_type endpos = startpos;
1251
        while (endpos < whole_file.length() && !isspace(whole_file[endpos])) ++endpos;
1252
        if (startpos != endpos) {
1253
            string arg (whole_file, startpos, endpos-startpos);
1254
            args.reserve(args.size()+1);
1255
            args.push_back(arg);
1256
        }
1257
        startpos = endpos;
1245
    string::size_type pos = 0;
1246

  
1247
    // parse file using a state machine, taking into account quoted strings and escaped chars
1248
    enum state {search_option, in_option, escaped_char, in_quoted_string, in_double_quoted_string};
1249
    state st = search_option ;
1250
    state last_st ;
1251
    bool first_double_quote = true ;
1252
    bool first_simple_quote = true ;
1253
    bool first_escape = true ;
1254
    string arg("") ;
1255
    while (pos < whole_file.length()) {
1256
       char curr_char = whole_file[pos] ;
1257
       switch(st) {
1258
           case search_option: // Wait for non space char
1259
               if(!isspace(curr_char))
1260
                   st = in_option ;
1261
               else
1262
                   break ;
1263

  
1264
           case in_option: // Get all chars up to a white space or a "="
1265
               if(curr_char == '\\') { // Escape char, we wait for next char
1266
                  last_st = st ; // memorize current state
1267
                   st = escaped_char ;
1268
                   break ;
1269
               }
1270
               if(isspace(curr_char)) { // end of option
1271
                  if(arg.length() != 0) { // end of word
1272
                       args.reserve(args.size()+1);
1273
                       args.push_back(arg);
1274
                   }
1275
                   arg = "" ;
1276
                   st = search_option ;
1277
                   break ;
1278
               }
1279
               arg += curr_char ;
1280
               if(curr_char == '=') { // get an argument
1281
                   // check nature of argument
1282
                   pos++ ;
1283
                   curr_char = whole_file[pos] ;
1284
                   if(curr_char == '\'') { // find begin of quoted string
1285
                        st = in_quoted_string ;
1286
                        break ;
1287
                   }
1288
                   if(curr_char == '"') { // find begin of double quoted string
1289
                        st = in_double_quoted_string ;
1290
                        break ;
1291
                   }
1292
                   if(curr_char == '\\') { // Escape char, we wait for next char
1293
                       last_st = st ; // memorize current state
1294
                       st = escaped_char ;
1295
                       break ;
1296
                   }
1297
                   arg += curr_char ;
1298
               }
1299
               break ;
1300

  
1301
           case in_quoted_string: // just store all chars inside string
1302
               if(first_simple_quote) {
1303
                  fl->v3warn(EC_INFO, 
1304
                          "Simple quoted strings in -f files may cause unexpected behavior");
1305
                  first_simple_quote = false ;
1306
               }
1307
               if(curr_char != '\'') {
1308
                  arg += curr_char ;
1309
               } else { // End of quoted string
1310
                  st = in_option;
1311
               }
1312
               break ;
1313

  
1314
           case in_double_quoted_string: // takes into account escaped chars
1315
               if(first_double_quote) {
1316
                       fl->v3warn(EC_INFO, 
1317
                               "Double quoted strings in -f files may cause unexpected behavior");
1318
                       first_double_quote = false ;
1319
               }
1320
               if(curr_char != '"') {
1321
                  if(curr_char == '\\') {
1322
                      last_st = st ; // memorize current state
1323
                      st = escaped_char ;
1324
                  } else {
1325
                    arg += curr_char ;
1326
                  }
1327
               } else { // End of double quoted string
1328
                  st = in_option ;
1329
               }
1330
               break ;
1331

  
1332
           case escaped_char : // Just add the escaped char
1333
               if(first_escape) {
1334
                       fl->v3warn(EC_INFO, 
1335
                               "Escaped chars in -f files may cause unexpected behavior");
1336
                       first_escape = false ;
1337
               }
1338
               arg += curr_char ;
1339
               st = last_st ; // and return to last state
1340
               break;
1341

  
1342
       }
1343
       ++pos ;
1344
    }
1345
    if (arg.length() != 0) { // add last word
1346
        args.reserve(args.size()+1);
1347
        args.push_back(arg);
1258 1348
    }
1259 1349

  
1260 1350
    // Path
test_regress/t/t_flag_define.v
55 55
      $write("%%Error: Missing define\n"); $stop;
56 56
`endif
57 57

  
58
`ifdef STRING1
59
    if (`STRING1 !== "New String") $stop;
60
`else
61
      $write("%%Error: Missing define\n"); $stop;
62
`endif
63

  
64
`ifdef STRING2
65
    if (`STRING2 !== "New String") $stop;
66
`else
67
      $write("%%Error: Missing define\n"); $stop;
68
`endif
69

  
70
`ifdef STRING3
71
    if (`STRING3 !== "New String") $stop;
72
`else
73
      $write("%%Error: Missing define\n"); $stop;
74
`endif
75

  
58 76
      $write("*-* All Finished *-*\n");
59 77
      $finish;
60 78
   end
test_regress/t/t_flag_define.vc
5 5
+define+D5A=VALA+D5B=VALB
6 6
// Quotes do NOT escape the plus
7 7
//+define+D5A="VALA+D5B"+D5C
8
+define+STRING1="\"New String\"" 
9
+define+STRING2='"New String"'
10
+define+STRING3=\"New\ String\"
test_regress/t/t_flag_parameter.pl
11 11

  
12 12
compile(
13 13
    # It is not possible to put them into the options file
14
    v_flags2 => ['-Gstring1="\"New String\"" -pvalue+string2="\"New String\"" -f t/t_flag_parameter.vc'],
14
    v_flags2 => ['-f t/t_flag_parameter.vc'],
15 15
    );
16 16

  
17 17
execute(
test_regress/t/t_flag_parameter.v
8 8
module t;
9 9
   parameter string1 = "Original String";
10 10
   parameter string2 = "Original String";
11
   parameter string11 = "Original String";
12
   parameter string12 = "Original String";
13
   parameter string21 = "Original String";
14
   parameter string22 = "Original String";
11 15

  
12 16
   parameter real11 = 0.1;
13 17
   parameter real12 = 0.1;
......
28 32
   initial begin
29 33
      `check(string1,"New String");
30 34
      `check(string2,"New String");
35
      `check(string11,"New String");
36
      `check(string12,"New String");
37
      `check(string21,"New String");
38
      `check(string22,"New String");
31 39
      `check(real11,0.2);
32 40
      `check(real12,0.2);
33 41
      `check(real21,400);
test_regress/t/t_flag_parameter.vc
1
-Gstring1="\"New String\"" 
2
-pvalue+string2="\"New String\"" 
3
-Gstring11='"New String"'
4
-pvalue+string12='"New String"'
5
-Gstring21=\"New\ String\"
6
-pvalue+string22=\"New\ String\"
1 7
-Greal11=0.2
2 8
-pvalue+real12=0.2
3 9
-Greal21=4e2