[SV 40361] Don't use vsnprintf(), which is an ISO C99 function.

* output.c (error, fatal, message): Take an extra argument specifying
how many bytes are used by the formatted arguments.
(get_buffer): New function that allocates the requested buffer size.
Remove msc_vsnprintf(), vfmtconcat(), and fmtconcat() as unneeded.
* makeint.h: Declare various helper macros for generating output.
* *.c: Change all error(), fatal(), message() calls to use the macros,
or pass the extra length argument directly.
This commit is contained in:
Paul Smith 2013-11-23 22:23:52 -05:00
parent 9d58570c77
commit 757849cd93
22 changed files with 427 additions and 383 deletions

View file

@ -42,7 +42,7 @@ MyExecute (char **argv)
buffer = AllocMem (len, MEMF_ANY);
if (!buffer)
fatal (NILF, "MyExecute: Cannot allocate space for calling a command");
O (fatal, NILF, "MyExecute: Cannot allocate space for calling a command\n");
ptr = buffer;

16
ar.c
View file

@ -43,7 +43,7 @@ ar_name (const char *name)
return 0;
if (p[1] == '(' && end[-1] == ')')
fatal (NILF, _("attempt to use unsupported feature: '%s'"), name);
OS (fatal, NILF, _("attempt to use unsupported feature: '%s'"), name);
return 1;
}
@ -120,7 +120,7 @@ ar_member_date (const char *name)
int
ar_touch (const char *name)
{
error (NILF, _("touch archive member is not available on VMS"));
O (error, NILF, _("touch archive member is not available on VMS"));
return -1;
}
#else
@ -144,24 +144,24 @@ ar_touch (const char *name)
switch (ar_member_touch (arname, memname))
{
case -1:
error (NILF, _("touch: Archive '%s' does not exist"), arname);
OS (error, NILF, _("touch: Archive '%s' does not exist"), arname);
break;
case -2:
error (NILF, _("touch: '%s' is not a valid archive"), arname);
OS (error, NILF, _("touch: '%s' is not a valid archive"), arname);
break;
case -3:
perror_with_name ("touch: ", arname);
break;
case 1:
error (NILF,
_("touch: Member '%s' does not exist in '%s'"), memname, arname);
OSS (error, NILF,
_("touch: Member '%s' does not exist in '%s'"), memname, arname);
break;
case 0:
val = 0;
break;
default:
error (NILF,
_("touch: Bad return code from ar_member_touch on '%s'"), name);
OS (error, NILF,
_("touch: Bad return code from ar_member_touch on '%s'"), name);
}
free (arname);

View file

@ -37,7 +37,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
static void *VMS_lib_idx;
static char *VMS_saved_memname;
static const char *VMS_saved_memname;
static time_t VMS_member_date;
@ -64,8 +64,9 @@ VMS_get_member_info (struct dsc$descriptor_s *module, unsigned long *rfa)
&bufdesc.dsc$w_length, 0);
if (! (status & 1))
{
error (NILF, _("lbr$set_module() failed to extract module info, status = %d"),
status);
ON (error, NILF,
_("lbr$set_module() failed to extract module info, status = %d"),
status);
lbr$close (&VMS_lib_idx);
@ -153,9 +154,10 @@ VMS_get_member_info (struct dsc$descriptor_s *module, unsigned long *rfa)
Returns 0 if have scanned successfully. */
long int
ar_scan (const char *archive, ar_member_func_t function, const void *arg)
ar_scan (const char *archive, ar_member_func_t function, const void *varg)
{
char *p;
const char *arg = varg;
static struct dsc$descriptor_s libdesc =
{ 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL };
@ -170,7 +172,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
if (! (status & 1))
{
error (NILF, _("lbr$ini_control() failed with status = %d"), status);
ON (error, NILF, _("lbr$ini_control() failed with status = %d"), status);
return -2;
}
@ -182,12 +184,12 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
if (! (status & 1))
{
error (NILF, _("unable to open library '%s' to lookup member '%s'"),
archive, (char *)arg);
OSS (error, NILF, _("unable to open library '%s' to lookup member '%s'"),
archive, arg);
return -1;
}
VMS_saved_memname = (char *)arg;
VMS_saved_memname = arg;
/* For comparison, delete .obj from arg name. */

View file

@ -403,7 +403,7 @@ chop_commands (struct commands *cmds)
CMDS->any_recurse flag. */
if (nlines > USHRT_MAX)
fatal (&cmds->fileinfo, _("Recipe has too many lines (%ud)"), nlines);
ON (fatal, &cmds->fileinfo, _("Recipe has too many lines (%ud)"), nlines);
cmds->ncommand_lines = nlines;
cmds->command_lines = lines;
@ -627,11 +627,13 @@ delete_target (struct file *file, const char *on_behalf_of)
if (ar_member_date (file->name) != file_date)
{
if (on_behalf_of)
error (NILF, _("*** [%s] Archive member '%s' may be bogus; not deleted"),
on_behalf_of, file->name);
OSS (error, NILF,
_("*** [%s] Archive member '%s' may be bogus; not deleted"),
on_behalf_of, file->name);
else
error (NILF, _("*** Archive member '%s' may be bogus; not deleted"),
file->name);
OS (error, NILF,
_("*** Archive member '%s' may be bogus; not deleted"),
file->name);
}
return;
}
@ -643,9 +645,10 @@ delete_target (struct file *file, const char *on_behalf_of)
&& FILE_TIMESTAMP_STAT_MODTIME (file->name, st) != file->last_mtime)
{
if (on_behalf_of)
error (NILF, _("*** [%s] Deleting file '%s'"), on_behalf_of, file->name);
OSS (error, NILF,
_("*** [%s] Deleting file '%s'"), on_behalf_of, file->name);
else
error (NILF, _("*** Deleting file '%s'"), file->name);
OS (error, NILF, _("*** Deleting file '%s'"), file->name);
if (unlink (file->name) < 0
&& errno != ENOENT) /* It disappeared; so what. */
perror_with_name ("unlink: ", file->name);

2
dir.c
View file

@ -674,7 +674,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
if (d == 0)
{
if (errno)
fatal (NILF, "INTERNAL: readdir: %s\n", strerror (errno));
pfatal_with_name ("INTERNAL: readdir");
break;
}

View file

@ -121,9 +121,9 @@ recursively_expand_for_file (struct variable *v, struct file *file)
{
if (!v->exp_count)
/* Expanding V causes infinite recursion. Lose. */
fatal (*expanding_var,
_("Recursive variable '%s' references itself (eventually)"),
v->name);
OS (fatal, *expanding_var,
_("Recursive variable '%s' references itself (eventually)"),
v->name);
--v->exp_count;
}
@ -266,7 +266,7 @@ variable_expand_string (char *line, const char *string, long length)
end = strchr (beg, closeparen);
if (end == 0)
/* Unterminated variable reference. */
fatal (*expanding_var, _("unterminated variable reference"));
O (fatal, *expanding_var, _("unterminated variable reference"));
p1 = lindex (beg, end, '$');
if (p1 != 0)
{

33
file.c
View file

@ -261,22 +261,25 @@ rehash_file (struct file *from_file, const char *to_hname)
to_file->cmds = from_file->cmds;
else if (from_file->cmds != to_file->cmds)
{
size_t l = strlen (from_file->name);
/* We have two sets of commands. We will go with the
one given in the rule explicitly mentioning this name,
but give a message to let the user know what's going on. */
if (to_file->cmds->fileinfo.filenm != 0)
error (&from_file->cmds->fileinfo,
l + strlen (to_file->cmds->fileinfo.filenm) + INTSTR_LENGTH,
_("Recipe was specified for file '%s' at %s:%lu,"),
from_file->name, to_file->cmds->fileinfo.filenm,
to_file->cmds->fileinfo.lineno);
else
error (&from_file->cmds->fileinfo,
error (&from_file->cmds->fileinfo, l,
_("Recipe for file '%s' was found by implicit rule search,"),
from_file->name);
error (&from_file->cmds->fileinfo,
l += strlen (to_hname);
error (&from_file->cmds->fileinfo, l,
_("but '%s' is now considered the same file as '%s'."),
from_file->name, to_hname);
error (&from_file->cmds->fileinfo,
error (&from_file->cmds->fileinfo, l,
_("Recipe for '%s' will be ignored in favor of the one for '%s'."),
to_hname, from_file->name);
}
@ -297,13 +300,14 @@ rehash_file (struct file *from_file, const char *to_hname)
merge_variable_set_lists (&to_file->variables, from_file->variables);
if (to_file->double_colon && from_file->is_target && !from_file->double_colon)
fatal (NILF, _("can't rename single-colon '%s' to double-colon '%s'"),
from_file->name, to_hname);
OSS (fatal, NILF, _("can't rename single-colon '%s' to double-colon '%s'"),
from_file->name, to_hname);
if (!to_file->double_colon && from_file->double_colon)
{
if (to_file->is_target)
fatal (NILF, _("can't rename double-colon '%s' to single-colon '%s'"),
from_file->name, to_hname);
OSS (fatal, NILF,
_("can't rename double-colon '%s' to single-colon '%s'"),
from_file->name, to_hname);
else
to_file->double_colon = from_file->double_colon;
}
@ -393,7 +397,8 @@ remove_intermediates (int sig)
if (!f->dontcare)
{
if (sig)
error (NILF, _("*** Deleting intermediate file '%s'"), f->name);
OS (error, NILF,
_("*** Deleting intermediate file '%s'"), f->name);
else
{
if (! doneany)
@ -803,10 +808,11 @@ file_timestamp_cons (const char *fname, time_t stamp, long int ns)
&& product <= ts && ts <= ORDINARY_MTIME_MAX))
{
char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
const char *f = fname ? fname : _("Current time");
ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX;
file_timestamp_sprintf (buf, ts);
error (NILF, _("%s: Timestamp out of range; substituting %s"),
fname ? fname : _("Current time"), buf);
OSS (error, NILF,
_("%s: Timestamp out of range; substituting %s"), f, buf);
}
return ts;
@ -1046,9 +1052,10 @@ print_file_data_base (void)
/* Verify the integrity of the data base of files. */
#define VERIFY_CACHED(_p,_n) \
do{\
if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \
error (NULL, _("%s: Field '%s' not cached: %s"), _p->name, # _n, _p->_n); \
do{ \
if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \
error (NULL, strlen (_p->name) + CSTRLEN (# _n) + strlen (_p->_n), \
_("%s: Field '%s' not cached: %s"), _p->name, # _n, _p->_n); \
}while(0)
static void

View file

@ -726,7 +726,7 @@ check_numeric (const char *s, const char *msg)
break;
if (s <= end || end - beg < 0)
fatal (*expanding_var, "%s: '%s'", msg, beg);
OSS (fatal, *expanding_var, "%s: '%s'", msg, beg);
}
@ -743,8 +743,8 @@ func_word (char *o, char **argv, const char *funcname UNUSED)
i = atoi (argv[0]);
if (i == 0)
fatal (*expanding_var,
_("first argument to 'word' function must be greater than 0"));
O (fatal, *expanding_var,
_("first argument to 'word' function must be greater than 0"));
end_p = argv[1];
while ((p = find_next_token (&end_p, 0)) != 0)
@ -770,8 +770,8 @@ func_wordlist (char *o, char **argv, const char *funcname UNUSED)
start = atoi (argv[0]);
if (start < 1)
fatal (*expanding_var,
"invalid first argument to 'wordlist' function: '%d'", start);
ON (fatal, *expanding_var,
"invalid first argument to 'wordlist' function: '%d'", start);
count = atoi (argv[1]) - start + 1;
@ -1082,10 +1082,10 @@ func_error (char *o, char **argv, const char *funcname)
switch (*funcname)
{
case 'e':
fatal (reading_file, "%s", msg);
OS (fatal, reading_file, "%s", msg);
case 'w':
error (reading_file, "%s", msg);
OS (error, reading_file, "%s", msg);
break;
case 'i':
@ -1094,7 +1094,7 @@ func_error (char *o, char **argv, const char *funcname)
break;
default:
fatal (*expanding_var, "Internal error: func_error: '%s'", funcname);
OS (fatal, *expanding_var, "Internal error: func_error: '%s'", funcname);
}
/* The warning function expands to the empty string. */
@ -1457,7 +1457,8 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
}
if (hIn == INVALID_HANDLE_VALUE)
{
error (NILF, _("windows32_openpipe: DuplicateHandle(In) failed (e=%ld)\n"), e);
ON (error, NILF,
_("windows32_openpipe: DuplicateHandle(In) failed (e=%ld)\n"), e);
return -1;
}
}
@ -1480,14 +1481,15 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
}
if (hErr == INVALID_HANDLE_VALUE)
{
error (NILF, _("windows32_openpipe: DuplicateHandle(Err) failed (e=%ld)\n"), e);
ON (error, NILF,
_("windows32_openpipe: DuplicateHandle(Err) failed (e=%ld)\n"), e);
return -1;
}
}
if (! CreatePipe (&hChildOutRd, &hChildOutWr, &saAttr, 0))
{
error (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
ON (error, NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
return -1;
}
@ -1495,7 +1497,7 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
if (!hProcess)
{
error (NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
O (error, NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
return -1;
}
@ -2007,7 +2009,7 @@ abspath (const char *name, char *apath)
{
#if defined(__CYGWIN__) && defined(HAVE_DOS_PATHS)
if (STOP_SET (name[0], MAP_PATHSEP))
root_len = 1;
root_len = 1;
#endif
strncpy (apath, name, root_len);
apath[root_len] = '\0';
@ -2148,20 +2150,25 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
fp = fopen (fn, mode);
if (fp == NULL)
fatal (reading_file, _("open: %s: %s"), fn, strerror (errno));
{
const char *err = strerror (errno);
OSS (fatal, reading_file, _("open: %s: %s"), fn, err);
}
else
{
int l = strlen (argv[1]);
int nl = (l == 0 || argv[1][l-1] != '\n');
if (fputs (argv[1], fp) == EOF || (nl && fputc ('\n', fp) == EOF))
fatal (reading_file, _("write: %s: %s"), fn, strerror (errno));
{
const char *err = strerror (errno);
OSS (fatal, reading_file, _("write: %s: %s"), fn, err);
}
fclose (fp);
}
}
else
fatal (reading_file, _("Invalid file operation: %s"), fn);
OS (fatal, reading_file, _("Invalid file operation: %s"), fn);
return o;
}
@ -2275,7 +2282,7 @@ expand_builtin_function (char *o, int argc, char **argv,
char *p;
if (argc < (int)entry_p->minimum_args)
fatal (*expanding_var,
fatal (*expanding_var, strlen (entry_p->name),
_("insufficient number of arguments (%d) to function '%s'"),
argc, entry_p->name);
@ -2287,8 +2294,8 @@ expand_builtin_function (char *o, int argc, char **argv,
return o;
if (!entry_p->fptr.func_ptr)
fatal (*expanding_var,
_("unimplemented on this platform: function '%s'"), entry_p->name);
OS (fatal, *expanding_var,
_("unimplemented on this platform: function '%s'"), entry_p->name);
if (!entry_p->alloc_fn)
return entry_p->fptr.func_ptr (o, argv, entry_p->name);
@ -2350,7 +2357,7 @@ handle_function (char **op, const char **stringp)
break;
if (count >= 0)
fatal (*expanding_var,
fatal (*expanding_var, strlen (entry_p->name),
_("unterminated call to function '%s': missing '%c'"),
entry_p->name, closeparen);
@ -2543,17 +2550,17 @@ define_new_function (const gmk_floc *flocp, const char *name,
len = e - name;
if (len == 0)
fatal (flocp, _("Empty function name\n"));
O (fatal, flocp, _("Empty function name"));
if (*name == '.' || *e != '\0')
fatal (flocp, _("Invalid function name: %s\n"), name);
OS (fatal, flocp, _("Invalid function name: %s"), name);
if (len > 255)
fatal (flocp, _("Function name too long: %s\n"), name);
OS (fatal, flocp, _("Function name too long: %s"), name);
if (min > 255)
fatal (flocp, _("Invalid minimum argument count (%d) for function %s\n"),
min, name);
ONS (fatal, flocp,
_("Invalid minimum argument count (%d) for function %s"), min, name);
if (max > 255 || (max && max < min))
fatal (flocp, _("Invalid maximum argument count (%d) for function %s\n"),
max, name);
ONS (fatal, flocp,
_("Invalid maximum argument count (%d) for function %s"), max, name);
ent = xmalloc (sizeof (struct function_table_entry));
ent->name = name;

72
job.c
View file

@ -359,7 +359,7 @@ create_batch_file (char const *base, int unixy, int *fd)
*fd = -1;
if (error_string == NULL)
error_string = _("Cannot create a temporary file\n");
fatal (NILF, error_string);
O (fatal, NILF, error_string);
/* not reached */
return NULL;
@ -474,6 +474,7 @@ child_error (struct child *child,
const struct file *f = child->file;
const gmk_floc *flocp = &f->cmds->fileinfo;
const char *nm;
size_t l = strlen (f->name);
if (ignored && silent_flag)
return;
@ -498,7 +499,10 @@ child_error (struct child *child,
OUTPUT_SET (&child->output);
message (0, _("%s: recipe for target '%s' failed"), nm, f->name);
message (0, l + strlen (nm),
_("%s: recipe for target '%s' failed"), nm, f->name);
l += strlen (pre) + strlen (post);
#ifdef VMS
if ((exit_code & 1) != 0)
@ -507,14 +511,17 @@ child_error (struct child *child,
return;
}
error (NILF, _("%s[%s] Error 0x%x%s"), pre, f->name, exit_code, post);
error (NILF, l + INTSTR_LENGTH,
_("%s[%s] Error 0x%x%s"), pre, f->name, exit_code, post);
#else
if (exit_sig == 0)
error (NILF, _("%s[%s] Error %d%s"), pre, f->name, exit_code, post);
error (NILF, l + INTSTR_LENGTH,
_("%s[%s] Error %d%s"), pre, f->name, exit_code, post);
else
{
const char *s = strsignal (exit_sig);
error (NILF, _("%s[%s] %s%s%s"), pre, f->name, s, dump, post);
error (NILF, l + strlen (s) + strlen (dump),
_("%s[%s] %s%s%s"), pre, f->name, s, dump, post);
}
#endif /* VMS */
@ -606,7 +613,7 @@ reap_children (int block, int err)
Only print this message once no matter how many jobs are left. */
fflush (stdout);
if (!printed)
error (NILF, _("*** Waiting for unfinished jobs...."));
O (error, NILF, _("*** Waiting for unfinished jobs...."));
printed = 1;
}
@ -992,8 +999,8 @@ free_child (struct child *child)
output_close (&child->output);
if (!jobserver_tokens)
fatal (NILF, "INTERNAL: Freeing child %p (%s) but no tokens left!\n",
child, child->file->name);
ONS (fatal, NILF, "INTERNAL: Freeing child %p (%s) but no tokens left!\n",
child, child->file->name);
/* If we're using the jobserver and this child is not the only outstanding
job, put a token back into the pipe for it. */
@ -1004,8 +1011,9 @@ free_child (struct child *child)
if (! release_jobserver_semaphore ())
{
DWORD err = GetLastError ();
fatal (NILF, _("release jobserver semaphore: (Error %ld: %s)"),
err, map_windows32_error_to_string (err));
const char *estr = map_windows32_error_to_string (err);
OSN (fatal, NILF,
_("release jobserver semaphore: (Error %ld: %s)"), err, estr);
}
DB (DB_JOBS, (_("Released token for child %p (%s).\n"), child, child->file->name));
@ -1277,7 +1285,7 @@ start_job_command (struct child *child)
/* Print the command if appropriate. */
if (just_print_flag || trace_flag
|| (!(flags & COMMANDS_SILENT) && !silent_flag))
message (0, "%s", p);
OS (message, 0, "%s", p);
/* Tell update_goal_chain that a command has been started on behalf of
this target. It is important that this happens here and not in
@ -1940,7 +1948,7 @@ new_job (struct file *file)
/* There must be at least one child already, or we have no business
waiting for a token. */
if (!children)
fatal (NILF, "INTERNAL: no children as we go to sleep on read\n");
O (fatal, NILF, "INTERNAL: no children as we go to sleep on read\n");
#ifdef WINDOWS32
/* On Windows we simply wait for the jobserver semaphore to become
@ -1950,8 +1958,10 @@ new_job (struct file *file)
if (got_token < 0)
{
DWORD err = GetLastError ();
fatal (NILF, _("semaphore or child process wait: (Error %ld: %s)"),
err, map_windows32_error_to_string (err));
const char *estr = map_windows32_error_to_string (err);
OSN (fatal, NILF,
_("semaphore or child process wait: (Error %ld: %s)"),
err, estr);
}
#else
/* Set interruptible system calls, and read() for a job token. */
@ -2000,10 +2010,11 @@ new_job (struct file *file)
}
if (newer[0] == '\0')
message (0, _("%s: target '%s' does not exist"), nm, c->file->name);
OSS (message, 0,
_("%s: target '%s' does not exist"), nm, c->file->name);
else
message (0, _("%s: update target '%s' due to: %s"), nm,
c->file->name, newer);
OSSS (message, 0,
_("%s: update target '%s' due to: %s"), nm, c->file->name, newer);
free (newer);
}
@ -2114,8 +2125,8 @@ load_too_high (void)
{
if (errno == 0)
/* An errno value of zero means getloadavg is just unsupported. */
error (NILF,
_("cannot enforce load limits on this operating system"));
O (error, NILF,
_("cannot enforce load limits on this operating system"));
else
perror_with_name (_("cannot enforce load limit: "), "getloadavg");
}
@ -2196,7 +2207,7 @@ child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
{
save_stdin = dup (FD_STDIN);
if (save_stdin < 0)
fatal (NILF, _("no more file handles: could not duplicate stdin\n"));
O (fatal, NILF, _("no more file handles: could not duplicate stdin\n"));
CLOSE_ON_EXEC (save_stdin);
dup2 (stdin_fd, FD_STDIN);
@ -2207,7 +2218,8 @@ child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
{
save_stdout = dup (FD_STDOUT);
if (save_stdout < 0)
fatal (NILF, _("no more file handles: could not duplicate stdout\n"));
O (fatal, NILF,
_("no more file handles: could not duplicate stdout\n"));
CLOSE_ON_EXEC (save_stdout);
dup2 (stdout_fd, FD_STDOUT);
@ -2220,7 +2232,8 @@ child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
{
save_stderr = dup (FD_STDERR);
if (save_stderr < 0)
fatal (NILF, _("no more file handles: could not duplicate stderr\n"));
O (fatal, NILF,
_("no more file handles: could not duplicate stderr\n"));
CLOSE_ON_EXEC (save_stderr);
}
@ -2235,7 +2248,7 @@ child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
if (save_stdin >= 0)
{
if (dup2 (save_stdin, FD_STDIN) != FD_STDIN)
fatal (NILF, _("Could not restore stdin\n"));
O (fatal, NILF, _("Could not restore stdin\n"));
else
close (save_stdin);
}
@ -2243,7 +2256,7 @@ child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
if (save_stdout >= 0)
{
if (dup2 (save_stdout, FD_STDOUT) != FD_STDOUT)
fatal (NILF, _("Could not restore stdout\n"));
O (fatal, NILF, _("Could not restore stdout\n"));
else
close (save_stdout);
}
@ -2251,7 +2264,7 @@ child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
if (save_stderr >= 0)
{
if (dup2 (save_stderr, FD_STDERR) != FD_STDERR)
fatal (NILF, _("Could not restore stderr\n"));
O (fatal, NILF, _("Could not restore stderr\n"));
else
close (save_stderr);
}
@ -2400,7 +2413,7 @@ exec_command (char **argv, char **envp)
switch (errno)
{
case ENOENT:
error (NILF, _("%s: Command not found"), argv[0]);
OS (error, NILF, _("%s: Command not found"), argv[0]);
break;
case ENOEXEC:
{
@ -2460,7 +2473,7 @@ exec_command (char **argv, char **envp)
execvp (shell, new_argv);
# endif
if (errno == ENOENT)
error (NILF, _("%s: Shell program not found"), shell);
OS (error, NILF, _("%s: Shell program not found"), shell);
else
perror_with_name ("execvp: ", shell);
break;
@ -2469,7 +2482,7 @@ exec_command (char **argv, char **envp)
# ifdef __EMX__
case EINVAL:
/* this nasty error was driving me nuts :-( */
error (NILF, _("spawnvpe: environment space might be exhausted"));
O (error, NILF, _("spawnvpe: environment space might be exhausted"));
/* FALLTHROUGH */
# endif
@ -3441,7 +3454,8 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
}
#else
else
fatal (NILF, _("%s (line %d) Bad shell context (!unixy && !batch_mode_shell)\n"),
fatal (NILF, CSTRLEN (__FILE__) + INTSTR_LENGTH,
_("%s (line %d) Bad shell context (!unixy && !batch_mode_shell)\n"),
__FILE__, __LINE__);
#endif

4
job.h
View file

@ -39,8 +39,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef NO_OUTPUT_SYNC
# define RECORD_SYNC_MUTEX(m) \
error (NILF, \
_("-O[TYPE] (--output-sync[=TYPE]) is not configured for this build."));
O (error, NILF, \
_("-O[TYPE] (--output-sync[=TYPE]) is not configured for this build."));
#else
# ifdef WINDOWS32
/* For emulations in w32/compat/posixfcn.c. */

29
load.c
View file

@ -50,7 +50,10 @@ load_object (const gmk_floc *flocp, int noerror,
{
global_dl = dlopen (NULL, RTLD_NOW|RTLD_GLOBAL);
if (! global_dl)
fatal (flocp, _("Failed to open global symbol table: %s"), dlerror ());
{
const char *err = dlerror ();
OS (fatal, flocp, _("Failed to open global symbol table: %s"), err);
}
}
symp = (load_func_t) dlsym (global_dl, symname);
@ -74,23 +77,28 @@ load_object (const gmk_floc *flocp, int noerror,
/* Still no? Then fail. */
if (! dlp)
{
const char *err = dlerror ();
if (noerror)
DB (DB_BASIC, ("%s", dlerror ()));
DB (DB_BASIC, ("%s", err));
else
error (flocp, "%s", dlerror ());
OS (error, flocp, "%s", err);
return NULL;
}
/* Assert that the GPL license symbol is defined. */
symp = (load_func_t) dlsym (dlp, "plugin_is_GPL_compatible");
if (! symp)
fatal (flocp, _("Loaded object %s is not declared to be GPL compatible"),
ldname);
OS (fatal, flocp,
_("Loaded object %s is not declared to be GPL compatible"),
ldname);
symp = (load_func_t) dlsym (dlp, symname);
if (! symp)
fatal (flocp, _("Failed to load symbol %s from %s: %s"),
symname, ldname, dlerror ());
{
const char *err = dlerror ();
OSSS (fatal, flocp, _("Failed to load symbol %s from %s: %s"),
symname, ldname, err);
}
/* Add this symbol to a trivial lookup table. This is not efficient but
it's highly unlikely we'll be loading lots of objects, and we only
@ -133,7 +141,7 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
++fp;
if (fp == ep)
fatal (flocp, _("Empty symbol name for load: %s"), *ldname);
OS (fatal, flocp, _("Empty symbol name for load: %s"), *ldname);
/* Make a copy of the ldname part. */
memcpy (new, *ldname, l);
@ -226,7 +234,8 @@ int
load_file (const gmk_floc *flocp, const char **ldname, int noerror)
{
if (! noerror)
fatal (flocp, _("The 'load' operation is not supported on this platform."));
O (fatal, flocp,
_("The 'load' operation is not supported on this platform."));
return 0;
}
@ -234,7 +243,7 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
void
unload_file (const char *name)
{
fatal (NILF, "INTERNAL: Cannot unload when load is not supported!");
O (fatal, NILF, "INTERNAL: Cannot unload when load is not supported!");
}
#endif /* MAKE_LOAD */

101
main.c
View file

@ -644,7 +644,7 @@ expand_command_line_file (char *name)
char *expanded = 0;
if (name[0] == '\0')
fatal (NILF, _("empty string invalid as file name"));
O (fatal, NILF, _("empty string invalid as file name"));
if (name[0] == '~')
{
@ -731,7 +731,8 @@ decode_debug_flags (void)
db_level |= DB_BASIC | DB_VERBOSE;
break;
default:
fatal (NILF, _("unknown debug level specification '%s'"), p);
OS (fatal, NILF,
_("unknown debug level specification '%s'"), p);
}
while (*(++p) != '\0')
@ -774,7 +775,7 @@ decode_output_sync_flags (void)
else if (streq (p, "recurse"))
output_sync = OUTPUT_SYNC_RECURSE;
else
fatal (NILF, _("unknown output-sync type '%s'"), p);
OS (fatal, NILF, _("unknown output-sync type '%s'"), p);
}
if (sync_mutex)
@ -784,7 +785,7 @@ decode_output_sync_flags (void)
for (idx = 1; idx < sync_mutex->idx; idx++)
if (!streq (sync_mutex->list[0], sync_mutex->list[idx]))
fatal (NILF, _("internal error: multiple --sync-mutex options"));
O (fatal, NILF, _("internal error: multiple --sync-mutex options"));
/* Now parse the mutex handle string. */
mp = sync_mutex->list[0];
@ -1238,7 +1239,7 @@ main (int argc, char **argv, char **envp)
#ifdef HAVE_GETCWD
perror_with_name ("getcwd", "");
#else
error (NILF, "getwd: %s", current_directory);
OS (error, NILF, "getwd: %s", current_directory);
#endif
current_directory[0] = '\0';
directory_before_chdir = 0;
@ -1530,7 +1531,8 @@ main (int argc, char **argv, char **envp)
for (ui=1; ui < jobserver_fds->idx; ++ui)
if (!streq (jobserver_fds->list[0], jobserver_fds->list[ui]))
fatal (NILF, _("internal error: multiple --jobserver-fds options"));
O (fatal, NILF,
_("internal error: multiple --jobserver-fds options"));
/* Now parse the fds string and make sure it has the proper format. */
@ -1540,14 +1542,16 @@ main (int argc, char **argv, char **envp)
if (! open_jobserver_semaphore (cp))
{
DWORD err = GetLastError ();
fatal (NILF, _("internal error: unable to open jobserver semaphore '%s': (Error %ld: %s)"),
cp, err, map_windows32_error_to_string (err));
const char *estr = map_windows32_error_to_string (err);
fatal (NILF, strlen (cp) + INTSTR_LENGTH + strlen (estr),
_("internal error: unable to open jobserver semaphore '%s': (Error %ld: %s)"),
cp, err, estr);
}
DB (DB_JOBS, (_("Jobserver client (semaphore %s)\n"), cp));
#else
if (sscanf (cp, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
fatal (NILF,
_("internal error: invalid --jobserver-fds string '%s'"), cp);
OS (fatal, NILF,
_("internal error: invalid --jobserver-fds string '%s'"), cp);
DB (DB_JOBS,
(_("Jobserver client (fds %d,%d)\n"), job_fds[0], job_fds[1]));
@ -1563,7 +1567,8 @@ main (int argc, char **argv, char **envp)
if (job_slots > 0)
{
if (! restarts)
error (NILF, _("warning: -jN forced in submake: disabling jobserver mode."));
O (error, NILF,
_("warning: -jN forced in submake: disabling jobserver mode."));
}
#ifndef WINDOWS32
#ifdef HAVE_FCNTL
@ -1581,8 +1586,8 @@ main (int argc, char **argv, char **envp)
if (errno != EBADF)
pfatal_with_name (_("dup jobserver"));
error (NILF,
_("warning: jobserver unavailable: using -j1. Add '+' to parent make rule."));
O (error, NILF,
_("warning: jobserver unavailable: using -j1. Add '+' to parent make rule."));
job_slots = 1;
job_fds[0] = job_fds[1] = -1;
}
@ -1723,7 +1728,7 @@ main (int argc, char **argv, char **envp)
#ifdef HAVE_GETCWD
perror_with_name ("getcwd", "");
#else
error (NILF, "getwd: %s", current_directory);
OS (error, NILF, "getwd: %s", current_directory);
#endif
starting_directory = 0;
}
@ -1748,7 +1753,8 @@ main (int argc, char **argv, char **envp)
char *template, *tmpdir;
if (stdin_nm)
fatal (NILF, _("Makefile from standard input specified twice."));
O (fatal, NILF,
_("Makefile from standard input specified twice."));
#ifdef VMS
# define DEFAULT_TMPDIR "sys$scratch:"
@ -1979,9 +1985,9 @@ main (int argc, char **argv, char **envp)
# endif
)
{
error (NILF,
_("Parallel jobs (-j) are not supported on this platform."));
error (NILF, _("Resetting to single job (-j1) mode."));
O (error, NILF,
_("Parallel jobs (-j) are not supported on this platform."));
O (error, NILF, _("Resetting to single job (-j1) mode."));
job_slots = 1;
}
#endif
@ -2008,8 +2014,9 @@ main (int argc, char **argv, char **envp)
if (! create_jobserver_semaphore (job_slots - 1))
{
DWORD err = GetLastError ();
fatal (NILF, _("creating jobserver semaphore: (Error %ld: %s)"),
err, map_windows32_error_to_string (err));
const char *estr = map_windows32_error_to_string (err);
OSN (fatal, NILF,
_("creating jobserver semaphore: (Error %ld: %s)"), err, estr);
}
#else
char c = '+';
@ -2061,7 +2068,7 @@ main (int argc, char **argv, char **envp)
#ifndef MAKE_SYMLINKS
if (check_symlink_flag)
{
error (NILF, _("Symbolic links not supported: disabling -L."));
O (error, NILF, _("Symbolic links not supported: disabling -L."));
check_symlink_flag = 0;
}
#endif
@ -2250,8 +2257,8 @@ main (int argc, char **argv, char **envp)
FILE_TIMESTAMP mtime;
/* The update failed and this makefile was not
from the MAKEFILES variable, so we care. */
error (NILF, _("Failed to remake makefile '%s'."),
d->file->name);
OS (error, NILF, _("Failed to remake makefile '%s'."),
d->file->name);
mtime = file_mtime_no_search (d->file);
any_remade |= (mtime != NONEXISTENT_MTIME
&& mtime != makefile_mtimes[i]);
@ -2262,18 +2269,20 @@ main (int argc, char **argv, char **envp)
/* This makefile was not found at all. */
if (! (d->changed & RM_DONTCARE))
{
const char *dnm = dep_name (d);
size_t l = strlen (dnm);
/* This is a makefile we care about. See how much. */
if (d->changed & RM_INCLUDED)
/* An included makefile. We don't need
to die, but we do want to complain. */
error (NILF,
_("Included makefile '%s' was not found."),
dep_name (d));
/* An included makefile. We don't need to die, but we
do want to complain. */
error (NILF, l,
_("Included makefile '%s' was not found."), dnm);
else
{
/* A normal makefile. We must die later. */
error (NILF, _("Makefile '%s' was not found"),
dep_name (d));
error (NILF, l,
_("Makefile '%s' was not found"), dnm);
any_failed = 1;
}
}
@ -2338,7 +2347,8 @@ main (int argc, char **argv, char **envp)
bad = 0;
}
if (bad)
fatal (NILF, _("Couldn't change back to original directory."));
O (fatal, NILF,
_("Couldn't change back to original directory."));
}
++restarts;
@ -2492,7 +2502,8 @@ main (int argc, char **argv, char **envp)
{
/* .DEFAULT_GOAL should contain one target. */
if (ns->next != 0)
fatal (NILF, _(".DEFAULT_GOAL contains more than one target"));
O (fatal, NILF,
_(".DEFAULT_GOAL contains more than one target"));
f = enter_file (strcache_add (ns->name));
@ -2515,9 +2526,9 @@ main (int argc, char **argv, char **envp)
if (!goals)
{
if (read_files == 0)
fatal (NILF, _("No targets specified and no makefile found"));
O (fatal, NILF, _("No targets specified and no makefile found"));
fatal (NILF, _("No targets"));
O (fatal, NILF, _("No targets"));
}
/* Update the goals. */
@ -2546,8 +2557,8 @@ main (int argc, char **argv, char **envp)
/* If we detected some clock skew, generate one last warning */
if (clock_skew_detected)
error (NILF,
_("warning: Clock skew detected. Your build may be incomplete."));
O (error, NILF,
_("warning: Clock skew detected. Your build may be incomplete."));
/* Exit. */
die (makefile_status);
@ -2807,7 +2818,8 @@ decode_switches (int argc, char **argv, int env)
else
op = cs->long_name;
error (NILF, _("the '%s%s' option requires a non-empty string argument"),
error (NILF, strlen (op),
_("the '%s%s' option requires a non-empty string argument"),
short_option (cs->c) ? "-" : "--", op);
bad = 1;
}
@ -2861,7 +2873,8 @@ decode_switches (int argc, char **argv, int env)
if (i < 1 || cp[0] != '\0')
{
error (NILF, _("the '-%c' option requires a positive integer argument"),
error (NILF, 0,
_("the '-%c' option requires a positive integer argument"),
cs->c);
bad = 1;
}
@ -3314,9 +3327,9 @@ clean_jobserver (int status)
#endif
{
if (status != 2)
error (NILF,
"INTERNAL: Exiting with %u jobserver tokens (should be 0)!",
jobserver_tokens);
ON (error, NILF,
"INTERNAL: Exiting with %u jobserver tokens (should be 0)!",
jobserver_tokens);
else
/* Don't write back the "free" token */
while (--jobserver_tokens)
@ -3354,9 +3367,9 @@ clean_jobserver (int status)
#endif
if (tcnt != master_job_slots)
error (NILF,
"INTERNAL: Exiting with %u jobserver tokens available; should be %u!",
tcnt, master_job_slots);
ONN (error, NILF,
"INTERNAL: Exiting with %u jobserver tokens available; should be %u!",
tcnt, master_job_slots);
#ifdef WINDOWS32
free_jobserver_semaphore ();

View file

@ -56,12 +56,6 @@ char *alloca ();
#endif
#include "gnumake.h"
/* Force MinGW64 to use a replacement for MS broken vsnprintf
implementation. */
#ifdef __MINGW64_VERSION_MAJOR
# define __USE_MINGW_ANSI_STDIO 1
#endif
#ifdef CRAY
/* This must happen before #include <signal.h> so
that the declaration therein is changed. */
@ -179,9 +173,6 @@ unsigned int get_path_max (void);
(! INTEGER_TYPE_SIGNED (t) ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))
#define INTEGER_TYPE_MAXIMUM(t) (~ (t) 0 - INTEGER_TYPE_MINIMUM (t))
/* The maximum number of digits needed to represent the largest integer. */
#define INTEGER_LENGTH sizeof("18446744073709551616")
#ifndef CHAR_MAX
# define CHAR_MAX INTEGER_TYPE_MAXIMUM (char)
#endif
@ -427,17 +418,36 @@ extern struct rlimit stack_limit;
#define NILF ((gmk_floc *)0)
#define CSTRLEN(_s) (sizeof (_s)-1)
#define CSTRLEN(_s) (sizeof (_s)-1)
#define STRING_SIZE_TUPLE(_s) (_s), CSTRLEN(_s)
/* The number of bytes needed to represent the largest integer as a string. */
#define INTSTR_LENGTH CSTRLEN ("18446744073709551616")
const char *concat (unsigned int, ...);
void message (int prefix, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
void error (const gmk_floc *flocp, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
void fatal (const gmk_floc *flocp, const char *fmt, ...)
__attribute__ ((noreturn, __format__ (__printf__, 2, 3)));
void message (int prefix, size_t length, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
void error (const gmk_floc *flocp, size_t length, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
void fatal (const gmk_floc *flocp, size_t length, const char *fmt, ...)
__attribute__ ((noreturn, __format__ (__printf__, 3, 4)));
#define O(_t,_a,_f) _t((_a), 0, (_f))
#define OS(_t,_a,_f,_s) _t((_a), strlen (_s), (_f), (_s))
#define OSS(_t,_a,_f,_s1,_s2) _t((_a), strlen (_s1) + strlen (_s2), \
(_f), (_s1), (_s2))
#define OSSS(_t,_a,_f,_s1,_s2,_s3) _t((_a), strlen (_s1) + strlen (_s2) + strlen (_s3), \
(_f), (_s1), (_s2), (_s3))
#define ON(_t,_a,_f,_n) _t((_a), INTSTR_LENGTH, (_f), (_n))
#define ONN(_t,_a,_f,_n1,_n2) _t((_a), INTSTR_LENGTH*2, (_f), (_n1), (_n2))
#define OSN(_t,_a,_f,_s,_n) _t((_a), strlen (_s) + INTSTR_LENGTH, \
(_f), (_s), (_n))
#define ONS(_t,_a,_f,_n,_s) _t((_a), INTSTR_LENGTH + strlen (_s), \
(_f), (_n), (_s))
#define OUT_OF_MEM() O (fatal, NILF, _("virtual memory exhausted"))
void die (int) __attribute__ ((noreturn));
void pfatal_with_name (const char *) __attribute__ ((noreturn));

10
misc.c
View file

@ -219,7 +219,7 @@ xmalloc (unsigned int size)
/* Make sure we don't allocate 0, for pre-ISO implementations. */
void *result = malloc (size ? size : 1);
if (result == 0)
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
return result;
}
@ -230,7 +230,7 @@ xcalloc (unsigned int size)
/* Make sure we don't allocate 0, for pre-ISO implementations. */
void *result = calloc (size ? size : 1, 1);
if (result == 0)
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
return result;
}
@ -245,7 +245,7 @@ xrealloc (void *ptr, unsigned int size)
size = 1;
result = ptr ? realloc (ptr, size) : malloc (size);
if (result == 0)
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
return result;
}
@ -262,7 +262,7 @@ xstrdup (const char *ptr)
#endif
if (result == 0)
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
#ifdef HAVE_STRDUP
return result;
@ -281,7 +281,7 @@ xstrndup (const char *str, unsigned int length)
#ifdef HAVE_STRNDUP
result = strndup (str, length);
if (result == 0)
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
#else
result = xmalloc (length + 1);
if (length > 0)

153
output.c
View file

@ -47,33 +47,9 @@ unsigned int stdio_traced = 0;
#define OUTPUT_ISSET(_out) ((_out)->out >= 0 || (_out)->err >= 0)
#ifdef HAVE_FCNTL
# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
#else
# define STREAM_OK(_s) 1
#endif
/* I really want to move to gnulib. However, this is a big undertaking
especially for non-UNIX platforms: how to get bootstrapping to work, etc.
I don't want to take the time to do it right now. Use a hack to get a
useful version of vsnprintf() for Windows. */
#ifdef __VMS
# define va_copy(_d, _s) ((_d) = (_s))
#endif
#ifdef _MSC_VER
# define va_copy(_d, _s) ((_d) = (_s))
# define vsnprintf msc_vsnprintf
static int
msc_vsnprintf (char *str, size_t size, const char *format, va_list ap)
{
int len = -1;
if (size > 0)
len = _vsnprintf_s (str, size, _TRUNCATE, format, ap);
if (len == -1)
len = _vscprintf (format, ap);
return len;
}
# define STREAM_OK(_s) 1
#endif
/* Write a string to the current STDOUT or STDERR. */
@ -117,7 +93,7 @@ log_working_directory (int entering)
char *p;
/* Get enough space for the longest possible output. */
need = strlen (program) + INTEGER_LENGTH + 2 + 1;
need = strlen (program) + INTSTR_LENGTH + 2 + 1;
if (starting_directory)
need += strlen (starting_directory);
@ -512,9 +488,9 @@ close_stdout (void)
if (prev_fail || fclose_fail)
{
if (fclose_fail)
error (NILF, _("write error: %s"), strerror (errno));
perror_with_name (_("write error: stdout"), "");
else
error (NILF, _("write error"));
O (error, NILF, _("write error: stdout"));
exit (EXIT_FAILURE);
}
}
@ -606,138 +582,117 @@ outputs (int is_err, const char *msg)
}
/* Return formatted string buffers.
If we move to gnulib we can use vasnprintf() etc. to make this simpler.
Note these functions use a static buffer, so each call overwrites the
results of the previous call. */
static struct fmtstring
{
char *buffer;
unsigned int size;
unsigned int len;
} fmtbuf = { NULL, 0, 0 };
size_t size;
} fmtbuf = { NULL, 0 };
/* Concatenate a formatted string onto the format buffer. */
static const char *
vfmtconcat (const char *fmt, va_list args)
static char *
get_buffer (size_t need)
{
va_list vcopy;
int tot;
int unused = fmtbuf.size - fmtbuf.len;
va_copy (vcopy, args);
tot = vsnprintf (&fmtbuf.buffer[fmtbuf.len], unused, fmt, args);
assert (tot >= 0);
if (tot >= unused)
/* Make sure we have room. */
if (need > fmtbuf.size)
{
fmtbuf.size += tot * 2;
fmtbuf.size += need * 2;
fmtbuf.buffer = xrealloc (fmtbuf.buffer, fmtbuf.size);
unused = fmtbuf.size - fmtbuf.len;
tot = vsnprintf (&fmtbuf.buffer[fmtbuf.len], unused, fmt, vcopy);
}
va_end (vcopy);
fmtbuf.len += tot;
fmtbuf.buffer[need] = '\0';
return fmtbuf.buffer;
}
static const char *
fmtconcat (const char *fmt, ...)
{
const char *p;
va_list args;
va_start (args, fmt);
p = vfmtconcat (fmt, args);
va_end (args);
return p;
}
/* Print a message on stdout. */
void
message (int prefix, const char *fmt, ...)
message (int prefix, size_t len, const char *fmt, ...)
{
va_list args;
char *p;
assert (fmt != NULL);
fmtbuf.len = 0;
len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1;
p = get_buffer (len);
if (prefix)
{
if (makelevel == 0)
fmtconcat ("%s: ", program);
sprintf (p, "%s: ", program);
else
fmtconcat ("%s[%u]: ", program, makelevel);
sprintf (p, "%s[%u]: ", program, makelevel);
p += strlen (p);
}
va_start (args, fmt);
vfmtconcat (fmt, args);
vsprintf (p, fmt, args);
va_end (args);
fmtconcat ("\n");
strcat (p, "\n");
assert (fmtbuf.buffer[len] == '\0');
outputs (0, fmtbuf.buffer);
}
/* Print an error message. */
void
error (const gmk_floc *flocp, const char *fmt, ...)
error (const gmk_floc *flocp, size_t len, const char *fmt, ...)
{
va_list args;
char *p;
assert (fmt != NULL);
fmtbuf.len = 0;
len += (strlen (fmt) + strlen (program)
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
+ INTSTR_LENGTH + 4 + 1 + 1);
p = get_buffer (len);
if (flocp && flocp->filenm)
fmtconcat ("%s:%lu: ", flocp->filenm, flocp->lineno);
sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno);
else if (makelevel == 0)
fmtconcat ("%s: ", program);
sprintf (p, "%s: ", program);
else
fmtconcat ("%s[%u]: ", program, makelevel);
sprintf (p, "%s[%u]: ", program, makelevel);
p += strlen (p);
va_start (args, fmt);
vfmtconcat (fmt, args);
vsprintf (p, fmt, args);
va_end (args);
fmtconcat ("\n");
strcat (p, "\n");
assert (fmtbuf.buffer[len] == '\0');
outputs (1, fmtbuf.buffer);
}
/* Print an error message and exit. */
void
fatal (const gmk_floc *flocp, const char *fmt, ...)
fatal (const gmk_floc *flocp, size_t len, const char *fmt, ...)
{
va_list args;
const char *stop = _(". Stop.\n");
char *p;
assert (fmt != NULL);
fmtbuf.len = 0;
len += (strlen (fmt) + strlen (program)
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
+ INTSTR_LENGTH + 8 + strlen (stop) + 1);
p = get_buffer (len);
if (flocp && flocp->filenm)
fmtconcat ("%s:%lu: *** ", flocp->filenm, flocp->lineno);
sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
else if (makelevel == 0)
fmtconcat ("%s: *** ", program);
sprintf (p, "%s: *** ", program);
else
fmtconcat ("%s[%u]: *** ", program, makelevel);
sprintf (p, "%s[%u]: *** ", program, makelevel);
p += strlen (p);
va_start (args, fmt);
vfmtconcat (fmt, args);
vsprintf (p, fmt, args);
va_end (args);
fmtconcat (_(". Stop.\n"));
strcat (p, stop);
assert (fmtbuf.buffer[len] == '\0');
outputs (1, fmtbuf.buffer);
die (2);
@ -748,7 +703,8 @@ fatal (const gmk_floc *flocp, const char *fmt, ...)
void
perror_with_name (const char *str, const char *name)
{
error (NILF, _("%s%s: %s"), str, name, strerror (errno));
const char *err = strerror (errno);
OSSS (error, NILF, _("%s%s: %s"), str, name, err);
}
/* Print an error message from errno and exit. */
@ -756,7 +712,8 @@ perror_with_name (const char *str, const char *name)
void
pfatal_with_name (const char *name)
{
fatal (NILF, _("%s: %s"), name, strerror (errno));
const char *err = strerror (errno);
OSS (fatal, NILF, _("%s: %s"), name, err);
/* NOTREACHED */
}

96
read.c
View file

@ -368,7 +368,10 @@ eval_makefile (const char *filename, int flags)
case ENFILE:
#endif
case ENOMEM:
fatal (reading_file, "%s", strerror (makefile_errno));
{
const char *err = strerror (makefile_errno);
OS (fatal, reading_file, "%s", err);
}
}
/* If the makefile wasn't found and it's either a makefile from
@ -783,7 +786,7 @@ eval (struct ebuffer *ebuf, int set_default)
if (i != -2)
{
if (i == -1)
fatal (fstart, _("invalid syntax in conditional"));
O (fatal, fstart, _("invalid syntax in conditional"));
ignoring = i;
continue;
@ -912,7 +915,10 @@ eval (struct ebuffer *ebuf, int set_default)
| (noerror ? RM_DONTCARE : 0)
| (set_default ? 0 : RM_NO_DEFAULT_GOAL)));
if (!r && !noerror)
error (fstart, "%s: %s", name, strerror (errno));
{
const char *err = strerror (errno);
OSS (error, fstart, "%s: %s", name, err);
}
}
/* Restore conditional state. */
@ -958,7 +964,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* Load the file. 0 means failure. */
r = load_file (&ebuf->floc, &name, noerror);
if (! r && ! noerror)
fatal (&ebuf->floc, _("%s: failed to load"), name);
OS (fatal, &ebuf->floc, _("%s: failed to load"), name);
free_ns (files);
files = next;
@ -984,7 +990,7 @@ eval (struct ebuffer *ebuf, int set_default)
was no preceding target, and the line might have been usable as a
variable definition. But now we know it is definitely lossage. */
if (line[0] == cmd_prefix)
fatal (fstart, _("recipe commences before first target"));
O (fatal, fstart, _("recipe commences before first target"));
/* This line describes some target files. This is complicated by
the existence of target-specific variables, because we can't
@ -1033,7 +1039,7 @@ eval (struct ebuffer *ebuf, int set_default)
{
case w_eol:
if (cmdleft != 0)
fatal (fstart, _("missing rule before recipe"));
O (fatal, fstart, _("missing rule before recipe"));
/* This line contained something but turned out to be nothing
but whitespace (a comment?). */
continue;
@ -1123,9 +1129,9 @@ eval (struct ebuffer *ebuf, int set_default)
/* There's no need to be ivory-tower about this: check for
one of the most common bugs found in makefiles... */
if (cmd_prefix == '\t' && !strneq (line, " ", 8))
fatal (fstart, _("missing separator (did you mean TAB instead of 8 spaces?)"));
O (fatal, fstart, _("missing separator (did you mean TAB instead of 8 spaces?)"));
else
fatal (fstart, _("missing separator"));
O (fatal, fstart, _("missing separator"));
}
/* Make the colon the end-of-string so we know where to stop
@ -1262,13 +1268,13 @@ eval (struct ebuffer *ebuf, int set_default)
PARSEFS_NOGLOB);
++p2;
if (target == 0)
fatal (fstart, _("missing target pattern"));
O (fatal, fstart, _("missing target pattern"));
else if (target->next != 0)
fatal (fstart, _("multiple target patterns"));
O (fatal, fstart, _("multiple target patterns"));
pattern_percent = find_percent_cached (&target->name);
pattern = target->name;
if (pattern_percent == 0)
fatal (fstart, _("target pattern contains no '%%'"));
O (fatal, fstart, _("target pattern contains no '%%'"));
free_ns (target);
}
else
@ -1390,7 +1396,7 @@ eval (struct ebuffer *ebuf, int set_default)
#undef word1eq
if (conditionals->if_cmds)
fatal (fstart, _("missing 'endif'"));
O (fatal, fstart, _("missing 'endif'"));
/* At eof, record the last rule. */
record_waiting_files ();
@ -1429,7 +1435,7 @@ do_undefine (char *name, enum variable_origin origin, struct ebuffer *ebuf)
var = allocated_variable_expand (name);
name = next_token (var);
if (*name == '\0')
fatal (&ebuf->floc, _("empty variable name"));
O (fatal, &ebuf->floc, _("empty variable name"));
p = name + strlen (name) - 1;
while (p > name && isblank ((unsigned char)*p))
--p;
@ -1464,7 +1470,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
else
{
if (var.value[0] != '\0')
error (&defstart, _("extraneous text after 'define' directive"));
O (error, &defstart, _("extraneous text after 'define' directive"));
/* Chop the string before the assignment token to get the name. */
var.name[var.length] = '\0';
@ -1474,7 +1480,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
n = allocated_variable_expand (name);
name = next_token (n);
if (name[0] == '\0')
fatal (&defstart, _("empty variable name"));
O (fatal, &defstart, _("empty variable name"));
p = name + strlen (name) - 1;
while (p > name && isblank ((unsigned char)*p))
--p;
@ -1489,7 +1495,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
/* If there is nothing left to be eval'd, there's no 'endef'!! */
if (nlines < 0)
fatal (&defstart, _("missing 'endef', unterminated 'define'"));
O (fatal, &defstart, _("missing 'endef', unterminated 'define'"));
ebuf->floc.lineno += nlines;
line = ebuf->buffer;
@ -1516,8 +1522,8 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
p += 5;
remove_comments (p);
if (*(next_token (p)) != '\0')
error (&ebuf->floc,
_("extraneous text after 'endef' directive"));
O (error, &ebuf->floc,
_("extraneous text after 'endef' directive"));
if (--nlevels == 0)
break;
@ -1588,16 +1594,17 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
/* Found one: skip past it and any whitespace after it. */
line = next_token (line + len);
#define EXTRANEOUS() error (flocp, _("extraneous text after '%s' directive"), cmdname)
#define EXTRATEXT() OS (error, flocp, _("extraneous text after '%s' directive"), cmdname)
#define EXTRACMD() OS (fatal, flocp, _("extraneous '%s'"), cmdname)
/* An 'endif' cannot contain extra text, and reduces the if-depth by 1 */
if (cmdtype == c_endif)
{
if (*line != '\0')
EXTRANEOUS ();
EXTRATEXT ();
if (!conditionals->if_cmds)
fatal (flocp, _("extraneous '%s'"), cmdname);
EXTRACMD ();
--conditionals->if_cmds;
@ -1611,12 +1618,12 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
const char *p;
if (!conditionals->if_cmds)
fatal (flocp, _("extraneous '%s'"), cmdname);
EXTRACMD ();
o = conditionals->if_cmds - 1;
if (conditionals->seen_else[o])
fatal (flocp, _("only one 'else' per conditional"));
O (fatal, flocp, _("only one 'else' per conditional"));
/* Change the state of ignorance. */
switch (conditionals->ignoring[o])
@ -1649,7 +1656,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
/* If it's 'else' or 'endif' or an illegal conditional, fail. */
if (word1eq ("else") || word1eq ("endif")
|| conditional_line (line, len, flocp) < 0)
EXTRANEOUS ();
EXTRATEXT ();
else
{
/* conditional_line() created a new level of conditional.
@ -1806,7 +1813,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
*line = '\0';
line = next_token (++line);
if (*line != '\0')
EXTRANEOUS ();
EXTRATEXT ();
s2 = variable_expand (s2);
conditionals->ignoring[o] = (streq (s1, s2) == (cmdtype == c_ifneq));
@ -1891,7 +1898,7 @@ record_target_var (struct nameseq *filenames, char *defn,
current_variable_set_list = f->variables;
v = try_variable_definition (flocp, defn, origin, 1);
if (!v)
fatal (flocp, _("Malformed target-specific variable definition"));
O (fatal, flocp, _("Malformed target-specific variable definition"));
current_variable_set_list = global;
}
@ -1950,7 +1957,7 @@ record_files (struct nameseq *filenames, const char *pattern,
at this time, since they won't get snapped and we'll get core dumps.
See Savannah bug # 12124. */
if (snapped_deps)
fatal (flocp, _("prerequisites cannot be defined in recipes"));
O (fatal, flocp, _("prerequisites cannot be defined in recipes"));
/* Determine if this is a pattern rule or not. */
name = filenames->name;
@ -2008,7 +2015,7 @@ record_files (struct nameseq *filenames, const char *pattern,
unsigned int c;
if (pattern != 0)
fatal (flocp, _("mixed implicit and static pattern rules"));
O (fatal, flocp, _("mixed implicit and static pattern rules"));
/* Count the targets to create an array of target names.
We already have the first one. */
@ -2031,7 +2038,7 @@ record_files (struct nameseq *filenames, const char *pattern,
implicit_percent = find_percent_cached (&name);
if (implicit_percent == 0)
fatal (flocp, _("mixed implicit and normal rules"));
O (fatal, flocp, _("mixed implicit and normal rules"));
targets[c] = name;
target_pats[c] = implicit_percent;
@ -2083,7 +2090,8 @@ record_files (struct nameseq *filenames, const char *pattern,
'targets: target%pattern: prereq%pattern; recipe',
make sure the pattern matches this target name. */
if (pattern && !pattern_matches (pattern, pattern_percent, name))
error (flocp, _("target '%s' doesn't match the target pattern"), name);
OS (error, flocp,
_("target '%s' doesn't match the target pattern"), name);
else if (deps)
/* If there are multiple targets, copy the chain DEPS for all but the
last one. It is not safe for the same deps to go in more than one
@ -2097,25 +2105,26 @@ record_files (struct nameseq *filenames, const char *pattern,
if any. */
f = enter_file (strcache_add (name));
if (f->double_colon)
fatal (flocp,
_("target file '%s' has both : and :: entries"), f->name);
OS (fatal, flocp,
_("target file '%s' has both : and :: entries"), f->name);
/* If CMDS == F->CMDS, this target was listed in this rule
more than once. Just give a warning since this is harmless. */
if (cmds != 0 && cmds == f->cmds)
error (flocp,
_("target '%s' given more than once in the same rule"),
f->name);
OS (error, flocp,
_("target '%s' given more than once in the same rule"),
f->name);
/* Check for two single-colon entries both with commands.
Check is_target so that we don't lose on files such as .c.o
whose commands were preinitialized. */
else if (cmds != 0 && f->cmds != 0 && f->is_target)
{
error (&cmds->fileinfo,
size_t l = strlen (f->name);
error (&cmds->fileinfo, l,
_("warning: overriding recipe for target '%s'"),
f->name);
error (&f->cmds->fileinfo,
error (&f->cmds->fileinfo, l,
_("warning: ignoring old recipe for target '%s'"),
f->name);
}
@ -2142,8 +2151,8 @@ record_files (struct nameseq *filenames, const char *pattern,
/* Check for both : and :: rules. Check is_target so we don't lose
on default suffix rules or makefiles. */
if (f != 0 && f->is_target && !f->double_colon)
fatal (flocp,
_("target file '%s' has both : and :: entries"), f->name);
OS (fatal, flocp,
_("target file '%s' has both : and :: entries"), f->name);
f = enter_file (strcache_add (name));
/* If there was an existing entry and it was a double-colon entry,
@ -2219,7 +2228,8 @@ record_files (struct nameseq *filenames, const char *pattern,
/* Reduce escaped percents. If there are any unescaped it's an error */
name = filenames->name;
if (find_percent_cached (&name))
error (flocp, _("*** mixed implicit and normal rules: deprecated syntax"));
O (error, flocp,
_("*** mixed implicit and normal rules: deprecated syntax"));
}
}
@ -2528,8 +2538,8 @@ readline (struct ebuffer *ebuf)
lossage strikes again! (xmkmf puts NULs in its makefiles.)
There is nothing really to be done; we synthesize a newline so
the following line doesn't appear to be part of this line. */
error (&ebuf->floc,
_("warning: NUL character seen; rest of line ignored"));
O (error, &ebuf->floc,
_("warning: NUL character seen; rest of line ignored"));
p[0] = '\n';
len = 1;
}
@ -3271,7 +3281,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
switch (glob (name, GLOB_NOSORT|GLOB_ALTDIRFUNC, NULL, &gl))
{
case GLOB_NOSPACE:
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
case 0:
/* Success. */

View file

@ -228,10 +228,10 @@ update_goal_chain (struct dep *goals)
&& file->update_status == us_success && !g->changed
/* Never give a message under -s or -q. */
&& !silent_flag && !question_flag)
message (1, ((file->phony || file->cmds == 0)
? _("Nothing to be done for '%s'.")
: _("'%s' is up to date.")),
file->name);
OS (message, 1, ((file->phony || file->cmds == 0)
? _("Nothing to be done for '%s'.")
: _("'%s' is up to date.")),
file->name);
/* This goal is finished. Remove it from the chain. */
if (lastgoal == 0)
@ -373,24 +373,30 @@ complain (struct file *file)
if (d == 0)
{
const char *msg_noparent
= _("%sNo rule to make target '%s'%s");
const char *msg_parent
= _("%sNo rule to make target '%s', needed by '%s'%s");
/* Didn't find any dependencies to complain about. */
if (!keep_going_flag)
if (file->parent)
{
if (file->parent == 0)
fatal (NILF, msg_noparent, "", file->name, "");
size_t l = strlen (file->name) + strlen (file->parent->name) + 4;
fatal (NILF, msg_parent, "", file->name, file->parent->name, "");
if (!keep_going_flag)
fatal (NILF, l,
_("%sNo rule to make target '%s', needed by '%s'%s"),
"", file->name, file->parent->name, "");
error (NILF, l, _("%sNo rule to make target '%s', needed by '%s'%s"),
"*** ", file->name, file->parent->name, ".");
}
if (file->parent == 0)
error (NILF, msg_noparent, "*** ", file->name, ".");
else
error (NILF, msg_parent, "*** ", file->name, file->parent->name, ".");
{
size_t l = strlen (file->name) + 4;
if (!keep_going_flag)
fatal (NILF, l,
_("%sNo rule to make target '%s'%s"), "", file->name, "");
error (NILF, l,
_("%sNo rule to make target '%s'%s"), "*** ", file->name, ".");
}
file->no_diag = 0;
}
@ -478,8 +484,9 @@ update_file_1 (struct file *file, unsigned int depth)
/* Avoid spurious rebuilds due to low resolution time stamps. */
int ns = FILE_TIMESTAMP_NS (this_mtime);
if (ns != 0)
error (NILF, _("*** Warning: .LOW_RESOLUTION_TIME file '%s' has a high resolution time stamp"),
file->name);
OS (error, NILF,
_("*** Warning: .LOW_RESOLUTION_TIME file '%s' has a high resolution time stamp"),
file->name);
this_mtime += FILE_TIMESTAMPS_PER_S - 1 - ns;
}
@ -532,8 +539,8 @@ update_file_1 (struct file *file, unsigned int depth)
if (is_updating (d->file))
{
error (NILF, _("Circular %s <- %s dependency dropped."),
file->name, d->file->name);
OSS (error, NILF, _("Circular %s <- %s dependency dropped."),
file->name, d->file->name);
/* We cannot free D here because our the caller will still have
a reference to it when we were called recursively via
check_dep below. */
@ -675,8 +682,8 @@ update_file_1 (struct file *file, unsigned int depth)
if (depth == 0 && keep_going_flag
&& !just_print_flag && !question_flag)
error (NILF,
_("Target '%s' not remade because of errors."), file->name);
OS (error, NILF,
_("Target '%s' not remade because of errors."), file->name);
return dep_status;
}
@ -1064,8 +1071,8 @@ check_dep (struct file *file, unsigned int depth,
if (is_updating (d->file))
{
error (NILF, _("Circular %s <- %s dependency dropped."),
file->name, d->file->name);
OSS (error, NILF, _("Circular %s <- %s dependency dropped."),
file->name, d->file->name);
if (ld == 0)
{
file->deps = d->next;
@ -1122,7 +1129,7 @@ static enum update_status
touch_file (struct file *file)
{
if (!silent_flag)
message (0, "touch %s", file->name);
OS (message, 0, "touch %s", file->name);
/* Print-only (-n) takes precedence over touch (-t). */
if (just_print_flag)
@ -1369,8 +1376,9 @@ f_mtime (struct file *file, int search)
if (adjusted_now < adjusted_mtime)
{
#ifdef NO_FLOAT
error (NILF, _("Warning: File '%s' has modification time in the future"),
file->name);
OS (error, NILF,
_("Warning: File '%s' has modification time in the future"),
file->name);
#else
double from_now =
(FILE_TIMESTAMP_S (mtime) - FILE_TIMESTAMP_S (now)
@ -1382,8 +1390,9 @@ f_mtime (struct file *file, int search)
sprintf (from_now_string, "%lu", (unsigned long) from_now);
else
sprintf (from_now_string, "%.2g", from_now);
error (NILF, _("Warning: File '%s' has modification time %s s in the future"),
file->name, from_now_string);
OSS (error, NILF,
_("Warning: File '%s' has modification time %s s in the future"),
file->name, from_now_string);
#endif
clock_skew_detected = 1;
}
@ -1580,7 +1589,8 @@ library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
if (!p3)
{
/* Give a warning if there is no pattern. */
error (NILF, _(".LIBPATTERNS element '%s' is not a pattern"), p);
OS (error, NILF,
_(".LIBPATTERNS element '%s' is not a pattern"), p);
p[len] = c;
continue;
}

View file

@ -151,7 +151,7 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
retsock = Rpc_UdpCreate (True, 0);
if (retsock < 0)
{
error (NILF, "exporting: Couldn't create return socket.");
O (error, NILF, "exporting: Couldn't create return socket.");
return 1;
}
@ -192,33 +192,35 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
host = gethostbyaddr ((char *)&permit.addr, sizeof(permit.addr), AF_INET);
if (status != RPC_SUCCESS)
{
(void) close (retsock);
(void) close (sock);
error (NILF, "exporting to %s: %s",
host ? host->h_name : inet_ntoa (permit.addr),
Rpc_ErrorMessage (status));
return 1;
}
else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
{
(void) close (retsock);
(void) close (sock);
error (NILF, "exporting to %s: %s",
host ? host->h_name : inet_ntoa (permit.addr),
msg);
return 1;
}
else
{
error (NILF, "*** exported to %s (id %u)",
host ? host->h_name : inet_ntoa (permit.addr),
permit.id);
}
{
const char *hnm = host ? host->h_name : inet_ntoa (permit.addr);
size_t hlen = strlen (hnm);
fflush (stdout);
fflush (stderr);
if (status != RPC_SUCCESS)
{
const char *err = Rpc_ErrorMessage (status);
(void) close (retsock);
(void) close (sock);
error (NILF, hlen + strlen (err),
"exporting to %s: %s", hnm, err);
return 1;
}
else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
{
(void) close (retsock);
(void) close (sock);
error (NILF, hlen + strlen (msg), "exporting to %s: %s", hnm, msg);
return 1;
}
else
{
error (NILF, hlen + INTSTR_LENGTH,
"*** exported to %s (id %u)", hnm, permit.id);
}
fflush (stdout);
fflush (stderr);
}
pid = fork ();
if (pid < 0)

4
rule.c
View file

@ -528,7 +528,7 @@ print_rule_data_base (void)
/* This can happen if a fatal error was detected while reading the
makefiles and thus count_implicit_rule_limits wasn't called yet. */
if (num_pattern_rules != 0)
fatal (NILF, _("BUG: num_pattern_rules is wrong! %u != %u"),
num_pattern_rules, rules);
ONN (fatal, NILF, _("BUG: num_pattern_rules is wrong! %u != %u"),
num_pattern_rules, rules);
}
}

View file

@ -1551,7 +1551,7 @@ assign_variable_definition (struct variable *v, char *line)
v->name = allocated_variable_expand (name);
if (v->name[0] == '\0')
fatal (&v->fileinfo, _("empty variable name"));
O (fatal, &v->fileinfo, _("empty variable name"));
return v;
}

View file

@ -219,10 +219,10 @@ void undefine_variable_in_set (const char *name, unsigned int length,
/* Warn that NAME is an undefined variable. */
#define warn_undefined(n,l) do{\
if (warn_undefined_variables_flag) \
error (reading_file, \
if (warn_undefined_variables_flag) \
error (reading_file, (l), \
_("warning: undefined variable '%.*s'"), \
(int)(l), (n)); \
(int)(l), (n)); \
}while(0)
char **target_environment (struct file *file);

View file

@ -175,8 +175,8 @@ vmsHandleChildTerm(struct child *child)
break;
default:
error (NILF, _("internal error: '%s' command_state"),
c->file->name);
OS (error, NILF,
_("internal error: '%s' command_state"), c->file->name);
abort ();
break;
}