diff --git a/amiga.c b/amiga.c index 73ed59a0..80254839 100644 --- a/amiga.c +++ b/amiga.c @@ -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; diff --git a/ar.c b/ar.c index afed591f..5d2f0009 100644 --- a/ar.c +++ b/ar.c @@ -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); diff --git a/arscan.c b/arscan.c index 2b3cd5df..e49137b7 100644 --- a/arscan.c +++ b/arscan.c @@ -37,7 +37,7 @@ this program. If not, see . */ 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. */ diff --git a/commands.c b/commands.c index f9103584..7c7eabfd 100644 --- a/commands.c +++ b/commands.c @@ -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); diff --git a/dir.c b/dir.c index d046bd9a..77b7bfeb 100644 --- a/dir.c +++ b/dir.c @@ -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; } diff --git a/expand.c b/expand.c index ba04e484..28ec198c 100644 --- a/expand.c +++ b/expand.c @@ -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) { diff --git a/file.c b/file.c index b209d880..92c40524 100644 --- a/file.c +++ b/file.c @@ -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 diff --git a/function.c b/function.c index ecce627f..5752d09b 100644 --- a/function.c +++ b/function.c @@ -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; diff --git a/job.c b/job.c index febfac0c..2b17f428 100644 --- a/job.c +++ b/job.c @@ -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 diff --git a/job.h b/job.h index 8a201778..207fe894 100644 --- a/job.h +++ b/job.h @@ -39,8 +39,8 @@ this program. If not, see . */ #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. */ diff --git a/load.c b/load.c index a2cbc25b..ca73ac4c 100644 --- a/load.c +++ b/load.c @@ -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 */ diff --git a/main.c b/main.c index 3b33ea54..80c08d96 100644 --- a/main.c +++ b/main.c @@ -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 (); diff --git a/makeint.h b/makeint.h index c591427c..f3f01115 100644 --- a/makeint.h +++ b/makeint.h @@ -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 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)); diff --git a/misc.c b/misc.c index bc54ce64..8e1ad4df 100644 --- a/misc.c +++ b/misc.c @@ -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) diff --git a/output.c b/output.c index 5e3b073d..000e2414 100644 --- a/output.c +++ b/output.c @@ -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 */ } diff --git a/read.c b/read.c index 2966ebec..663ffe89 100644 --- a/read.c +++ b/read.c @@ -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. */ diff --git a/remake.c b/remake.c index 138cdc68..ff222771 100644 --- a/remake.c +++ b/remake.c @@ -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; } diff --git a/remote-cstms.c b/remote-cstms.c index 8d6c635d..a5ef99b0 100644 --- a/remote-cstms.c +++ b/remote-cstms.c @@ -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) diff --git a/rule.c b/rule.c index cb355376..e5716c5e 100644 --- a/rule.c +++ b/rule.c @@ -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); } } diff --git a/variable.c b/variable.c index 2ff14b64..a782305e 100644 --- a/variable.c +++ b/variable.c @@ -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; } diff --git a/variable.h b/variable.h index dec75b1c..eda2493f 100644 --- a/variable.h +++ b/variable.h @@ -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); diff --git a/vmsjobs.c b/vmsjobs.c index 8bacc866..8109b5be 100644 --- a/vmsjobs.c +++ b/vmsjobs.c @@ -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; }