From 75b65b10947e5aa8d8e9e4642392c3e71840c11d Mon Sep 17 00:00:00 2001 From: Michael Wood Date: Tue, 11 Nov 2025 20:34:40 -0500 Subject: [PATCH 1/2] Transfer comments sensibly during transpilation --- Makefile.in | 1 + burp.c | 6 ---- dynamo.c | 2 +- parse.y | 20 +++++++---- tests/SWAG_tests/comments | 13 +++++-- translate.c | 71 +++++++-------------------------------- 6 files changed, 38 insertions(+), 75 deletions(-) diff --git a/Makefile.in b/Makefile.in index d16befc..38e4eee 100644 --- a/Makefile.in +++ b/Makefile.in @@ -595,6 +595,7 @@ buildversion.o: version.h conftypes.h patchlevel.h $(srcdir)/version.c bash2py: .made mv bash bash2py + @chmod a+rx bash2py # This is missing some dependencies. Can build by pasting the whole bash.exe command & changing to fix_string. fix_string: burp.o translate_expr.o fix_string.c diff --git a/burp.c b/burp.c index 9aa006d..c9af03c 100755 --- a/burp.c +++ b/burp.c @@ -99,12 +99,6 @@ static void increase_burp(burpT *burpP) return; } max = burpP->m_max << 1; - if (max & 0x40000000) { - // Very serious problems trying to print whatever it might be.. - fprintf(stderr,"Burp can't print\n"); - assert(FALSE); - exit(1); - } burpP->m_P = realloc(burpP->m_P, max); if (!burpP->m_P) { fprintf(stderr, "Burp can't realloc(%d)\n", max); diff --git a/dynamo.c b/dynamo.c index e774d50..6568e0e 100644 --- a/dynamo.c +++ b/dynamo.c @@ -498,7 +498,7 @@ void write_function(char *first_line, ...) // first arg is broken out to comply *pFmt = '\0'; if (g_inside_class) - fprintf(outputF, " #\n"); + fprintf(outputF, "\n"); va_start(lines, first_line); vfprintf(outputF, fmt, lines); va_end(lines); diff --git a/parse.y b/parse.y index 163b8cf..bea0c5b 100644 --- a/parse.y +++ b/parse.y @@ -118,7 +118,7 @@ extern int extended_glob; #endif #ifdef BASH2PY -extern burpT g_output; +extern burpT g_commentBuffer, g_output; #define LINE_NUMBER position.line #define VALUE(X) X.value #else @@ -143,9 +143,6 @@ extern int bash_input_fd_changed; #endif extern int errno; -#ifdef BASH2PY -extern void seen_comment_char(int c); -#endif /* **************************************************************** */ /* */ @@ -455,6 +452,7 @@ inputunit: simple_list simple_list_terminator /* Case of regular command, but not a very interesting one. Return a NULL command. */ global_command = (COMMAND *)NULL; + if (g_commentBuffer.m_lth == 0) burpc(&g_commentBuffer, '\n'); if (parser_state & PST_CMDSUBST) parser_state |= PST_EOFTOKEN; YYACCEPT; @@ -3000,11 +2998,11 @@ discard_until (character) int c; #ifdef BASH2PY - seen_comment_char(-1); + burpc(&g_commentBuffer, '#'); #endif while ((c = shell_getc (0)) != EOF) { #ifdef BASH2PY - seen_comment_char(c); + burpc(&g_commentBuffer, (char)c); #endif if (c == character) { break; @@ -3492,6 +3490,16 @@ read_token (command) re_read_token: #endif /* ALIAS */ +#ifdef BASH2PY + /* If there is a pending comment flush it. This should be a whole-line comment + that precedes the next command, not an end-of-line comment. */ + if (g_commentBuffer.m_lth > 0) + { + burps(&g_output, g_commentBuffer.m_P); + burp_reset(&g_commentBuffer); + } +#endif + /* Read a single word from input. Start by skipping blanks. */ while ((character = shell_getc (1)) != EOF && shellblank (character)) ; diff --git a/tests/SWAG_tests/comments b/tests/SWAG_tests/comments index b906780..cc7e272 100644 --- a/tests/SWAG_tests/comments +++ b/tests/SWAG_tests/comments @@ -1,4 +1,11 @@ -#A comment -x=1 #Another -y=2 #Final + + +#A whole-line comment +x=1 #First EOL comment + +# Full-line comment after a blank line +# Second consecutive full-line comment +y=2 #Second EOL comment echo "$x+$y" + +# Comment at EOF diff --git a/translate.c b/translate.c index 37f0862..eabe6cd 100755 --- a/translate.c +++ b/translate.c @@ -93,7 +93,7 @@ static burpT g_case_var = {0,0,0,0,0,0}; burpT g_output = {0, 0, 0, 0, 0, 0}; -static burpT g_commentBuffer = {0, 0, 0, 0, 0, 0}; +burpT g_commentBuffer = {0, 0, 0, 0, 0, 0}; static burpT g_temp = {0, 0, 0, 0, 0, 0}; static burpT save = {0,0,0,0,0,0}; @@ -174,9 +174,6 @@ void seen_global(const char *nameP, _BOOL local) //#define UNCHANGED burps(&g_output, "^^") #define UNCHANGED -extern POSITION position; -static int comment_byte = -1; - static void print_heredoc_header (REDIRECT *redirect) { int kill_leading; @@ -827,22 +824,6 @@ typedef struct commentS { char *m_textP; } commentT; -commentT *g_comment_headP = NULL, *g_comment_tailP = NULL; - -static void print_comments(int before_byte) -{ - commentT *commentP = g_comment_headP; - - while (commentP && commentP->m_byte < before_byte) { - //MMMM deprecated, but we should print the comment sans html: burps_html(&g_output, commentP->m_textP); - newline(""); - commentT* temp = commentP; - commentP = commentP->m_nextP; - free(temp); - } - g_comment_headP = NULL; -} - static void translate_unary_operation(char *operatorP, int complex1, char *term1P) { int left, mode; @@ -2865,9 +2846,6 @@ static void emit_command (COMMAND *command) if (!command) return; - assert(0 <= command->position.byte); - print_comments(command->position.byte); - handle_redirection_list(&command->redirects); if (command->flags & CMD_TIME_PIPELINE) { UNCHANGED; @@ -3018,41 +2996,14 @@ char * make_command_string (COMMAND *command) void print_command (COMMAND *command) { make_command_string (command); - burpc(&g_output, '\n'); -} - -// This is a worrisome function that would probably break if ever (indirectly) used by print_comments() -void seen_comment_char(int c) -{ - char *P; - - if (c < 0) { - /* Start */ - - comment_byte = position.byte; - g_commentBuffer.m_lth = 0; - // burpc(&g_commentBuffer, '\n'); - c = '#'; - } - if (c == '\n') { - - /* End */ - P = g_commentBuffer.m_P; - if (*P != '#' || P[1] != '!') { - commentT *commentP = (commentT *) malloc(sizeof(commentT)); - commentP->m_nextP = NULL; - commentP->m_byte = comment_byte; - commentP->m_textP = P; // So every comment points to the same place??? - g_comment_tailP = commentP; - if (!g_comment_headP) g_comment_headP = g_comment_tailP; - g_commentBuffer.m_lth = 0; - g_commentBuffer.m_max = 0; - g_commentBuffer.m_P = NULL; - } - return; + /* Append buffered EOL comment if there is one. */ + if (g_commentBuffer.m_lth > 0) { + burpc(&g_output, ' '); + burps(&g_output, g_commentBuffer.m_P); + burp_reset(&g_commentBuffer); } - if (c) { - burpc(&g_commentBuffer, c); + else { + burpc(&g_output, '\n'); } } @@ -3563,8 +3514,10 @@ static void emitBash2PyClass(void) void close_translator(const char *output_fname) { - //TODO This is probably here to flush any remaining comments but is a no-op. - print_comments(999999999); + if (g_commentBuffer.m_lth > 0) { + burps(&g_output, g_commentBuffer.m_P); + burp_reset(&g_commentBuffer); + } // What do we need neededExpands(); From 7539edbd0be5759a4881c11268b074dbffcabb16 Mon Sep 17 00:00:00 2001 From: Michael Wood Date: Tue, 11 Nov 2025 20:41:19 -0500 Subject: [PATCH 2/2] Use BASH2PY macros where needed --- parse.y | 2 ++ 1 file changed, 2 insertions(+) diff --git a/parse.y b/parse.y index bea0c5b..31f7be5 100644 --- a/parse.y +++ b/parse.y @@ -452,7 +452,9 @@ inputunit: simple_list simple_list_terminator /* Case of regular command, but not a very interesting one. Return a NULL command. */ global_command = (COMMAND *)NULL; +#ifdef BASH2PY if (g_commentBuffer.m_lth == 0) burpc(&g_commentBuffer, '\n'); +#endif if (parser_state & PST_CMDSUBST) parser_state |= PST_EOFTOKEN; YYACCEPT;