8 /* Buffer for building field content */
9 static char field_buffer[8192];
10 static size_t field_pos = 0;
12 void reset_field_buffer() {
14 field_buffer[0] = '\0';
17 void append_to_field(char c) {
18 if (field_pos < sizeof(field_buffer) - 1) { /* Reserve space for null terminator */
19 field_buffer[field_pos++] = c;
20 field_buffer[field_pos] = '\0';
24 void append_string_to_field(const char* s) {
25 while (*s && field_pos < sizeof(field_buffer) - 1) { /* Reserve space for null terminator */
26 field_buffer[field_pos++] = *s++;
28 field_buffer[field_pos] = '\0';
31 char* get_field_content() {
32 char* result = strdup(field_buffer); /* NOTE: Caller must free() this memory */
34 fprintf(stderr, "Memory allocation failed in get_field_content()\n");
35 exit(1); /* Conservative approach: exit on memory failure */
48 TEXTDATA [\x20-\x21\x23-\x2B\x2D-\x7E]
58 /* Check if we need to emit an empty field before the comma */
59 /* This will be handled by the parser grammar instead */
63 {CRLF} { return CRLF_TOK; }
65 {LF} { return CRLF_TOK; }
72 <ESCAPED_FIELD>{DQUOTE}{DQUOTE} { append_to_field('"'); }
74 <ESCAPED_FIELD>{DQUOTE} {
75 yylval.str = get_field_content();
80 <ESCAPED_FIELD>{TEXTDATA} { append_to_field(yytext[0]); }
82 <ESCAPED_FIELD>{COMMA} { append_to_field(','); }
84 <ESCAPED_FIELD>{CR} { append_to_field('\r'); }
86 <ESCAPED_FIELD>{LF} { append_to_field('\n'); }
88 <ESCAPED_FIELD>. { append_to_field(yytext[0]); }
90 <ESCAPED_FIELD><<EOF>> {
91 /* Handle unterminated quoted field */
92 yylval.str = get_field_content();
98 yylval.str = strdup(yytext); /* NOTE: Caller must free() this memory */
100 fprintf(stderr, "Memory allocation failed in TEXTDATA rule\n");
101 exit(1); /* Conservative approach: exit on memory failure */
106 [ \t] { /* ignore whitespace outside of fields */ }
108 . { return yytext[0]; }