Browse Source

better string parsing

David Rose 21 years ago
parent
commit
c779474e82

+ 304 - 207
direct/src/dcparser/dcLexer.cxx.prebuilt

@@ -300,30 +300,30 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
 	*yy_cp = '\0'; \
 	yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 48
-#define YY_END_OF_BUFFER 49
-static yyconst short int yy_accept[188] =
+#define YY_NUM_RULES 49
+#define YY_END_OF_BUFFER 50
+static yyconst short int yy_accept[189] =
     {   0,
-        0,    0,   49,   47,    2,    1,   44,   47,   47,   47,
-       40,   40,   45,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,    1,    0,   41,   43,
-        4,    3,   43,   40,   42,   46,   46,   46,   46,   46,
-       46,   35,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,    0,    3,   42,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       33,   34,   46,   46,   46,   46,   46,    0,   43,   46,
-       22,   46,   11,   46,   46,   46,   46,    7,   46,   46,
-       46,   46,   12,   46,   46,   46,   46,   46,   46,   46,
-
-       46,   46,   46,   46,   46,   46,   46,   46,   13,   14,
-       15,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   16,   39,   23,   46,   37,   36,    5,   46,    8,
-       46,   46,   46,   46,   46,   21,    6,   10,   46,   17,
-       18,   19,   46,   46,   20,   46,   46,   46,   38,   46,
-        9,   46,   46,   46,   46,   46,   46,   46,   46,   31,
-       46,   46,   46,   46,   32,   46,   46,   24,   46,   46,
-       46,   46,   25,   26,   46,   46,   46,   27,   28,   29,
-       46,   46,   46,   46,   46,   30,    0
+        0,    0,   50,   48,    2,    1,   44,   45,   48,   48,
+       48,   40,   40,   46,   47,   47,   47,   47,   47,   47,
+       47,   47,   47,   47,   47,   47,   47,    1,    0,   41,
+       43,    4,    3,   43,   40,   42,   47,   47,   47,   47,
+       47,   47,   35,   47,   47,   47,   47,   47,   47,   47,
+       47,   47,   47,   47,   47,   47,    0,    3,   42,   47,
+       47,   47,   47,   47,   47,   47,   47,   47,   47,   47,
+       47,   33,   34,   47,   47,   47,   47,   47,    0,   43,
+       47,   22,   47,   11,   47,   47,   47,   47,    7,   47,
+       47,   47,   47,   12,   47,   47,   47,   47,   47,   47,
+
+       47,   47,   47,   47,   47,   47,   47,   47,   47,   13,
+       14,   15,   47,   47,   47,   47,   47,   47,   47,   47,
+       47,   47,   16,   39,   23,   47,   37,   36,    5,   47,
+        8,   47,   47,   47,   47,   47,   21,    6,   10,   47,
+       17,   18,   19,   47,   47,   20,   47,   47,   47,   38,
+       47,    9,   47,   47,   47,   47,   47,   47,   47,   47,
+       31,   47,   47,   47,   47,   32,   47,   47,   24,   47,
+       47,   47,   47,   25,   26,   47,   47,   47,   27,   28,
+       29,   47,   47,   47,   47,   47,   30,    0
     } ;
 
 static yyconst int yy_ec[256] =
@@ -331,17 +331,17 @@ static yyconst int yy_ec[256] =
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    1,    4,    1,    1,    1,    1,    1,    1,
-        1,    5,    6,    1,    6,    7,    8,    9,   10,   11,
-       12,   13,   14,   15,   14,   16,   14,    1,    1,   17,
-        1,    1,    1,    1,   18,   18,   18,   18,   19,   18,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-        1,    1,    1,    1,   20,    1,   21,   22,   23,   24,
-
-       25,   26,   27,   28,   29,   20,   20,   30,   31,   32,
-       33,   34,   35,   36,   37,   38,   39,   40,   41,   42,
-       43,   20,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    4,    1,    1,    1,    1,    5,    1,
+        1,    6,    7,    1,    7,    8,    9,   10,   11,   12,
+       13,   14,   15,   16,   15,   17,   15,    1,    1,   18,
+        1,    1,    1,    1,   19,   19,   19,   19,   20,   19,
+       21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
+       21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
+        1,    1,    1,    1,   21,    1,   22,   23,   24,   25,
+
+       26,   27,   28,   29,   30,   21,   21,   31,   32,   33,
+       34,   35,   36,   37,   38,   39,   40,   41,   42,   43,
+       44,   21,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -358,133 +358,133 @@ static yyconst int yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst int yy_meta[44] =
+static yyconst int yy_meta[45] =
     {   0,
-        1,    1,    2,    1,    1,    3,    4,    1,    5,    5,
-        5,    5,    5,    5,    5,    5,    1,    6,    6,    7,
-        6,    6,    6,    6,    6,    6,    7,    7,    7,    7,
+        1,    1,    2,    1,    1,    1,    3,    4,    1,    5,
+        5,    5,    5,    5,    5,    5,    5,    1,    6,    6,
+        7,    6,    6,    6,    6,    6,    6,    7,    7,    7,
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-        7,    8,    7
+        7,    7,    8,    7
     } ;
 
-static yyconst short int yy_base[196] =
+static yyconst short int yy_base[197] =
     {   0,
-        0,    0,  230,  231,  231,    0,  231,  222,    0,   39,
-       38,   39,  231,    0,  199,   18,   28,   28,   23,   24,
-      186,  215,   36,   22,  182,  195,    0,    0,  216,   43,
-      231,    0,    0,    0,    0,    0,  186,  188,  187,  182,
-       28,    0,  188,  184,  183,  181,  176,  181,  178,  180,
-      175,  173,  179,  173,  174,  199,    0,    0,  179,  181,
-      181,  176,  175,  174,  177,  176,  165,  162,   57,  157,
-        0,    0,  154,   37,  154,  166,  152,  183,  182,  164,
-      174,  161,    0,  161,  151,  145,  143,    0,  144,  164,
-      167,  164,  155,  150,  145,  141,  149,  148,  146,   67,
-
-      129,  157,  144,  126,  141,  127,  148,  124,  140,  139,
-        0,  123,  126,  121,  129,  117,  126,  128,  137,  140,
-      137,  128,    0,    0,  127,    0,    0,    0,  134,    0,
-      110,  109,  108,  119,  117,    0,    0,    0,  115,  119,
-       31,    0,  103,  101,    0,  101,  100,  114,    0,  110,
-        0,   97,   96,  102,   94,   91,  107,  106,   83,    0,
-       89,   88,   91,  101,    0,   78,   77,    0,   98,   97,
-       79,   73,    0,    0,   71,   61,   81,    0,    0,    0,
-       75,   49,   42,   54,   31,    0,  231,   83,   88,   66,
-       90,   94,  102,  106,  110
+        0,    0,  231,  232,  232,    0,  232,  232,  222,    0,
+       39,   38,   39,  232,    0,  199,   18,   28,   28,   23,
+       24,  186,  215,   36,   22,  182,  195,    0,    0,  216,
+       43,  232,    0,    0,    0,    0,    0,  186,  188,  187,
+      182,   28,    0,  188,  184,  183,  181,  176,  181,  178,
+      180,  175,  173,  179,  173,  174,  199,    0,    0,  179,
+      181,  181,  176,  175,  174,  177,  176,  165,  162,   57,
+      157,    0,    0,  154,   37,  154,  166,  152,  183,  182,
+      164,  174,  161,    0,  161,  151,  145,  143,    0,  144,
+      164,  167,  164,  155,  150,  145,  141,  149,  148,  146,
+
+       67,  129,  157,  144,  126,  141,  127,  148,  124,  140,
+      139,    0,  123,  126,  121,  129,  117,  126,  128,  137,
+      140,  137,  128,    0,    0,  127,    0,    0,    0,  134,
+        0,  110,  109,  108,  119,  117,    0,    0,    0,  115,
+      119,   31,    0,  103,  101,    0,  101,  100,  114,    0,
+      110,    0,   97,   96,  102,   94,   91,  107,  106,   83,
+        0,   89,   88,   91,  101,    0,   78,   77,    0,   98,
+       97,   79,   73,    0,    0,   71,   61,   81,    0,    0,
+        0,   75,   49,   42,   54,   31,    0,  232,   84,   89,
+       67,   91,   95,  103,  107,  111
 
     } ;
 
-static yyconst short int yy_def[196] =
+static yyconst short int yy_def[197] =
     {   0,
-      187,    1,  187,  187,  187,  188,  187,  189,  190,  187,
-      191,  191,  187,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  188,  190,  189,  190,
-      187,  193,   30,   12,  194,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  195,  193,  194,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  195,  195,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,  192,  192,  192,  192,
-      192,  192,  192,  192,  192,  192,    0,  187,  187,  187,
-      187,  187,  187,  187,  187
+      188,    1,  188,  188,  188,  189,  188,  188,  190,  191,
+      188,  192,  192,  188,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  189,  191,  190,
+      191,  188,  194,   31,   13,  195,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  196,  194,  195,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  196,  196,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,    0,  188,  188,
+      188,  188,  188,  188,  188,  188
 
     } ;
 
-static yyconst short int yy_nxt[275] =
+static yyconst short int yy_nxt[277] =
     {   0,
-        4,    5,    6,    7,    4,    8,    9,   10,   11,   12,
-       12,   12,   12,   12,   12,   12,   13,   14,   14,   14,
-       15,   16,   17,   18,   14,   19,   14,   14,   20,   14,
-       14,   14,   21,   22,   14,   23,   24,   25,   26,   14,
-       14,   14,   14,   31,   33,   33,   32,   38,   40,   42,
-       43,  153,   44,   39,   46,   47,   50,   41,   45,   52,
-       51,   56,   53,   63,   64,   96,   90,   56,   91,  154,
-       30,   92,   93,  186,  185,   97,  119,  184,  120,   35,
-      187,  121,  122,   27,  183,   27,   27,   27,   27,   27,
-       27,   29,   29,   34,   34,  182,  181,   34,   36,   36,
-
-       36,   36,   57,  180,   57,   57,   57,   57,   57,   57,
-       58,   58,   79,  179,   79,  178,  177,  176,  175,  174,
-      173,  172,  171,  170,  169,  168,  167,  166,  165,  164,
-      163,  162,  161,  160,  159,  158,  157,  156,  155,  152,
-      151,  150,  149,  148,  147,  146,  145,  144,  143,  142,
-      141,  140,  139,  138,  137,  136,  135,  134,  133,  132,
-      131,  130,  129,  128,  127,  126,  125,  124,  123,  118,
-      117,  116,  115,  114,  113,  112,  111,  110,  109,  108,
-      107,  106,  105,  104,  103,  102,  101,  187,  187,  100,
-       99,   98,   95,   94,   89,   88,   87,   86,   85,   84,
-
-       83,   82,   81,   80,   78,   77,   76,   75,   74,   73,
-       72,   71,   70,   69,   68,   67,   66,   65,   62,   61,
-       60,   59,   33,   55,   54,   49,   48,   37,   28,  187,
-        3,  187,  187,  187,  187,  187,  187,  187,  187,  187,
-      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
-      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
-      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
-      187,  187,  187,  187
+        4,    5,    6,    7,    8,    4,    9,   10,   11,   12,
+       13,   13,   13,   13,   13,   13,   13,   14,   15,   15,
+       15,   16,   17,   18,   19,   15,   20,   15,   15,   21,
+       15,   15,   15,   22,   23,   15,   24,   25,   26,   27,
+       15,   15,   15,   15,   32,   34,   34,   33,   39,   41,
+       43,   44,  154,   45,   40,   47,   48,   51,   42,   46,
+       53,   52,   57,   54,   64,   65,   97,   91,   57,   92,
+      155,   31,   93,   94,  187,  186,   98,  120,  185,  121,
+       36,  188,  122,  123,   28,  184,   28,   28,   28,   28,
+       28,   28,   30,   30,   35,   35,  183,  182,   35,   37,
+
+       37,   37,   37,   58,  181,   58,   58,   58,   58,   58,
+       58,   59,   59,   80,  180,   80,  179,  178,  177,  176,
+      175,  174,  173,  172,  171,  170,  169,  168,  167,  166,
+      165,  164,  163,  162,  161,  160,  159,  158,  157,  156,
+      153,  152,  151,  150,  149,  148,  147,  146,  145,  144,
+      143,  142,  141,  140,  139,  138,  137,  136,  135,  134,
+      133,  132,  131,  130,  129,  128,  127,  126,  125,  124,
+      119,  118,  117,  116,  115,  114,  113,  112,  111,  110,
+      109,  108,  107,  106,  105,  104,  103,  102,  188,  188,
+      101,  100,   99,   96,   95,   90,   89,   88,   87,   86,
+
+       85,   84,   83,   82,   81,   79,   78,   77,   76,   75,
+       74,   73,   72,   71,   70,   69,   68,   67,   66,   63,
+       62,   61,   60,   34,   56,   55,   50,   49,   38,   29,
+      188,    3,  188,  188,  188,  188,  188,  188,  188,  188,
+      188,  188,  188,  188,  188,  188,  188,  188,  188,  188,
+      188,  188,  188,  188,  188,  188,  188,  188,  188,  188,
+      188,  188,  188,  188,  188,  188,  188,  188,  188,  188,
+      188,  188,  188,  188,  188,  188
     } ;
 
-static yyconst short int yy_chk[275] =
+static yyconst short int yy_chk[277] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,   10,   11,   12,   10,   16,   17,   18,
-       18,  141,   19,   16,   20,   20,   23,   17,   19,   24,
-       23,   30,   24,   41,   41,   74,   69,   30,   69,  141,
-      190,   69,   69,  185,  184,   74,  100,  183,  100,   11,
-       12,  100,  100,  188,  182,  188,  188,  188,  188,  188,
-      188,  189,  189,  191,  191,  181,  177,  191,  192,  192,
-
-      192,  192,  193,  176,  193,  193,  193,  193,  193,  193,
-      194,  194,  195,  175,  195,  172,  171,  170,  169,  167,
-      166,  164,  163,  162,  161,  159,  158,  157,  156,  155,
-      154,  153,  152,  150,  148,  147,  146,  144,  143,  140,
-      139,  135,  134,  133,  132,  131,  129,  125,  122,  121,
-      120,  119,  118,  117,  116,  115,  114,  113,  112,  110,
-      109,  108,  107,  106,  105,  104,  103,  102,  101,   99,
-       98,   97,   96,   95,   94,   93,   92,   91,   90,   89,
-       87,   86,   85,   84,   82,   81,   80,   79,   78,   77,
-       76,   75,   73,   70,   68,   67,   66,   65,   64,   63,
-
-       62,   61,   60,   59,   56,   55,   54,   53,   52,   51,
-       50,   49,   48,   47,   46,   45,   44,   43,   40,   39,
-       38,   37,   29,   26,   25,   22,   21,   15,    8,    3,
-      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
-      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
-      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
-      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
-      187,  187,  187,  187
+        1,    1,    1,    1,   11,   12,   13,   11,   17,   18,
+       19,   19,  142,   20,   17,   21,   21,   24,   18,   20,
+       25,   24,   31,   25,   42,   42,   75,   70,   31,   70,
+      142,  191,   70,   70,  186,  185,   75,  101,  184,  101,
+       12,   13,  101,  101,  189,  183,  189,  189,  189,  189,
+      189,  189,  190,  190,  192,  192,  182,  178,  192,  193,
+
+      193,  193,  193,  194,  177,  194,  194,  194,  194,  194,
+      194,  195,  195,  196,  176,  196,  173,  172,  171,  170,
+      168,  167,  165,  164,  163,  162,  160,  159,  158,  157,
+      156,  155,  154,  153,  151,  149,  148,  147,  145,  144,
+      141,  140,  136,  135,  134,  133,  132,  130,  126,  123,
+      122,  121,  120,  119,  118,  117,  116,  115,  114,  113,
+      111,  110,  109,  108,  107,  106,  105,  104,  103,  102,
+      100,   99,   98,   97,   96,   95,   94,   93,   92,   91,
+       90,   88,   87,   86,   85,   83,   82,   81,   80,   79,
+       78,   77,   76,   74,   71,   69,   68,   67,   66,   65,
+
+       64,   63,   62,   61,   60,   57,   56,   55,   54,   53,
+       52,   51,   50,   49,   48,   47,   46,   45,   44,   41,
+       40,   39,   38,   30,   27,   26,   23,   22,   16,    9,
+        3,  188,  188,  188,  188,  188,  188,  188,  188,  188,
+      188,  188,  188,  188,  188,  188,  188,  188,  188,  188,
+      188,  188,  188,  188,  188,  188,  188,  188,  188,  188,
+      188,  188,  188,  188,  188,  188,  188,  188,  188,  188,
+      188,  188,  188,  188,  188,  188
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -669,7 +669,7 @@ read_char(int &line, int &col) {
 // scan_quoted_string reads a string delimited by quotation marks and
 // returns it.
 static string
-scan_quoted_string() {
+scan_quoted_string(char quote_mark) {
   string result;
 
   // We don't touch the current line number and column number during
@@ -686,9 +686,96 @@ scan_quoted_string() {
 
   int c;
   c = read_char(line, col);
-  while (c != '"' && c != EOF) {
-    result += c;
-    c = read_char(line, col);
+  while (c != quote_mark && c != EOF) {
+    // A newline is not allowed within a string unless it is escaped.
+    if (c == '\n') {
+      c = EOF;
+      break;
+
+    } else if (c == '\\') {
+      // Backslash escapes the following character.  We also respect
+      // some C conventions.
+      c = read_char(line, col);
+      switch (c) {
+      case 'a':
+        result += '\a';
+        c = read_char(line, col);
+        break;
+
+      case 'n':
+        result += '\n';
+        c = read_char(line, col);
+        break;
+
+      case 'r':
+        result += '\r';
+        c = read_char(line, col);
+        break;
+
+      case 't':
+        result += '\t';
+        c = read_char(line, col);
+        break;
+
+      case 'x':
+        {
+          int hex = 0;
+          c = read_char(line, col);
+          for (int i = 0; i < 2 && isxdigit(c); i++) {
+            hex = hex * 16 + (isdigit(c) ? c - '0' : tolower(c) - 'a' + 10);
+            c = read_char(line, col);
+          }
+
+          result += hex;
+        }
+        break;
+
+      case '0':
+        {
+          int oct = 0;
+          c = read_char(line, col);
+          for (int i = 0; i < 3 && (c >= '0' && c < '7'); i++) {
+            oct = oct * 8 + (c - '0');
+            c = read_char(line, col);
+          }
+
+          result += oct;
+        }
+        break;
+
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        {
+          int dec = 0;
+          c = read_char(line, col);
+          for (int i = 0; i < 3 && isdigit(c); i++) {
+            dec = dec * 10 + (c - '0');
+            c = read_char(line, col);
+          }
+
+          result += dec;
+        }
+        break;
+
+      case EOF:
+        break;
+
+      default:
+        result += c;
+        c = read_char(line, col);
+      }
+
+    } else {
+      result += c;
+      c = read_char(line, col);
+    }
   }
 
   if (c == EOF) {
@@ -799,7 +886,7 @@ inline void accept() {
   col_number += yyleng;
 }
 
-#line 804 "lex.yy.c"
+#line 891 "lex.yy.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -950,7 +1037,7 @@ YY_DECL
 	register char *yy_cp = NULL, *yy_bp = NULL;
 	register int yy_act;
 
-#line 308 "dcLexer.lxx"
+#line 395 "dcLexer.lxx"
 
 
 
@@ -961,7 +1048,7 @@ YY_DECL
   }
 
 
-#line 966 "lex.yy.c"
+#line 1053 "lex.yy.c"
 
 	if ( yy_init )
 		{
@@ -1012,13 +1099,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 188 )
+				if ( yy_current_state >= 189 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 231 );
+		while ( yy_base[yy_current_state] != 232 );
 
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
@@ -1046,7 +1133,7 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 318 "dcLexer.lxx"
+#line 405 "dcLexer.lxx"
 {
   // New line.  Save a copy of the line so we can print it out for the
   // benefit of the user in case we get an error.
@@ -1063,7 +1150,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 332 "dcLexer.lxx"
+#line 419 "dcLexer.lxx"
 { 
   // Eat whitespace.
   accept();
@@ -1071,7 +1158,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 337 "dcLexer.lxx"
+#line 424 "dcLexer.lxx"
 { 
   // Eat C++-style comments.
   accept();
@@ -1079,7 +1166,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 342 "dcLexer.lxx"
+#line 429 "dcLexer.lxx"
 {
   // Eat C-style comments.
   accept();
@@ -1088,7 +1175,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 349 "dcLexer.lxx"
+#line 436 "dcLexer.lxx"
 {
   accept();
   return KW_DCLASS;
@@ -1096,7 +1183,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 354 "dcLexer.lxx"
+#line 441 "dcLexer.lxx"
 {
   accept();
   return KW_STRUCT;
@@ -1104,7 +1191,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 359 "dcLexer.lxx"
+#line 446 "dcLexer.lxx"
 {
   accept();
   return KW_FROM;
@@ -1112,7 +1199,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 364 "dcLexer.lxx"
+#line 451 "dcLexer.lxx"
 {
   accept();
   return KW_IMPORT;
@@ -1120,7 +1207,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 369 "dcLexer.lxx"
+#line 456 "dcLexer.lxx"
 {
   accept();
   return KW_TYPEDEF;
@@ -1128,7 +1215,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 374 "dcLexer.lxx"
+#line 461 "dcLexer.lxx"
 {
   accept();
   return KW_SWITCH;
@@ -1136,7 +1223,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 379 "dcLexer.lxx"
+#line 466 "dcLexer.lxx"
 {
   accept();
   return KW_CASE;
@@ -1144,7 +1231,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 384 "dcLexer.lxx"
+#line 471 "dcLexer.lxx"
 {
   accept();
   return KW_INT8;
@@ -1152,7 +1239,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 389 "dcLexer.lxx"
+#line 476 "dcLexer.lxx"
 {
   accept();
   return KW_INT16;
@@ -1160,7 +1247,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 394 "dcLexer.lxx"
+#line 481 "dcLexer.lxx"
 {
   accept();
   return KW_INT32;
@@ -1168,7 +1255,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 399 "dcLexer.lxx"
+#line 486 "dcLexer.lxx"
 {
   accept();
   return KW_INT64;
@@ -1176,7 +1263,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 404 "dcLexer.lxx"
+#line 491 "dcLexer.lxx"
 {
   accept();
   return KW_UINT8;
@@ -1184,7 +1271,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 409 "dcLexer.lxx"
+#line 496 "dcLexer.lxx"
 {
   accept();
   return KW_UINT16;
@@ -1192,7 +1279,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 414 "dcLexer.lxx"
+#line 501 "dcLexer.lxx"
 {
   accept();
   return KW_UINT32;
@@ -1200,7 +1287,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 419 "dcLexer.lxx"
+#line 506 "dcLexer.lxx"
 {
   accept();
   return KW_UINT64;
@@ -1208,7 +1295,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 424 "dcLexer.lxx"
+#line 511 "dcLexer.lxx"
 {
   accept();
   return KW_FLOAT64;
@@ -1216,7 +1303,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 429 "dcLexer.lxx"
+#line 516 "dcLexer.lxx"
 {
   accept();
   return KW_STRING;
@@ -1224,7 +1311,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 434 "dcLexer.lxx"
+#line 521 "dcLexer.lxx"
 {
   accept();
   return KW_BLOB;
@@ -1232,7 +1319,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 439 "dcLexer.lxx"
+#line 526 "dcLexer.lxx"
 {
   accept();
   return KW_BLOB32;
@@ -1240,7 +1327,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 444 "dcLexer.lxx"
+#line 531 "dcLexer.lxx"
 {
   accept();
   return KW_INT8ARRAY;
@@ -1248,7 +1335,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 449 "dcLexer.lxx"
+#line 536 "dcLexer.lxx"
 {
   accept();
   return KW_INT16ARRAY;
@@ -1256,7 +1343,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 454 "dcLexer.lxx"
+#line 541 "dcLexer.lxx"
 {
   accept();
   return KW_INT32ARRAY;
@@ -1264,7 +1351,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 459 "dcLexer.lxx"
+#line 546 "dcLexer.lxx"
 {
   accept();
   return KW_UINT8ARRAY;
@@ -1272,7 +1359,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 464 "dcLexer.lxx"
+#line 551 "dcLexer.lxx"
 {
   accept();
   return KW_UINT16ARRAY;
@@ -1280,7 +1367,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 469 "dcLexer.lxx"
+#line 556 "dcLexer.lxx"
 {
   accept();
   return KW_UINT32ARRAY;
@@ -1288,7 +1375,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 474 "dcLexer.lxx"
+#line 561 "dcLexer.lxx"
 {
   accept();
   return KW_UINT32UINT8ARRAY;
@@ -1296,7 +1383,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 479 "dcLexer.lxx"
+#line 566 "dcLexer.lxx"
 {
   accept();
   return KW_REQUIRED;
@@ -1304,7 +1391,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 484 "dcLexer.lxx"
+#line 571 "dcLexer.lxx"
 {
   accept();
   return KW_BROADCAST;
@@ -1312,7 +1399,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 489 "dcLexer.lxx"
+#line 576 "dcLexer.lxx"
 {
   accept();
   return KW_P2P;
@@ -1320,7 +1407,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 494 "dcLexer.lxx"
+#line 581 "dcLexer.lxx"
 {
   accept();
   return KW_RAM;
@@ -1328,7 +1415,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 499 "dcLexer.lxx"
+#line 586 "dcLexer.lxx"
 {
   accept();
   return KW_DB;
@@ -1336,7 +1423,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 504 "dcLexer.lxx"
+#line 591 "dcLexer.lxx"
 {
   accept();
   return KW_CLSEND;
@@ -1344,7 +1431,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 509 "dcLexer.lxx"
+#line 596 "dcLexer.lxx"
 {
   accept();
   return KW_CLRECV;
@@ -1352,7 +1439,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 514 "dcLexer.lxx"
+#line 601 "dcLexer.lxx"
 {
   accept();
   return KW_OWNSEND;
@@ -1360,7 +1447,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 519 "dcLexer.lxx"
+#line 606 "dcLexer.lxx"
 {
   accept();
   return KW_AIRECV;
@@ -1368,7 +1455,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 524 "dcLexer.lxx"
+#line 611 "dcLexer.lxx"
 { 
   // An unsigned integer number.
   accept();
@@ -1394,7 +1481,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 547 "dcLexer.lxx"
+#line 634 "dcLexer.lxx"
 { 
   // A signed integer number.
   accept();
@@ -1443,7 +1530,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 593 "dcLexer.lxx"
+#line 680 "dcLexer.lxx"
 {
   // A hexadecimal integer number.
   accept(); 
@@ -1473,7 +1560,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 620 "dcLexer.lxx"
+#line 707 "dcLexer.lxx"
 { 
   // A floating-point number.
   accept(); 
@@ -1484,17 +1571,27 @@ YY_RULE_SETUP
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 628 "dcLexer.lxx"
+#line 715 "dcLexer.lxx"
 {
   // Quoted string.
   accept();
-  dcyylval.str = scan_quoted_string();
+  dcyylval.str = scan_quoted_string('"');
   return STRING;
 }
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 635 "dcLexer.lxx"
+#line 722 "dcLexer.lxx"
+{
+  // Single-quoted string.
+  accept();
+  dcyylval.str = scan_quoted_string('\'');
+  return STRING;
+}
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 729 "dcLexer.lxx"
 {
   // Long hex string.
   accept();
@@ -1502,9 +1599,9 @@ YY_RULE_SETUP
   return HEX_STRING;
 }
 	YY_BREAK
-case 46:
+case 47:
 YY_RULE_SETUP
-#line 642 "dcLexer.lxx"
+#line 736 "dcLexer.lxx"
 { 
   // Identifier.
   accept();
@@ -1512,21 +1609,21 @@ YY_RULE_SETUP
   return IDENTIFIER;
 }
 	YY_BREAK
-case 47:
+case 48:
 YY_RULE_SETUP
-#line 650 "dcLexer.lxx"
+#line 744 "dcLexer.lxx"
 {
   // Send any other printable character as itself.
   accept(); 
   return dcyytext[0];
 }
 	YY_BREAK
-case 48:
+case 49:
 YY_RULE_SETUP
-#line 656 "dcLexer.lxx"
+#line 750 "dcLexer.lxx"
 ECHO;
 	YY_BREAK
-#line 1531 "lex.yy.c"
+#line 1628 "lex.yy.c"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -1818,7 +1915,7 @@ static yy_state_type yy_get_previous_state()
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 188 )
+			if ( yy_current_state >= 189 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1853,11 +1950,11 @@ yy_state_type yy_current_state;
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 188 )
+		if ( yy_current_state >= 189 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 187);
+	yy_is_jam = (yy_current_state == 188);
 
 	return yy_is_jam ? 0 : yy_current_state;
 	}
@@ -2407,4 +2504,4 @@ int main()
 	return 0;
 	}
 #endif
-#line 656 "dcLexer.lxx"
+#line 750 "dcLexer.lxx"

+ 99 - 5
direct/src/dcparser/dcLexer.lxx

@@ -168,7 +168,7 @@ read_char(int &line, int &col) {
 // scan_quoted_string reads a string delimited by quotation marks and
 // returns it.
 static string
-scan_quoted_string() {
+scan_quoted_string(char quote_mark) {
   string result;
 
   // We don't touch the current line number and column number during
@@ -185,9 +185,96 @@ scan_quoted_string() {
 
   int c;
   c = read_char(line, col);
-  while (c != '"' && c != EOF) {
-    result += c;
-    c = read_char(line, col);
+  while (c != quote_mark && c != EOF) {
+    // A newline is not allowed within a string unless it is escaped.
+    if (c == '\n') {
+      c = EOF;
+      break;
+
+    } else if (c == '\\') {
+      // Backslash escapes the following character.  We also respect
+      // some C conventions.
+      c = read_char(line, col);
+      switch (c) {
+      case 'a':
+        result += '\a';
+        c = read_char(line, col);
+        break;
+
+      case 'n':
+        result += '\n';
+        c = read_char(line, col);
+        break;
+
+      case 'r':
+        result += '\r';
+        c = read_char(line, col);
+        break;
+
+      case 't':
+        result += '\t';
+        c = read_char(line, col);
+        break;
+
+      case 'x':
+        {
+          int hex = 0;
+          c = read_char(line, col);
+          for (int i = 0; i < 2 && isxdigit(c); i++) {
+            hex = hex * 16 + (isdigit(c) ? c - '0' : tolower(c) - 'a' + 10);
+            c = read_char(line, col);
+          }
+
+          result += hex;
+        }
+        break;
+
+      case '0':
+        {
+          int oct = 0;
+          c = read_char(line, col);
+          for (int i = 0; i < 3 && (c >= '0' && c < '7'); i++) {
+            oct = oct * 8 + (c - '0');
+            c = read_char(line, col);
+          }
+
+          result += oct;
+        }
+        break;
+
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        {
+          int dec = 0;
+          c = read_char(line, col);
+          for (int i = 0; i < 3 && isdigit(c); i++) {
+            dec = dec * 10 + (c - '0');
+            c = read_char(line, col);
+          }
+
+          result += dec;
+        }
+        break;
+
+      case EOF:
+        break;
+
+      default:
+        result += c;
+        c = read_char(line, col);
+      }
+
+    } else {
+      result += c;
+      c = read_char(line, col);
+    }
   }
 
   if (c == EOF) {
@@ -628,7 +715,14 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
 ["] {
   // Quoted string.
   accept();
-  dcyylval.str = scan_quoted_string();
+  dcyylval.str = scan_quoted_string('"');
+  return STRING;
+}
+
+['] {
+  // Single-quoted string.
+  accept();
+  dcyylval.str = scan_quoted_string('\'');
   return STRING;
 }
 

+ 27 - 1
direct/src/dcparser/dcPacker.cxx

@@ -804,7 +804,7 @@ unpack_and_format(ostream &out) {
     break;
 
   case PT_string:
-    out << '"' << unpack_string() << '"';
+    enquote_string(out, '"', unpack_string());
     break;
 
   default:
@@ -945,3 +945,29 @@ set_unpack_data(const char *unpack_data, size_t unpack_length,
   _unpack_length = unpack_length;
   _owns_unpack_data = owns_unpack_data;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCPacker::enquote_string
+//       Access: Private
+//  Description: Outputs the indicated string within quotation marks.
+////////////////////////////////////////////////////////////////////
+void DCPacker::
+enquote_string(ostream &out, char quote_mark, const string &str) const {
+  out << quote_mark;
+  for (string::const_iterator pi = str.begin();
+       pi != str.end();
+       ++pi) {
+    if ((*pi) == quote_mark || (*pi) == '\\') {
+      out << '\\' << (*pi);
+
+    } else if (!isprint(*pi)) {
+      char buffer[10];
+      sprintf(buffer, "%02x", (unsigned int)(*pi));
+      out << "\\x" << buffer;
+
+    } else {
+      out << (*pi);
+    }
+  }
+  out << quote_mark;
+}

+ 1 - 0
direct/src/dcparser/dcPacker.h

@@ -130,6 +130,7 @@ private:
   void clear();
   void set_unpack_data(const char *unpack_data, size_t unpack_length, 
                        bool owns_unpack_data);
+  void enquote_string(ostream &out, char quote_mark, const string &str) const;
 
 private:
   enum Mode {