8 /* Fix for bison-bridge with prefix */
9 #define YYSTYPE CSV_STYPE
11 /* Buffer for building field content */
12 static char field_buffer[8192];
13 static size_t field_pos = 0;
15 void reset_field_buffer() {
17 field_buffer[0] = '\0';
20 void append_to_field(char c) {
21 if (field_pos < sizeof(field_buffer) - 1) { /* Reserve space for null terminator */
22 field_buffer[field_pos++] = c;
23 field_buffer[field_pos] = '\0';
27 void append_string_to_field(const char* s) {
28 while (*s && field_pos < sizeof(field_buffer) - 1) { /* Reserve space for null terminator */
29 field_buffer[field_pos++] = *s++;
31 field_buffer[field_pos] = '\0';
34 char* get_field_content() {
35 char* result = strdup(field_buffer); /* NOTE: Caller must free() this memory */
37 fprintf(stderr, "Memory allocation failed in get_field_content()\n");
38 exit(1); /* Conservative approach: exit on memory failure */
54 TEXTDATA [\x20-\x21\x23-\x2B\x2D-\x7E]
64 /* Check if we need to emit an empty field before the comma */
65 /* This will be handled by the parser grammar instead */
69 {CRLF} { return CRLF_TOK; }
71 {LF} { return CRLF_TOK; }
78 <ESCAPED_FIELD>{DQUOTE}{DQUOTE} { append_to_field('"'); }
80 <ESCAPED_FIELD>{DQUOTE} {
81 yylval->str = get_field_content();
86 <ESCAPED_FIELD>{TEXTDATA} { append_to_field(yytext[0]); }
88 <ESCAPED_FIELD>{COMMA} { append_to_field(','); }
90 <ESCAPED_FIELD>{CR} { append_to_field('\r'); }
92 <ESCAPED_FIELD>{LF} { append_to_field('\n'); }
94 <ESCAPED_FIELD>. { append_to_field(yytext[0]); }
96 <ESCAPED_FIELD><<EOF>> {
97 /* Handle unterminated quoted field */
98 yylval->str = get_field_content();
104 yylval->str = strdup(yytext); /* NOTE: Caller must free() this memory */
106 fprintf(stderr, "Memory allocation failed in TEXTDATA rule\n");
107 exit(1); /* Conservative approach: exit on memory failure */
112 [ \t] { /* ignore whitespace outside of fields */ }
114 . { return yytext[0]; }