From 42983848528e1e415dc488e5d1816f0dece10de1 Mon Sep 17 00:00:00 2001 From: Joe George Date: Tue, 10 Nov 2026 10:11:03 -0500 Subject: [PATCH 1/4] Add the -k option to keep horizontal whitespace With -k, spaces and tabs are written out as they are in the input, and each comment becomes spaces of the same length, so a token keeps the column it has in the source file. --- directive.c | 1 + internal.H | 2 ++ mcpp_main.c | 4 +++- support.c | 22 +++++++++++++++++++++- system.c | 7 ++++++- 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/directive.c b/directive.c index 2d0ec34..7a16d63 100644 --- a/directive.c +++ b/directive.c @@ -342,6 +342,7 @@ void directive( void) ret: in_directive = FALSE; keep_comments = option_flags.c && compiling && !no_output; + keep_spaces = option_flags.k && compiling; /* keep_spaces is on for #define line even if no_output is TRUE */ if (! wrong_line) newlines++; diff --git a/internal.H b/internal.H index 85de2ab..7aba606 100644 --- a/internal.H +++ b/internal.H @@ -324,6 +324,7 @@ extern struct std_limits_ { /* The boolean flags specified by the execution options. */ extern struct option_flags_ { int c; /* -C option (keep comments) */ + int k; /* -k option (keep white spaces)*/ } option_flags; extern int stdc_val; /* Value of __STDC__ */ @@ -335,6 +336,7 @@ extern long src_line; /* Current source line number */ extern int wrong_line; /* Force #line to compiler */ extern int newlines; /* Count of blank lines */ extern int keep_comments; /* Don't remove comments */ +extern int keep_spaces; /* Don't remove white spaces */ extern int include_nest; /* Nesting level of #include */ extern const char * null; /* "" string for convenience */ extern const char ** inc_dirp; /* Directory of #includer */ diff --git a/mcpp_main.c b/mcpp_main.c index 44265ad..349d73e 100644 --- a/mcpp_main.c +++ b/mcpp_main.c @@ -45,6 +45,7 @@ /* The boolean flags specified by the execution options. */ struct option_flags_ option_flags = { FALSE, /* c: -C (keep comments) */ + FALSE, /* k: -k (keep white spaces) */ }; int mcpp_mode = STD; /* Mode of preprocessing */ @@ -263,7 +264,7 @@ static void init_main( void) std_limits.str_len = NBUFF; std_limits.id_len = IDMAX; std_limits.n_mac_pars = NMACPARS; - option_flags.c = FALSE; + option_flags.c = option_flags.k = FALSE; sh_file = NULL; sh_line = 0; } @@ -455,6 +456,7 @@ static void mcpp_main( void) LINE_COL line_col; /* Location of macro call in source */ keep_comments = option_flags.c && !no_output; + keep_spaces = option_flags.k; /* Will be turned off if !compiling */ line_col.col = line_col.line = 0L; /* diff --git a/support.c b/support.c index fdaaa18..b03ead1 100644 --- a/support.c +++ b/support.c @@ -1108,6 +1108,13 @@ static char * parse_line( void) free( temp); /* End of file with un- */ return NULL; /* terminated comment */ } + if (keep_spaces) { + if (tp + com_size >= limit - 1) /* Too long comment */ + com_size = limit - tp - 1; /* Truncate */ + while (com_size--) + *tp++ = ' '; /* Spaces of the comment length */ + break; + } if (temp == tp || ! (char_type[ *(tp - 1) & UCHARMAX] & HSP)) *tp++ = ' '; /* Squeeze white spaces */ @@ -1141,7 +1148,12 @@ static char * parse_line( void) , NULL, (long) c, NULL); case '\t': /* Horizontal space */ case ' ': - if (! (char_type[ *(tp - 1) & UCHARMAX] & HSP)) { + if (keep_spaces) { + if (c == '\t') + *tp++ = '\t'; + else + *tp++ = ' '; /* Convert to ' ' */ + } else if (! (char_type[ *(tp - 1) & UCHARMAX] & HSP)) { *tp++ = ' '; /* Squeeze white spaces */ } break; @@ -1206,6 +1218,10 @@ static char * read_a_comment( char * saved_sp; int cat_line = 0; /* Number of catenated lines */ + if (keep_spaces) { + saved_sp = sp - 2; /* '-2' for beginning / and * */ + *sizp = 0; + } if (keep_comments) /* If writing comments */ mcpp_fputs( "/*", OUT); /* Write the initializer*/ c = *sp++; @@ -1232,6 +1248,8 @@ static char * read_a_comment( /* trouble on some other tools such as rpcgen. */ wrong_line = TRUE; } + if (keep_spaces) /* Save the length */ + *sizp = *sizp + (sp - saved_sp); if ((mcpp_debug & MACRO_CALL) && compiling) { if (cat_line) { cat_line++; @@ -1244,6 +1262,8 @@ static char * read_a_comment( } return sp; /* End of comment */ case '\n': /* Line-crossing comment*/ + if (keep_spaces) /* Save the length */ + *sizp = *sizp + (sp - saved_sp) - 1; /* '-1' for '\n' */ if ((mcpp_debug & MACRO_CALL) && compiling) { /* Save location informations */ if (cat_line == 0) /* First line of catenation */ diff --git a/system.c b/system.c index 0a15aec..4d99925 100644 --- a/system.c +++ b/system.c @@ -377,6 +377,9 @@ opt_search: ; } break; + case 'k': /* Keep white spaces */ + option_flags.k = TRUE; + break; case 'M': /* Output source file dependency line */ if (argv[ mcpp_optind - 1] == mcpp_optarg) { /* -M */ @@ -488,6 +491,8 @@ static void usage( "-I- Unset system or site specific include directories.\n", +"-k Keep white spaces of input lines as they are.\n", + "-M file\n", " Output source file dependency line for makefile.\n", "-U Undefine .\n", @@ -532,7 +537,7 @@ static void set_opt_list( const char * const * lp = & list[ 0]; - strcpy( optlist, "e:CD:I:M:U:"); + strcpy( optlist, "e:kCD:I:M:U:"); /* Default options */ while (*lp) strcat( optlist, *lp++); From c5996f439b4aec2c153c4fd98c5491a837fdd540 Mon Sep 17 00:00:00 2001 From: Joe George Date: Tue, 10 Nov 2026 10:27:58 -0500 Subject: [PATCH 2/4] Keep comment padding within the line buffer With -k, a comment that follows a truncated comment and a token on the same line had its padding length computed as a negative number, which became a huge count. --- support.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/support.c b/support.c index b03ead1..a2bc5f1 100644 --- a/support.c +++ b/support.c @@ -1109,8 +1109,16 @@ static char * parse_line( void) return NULL; /* terminated comment */ } if (keep_spaces) { + /* + * Truncate a comment too long for the rest of the buffer. + * The buffer may already be full: an earlier comment of + * this line was truncated to end at 'limit - 1', and a + * token after it moved 'tp' to 'limit'. 'limit - tp - 1' + * is then negative, and would become a huge 'com_size', + * so the comment gets no padding instead. + */ if (tp + com_size >= limit - 1) /* Too long comment */ - com_size = limit - tp - 1; /* Truncate */ + com_size = (tp < limit - 1) ? limit - tp - 1 : 0; while (com_size--) *tp++ = ' '; /* Spaces of the comment length */ break; From 0133d039559e98d821dea81f6ec6dcf8f39808d4 Mon Sep 17 00:00:00 2001 From: Joe George Date: Thu, 12 Nov 2026 10:53:48 -0500 Subject: [PATCH 3/4] Clear the saved source column when the output is suppressed With -k and -M, a function-like macro call that spans lines and has tokens after it sets 'src_col', and every later directive is then skipped, so the dependency line misses the files included after it. --- mcpp_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mcpp_main.c b/mcpp_main.c index 349d73e..dc4e242 100644 --- a/mcpp_main.c +++ b/mcpp_main.c @@ -510,6 +510,12 @@ static void mcpp_main( void) */ if (no_output) { wrong_line = FALSE; + /* + * Nothing is output, so there are no columns to adjust. + * A 'src_col' left set would make the loop above skip + * directive() on every following line. + */ + src_col = 0; } else { if (wrong_line || newlines > 10) { sharp( NULL, 0); /* Output # line number */ From ef1e5eb73f08a23fb6569d1966a4582f27811291 Mon Sep 17 00:00:00 2001 From: Joe George Date: Thu, 12 Nov 2026 11:28:14 -0500 Subject: [PATCH 4/4] Revert "Clear the saved source column when the output is suppressed" This reverts commit 0133d039559e98d821dea81f6ec6dcf8f39808d4. --- mcpp_main.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mcpp_main.c b/mcpp_main.c index dc4e242..349d73e 100644 --- a/mcpp_main.c +++ b/mcpp_main.c @@ -510,12 +510,6 @@ static void mcpp_main( void) */ if (no_output) { wrong_line = FALSE; - /* - * Nothing is output, so there are no columns to adjust. - * A 'src_col' left set would make the loop above skip - * directive() on every following line. - */ - src_col = 0; } else { if (wrong_line || newlines > 10) { sharp( NULL, 0); /* Output # line number */