From 673d6e747b4b28916dc1c049480d52c5f6339e2e Mon Sep 17 00:00:00 2001 From: Fabrice Le Fessant Date: Tue, 6 Jun 2023 11:31:45 +0200 Subject: [PATCH] Cleaner replacement for alt_space in ppecho --- cobc/ChangeLog | 5 ++ cobc/pplex.l | 134 ++++++++++++++++++-------------- tests/testsuite.src/syn_copy.at | 9 +-- 3 files changed, 86 insertions(+), 62 deletions(-) diff --git a/cobc/ChangeLog b/cobc/ChangeLog index d9d7496e7..dbe36918f 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,9 @@ +2023-07-02 Fabrice Le Fessant + + * pplex.l (ppecho, ppecho_direct): replace alt_space by passing a + second equivalent token + 2023-07-01 Simon Sobisch * scanner.l: add check for reserved word FUNCTION, add missing diff --git a/cobc/pplex.l b/cobc/pplex.l index 6436395cf..c5bfb2efd 100644 --- a/cobc/pplex.l +++ b/cobc/pplex.l @@ -161,7 +161,14 @@ static struct cb_replace_list *current_replace_list = NULL; static struct cb_replace_list *save_current_replace = NULL; static struct cb_replace_list *base_replace_list = NULL; -static struct cb_text_list *text_queue = NULL; +struct cb_token_list { + struct cb_token_list *next; /* next pointer */ + struct cb_token_list *last; + const char *text; + const char *token; +}; + +static struct cb_token_list *text_queue = NULL; static size_t check_partial_match = 0; static struct copy_info *copy_stack = NULL; @@ -170,10 +177,10 @@ static struct plex_stack plex_cond_stack[PLEX_COND_DEPTH]; /* Function declarations */ static int ppinput (char *, const size_t); -static void ppecho (const char *, const cob_u32_t, - const int); -static void ppecho_direct (const char *); -static int ppecho_replace (struct cb_replace_list *); +static void ppecho (const char *text, const char *token); +static void ppecho_direct (const char *text, const char *token); +static int ppecho_replace (struct cb_replace_list *); + static void switch_to_buffer (const int, const char *, const YY_BUFFER_STATE); static void check_listing (const char *, const unsigned int); @@ -226,7 +233,7 @@ MAYBE_AREA_A [ ]?#? /* 2002+: inline comment */ #if 0 /* RXWRXW - Directive state */ if (YY_START != DIRECTIVE_STATE && YY_START != SET_DIRECTIVE_STATE) { - ppecho (" ", 0, 1); + ppecho (" ", NULL); } #endif } @@ -516,7 +523,7 @@ MAYBE_AREA_A [ ]?#? DEFAULT SECTION where compile-time defaults are specified. */ /* cf `ppparse.y`, grammar entry `program_with_control_division`, along with `parser.y`, entry `_control_division`. */ - ppecho (yytext, 0, (int)yyleng); + ppecho (yytext, NULL); yy_push_state (CONTROL_DIVISION_STATE); return CONTROL_DIVISION; } @@ -528,7 +535,7 @@ MAYBE_AREA_A [ ]?#? } \. { /* Pass dots to the parser to handle DEFAULT SECTION. */ - ppecho (yytext, 0, (int)yyleng); + ppecho (yytext, NULL); return DOT; } } @@ -554,7 +561,7 @@ SUBSTITUTION_SECTION_STATE>{ while (YY_START == CONTROL_DIVISION_STATE || YY_START == SUBSTITUTION_SECTION_STATE) yy_pop_state (); - ppecho (yytext, 0, (int)yyleng); + ppecho (yytext, NULL); } [,;]?\n { ECHO; @@ -574,25 +581,25 @@ SUBSTITUTION_SECTION_STATE> yy_pop_state (); /* Allow comment sentences/paragraphs */ comment_allowed = 1; - ppecho (yytext, 0, (int)yyleng); + ppecho (yytext, NULL); } "PROGRAM-ID"/[ .,;\n] { /* Allow comment sentences/paragraphs */ comment_allowed = 1; - ppecho (yytext, 0, (int)yyleng); + ppecho (yytext, NULL); } "DIVISION"/[ .,;\n] { /* Disallow comment sentences/paragraphs */ comment_allowed = 0; - ppecho (yytext, 0, (int)yyleng); + ppecho (yytext, NULL); } "SECTION"/[ .,;\n] { /* Disallow comment sentences/paragraphs */ comment_allowed = 0; - ppecho (yytext, 0, (int)yyleng); + ppecho (yytext, NULL); } ^{MAYBE_AREA_A}[ ]*"EJECT"([ ]*\.)? | @@ -641,43 +648,43 @@ SUBSTITUTION_SECTION_STATE> /* Pick up early - Also activates debugging lines */ cb_verify (cb_debugging_mode, "DEBUGGING MODE"); cb_flag_debugging_line = 1; - ppecho (yytext, 0, (int)yyleng); + ppecho (yytext, NULL); } [,;]?\n { - ppecho ("\n", 0, 1); + ppecho ("\n", NULL); cb_source_line++; } [;]?[ ]+ { - ppecho (" ", 1U, 1); + ppecho (" ", yytext); } [,]?[ ]+ { if (inside_bracket) { - ppecho (", ", 0, 2); + ppecho (", ", NULL); } else { - ppecho (" ", 1U, 1); + ppecho (" ", yytext); } } "(" { - inside_bracket++; - ppecho ("(", 0, 1); + inside_bracket++; + ppecho (yytext, NULL); } ")" { if (inside_bracket) { inside_bracket--; } - ppecho (")", 0, 1); + ppecho (yytext, NULL); } {WORD} | {NUMRIC_LITERAL} | {ALNUM_LITERAL} | . { - ppecho (yytext, 0, (int)yyleng); + ppecho (yytext, NULL); } token = NULL; + } else { + int token_size = strlen (token); + tp = cobc_plex_malloc( text_size + token_size + 2); + memcpy (tp+text_size+1, token, token_size); + p->token = tp+text_size+1; + } + memcpy (tp, text, text_size); + p->text = tp; + if (!list) { + p->last = p; + return p; + } + list->last->next = p; + list->last = p; + return list; +} + static void -ppecho (const char *text, const cob_u32_t alt_space, const int textlen) +ppecho (const char *text, const char *token) { /* performance note (last verified with GnuCOBOL 2.2): while this function used 5% (according to callgrind) @@ -2603,8 +2640,7 @@ ppecho (const char *text, const cob_u32_t alt_space, const int textlen) for optimization */ struct cb_replace_list *save_ptr; - const char *s; - struct cb_text_list *save_ptr_text_queue; + struct cb_token_list *save_ptr_text_queue; int status, save_status; #if 0 /* Simon: disabled until found necessary, as this takes together with frwite @@ -2613,33 +2649,16 @@ ppecho (const char *text, const cob_u32_t alt_space, const int textlen) fflush (ppout); #endif - /* Check for replacement text before outputting */ - if (alt_space) { - s = yytext; - } else { - s = text; - } - if (text_queue == NULL && (text[0] == ' ' || text[0] == '\n')) { - /* No replacement */ - fwrite (text, (size_t)textlen, (size_t)1, ppout); - /* TODO: instead of \n (empty line: set "needs source-loc" flag and - before first non-empty line output a #line directive, saving - quite some file io [keep 1 empty line]) */ - if (cb_listing_file) { - check_listing (s, 0); - } + ppecho_direct (text, token); return; } if (!current_replace_list && !base_replace_list) { /* Output queue */ for (; text_queue; text_queue = text_queue->next) { - fputs (text_queue->text, ppout); - } - fwrite (text, (size_t)textlen, (size_t)1, ppout); - if (cb_listing_file) { - check_listing (s, 0); + ppecho_direct(text_queue->text, text_queue->token); } + ppecho_direct(text, token); return; } if (!current_replace_list) { @@ -2651,7 +2670,7 @@ ppecho (const char *text, const cob_u32_t alt_space, const int textlen) } /* Do replacement */ - text_queue = pp_text_list_add (text_queue, text, (size_t)textlen); + text_queue = pp_token_list_add (text_queue, text, token); save_ptr_text_queue = text_queue; status = ppecho_replace (save_ptr); @@ -2661,7 +2680,8 @@ ppecho (const char *text, const cob_u32_t alt_space, const int textlen) text_queue = save_ptr_text_queue; while (text_queue && check_partial_match) { if (is_space_or_nl (text_queue->text[0])) { - ppecho_direct (text_queue->text); + ppecho_direct (text_queue->text, + text_queue->token); text_queue = text_queue->next; continue; } @@ -2672,7 +2692,8 @@ ppecho (const char *text, const cob_u32_t alt_space, const int textlen) if (text_queue) { /* Write text_queue if is not replaced */ if (status != -1 && check_partial_match) { - ppecho_direct (text_queue->text); + ppecho_direct (text_queue->text, + text_queue->token); } text_queue = text_queue->next; } @@ -2692,7 +2713,7 @@ ppecho (const char *text, const cob_u32_t alt_space, const int textlen) /* No match */ for (; text_queue; text_queue = text_queue->next) { - ppecho_direct (text_queue->text); + ppecho_direct (text_queue->text, text_queue->token); } } @@ -2703,8 +2724,8 @@ ppecho_replace (struct cb_replace_list *save_ptr) char *temp_ptr; size_t size; size_t size2; - struct cb_text_list *queue; - struct cb_text_list *save_queue; + struct cb_token_list *queue; + struct cb_token_list *save_queue; const struct cb_text_list *lno; struct cb_replace_list *r; @@ -2778,12 +2799,12 @@ ppecho_replace (struct cb_replace_list *save_ptr) } } for (lno = r->new_text; lno; lno = lno->next) { - ppecho_direct (lno->text); + ppecho_direct (lno->text, NULL); } if (r->src->lead_trail == CB_REPLACE_LEADING && save_queue /* <- silence warnings */) { /* Non-matched part of original text */ - ppecho_direct (save_queue->text + size); + ppecho_direct (save_queue->text + size, NULL); } check_partial_match = 0; text_queue = queue; @@ -2831,12 +2852,11 @@ display_finish (void) unput ('\n'); } -static void -ppecho_direct (const char *text) +void ppecho_direct (const char *text, const char *token ) { fputs (text, ppout); if (cb_listing_file) { - check_listing (text, 0); + check_listing (token != NULL ? token : text, 0); } } diff --git a/tests/testsuite.src/syn_copy.at b/tests/testsuite.src/syn_copy.at index 9fbb52f4c..aeb6b9dec 100644 --- a/tests/testsuite.src/syn_copy.at +++ b/tests/testsuite.src/syn_copy.at @@ -933,12 +933,9 @@ AT_KEYWORDS([copy]) # continue the loop with the - potential partially replaced - # new content. -AT_XFAIL_IF([true]) - AT_DATA([copy.inc], [ 01 VAR-:TEST: PIC X(2) VALUE "OK". ]) - AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. PROGRAM-ID. prog. @@ -954,6 +951,8 @@ AT_DATA([prog.cob], [ REPLACE OFF. ]) -AT_CHECK([$COMPILE_ONLY prog.cob], [0], [], []) +AT_CHECK([$COMPILE_ONLY prog.cob], [1], [], +[prog.cob:10: error: 'VAR-COMMA' is not defined +]) -AT_CLEANUP \ No newline at end of file +AT_CLEANUP