1 /* GNU m4 -- A simple macro processor
3 Copyright (C) 1991, 1992, 1993, 1994, 2004, 2006, 2007, 2008 Free
4 Software Foundation, Inc.
6 This file is part of GNU M4.
8 GNU M4 is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU M4 is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 /* File for debugging output. */
30 /* Obstack for trace messages. */
31 static struct obstack trace
;
33 static void debug_set_file (const char *, FILE *);
35 /*----------------------------------.
36 | Initialise the debugging module. |
37 `----------------------------------*/
42 debug_set_file (NULL
, stderr
);
43 obstack_init (&trace
);
46 /*-----------------------------------------------------------------.
47 | Function to decode the debugging flags OPTS. Used by main while |
48 | processing option -d, and by the builtin debugmode (). |
49 `-----------------------------------------------------------------*/
52 debug_decode (const char *opts
)
56 if (opts
== NULL
|| *opts
== '\0')
57 level
= DEBUG_TRACE_DEFAULT
;
60 for (level
= 0; *opts
; opts
++)
65 level
|= DEBUG_TRACE_ARGS
;
69 level
|= DEBUG_TRACE_EXPANSION
;
73 level
|= DEBUG_TRACE_QUOTE
;
77 level
|= DEBUG_TRACE_ALL
;
81 level
|= DEBUG_TRACE_LINE
;
85 level
|= DEBUG_TRACE_FILE
;
89 level
|= DEBUG_TRACE_PATH
;
93 level
|= DEBUG_TRACE_CALL
;
97 level
|= DEBUG_TRACE_INPUT
;
101 level
|= DEBUG_TRACE_CALLID
;
105 level
|= DEBUG_TRACE_VERBOSE
;
116 /*------------------------------------------------------------------------.
117 | Change the debug output stream to FP. If the underlying file is the |
118 | same as stdout, use stdout instead so that debug messages appear in the |
119 | correct relative position. |
120 `------------------------------------------------------------------------*/
123 debug_set_file (const char *caller
, FILE *fp
)
125 struct stat stdout_stat
, debug_stat
;
127 if (debug
!= NULL
&& debug
!= stderr
&& debug
!= stdout
128 && close_stream (debug
) != 0)
129 m4_error (0, errno
, caller
, _("error writing to debug stream"));
132 if (debug
!= NULL
&& debug
!= stdout
)
134 if (fstat (STDOUT_FILENO
, &stdout_stat
) < 0)
136 if (fstat (fileno (debug
), &debug_stat
) < 0)
139 /* mingw has a bug where fstat on a regular file reports st_ino
140 of 0. On normal system, st_ino should never be 0. */
141 if (stdout_stat
.st_ino
== debug_stat
.st_ino
142 && stdout_stat
.st_dev
== debug_stat
.st_dev
143 && stdout_stat
.st_ino
!= 0)
145 if (debug
!= stderr
&& close_stream (debug
) != 0)
146 m4_error (0, errno
, caller
, _("error writing to debug stream"));
152 /*-----------------------------------------------------------.
153 | Serialize files. Used before executing a system command. |
154 `-----------------------------------------------------------*/
157 debug_flush_files (void)
161 if (debug
!= NULL
&& debug
!= stdout
&& debug
!= stderr
)
163 /* POSIX requires that if m4 doesn't consume all input, but stdin is
164 opened on a seekable file, that the file pointer be left at the
165 next character on exit (but places no restrictions on the file
166 pointer location on a non-seekable file). It also requires that
167 fflush() followed by fseeko() on an input file set the underlying
168 file pointer, and gnulib guarantees these semantics. However,
169 fflush() on a non-seekable file can lose buffered data, which we
170 might otherwise want to process after syscmd. Hence, we must
171 check whether stdin is seekable. We must also be tolerant of
172 operating with stdin closed, so we don't report any failures in
173 this attempt. The stdio-safer module and friends are essential,
174 so that if stdin was closed, this lseek is not on some other file
175 that we have since opened. */
176 if (lseek (STDIN_FILENO
, 0, SEEK_CUR
) >= 0
177 && fflush (stdin
) == 0)
179 fseeko (stdin
, 0, SEEK_CUR
);
183 /*-------------------------------------------------------------------.
184 | Change the debug output to file NAME. If NAME is NULL, debug |
185 | output is reverted to stderr, and if empty, debug output is |
186 | discarded. Return true iff the output stream was changed. Report |
187 | errors on behalf of CALLER. |
188 `-------------------------------------------------------------------*/
191 debug_set_output (const char *caller
, const char *name
)
196 debug_set_file (caller
, stderr
);
197 else if (*name
== '\0')
198 debug_set_file (caller
, NULL
);
201 fp
= fopen (name
, "a");
205 if (set_cloexec_flag (fileno (fp
), true) != 0)
206 m4_warn (errno
, caller
, _("cannot protect debug file across forks"));
207 debug_set_file (caller
, fp
);
212 /*-----------------------------------------------------------------------.
213 | Print the header of a one-line debug message, starting by "m4 debug". |
214 `-----------------------------------------------------------------------*/
217 debug_message_prefix (void)
219 xfprintf (debug
, "m4debug:");
222 if (debug_level
& DEBUG_TRACE_FILE
)
223 xfprintf (debug
, "%s:", current_file
);
224 if (debug_level
& DEBUG_TRACE_LINE
)
225 xfprintf (debug
, "%d:", current_line
);
230 /* The rest of this file contains the functions for macro tracing output.
231 All tracing output for a macro call is collected on an obstack TRACE,
232 and printed whenever the line is complete. This prevents tracing
233 output from interfering with other debug messages generated by the
236 /*-------------------------------------------------------------------.
237 | Tracing output to the obstack is formatted here, by a simplified |
238 | printf-like function trace_format (). Understands only %B (1 arg: |
239 | input block), %S (1 arg: length-limited text), %s (1 arg: text), |
240 | %d (1 arg: integer), %l (0 args: optional left quote) and %r (0 |
241 | args: optional right quote). |
242 `-------------------------------------------------------------------*/
245 trace_format (const char *fmt
, ...)
253 va_start (args
, fmt
);
257 while ((ch
= *fmt
++) != '\0' && ch
!= '%')
258 obstack_1grow (&trace
, ch
);
268 input_print (&trace
, va_arg (args
, input_block
*));
272 maxlen
= max_debug_argument_length
;
276 s
= va_arg (args
, const char *);
280 s
= (debug_level
& DEBUG_TRACE_QUOTE
) ? curr_quote
.str1
: "";
284 s
= (debug_level
& DEBUG_TRACE_QUOTE
) ? curr_quote
.str2
: "";
288 d
= va_arg (args
, int);
297 if (shipout_string_trunc (&trace
, s
, SIZE_MAX
, &maxlen
))
304 /*------------------------------------------------------------------.
305 | Format the standard header attached to all tracing output lines. |
306 | ID is the current macro id. |
307 `------------------------------------------------------------------*/
310 trace_header (int id
)
312 trace_format ("m4trace:");
315 if (debug_level
& DEBUG_TRACE_FILE
)
316 trace_format ("%s:", current_file
);
317 if (debug_level
& DEBUG_TRACE_LINE
)
318 trace_format ("%d:", current_line
);
320 trace_format (" -%d- ", expansion_level
);
321 if (debug_level
& DEBUG_TRACE_CALLID
)
322 trace_format ("id %d: ", id
);
325 /*----------------------------------------------------.
326 | Print current tracing line, and clear the obstack. |
327 `----------------------------------------------------*/
334 obstack_1grow (&trace
, '\0');
335 line
= (char *) obstack_finish (&trace
);
336 DEBUG_PRINT1 ("%s\n", line
);
337 obstack_free (&trace
, line
);
340 /*----------------------------------------------------------------.
341 | Do pre-argument-collection tracing for macro NAME, with a given |
342 | ID. Used from expand_macro (). |
343 `----------------------------------------------------------------*/
346 trace_prepre (const char *name
, int id
)
349 trace_format ("%s ...", name
);
353 /*-----------------------------------------------------------------.
354 | Format the parts of a trace line that are known before the macro |
355 | is actually expanded. Called for the macro NAME with ID, and |
356 | arguments ARGV. Used from expand_macro (). |
357 `-----------------------------------------------------------------*/
360 trace_pre (const char *name
, int id
, macro_arguments
*argv
)
363 trace_format ("%s", name
);
365 if (arg_argc (argv
) > 1 && (debug_level
& DEBUG_TRACE_ARGS
))
367 size_t len
= max_debug_argument_length
;
369 arg_print (&trace
, argv
, 1,
370 (debug_level
& DEBUG_TRACE_QUOTE
) ? &curr_quote
: NULL
,
371 false, ", ", &len
, true);
375 if (debug_level
& DEBUG_TRACE_CALL
)
377 trace_format (" -> ???");
382 /*-------------------------------------------------------------------.
383 | Format the final part of a trace line and print it all. Print |
384 | details for macro NAME with ID, given arguemnts ARGV and expansion |
385 | EXPANDED. Used from expand_macro (). |
386 `-------------------------------------------------------------------*/
389 trace_post (const char *name
, int id
, macro_arguments
*argv
,
390 const input_block
*expanded
)
392 int argc
= arg_argc (argv
);
394 if (debug_level
& DEBUG_TRACE_CALL
)
397 trace_format ("%s%s", name
, (argc
> 1) ? "(...)" : "");
400 if (expanded
&& (debug_level
& DEBUG_TRACE_EXPANSION
))
401 trace_format (" -> %l%B%r", expanded
);