1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
|
From acb2f0a7f3689805b954ea19a927b5021fc69409 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 29 Jun 2020 21:19:16 -0400
Subject: [PATCH] Avoid duplicate declarations of bsdindent's global variables.
Arrange for all the variable declarations in indent_globs.h to look
like "extern" declarations to every .c file except indent.c.
This prevents linker failure due to duplicated global variables when
the code is built with -fno-common, which is soon to be gcc's default.
The method of temporarily #define'ing "extern" to empty is a hack,
no doubt, but it avoids requiring a duplicate set of variable
definitions, so it seemed like the best way.
Discussion: https://postgr.es/m/20200629165051.xlfqhstajf6ynxyv@alap3.anarazel.de
---
indent.c | 4 ++
indent_globs.h | 158 +++++++++++++++++++++++++++----------------------
2 files changed, 90 insertions(+), 72 deletions(-)
diff --git a/indent.c b/indent.c
index 62d4d01..d3a0ece 100644
--- a/indent.c
+++ b/indent.c
@@ -49,6 +49,10 @@ static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93";
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+
+/* Tell indent_globs.h to define our global variables here */
+#define DECLARE_INDENT_GLOBALS 1
+
#include "indent_globs.h"
#include "indent_codes.h"
#include "indent.h"
diff --git a/indent_globs.h b/indent_globs.h
index d018af1..398784b 100644
--- a/indent_globs.h
+++ b/indent_globs.h
@@ -50,9 +50,16 @@
#define true 1
#endif
+/*
+ * Exactly one calling file should define this symbol. The global variables
+ * will be defined in that file, and just referenced elsewhere.
+ */
+#ifdef DECLARE_INDENT_GLOBALS
+#define extern
+#endif
-FILE *input; /* the fid for the input file */
-FILE *output; /* the output file */
+extern FILE *input; /* the fid for the input file */
+extern FILE *output; /* the output file */
#define CHECK_SIZE_CODE(desired_size) \
if (e_code + (desired_size) >= l_code) { \
@@ -106,94 +113,94 @@ FILE *output; /* the output file */
s_token = tokenbuf + 1; \
}
-char *labbuf; /* buffer for label */
-char *s_lab; /* start ... */
-char *e_lab; /* .. and end of stored label */
-char *l_lab; /* limit of label buffer */
+extern char *labbuf; /* buffer for label */
+extern char *s_lab; /* start ... */
+extern char *e_lab; /* .. and end of stored label */
+extern char *l_lab; /* limit of label buffer */
-char *codebuf; /* buffer for code section */
-char *s_code; /* start ... */
-char *e_code; /* .. and end of stored code */
-char *l_code; /* limit of code section */
+extern char *codebuf; /* buffer for code section */
+extern char *s_code; /* start ... */
+extern char *e_code; /* .. and end of stored code */
+extern char *l_code; /* limit of code section */
-char *combuf; /* buffer for comments */
-char *s_com; /* start ... */
-char *e_com; /* ... and end of stored comments */
-char *l_com; /* limit of comment buffer */
+extern char *combuf; /* buffer for comments */
+extern char *s_com; /* start ... */
+extern char *e_com; /* ... and end of stored comments */
+extern char *l_com; /* limit of comment buffer */
#define token s_token
-char *tokenbuf; /* the last token scanned */
-char *s_token;
-char *e_token;
-char *l_token;
+extern char *tokenbuf; /* the last token scanned */
+extern char *s_token;
+extern char *e_token;
+extern char *l_token;
-char *in_buffer; /* input buffer */
-char *in_buffer_limit; /* the end of the input buffer */
-char *buf_ptr; /* ptr to next character to be taken from
+extern char *in_buffer; /* input buffer */
+extern char *in_buffer_limit; /* the end of the input buffer */
+extern char *buf_ptr; /* ptr to next character to be taken from
* in_buffer */
-char *buf_end; /* ptr to first after last char in in_buffer */
+extern char *buf_end; /* ptr to first after last char in in_buffer */
-char sc_buf[sc_size]; /* input text is saved here when looking for
+extern char sc_buf[sc_size]; /* input text is saved here when looking for
* the brace after an if, while, etc */
-char *save_com; /* start of the comment stored in sc_buf */
-char *sc_end; /* pointer into save_com buffer */
+extern char *save_com; /* start of the comment stored in sc_buf */
+extern char *sc_end; /* pointer into save_com buffer */
-char *bp_save; /* saved value of buf_ptr when taking input
+extern char *bp_save; /* saved value of buf_ptr when taking input
* from save_com */
-char *be_save; /* similarly saved value of buf_end */
+extern char *be_save; /* similarly saved value of buf_end */
-int found_err;
-int blanklines_after_declarations;
-int blanklines_before_blockcomments;
-int blanklines_after_procs;
-int blanklines_around_conditional_compilation;
-int swallow_optional_blanklines;
-int n_real_blanklines;
-int prefix_blankline_requested;
-int postfix_blankline_requested;
-int break_comma; /* when true and not in parens, break after a
+extern int found_err;
+extern int blanklines_after_declarations;
+extern int blanklines_before_blockcomments;
+extern int blanklines_after_procs;
+extern int blanklines_around_conditional_compilation;
+extern int swallow_optional_blanklines;
+extern int n_real_blanklines;
+extern int prefix_blankline_requested;
+extern int postfix_blankline_requested;
+extern int break_comma; /* when true and not in parens, break after a
* comma */
-int btype_2; /* when true, brace should be on same line as
+extern int btype_2; /* when true, brace should be on same line as
* if, while, etc */
-float case_ind; /* indentation level to be used for a "case
+extern float case_ind; /* indentation level to be used for a "case
* n:" */
-int code_lines; /* count of lines with code */
-int had_eof; /* set to true when input is exhausted */
-int line_no; /* the current line number. */
-int max_col; /* the maximum allowable line length */
-int verbose; /* when true, non-essential error messages are
+extern int code_lines; /* count of lines with code */
+extern int had_eof; /* set to true when input is exhausted */
+extern int line_no; /* the current line number. */
+extern int max_col; /* the maximum allowable line length */
+extern int verbose; /* when true, non-essential error messages are
* printed */
-int cuddle_else; /* true if else should cuddle up to '}' */
-int star_comment_cont; /* true iff comment continuation lines should
+extern int cuddle_else; /* true if else should cuddle up to '}' */
+extern int star_comment_cont; /* true iff comment continuation lines should
* have stars at the beginning of each line. */
-int comment_delimiter_on_blankline;
-int troff; /* true iff were generating troff input */
-int procnames_start_line; /* if true, the names of procedures
+extern int comment_delimiter_on_blankline;
+extern int troff; /* true iff were generating troff input */
+extern int procnames_start_line; /* if true, the names of procedures
* being defined get placed in column
* 1 (ie. a newline is placed between
* the type of the procedure and its
* name) */
-int proc_calls_space; /* If true, procedure calls look like:
+extern int proc_calls_space; /* If true, procedure calls look like:
* foo(bar) rather than foo (bar) */
-int format_block_comments; /* true if comments beginning with
+extern int format_block_comments; /* true if comments beginning with
* `/ * \n' are to be reformatted */
-int format_col1_comments; /* If comments which start in column 1
+extern int format_col1_comments; /* If comments which start in column 1
* are to be magically reformatted
* (just like comments that begin in
* later columns) */
-int inhibit_formatting; /* true if INDENT OFF is in effect */
-int suppress_blanklines;/* set iff following blanklines should be
+extern int inhibit_formatting; /* true if INDENT OFF is in effect */
+extern int suppress_blanklines;/* set iff following blanklines should be
* suppressed */
-int continuation_indent;/* set to the indentation between the edge of
+extern int continuation_indent;/* set to the indentation between the edge of
* code and continuation lines */
-int lineup_to_parens; /* if true, continued code within parens will
+extern int lineup_to_parens; /* if true, continued code within parens will
* be lined up to the open paren */
-int lineup_to_parens_always; /* if true, do not attempt to keep
+extern int lineup_to_parens_always; /* if true, do not attempt to keep
* lined-up code within the margin */
-int Bill_Shannon; /* true iff a blank should always be inserted
+extern int Bill_Shannon; /* true iff a blank should always be inserted
* after sizeof */
-int blanklines_after_declarations_at_proctop; /* This is vaguely
+extern int blanklines_after_declarations_at_proctop; /* This is vaguely
* similar to
* blanklines_after_decla
* rations except that
@@ -206,26 +213,28 @@ int blanklines_after_declarations_at_proctop; /* This is vaguely
* to be generated even
* if there are no
* declarations */
-int block_comment_max_col;
-int extra_expression_indent; /* true if continuation lines from the
+extern int block_comment_max_col;
+extern int extra_expression_indent; /* true if continuation lines from the
* expression part of "if(e)",
* "while(e)", "for(e;e;e)" should be
* indented an extra tab stop so that
* they don't conflict with the code
* that follows */
-int function_brace_split; /* split function declaration and
+extern int function_brace_split; /* split function declaration and
* brace onto separate lines */
-int use_tabs; /* set true to use tabs for spacing,
+extern int use_tabs; /* set true to use tabs for spacing,
* false uses all spaces */
-int auto_typedefs; /* set true to recognize identifiers
+extern int auto_typedefs; /* set true to recognize identifiers
* ending in "_t" like typedefs */
-int space_after_cast; /* "b = (int) a" vs "b = (int)a" */
-int postgres_tab_rules; /* use Postgres tab-vs-space rules */
-int tabsize; /* the size of a tab */
-int else_endif_com_ind; /* the column in which comments to
+extern int space_after_cast; /* "b = (int) a" vs "b = (int)a" */
+extern int postgres_tab_rules; /* use Postgres tab-vs-space rules */
+extern int tabsize; /* the size of a tab */
+extern int else_endif_com_ind; /* the column in which comments to
* the right of #else and #endif
* should start */
+extern int ifdef_level;
+
struct parser_state {
int last_token;
int p_stack[256]; /* this is the parsers stack */
@@ -322,8 +331,13 @@ struct parser_state {
int tos; /* pointer to top of stack */
char procname[100]; /* The name of the current procedure */
int just_saw_decl;
-} ps;
+};
-int ifdef_level;
-struct parser_state state_stack[5];
-struct parser_state match_state[5];
+extern struct parser_state ps;
+extern struct parser_state state_stack[5];
+extern struct parser_state match_state[5];
+
+/* Undo previous hackery */
+#ifdef DECLARE_INDENT_GLOBALS
+#undef extern
+#endif
--
2.20.1
|