--- cfg_syn_scan.l 2002/07/05 18:32:37 1.4
+++ cfg_syn_scan.l 2002/07/05 20:49:58 1.5
@@ -59,6 +59,8 @@
yylloc->last = yylloc->first
static char closing_brace(char open);
+static int hex_nibble(const char hex);
+static int hex_sequence(char *out_ptr, size_t out_len, const char *in_ptr, size_t in_len);
%}
/* scanner options */
@@ -121,6 +123,9 @@
BEGIN(INITIAL);
return T_STRING;
}
+<SS_DQ>\\\n[ \t]* {
+ /* no-op */
+}
<SS_DQ>\\[0-7]{1,3} {
unsigned int result;
(void)sscanf(yytext+1, "%o", &result);
@@ -130,23 +135,19 @@
}
*cpStr++ = result;
}
-<SS_DQ>\\x[0-9a-fA-F]{2} {
- unsigned int result;
- (void)sscanf(yytext+1, "%x", &result);
- if (result > 0xff) {
- cfg_syn_error(CTX, CFG_ERR_SYN, yylloc, "escape sequence out of bound");
- return 0;
- }
- *cpStr++ = result;
+<SS_DQ>\\x\{[0-9a-fA-F]+\} {
+ cpStr += hex_sequence(cpStr, sizeof(caStr)-(cpStr-caStr), yytext+3, yyleng-3-1);
}
-<SS_DQ>\\\n[ \t]* {
- /* no-op */
+<SS_DQ>\\x[0-9a-fA-F]{2} {
+ cpStr += hex_sequence(cpStr, sizeof(caStr)-(cpStr-caStr), yytext+2, 2);
}
<SS_DQ>\\n { *cpStr++ = '\n'; }
<SS_DQ>\\r { *cpStr++ = '\r'; }
<SS_DQ>\\t { *cpStr++ = '\t'; }
<SS_DQ>\\b { *cpStr++ = '\b'; }
<SS_DQ>\\f { *cpStr++ = '\f'; }
+<SS_DQ>\\a { *cpStr++ = '\007'; }
+<SS_DQ>\\e { *cpStr++ = '\033'; }
<SS_DQ>\\(.|\n) {
*cpStr++ = yytext[1];
}
@@ -312,3 +313,41 @@
return open;
}
+/* convert a hex digit into a nibble */
+static int hex_nibble(const char hex)
+{
+ unsigned char nibble;
+
+ if (hex >= '0' && hex <= '9')
+ nibble = (unsigned char)(hex - '0');
+ else if (hex >= 'a' && hex <= 'f')
+ nibble = (unsigned char)(hex - 'a' + 10);
+ else if (hex >= 'A' && hex <= 'F')
+ nibble = (unsigned char)(hex - 'A' + 10);
+ else
+ nibble = -1;
+ return nibble;
+}
+
+/* convert a hex digit sequence into an octet stream */
+static int hex_sequence(char *out_ptr, size_t out_len, const char *in_ptr, size_t in_len)
+{
+ int i;
+ size_t out_max;
+
+ out_max = out_len;
+ if (in_len % 2 != 0) {
+ *out_ptr++ = hex_nibble(in_ptr[0]);
+ out_len--;
+ in_ptr++;
+ in_len--;
+ }
+ for (i = 0; in_len > 0 && out_len > 0; i++) {
+ *out_ptr++ = ((hex_nibble(in_ptr[0]) << 4) | (hex_nibble(in_ptr[1])));
+ out_len--;
+ in_ptr += 2;
+ in_len -= 2;
+ }
+ return (out_max - out_len);
+}
+
|