1 /* Miscellaneous generic support functions for GNU Make.
2 Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
4 2010 Free Software Foundation, Inc.
5 This file is part of GNU Make.
6 
7 GNU Make is free software; you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation; either version 3 of the License, or (at your option) any later
10 version.
11 
12 GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License along with
17 this program.  If not, see <http://www.gnu.org/licenses/>.  */
18 
19 #include "make.h"
20 #include "dep.h"
21 #include "debug.h"
22 #if defined (CONFIG_WITH_VALUE_LENGTH) || defined (CONFIG_WITH_ALLOC_CACHES)
23 # include <assert.h>
24 #endif
25 #ifdef CONFIG_WITH_PRINT_STATS_SWITCH
26 # ifdef __APPLE__
27 #  include <malloc/malloc.h>
28 # endif
29 # if defined(__GLIBC__) || defined(HAVE_MALLINFO)
30 #  include <malloc.h>
31 # endif
32 #endif
33 
34 #if defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_PRINT_TIME_SWITCH)
35 # ifdef WINDOWS32
36 #  include <Windows.h>
37 # endif
38 #endif
39 
40 /* All bcopy calls in this file can be replaced by memcpy and save a tick or two. */
41 #ifdef CONFIG_WITH_OPTIMIZATION_HACKS
42 # undef bcopy
43 # if defined(__GNUC__) && defined(CONFIG_WITH_OPTIMIZATION_HACKS)
44 #  define bcopy(src, dst, size)   __builtin_memcpy ((dst), (src), (size))
45 # else
46 #  define bcopy(src, dst, size)   memcpy ((dst), (src), (size))
47 # endif
48 #endif
49 
50 /* Variadic functions.  We go through contortions to allow proper function
51    prototypes for both ANSI and pre-ANSI C compilers, and also for those
52    which support stdarg.h vs. varargs.h, and finally those which have
53    vfprintf(), etc. and those who have _doprnt... or nothing.
54 
55    This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and
56    VA_END macros used here since we have multiple print functions.  */
57 
58 #if USE_VARIADIC
59 # if HAVE_STDARG_H
60 #  include <stdarg.h>
61 #  define VA_START(args, lastarg) va_start(args, lastarg)
62 # else
63 #  include <varargs.h>
64 #  define VA_START(args, lastarg) va_start(args)
65 # endif
66 # if HAVE_VPRINTF
67 #  define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args))
68 # else
69 #  define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp))
70 # endif
71 # define VA_END(args) va_end(args)
72 #else
73 /* We can't use any variadic interface! */
74 # define va_alist a1, a2, a3, a4, a5, a6, a7, a8
75 # define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
76 # define VA_START(args, lastarg)
77 # define VA_PRINTF(fp, lastarg, args) fprintf((fp), (lastarg), va_alist)
78 # define VA_END(args)
79 #endif
80 
81 
82 /* Compare strings *S1 and *S2.
83    Return negative if the first is less, positive if it is greater,
84    zero if they are equal.  */
85 
86 int
alpha_compare(const void * v1,const void * v2)87 alpha_compare (const void *v1, const void *v2)
88 {
89   const char *s1 = *((char **)v1);
90   const char *s2 = *((char **)v2);
91 
92   if (*s1 != *s2)
93     return *s1 - *s2;
94   return strcmp (s1, s2);
95 }
96 
97 /* Discard each backslash-newline combination from LINE.
98    Backslash-backslash-newline combinations become backslash-newlines.
99    This is done by copying the text at LINE into itself.  */
100 
101 #ifndef CONFIG_WITH_VALUE_LENGTH
102 void
collapse_continuations(char * line)103 collapse_continuations (char *line)
104 #else
105 char *
106 collapse_continuations (char *line, unsigned int linelen)
107 #endif
108 {
109   register char *in, *out, *p;
110   register int backslash;
111   register unsigned int bs_write;
112 
113 #ifndef CONFIG_WITH_VALUE_LENGTH
114   in = strchr (line, '\n');
115   if (in == 0)
116     return;
117 #else
118   assert (strlen (line) == linelen);
119   in = memchr (line, '\n', linelen);
120   if (in == 0)
121       return line + linelen;
122   if (in == line || in[-1] != '\\')
123     {
124       do
125         {
126           unsigned int off_in = in - line;
127           if (off_in == linelen)
128             return in;
129           in = memchr (in + 1, '\n', linelen - off_in - 1);
130           if (in == 0)
131             return line + linelen;
132         }
133       while (in[-1] != '\\');
134     }
135 #endif
136 
137   out = in;
138   while (out > line && out[-1] == '\\')
139     --out;
140 
141   while (*in != '\0')
142     {
143       /* BS_WRITE gets the number of quoted backslashes at
144 	 the end just before IN, and BACKSLASH gets nonzero
145 	 if the next character is quoted.  */
146       backslash = 0;
147       bs_write = 0;
148       for (p = in - 1; p >= line && *p == '\\'; --p)
149 	{
150 	  if (backslash)
151 	    ++bs_write;
152 	  backslash = !backslash;
153 
154 	  /* It should be impossible to go back this far without exiting,
155 	     but if we do, we can't get the right answer.  */
156 	  if (in == out - 1)
157 	    abort ();
158 	}
159 
160       /* Output the appropriate number of backslashes.  */
161       while (bs_write-- > 0)
162 	*out++ = '\\';
163 
164       /* Skip the newline.  */
165       ++in;
166 
167       /* If the newline is escaped, discard following whitespace leaving just
168 	 one space.  POSIX requires that each backslash/newline/following
169 	 whitespace sequence be reduced to a single space.  */
170       if (backslash)
171 	{
172 	  in = next_token (in);
173           /* Removing this loop will fix Savannah bug #16670: do we want to? */
174 	  while (out > line && isblank ((unsigned char)out[-1]))
175 	    --out;
176 	  *out++ = ' ';
177 	}
178       else
179 	/* If the newline isn't quoted, put it in the output.  */
180 	*out++ = '\n';
181 
182       /* Now copy the following line to the output.
183 	 Stop when we find backslashes followed by a newline.  */
184       while (*in != '\0')
185 	if (*in == '\\')
186 	  {
187 	    p = in + 1;
188 	    while (*p == '\\')
189 	      ++p;
190 	    if (*p == '\n')
191 	      {
192 		in = p;
193 		break;
194 	      }
195 	    while (in < p)
196 	      *out++ = *in++;
197 	  }
198 	else
199 	  *out++ = *in++;
200     }
201 
202   *out = '\0';
203 #ifdef CONFIG_WITH_VALUE_LENGTH
204   assert (strchr (line, '\0') == out);
205   return out;
206 #endif
207 }
208 
209 /* Print N spaces (used in debug for target-depth).  */
210 
211 void
print_spaces(unsigned int n)212 print_spaces (unsigned int n)
213 {
214   while (n-- > 0)
215     putchar (' ');
216 }
217 
218 
219 /* Return a string whose contents concatenate the NUM strings provided
220    This string lives in static, re-used memory.  */
221 
222 const char *
223 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
concat(unsigned int num,...)224 concat (unsigned int num, ...)
225 #else
226 concat (num, va_alist)
227      unsigned int num;
228      va_dcl
229 #endif
230 {
231   static unsigned int rlen = 0;
232   static char *result = NULL;
233   unsigned int ri = 0; /* bird: must be unsigned */
234 
235 #if USE_VARIADIC
236   va_list args;
237 #endif
238 
239   VA_START (args, num);
240 
241   while (num-- > 0)
242     {
243       const char *s = va_arg (args, const char *);
244       unsigned int l = s ? strlen (s) : 0;
245 
246       if (l == 0)
247         continue;
248 
249       if (ri + l > rlen)
250         {
251           rlen = ((rlen ? rlen : 60) + l) * 2;
252           result = xrealloc (result, rlen);
253         }
254 
255       memcpy (result + ri, s, l);
256       ri += l;
257     }
258 
259   VA_END (args);
260 
261   /* Get some more memory if we don't have enough space for the
262      terminating '\0'.   */
263   if (ri == rlen)
264     {
265       rlen = (rlen ? rlen : 60) * 2;
266       result = xrealloc (result, rlen);
267     }
268 
269   result[ri] = '\0';
270 
271   return result;
272 }
273 
274 /* Print a message on stdout.  */
275 
276 void
277 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
message(int prefix,const char * fmt,...)278 message (int prefix, const char *fmt, ...)
279 #else
280 message (prefix, fmt, va_alist)
281      int prefix;
282      const char *fmt;
283      va_dcl
284 #endif
285 {
286 #if USE_VARIADIC
287   va_list args;
288 #endif
289 
290   log_working_directory (1);
291 
292   if (fmt != 0)
293     {
294 #ifdef KBUILD_OS_WINDOWS
295       char szMsg[16384];
296       int cchMsg = 0;
297       int cchUser;
298       if (prefix)
299         {
300           if (makelevel == 0)
301             cchMsg = snprintf (szMsg, sizeof(szMsg), "%s: ", program);
302           else
303             cchMsg = snprintf (szMsg, sizeof(szMsg), "%s[%u]: ", program, makelevel);
304         }
305       VA_START (args, fmt);
306       cchMsg += cchUser = vsnprintf (&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);
307       VA_END (args);
308       if (   cchMsg < sizeof(szMsg)
309           && cchUser >= 0)
310         {
311           extern size_t maybe_con_fwrite(void const *, size_t, size_t, FILE *);
312           szMsg[cchMsg++] = '\n';
313           maybe_con_fwrite(szMsg, cchMsg, 1, stdout);
314         }
315       else
316         {
317 #endif
318       if (prefix)
319 	{
320 	  if (makelevel == 0)
321 	    printf ("%s: ", program);
322 	  else
323 	    printf ("%s[%u]: ", program, makelevel);
324 	}
325       VA_START (args, fmt);
326       VA_PRINTF (stdout, fmt, args);
327       VA_END (args);
328       putchar ('\n');
329 #ifdef KBUILD_OS_WINDOWS
330         }
331 #endif
332     }
333 
334   fflush (stdout);
335 }
336 
337 /* Print an error message.  */
338 
339 void
340 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
error(const struct floc * flocp,const char * fmt,...)341 error (const struct floc *flocp, const char *fmt, ...)
342 #else
343 error (flocp, fmt, va_alist)
344      const struct floc *flocp;
345      const char *fmt;
346      va_dcl
347 #endif
348 {
349 #if USE_VARIADIC
350   va_list args;
351 #endif
352 #ifdef KMK
353   char szMsg[16384];
354   int cchMsg = 0;
355   int cchUser;
356 #endif
357 
358   log_working_directory (1);
359 
360 #ifdef KMK /* Try avoid getting the error split by child output.  */
361   if (flocp && flocp->filenm)
362     cchMsg = snprintf (szMsg, sizeof(szMsg), "%s:%lu: ", flocp->filenm, flocp->lineno);
363   else if (makelevel == 0)
364     cchMsg = snprintf (szMsg, sizeof(szMsg), "%s: ", program);
365   else
366     cchMsg = snprintf (szMsg, sizeof(szMsg), "%s[%u]: ", program, makelevel);
367 
368   VA_START (args, fmt);
369   cchMsg += cchUser = vsnprintf (&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);
370   VA_END (args);
371   if (   cchMsg < (int)sizeof(szMsg)
372       && cchUser >= 0)
373     {
374       extern size_t maybe_con_fwrite(void const *, size_t, size_t, FILE *);
375       szMsg[cchMsg++] = '\n';
376       maybe_con_fwrite(szMsg, cchMsg, 1, stderr);
377     }
378   else
379     {
380 #endif /* KMK */
381 
382   if (flocp && flocp->filenm)
383     fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno);
384   else if (makelevel == 0)
385     fprintf (stderr, "%s: ", program);
386   else
387     fprintf (stderr, "%s[%u]: ", program, makelevel);
388 
389   VA_START(args, fmt);
390   VA_PRINTF (stderr, fmt, args);
391   VA_END (args);
392 
393   putc ('\n', stderr);
394 #ifdef KMK
395     }
396 #endif
397   fflush (stderr);
398 }
399 
400 /* Print an error message and exit.  */
401 
402 void
403 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
fatal(const struct floc * flocp,const char * fmt,...)404 fatal (const struct floc *flocp, const char *fmt, ...)
405 #else
406 fatal (flocp, fmt, va_alist)
407      const struct floc *flocp;
408      const char *fmt;
409      va_dcl
410 #endif
411 {
412 #if USE_VARIADIC
413   va_list args;
414 #endif
415 #ifdef KMK
416   char szMsg[16384];
417   int cchMsg = 0;
418   int cchUser;
419   const char *pszStop = _(".  Stop.\n");
420   int         cchStop = (int)strlen(pszStop);
421 #endif
422 
423   log_working_directory (1);
424 
425 #ifdef KMK /* Try avoid getting the error split by child output.  */
426   if (flocp && flocp->filenm)
427     cchMsg = snprintf (szMsg, sizeof(szMsg), "%s:%lu: *** ", flocp->filenm, flocp->lineno);
428   else if (makelevel == 0)
429     cchMsg = snprintf (szMsg, sizeof(szMsg), "%s: *** ", program);
430   else
431     cchMsg = snprintf (szMsg, sizeof(szMsg), "%s[%u]: *** ", program, makelevel);
432 
433   VA_START (args, fmt);
434   cchMsg += cchUser = vsnprintf (&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);
435   VA_END (args);
436   if (   cchMsg + cchStop <= (int)sizeof(szMsg)
437       && cchUser >= 0)
438     {
439       extern size_t maybe_con_fwrite(void const *, size_t, size_t, FILE *);
440       memcpy(&szMsg[cchMsg], pszStop, cchStop);
441       cchMsg += cchStop;
442       maybe_con_fwrite(szMsg, cchMsg, 1, stderr);
443     }
444   else
445     {
446 #endif /* KMK */
447   if (flocp && flocp->filenm)
448     fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
449   else if (makelevel == 0)
450     fprintf (stderr, "%s: *** ", program);
451   else
452     fprintf (stderr, "%s[%u]: *** ", program, makelevel);
453 
454   VA_START(args, fmt);
455   VA_PRINTF (stderr, fmt, args);
456   VA_END (args);
457 
458   fputs (_(".  Stop.\n"), stderr);
459 #ifdef KMK
460     }
461 #endif
462 
463   die (2);
464 }
465 
466 #ifndef HAVE_STRERROR
467 
468 #undef	strerror
469 
470 char *
strerror(int errnum)471 strerror (int errnum)
472 {
473   extern int errno, sys_nerr;
474 #ifndef __DECC
475   extern char *sys_errlist[];
476 #endif
477   static char buf[] = "Unknown error 12345678901234567890";
478 
479   if (errno < sys_nerr)
480     return sys_errlist[errnum];
481 
482   sprintf (buf, _("Unknown error %d"), errnum);
483   return buf;
484 }
485 #endif
486 
487 /* Print an error message from errno.  */
488 
489 void
perror_with_name(const char * str,const char * name)490 perror_with_name (const char *str, const char *name)
491 {
492   error (NILF, _("%s%s: %s"), str, name, strerror (errno));
493 }
494 
495 /* Print an error message from errno and exit.  */
496 
497 void
pfatal_with_name(const char * name)498 pfatal_with_name (const char *name)
499 {
500   fatal (NILF, _("%s: %s"), name, strerror (errno));
501 
502   /* NOTREACHED */
503 }
504 
505 /* Like malloc but get fatal error if memory is exhausted.  */
506 /* Don't bother if we're using dmalloc; it provides these for us.  */
507 
508 #if !defined(HAVE_DMALLOC_H) && !defined(ELECTRIC_HEAP) /* bird */
509 
510 #undef xmalloc
511 #undef xcalloc
512 #undef xrealloc
513 #undef xstrdup
514 
515 void *
xmalloc(unsigned int size)516 xmalloc (unsigned int size)
517 {
518   /* Make sure we don't allocate 0, for pre-ISO implementations.  */
519   void *result = malloc (size ? size : 1);
520   if (result == 0)
521     fatal (NILF, _("virtual memory exhausted"));
522 
523 #ifdef CONFIG_WITH_MAKE_STATS
524   make_stats_allocations++;
525   if (make_expensive_statistics)
526     make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
527   else
528     make_stats_allocated += size;
529 #endif
530   return result;
531 }
532 
533 
534 void *
xcalloc(unsigned int size)535 xcalloc (unsigned int size)
536 {
537   /* Make sure we don't allocate 0, for pre-ISO implementations.  */
538   void *result = calloc (size ? size : 1, 1);
539   if (result == 0)
540     fatal (NILF, _("virtual memory exhausted"));
541 
542 #ifdef CONFIG_WITH_MAKE_STATS
543   make_stats_allocations++;
544   if (make_expensive_statistics)
545     make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
546   else
547     make_stats_allocated += size;
548 #endif
549   return result;
550 }
551 
552 
553 void *
xrealloc(void * ptr,unsigned int size)554 xrealloc (void *ptr, unsigned int size)
555 {
556   void *result;
557 #ifdef CONFIG_WITH_MAKE_STATS
558   if (make_expensive_statistics && ptr != NULL)
559     make_stats_allocated -= SIZE_OF_HEAP_BLOCK (ptr);
560   if (ptr)
561     make_stats_reallocations++;
562   else
563     make_stats_allocations++;
564 #endif
565 
566   /* Some older implementations of realloc() don't conform to ISO.  */
567   if (! size)
568     size = 1;
569   result = ptr ? realloc (ptr, size) : malloc (size);
570   if (result == 0)
571     fatal (NILF, _("virtual memory exhausted"));
572 
573 #ifdef CONFIG_WITH_MAKE_STATS
574   if (make_expensive_statistics)
575     make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
576   else
577     make_stats_allocated += size;
578 #endif
579   return result;
580 }
581 
582 
583 char *
xstrdup(const char * ptr)584 xstrdup (const char *ptr)
585 {
586   char *result;
587 
588 #ifdef HAVE_STRDUP
589   result = strdup (ptr);
590 #else
591   result = malloc (strlen (ptr) + 1);
592 #endif
593 
594   if (result == 0)
595     fatal (NILF, _("virtual memory exhausted"));
596 
597 #ifdef CONFIG_WITH_MAKE_STATS
598   make_stats_allocations++;
599   if (make_expensive_statistics)
600     make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
601   else
602     make_stats_allocated += strlen (ptr) + 1;
603 #endif
604 #ifdef HAVE_STRDUP
605   return result;
606 #else
607   return strcpy (result, ptr);
608 #endif
609 }
610 
611 #endif  /* HAVE_DMALLOC_H */
612 
613 char *
xstrndup(const char * str,unsigned int length)614 xstrndup (const char *str, unsigned int length)
615 {
616   char *result;
617 
618 #if defined(HAVE_STRNDUP) && !defined(KMK)
619   result = strndup (str, length);
620   if (result == 0)
621     fatal (NILF, _("virtual memory exhausted"));
622 #else
623   result = xmalloc (length + 1);
624   if (length > 0)
625     strncpy (result, str, length);
626   result[length] = '\0';
627 #endif
628 
629   return result;
630 }
631 
632 
633 #ifndef CONFIG_WITH_OPTIMIZATION_HACKS /* This is really a reimplemntation of
634    memchr, only slower. It's been replaced by a macro in the header file. */
635 
636 /* Limited INDEX:
637    Search through the string STRING, which ends at LIMIT, for the character C.
638    Returns a pointer to the first occurrence, or nil if none is found.
639    Like INDEX except that the string searched ends where specified
640    instead of at the first null.  */
641 
642 char *
lindex(const char * s,const char * limit,int c)643 lindex (const char *s, const char *limit, int c)
644 {
645   while (s < limit)
646     if (*s++ == c)
647       return (char *)(s - 1);
648 
649   return 0;
650 }
651 #endif /* CONFIG_WITH_OPTIMIZATION_HACKS */
652 
653 /* Return the address of the first whitespace or null in the string S.  */
654 
655 char *
end_of_token(const char * s)656 end_of_token (const char *s)
657 {
658 #ifdef KMK
659     for (;;)
660       {
661         unsigned char ch0, ch1, ch2, ch3;
662 
663         ch0 = *s;
664         if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch0)))
665           return (char *)s;
666         ch1 = s[1];
667         if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch1)))
668           return (char *)s + 1;
669         ch2 = s[2];
670         if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch2)))
671           return (char *)s + 2;
672         ch3 = s[3];
673         if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch3)))
674           return (char *)s + 3;
675 
676         s += 4;
677       }
678 
679 #else
680   while (*s != '\0' && !isblank ((unsigned char)*s))
681     ++s;
682   return (char *)s;
683 #endif
684 }
685 
686 #ifdef WINDOWS32
687 /*
688  * Same as end_of_token, but take into account a stop character
689  */
690 char *
end_of_token_w32(const char * s,char stopchar)691 end_of_token_w32 (const char *s, char stopchar)
692 {
693   const char *p = s;
694   int backslash = 0;
695 
696   while (*p != '\0' && *p != stopchar
697 	 && (backslash || !isblank ((unsigned char)*p)))
698     {
699       if (*p++ == '\\')
700         {
701           backslash = !backslash;
702           while (*p == '\\')
703             {
704               backslash = !backslash;
705               ++p;
706             }
707         }
708       else
709         backslash = 0;
710     }
711 
712   return (char *)p;
713 }
714 #endif
715 
716 /* Return the address of the first nonwhitespace or null in the string S.  */
717 
718 char *
next_token(const char * s)719 next_token (const char *s)
720 {
721 #ifdef KMK
722   for (;;)
723     {
724       unsigned char ch0, ch1, ch2, ch3;
725 
726       ch0 = *s;
727       if (MY_PREDICT_FALSE(!MY_IS_BLANK(ch0)))
728           return (char *)s;
729       ch1 = s[1];
730       if (MY_PREDICT_TRUE(!MY_IS_BLANK(ch1)))
731         return (char *)s + 1;
732       ch2 = s[2];
733       if (MY_PREDICT_FALSE(!MY_IS_BLANK(ch2)))
734         return (char *)s + 2;
735       ch3 = s[3];
736       if (MY_PREDICT_TRUE(!MY_IS_BLANK(ch3)))
737         return (char *)s + 3;
738 
739       s += 4;
740     }
741 
742 #else  /* !KMK */
743   while (isblank ((unsigned char)*s))
744     ++s;
745   return (char *)s;
746 #endif /* !KMK */
747 }
748 
749 /* Find the next token in PTR; return the address of it, and store the length
750    of the token into *LENGTHPTR if LENGTHPTR is not nil.  Set *PTR to the end
751    of the token, so this function can be called repeatedly in a loop.  */
752 
753 char *
find_next_token(const char ** ptr,unsigned int * lengthptr)754 find_next_token (const char **ptr, unsigned int *lengthptr)
755 {
756 #ifdef KMK
757   const char *p = *ptr;
758   const char *e;
759 
760   /* skip blanks */
761 # if 0 /* a moderate version */
762   for (;; p++)
763     {
764       unsigned char ch = *p;
765       if (!MY_IS_BLANK(ch))
766         {
767           if (!ch)
768             return NULL;
769           break;
770         }
771     }
772 
773 # else  /* (too) big unroll */
774   for (;; p += 4)
775     {
776       unsigned char ch0, ch1, ch2, ch3;
777 
778       ch0 = *p;
779       if (MY_PREDICT_FALSE(!MY_IS_BLANK(ch0)))
780         {
781           if (!ch0)
782             return NULL;
783           break;
784         }
785       ch1 = p[1];
786       if (MY_PREDICT_TRUE(!MY_IS_BLANK(ch1)))
787         {
788           if (!ch1)
789             return NULL;
790           p += 1;
791           break;
792         }
793       ch2 = p[2];
794       if (MY_PREDICT_FALSE(!MY_IS_BLANK(ch2)))
795         {
796           if (!ch2)
797             return NULL;
798           p += 2;
799           break;
800         }
801       ch3 = p[3];
802       if (MY_PREDICT_TRUE(!MY_IS_BLANK(ch3)))
803         {
804           if (!ch3)
805             return NULL;
806           p += 3;
807           break;
808         }
809     }
810 # endif
811 
812   /* skip ahead until EOS or blanks. */
813 # if 0 /* a moderate version */
814   for (e = p + 1;  ; e++)
815     {
816       unsigned char ch = *e;
817       if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch)))
818         break;
819     }
820 # else  /* (too) big unroll */
821   for (e = p + 1;  ; e += 4)
822     {
823       unsigned char ch0, ch1, ch2, ch3;
824 
825       ch0 = *e;
826       if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch0)))
827         break;
828       ch1 = e[1];
829       if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch1)))
830         {
831           e += 1;
832           break;
833         }
834       ch2 = e[2];
835       if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch2)))
836         {
837           e += 2;
838           break;
839         }
840       ch3 = e[3];
841       if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch3)))
842         {
843           e += 3;
844           break;
845         }
846     }
847 # endif
848   *ptr = e;
849 
850   if (lengthptr != 0)
851     *lengthptr = e - p;
852 
853   return (char *)p;
854 
855 #else
856   const char *p = next_token (*ptr);
857 
858   if (*p == '\0')
859     return 0;
860 
861   *ptr = end_of_token (p);
862   if (lengthptr != 0)
863     *lengthptr = *ptr - p;
864 
865   return (char *)p;
866 #endif
867 }
868 #ifdef KMK
869 
870 /* Same as find_next_token with two exception:
871       - The string ends at EOS or '\0'.
872       - We keep track of $() and ${}, allowing functions to be used. */
873 
874 char *
find_next_token_eos(const char ** ptr,const char * eos,unsigned int * lengthptr)875 find_next_token_eos (const char **ptr, const char *eos, unsigned int *lengthptr)
876 {
877   const char *p = *ptr;
878   const char *e;
879   int level = 0;
880 
881   /* skip blanks */
882   for (; p != eos; p++)
883     {
884       unsigned char ch = *p;
885       if (!MY_IS_BLANK(ch))
886         {
887           if (!ch)
888             return NULL;
889           break;
890         }
891     }
892   if (p == eos)
893     return NULL;
894 
895   /* skip ahead until EOS or blanks. */
896   for (e = p; e != eos; e++)
897     {
898       unsigned char ch = *e;
899       if (MY_IS_BLANK_OR_EOS(ch))
900         {
901           if (!ch || level == 0)
902             break;
903         }
904       else if (ch == '$')
905         {
906           if (&e[1] != eos && (e[1] == '(' || e[1] == '{'))
907             {
908               level++;
909               e++;
910             }
911         }
912       else if ((ch == ')' || ch == '}') &&  level > 0)
913         level--;
914     }
915 
916   *ptr = e;
917   if (lengthptr != 0)
918     *lengthptr = e - p;
919 
920   return (char *)p;
921 }
922 
923 #endif /* KMK */
924 
925 
926 /* Copy a chain of `struct dep'.  For 2nd expansion deps, dup the name.  */
927 
928 struct dep *
copy_dep_chain(const struct dep * d)929 copy_dep_chain (const struct dep *d)
930 {
931   struct dep *firstnew = 0;
932   struct dep *lastnew = 0;
933 
934   while (d != 0)
935     {
936 #ifndef CONFIG_WITH_ALLOC_CACHES
937       struct dep *c = xmalloc (sizeof (struct dep));
938 #else
939       struct dep *c = alloccache_alloc(&dep_cache);
940 #endif
941       memcpy (c, d, sizeof (struct dep));
942 
943       /** @todo KMK: Check if we need this duplication! */
944       if (c->need_2nd_expansion)
945         c->name = xstrdup (c->name);
946 
947       c->next = 0;
948       if (firstnew == 0)
949 	firstnew = lastnew = c;
950       else
951 	lastnew = lastnew->next = c;
952 
953       d = d->next;
954     }
955 
956   return firstnew;
957 }
958 
959 /* Free a chain of 'struct dep'.  */
960 
961 void
free_dep_chain(struct dep * d)962 free_dep_chain (struct dep *d)
963 {
964   while (d != 0)
965     {
966       struct dep *df = d;
967       d = d->next;
968       free_dep (df);
969     }
970 }
971 
972 /* Free a chain of struct nameseq.
973    For struct dep chains use free_dep_chain.  */
974 
975 void
free_ns_chain(struct nameseq * ns)976 free_ns_chain (struct nameseq *ns)
977 {
978   while (ns != 0)
979     {
980       struct nameseq *t = ns;
981       ns = ns->next;
982 #ifndef CONFIG_WITH_ALLOC_CACHES
983       free (t);
984 #else
985       alloccache_free (&nameseq_cache, t);
986 #endif
987     }
988 }
989 
990 
991 #if !HAVE_STRCASECMP && !HAVE_STRICMP && !HAVE_STRCMPI
992 
993 /* If we don't have strcasecmp() (from POSIX), or anything that can substitute
994    for it, define our own version.  */
995 
996 int
strcasecmp(const char * s1,const char * s2)997 strcasecmp (const char *s1, const char *s2)
998 {
999   while (1)
1000     {
1001       int c1 = (int) *(s1++);
1002       int c2 = (int) *(s2++);
1003 
1004       if (isalpha (c1))
1005         c1 = tolower (c1);
1006       if (isalpha (c2))
1007         c2 = tolower (c2);
1008 
1009       if (c1 != '\0' && c1 == c2)
1010         continue;
1011 
1012       return (c1 - c2);
1013     }
1014 }
1015 #endif
1016 
1017 #if !HAVE_STRNCASECMP && !HAVE_STRNICMP && !HAVE_STRNCMPI
1018 
1019 /* If we don't have strncasecmp() (from POSIX), or anything that can
1020    substitute for it, define our own version.  */
1021 
1022 int
strncasecmp(const char * s1,const char * s2,int n)1023 strncasecmp (const char *s1, const char *s2, int n)
1024 {
1025   while (n-- > 0)
1026     {
1027       int c1 = (int) *(s1++);
1028       int c2 = (int) *(s2++);
1029 
1030       if (isalpha (c1))
1031         c1 = tolower (c1);
1032       if (isalpha (c2))
1033         c2 = tolower (c2);
1034 
1035       if (c1 != '\0' && c1 == c2)
1036         continue;
1037 
1038       return (c1 - c2);
1039     }
1040 
1041   return 0;
1042 }
1043 #endif
1044 
1045 #ifdef	GETLOADAVG_PRIVILEGED
1046 
1047 #ifdef POSIX
1048 
1049 /* Hopefully if a system says it's POSIX.1 and has the setuid and setgid
1050    functions, they work as POSIX.1 says.  Some systems (Alpha OSF/1 1.2,
1051    for example) which claim to be POSIX.1 also have the BSD setreuid and
1052    setregid functions, but they don't work as in BSD and only the POSIX.1
1053    way works.  */
1054 
1055 #undef HAVE_SETREUID
1056 #undef HAVE_SETREGID
1057 
1058 #else	/* Not POSIX.  */
1059 
1060 /* Some POSIX.1 systems have the seteuid and setegid functions.  In a
1061    POSIX-like system, they are the best thing to use.  However, some
1062    non-POSIX systems have them too but they do not work in the POSIX style
1063    and we must use setreuid and setregid instead.  */
1064 
1065 #undef HAVE_SETEUID
1066 #undef HAVE_SETEGID
1067 
1068 #endif	/* POSIX.  */
1069 
1070 #ifndef	HAVE_UNISTD_H
1071 extern int getuid (), getgid (), geteuid (), getegid ();
1072 extern int setuid (), setgid ();
1073 #ifdef HAVE_SETEUID
1074 extern int seteuid ();
1075 #else
1076 #ifdef	HAVE_SETREUID
1077 extern int setreuid ();
1078 #endif	/* Have setreuid.  */
1079 #endif	/* Have seteuid.  */
1080 #ifdef HAVE_SETEGID
1081 extern int setegid ();
1082 #else
1083 #ifdef	HAVE_SETREGID
1084 extern int setregid ();
1085 #endif	/* Have setregid.  */
1086 #endif	/* Have setegid.  */
1087 #endif	/* No <unistd.h>.  */
1088 
1089 /* Keep track of the user and group IDs for user- and make- access.  */
1090 static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1;
1091 #define	access_inited	(user_uid != -1)
1092 static enum { make, user } current_access;
1093 
1094 
1095 /* Under -d, write a message describing the current IDs.  */
1096 
1097 static void
log_access(const char * flavor)1098 log_access (const char *flavor)
1099 {
1100   if (! ISDB (DB_JOBS))
1101     return;
1102 
1103   /* All the other debugging messages go to stdout,
1104      but we write this one to stderr because it might be
1105      run in a child fork whose stdout is piped.  */
1106 
1107   fprintf (stderr, _("%s: user %lu (real %lu), group %lu (real %lu)\n"),
1108 	   flavor, (unsigned long) geteuid (), (unsigned long) getuid (),
1109            (unsigned long) getegid (), (unsigned long) getgid ());
1110   fflush (stderr);
1111 }
1112 
1113 
1114 static void
init_access(void)1115 init_access (void)
1116 {
1117 #ifndef VMS
1118   user_uid = getuid ();
1119   user_gid = getgid ();
1120 
1121   make_uid = geteuid ();
1122   make_gid = getegid ();
1123 
1124   /* Do these ever fail?  */
1125   if (user_uid == -1 || user_gid == -1 || make_uid == -1 || make_gid == -1)
1126     pfatal_with_name ("get{e}[gu]id");
1127 
1128   log_access (_("Initialized access"));
1129 
1130   current_access = make;
1131 #endif
1132 }
1133 
1134 #endif	/* GETLOADAVG_PRIVILEGED */
1135 
1136 /* Give the process appropriate permissions for access to
1137    user data (i.e., to stat files, or to spawn a child process).  */
1138 void
user_access(void)1139 user_access (void)
1140 {
1141 #ifdef	GETLOADAVG_PRIVILEGED
1142 
1143   if (!access_inited)
1144     init_access ();
1145 
1146   if (current_access == user)
1147     return;
1148 
1149   /* We are in "make access" mode.  This means that the effective user and
1150      group IDs are those of make (if it was installed setuid or setgid).
1151      We now want to set the effective user and group IDs to the real IDs,
1152      which are the IDs of the process that exec'd make.  */
1153 
1154 #ifdef	HAVE_SETEUID
1155 
1156   /* Modern systems have the seteuid/setegid calls which set only the
1157      effective IDs, which is ideal.  */
1158 
1159   if (seteuid (user_uid) < 0)
1160     pfatal_with_name ("user_access: seteuid");
1161 
1162 #else	/* Not HAVE_SETEUID.  */
1163 
1164 #ifndef	HAVE_SETREUID
1165 
1166   /* System V has only the setuid/setgid calls to set user/group IDs.
1167      There is an effective ID, which can be set by setuid/setgid.
1168      It can be set (unless you are root) only to either what it already is
1169      (returned by geteuid/getegid, now in make_uid/make_gid),
1170      the real ID (return by getuid/getgid, now in user_uid/user_gid),
1171      or the saved set ID (what the effective ID was before this set-ID
1172      executable (make) was exec'd).  */
1173 
1174   if (setuid (user_uid) < 0)
1175     pfatal_with_name ("user_access: setuid");
1176 
1177 #else	/* HAVE_SETREUID.  */
1178 
1179   /* In 4BSD, the setreuid/setregid calls set both the real and effective IDs.
1180      They may be set to themselves or each other.  So you have two alternatives
1181      at any one time.  If you use setuid/setgid, the effective will be set to
1182      the real, leaving only one alternative.  Using setreuid/setregid, however,
1183      you can toggle between your two alternatives by swapping the values in a
1184      single setreuid or setregid call.  */
1185 
1186   if (setreuid (make_uid, user_uid) < 0)
1187     pfatal_with_name ("user_access: setreuid");
1188 
1189 #endif	/* Not HAVE_SETREUID.  */
1190 #endif	/* HAVE_SETEUID.  */
1191 
1192 #ifdef	HAVE_SETEGID
1193   if (setegid (user_gid) < 0)
1194     pfatal_with_name ("user_access: setegid");
1195 #else
1196 #ifndef	HAVE_SETREGID
1197   if (setgid (user_gid) < 0)
1198     pfatal_with_name ("user_access: setgid");
1199 #else
1200   if (setregid (make_gid, user_gid) < 0)
1201     pfatal_with_name ("user_access: setregid");
1202 #endif
1203 #endif
1204 
1205   current_access = user;
1206 
1207   log_access (_("User access"));
1208 
1209 #endif	/* GETLOADAVG_PRIVILEGED */
1210 }
1211 
1212 /* Give the process appropriate permissions for access to
1213    make data (i.e., the load average).  */
1214 void
make_access(void)1215 make_access (void)
1216 {
1217 #ifdef	GETLOADAVG_PRIVILEGED
1218 
1219   if (!access_inited)
1220     init_access ();
1221 
1222   if (current_access == make)
1223     return;
1224 
1225   /* See comments in user_access, above.  */
1226 
1227 #ifdef	HAVE_SETEUID
1228   if (seteuid (make_uid) < 0)
1229     pfatal_with_name ("make_access: seteuid");
1230 #else
1231 #ifndef	HAVE_SETREUID
1232   if (setuid (make_uid) < 0)
1233     pfatal_with_name ("make_access: setuid");
1234 #else
1235   if (setreuid (user_uid, make_uid) < 0)
1236     pfatal_with_name ("make_access: setreuid");
1237 #endif
1238 #endif
1239 
1240 #ifdef	HAVE_SETEGID
1241   if (setegid (make_gid) < 0)
1242     pfatal_with_name ("make_access: setegid");
1243 #else
1244 #ifndef	HAVE_SETREGID
1245   if (setgid (make_gid) < 0)
1246     pfatal_with_name ("make_access: setgid");
1247 #else
1248   if (setregid (user_gid, make_gid) < 0)
1249     pfatal_with_name ("make_access: setregid");
1250 #endif
1251 #endif
1252 
1253   current_access = make;
1254 
1255   log_access (_("Make access"));
1256 
1257 #endif	/* GETLOADAVG_PRIVILEGED */
1258 }
1259 
1260 /* Give the process appropriate permissions for a child process.
1261    This is like user_access, but you can't get back to make_access.  */
1262 void
child_access(void)1263 child_access (void)
1264 {
1265 #ifdef	GETLOADAVG_PRIVILEGED
1266 
1267   if (!access_inited)
1268     abort ();
1269 
1270   /* Set both the real and effective UID and GID to the user's.
1271      They cannot be changed back to make's.  */
1272 
1273 #ifndef	HAVE_SETREUID
1274   if (setuid (user_uid) < 0)
1275     pfatal_with_name ("child_access: setuid");
1276 #else
1277   if (setreuid (user_uid, user_uid) < 0)
1278     pfatal_with_name ("child_access: setreuid");
1279 #endif
1280 
1281 #ifndef	HAVE_SETREGID
1282   if (setgid (user_gid) < 0)
1283     pfatal_with_name ("child_access: setgid");
1284 #else
1285   if (setregid (user_gid, user_gid) < 0)
1286     pfatal_with_name ("child_access: setregid");
1287 #endif
1288 
1289   log_access (_("Child access"));
1290 
1291 #endif	/* GETLOADAVG_PRIVILEGED */
1292 }
1293 
1294 #ifdef NEED_GET_PATH_MAX
1295 unsigned int
get_path_max(void)1296 get_path_max (void)
1297 {
1298   static unsigned int value;
1299 
1300   if (value == 0)
1301     {
1302       long int x = pathconf ("/", _PC_PATH_MAX);
1303       if (x > 0)
1304 	value = x;
1305       else
1306 	return MAXPATHLEN;
1307     }
1308 
1309   return value;
1310 }
1311 #endif
1312 
1313 
1314 /* This code is stolen from gnulib.
1315    If/when we abandon the requirement to work with K&R compilers, we can
1316    remove this (and perhaps other parts of GNU make!) and migrate to using
1317    gnulib directly.
1318 
1319    This is called only through atexit(), which means die() has already been
1320    invoked.  So, call exit() here directly.  Apparently that works...?
1321 */
1322 
1323 /* Close standard output, exiting with status 'exit_failure' on failure.
1324    If a program writes *anything* to stdout, that program should close
1325    stdout and make sure that it succeeds before exiting.  Otherwise,
1326    suppose that you go to the extreme of checking the return status
1327    of every function that does an explicit write to stdout.  The last
1328    printf can succeed in writing to the internal stream buffer, and yet
1329    the fclose(stdout) could still fail (due e.g., to a disk full error)
1330    when it tries to write out that buffered data.  Thus, you would be
1331    left with an incomplete output file and the offending program would
1332    exit successfully.  Even calling fflush is not always sufficient,
1333    since some file systems (NFS and CODA) buffer written/flushed data
1334    until an actual close call.
1335 
1336    Besides, it's wasteful to check the return value from every call
1337    that writes to stdout -- just let the internal stream state record
1338    the failure.  That's what the ferror test is checking below.
1339 
1340    It's important to detect such failures and exit nonzero because many
1341    tools (most notably `make' and other build-management systems) depend
1342    on being able to detect failure in other tools via their exit status.  */
1343 
1344 void
close_stdout(void)1345 close_stdout (void)
1346 {
1347   int prev_fail = ferror (stdout);
1348   int fclose_fail = fclose (stdout);
1349 
1350   if (prev_fail || fclose_fail)
1351     {
1352       if (fclose_fail)
1353         error (NILF, _("write error: %s"), strerror (errno));
1354       else
1355         error (NILF, _("write error"));
1356       exit (EXIT_FAILURE);
1357     }
1358 }
1359 
1360 #ifdef CONFIG_WITH_PRINT_STATS_SWITCH
1361 /* Print heap statistics if supported by the platform. */
1362 void
print_heap_stats(void)1363 print_heap_stats (void)
1364 {
1365   /* Darwin / Mac OS X */
1366 # ifdef __APPLE__
1367   malloc_statistics_t s;
1368 
1369   malloc_zone_statistics (NULL, &s);
1370   printf (_("\n# CRT Heap: %u bytes in use, in %u blocks, avg %u bytes/block\n"),
1371           (unsigned)s.size_in_use, (unsigned)s.blocks_in_use,
1372           (unsigned)(s.size_in_use / s.blocks_in_use));
1373   printf (_("#           %u bytes max in use (high water mark)\n"),
1374           (unsigned)s.max_size_in_use);
1375   printf (_("#           %u bytes reserved,  %u bytes free (estimate)\n"),
1376           (unsigned)s.size_allocated,
1377           (unsigned)(s.size_allocated - s.size_in_use));
1378 # endif /* __APPLE__ */
1379 
1380   /* MSC / Windows  */
1381 # ifdef _MSC_VER
1382   unsigned int blocks_used = 0;
1383   unsigned int bytes_used = 0;
1384   unsigned int blocks_avail = 0;
1385   unsigned int bytes_avail = 0;
1386   _HEAPINFO hinfo;
1387 
1388   memset (&hinfo, '\0', sizeof (hinfo));
1389   while (_heapwalk(&hinfo) == _HEAPOK)
1390     {
1391       if (hinfo._useflag == _USEDENTRY)
1392         {
1393           blocks_used++;
1394           bytes_used += hinfo._size;
1395         }
1396       else
1397         {
1398           blocks_avail++;
1399           bytes_avail += hinfo._size;
1400         }
1401     }
1402 
1403   printf (_("\n# CRT Heap: %u bytes in use, in %u blocks, avg %u bytes/block\n"),
1404           bytes_used, blocks_used, bytes_used / blocks_used);
1405   printf (_("#           %u bytes avail, in %u blocks, avg %u bytes/block\n"),
1406           bytes_avail, blocks_avail, bytes_avail / blocks_avail);
1407 # endif /* _MSC_VER */
1408 
1409   /* Darwin Libc sources indicates that something like this may be
1410      found in GLIBC, however, it's not in any current one...  */
1411 # if 0 /* ??? */
1412   struct mstats m;
1413 
1414   m = mstats();
1415   printf (_("\n# CRT Heap: %zu blocks / %zu bytes in use,  %zu blocks / %zu bytes free\n"),
1416           m.chunks_used, m.bytes_used, m.chunks_free, m.bytes_free);
1417   printf (_("#           %zu bytes reserved\n"),
1418           m.bytes_total);
1419 # endif /* ??? */
1420 
1421    /* XVID2/XPG mallinfo (displayed per GLIBC documentation).  */
1422 # if defined(__GLIBC__) || defined(HAVE_MALLINFO)
1423   struct mallinfo m;
1424 
1425   m = mallinfo();
1426   printf (_("\n# CRT Heap: %d bytes in use,  %d bytes free\n"),
1427           m.uordblks, m.fordblks);
1428 
1429   printf (_("#           # free chunks=%d,  # fastbin blocks=%d\n"),
1430           m.ordblks, m.smblks);
1431   printf (_("#           # mapped regions=%d,  space in mapped regions=%d\n"),
1432           m.hblks, m.hblkhd);
1433   printf (_("#           non-mapped space allocated from system=%d\n"),
1434           m.arena);
1435   printf (_("#           maximum total allocated space=%d\n"),
1436           m.usmblks);
1437   printf (_("#           top-most releasable space=%d\n"),
1438           m.keepcost);
1439 # endif /* __GLIBC__ || HAVE_MALLINFO */
1440 
1441 # ifdef CONFIG_WITH_MAKE_STATS
1442   printf(_("#            %lu malloc calls,  %lu realloc calls\n"),
1443          make_stats_allocations, make_stats_reallocations);
1444   printf(_("#            %lu MBs alloc sum, not counting freed, add pinch of salt\n"), /* XXX: better wording */
1445          make_stats_allocated / (1024*1024));
1446 # endif
1447 
1448   /* XXX: windows */
1449 }
1450 #endif /* CONFIG_WITH_PRINT_STATS_SWITCH */
1451 
1452 #ifdef CONFIG_WITH_PRINT_TIME_SWITCH
1453 /* Get a nanosecond timestamp, from a monotonic time source if
1454    possible.  Returns -1 after calling error() on failure.  */
1455 
1456 big_int
nano_timestamp(void)1457 nano_timestamp (void)
1458 {
1459   big_int ts;
1460 #if defined (WINDOWS32)
1461   static int s_state = -1;
1462   static LARGE_INTEGER s_freq;
1463 
1464   if (s_state == -1)
1465     s_state = QueryPerformanceFrequency (&s_freq);
1466   if (s_state)
1467     {
1468       LARGE_INTEGER pc;
1469       if (!QueryPerformanceCounter (&pc))
1470         {
1471           s_state = 0;
1472           return nano_timestamp ();
1473         }
1474       ts = (big_int)((long double)pc.QuadPart / (long double)s_freq.QuadPart * 1000000000);
1475     }
1476   else
1477     {
1478       /* fall back to low resolution system time. */
1479       LARGE_INTEGER bigint;
1480       FILETIME ft = {0,0};
1481       GetSystemTimeAsFileTime (&ft);
1482       bigint.u.LowPart = ft.dwLowDateTime;
1483       bigint.u.HighPart = ft.dwLowDateTime;
1484       ts = bigint.QuadPart * 100;
1485     }
1486 
1487 #elif HAVE_GETTIMEOFDAY
1488 /* FIXME: Linux and others have the realtime clock_* api, detect and use it. */
1489   struct timeval tv;
1490   if (!gettimeofday (&tv, NULL))
1491     ts = (big_int)tv.tv_sec * 1000000000
1492        + tv.tv_usec * 1000;
1493   else
1494     {
1495       error (NILF, _("gettimeofday failed"));
1496       ts = -1;
1497     }
1498 
1499 #else
1500 # error "PORTME"
1501 #endif
1502 
1503   return ts;
1504 }
1505 
1506 /* Formats the elapsed time (nano seconds) in the manner easiest
1507    to read, with millisecond percision for larger numbers.  */
1508 
1509 int
format_elapsed_nano(char * buf,size_t size,big_int ts)1510 format_elapsed_nano (char *buf, size_t size, big_int ts)
1511 {
1512   unsigned sz;
1513   if (ts < 1000)
1514     sz = sprintf (buf, "%uns", (unsigned)ts);
1515   else if (ts < 100000)
1516     sz = sprintf (buf, "%u.%03uus",
1517                   (unsigned)(ts / 1000),
1518                   (unsigned)(ts % 1000));
1519   else
1520     {
1521       ts /= 1000;
1522       if (ts < 1000)
1523         sz = sprintf (buf, "%uus", (unsigned)ts);
1524       else if (ts < 100000)
1525         sz = sprintf (buf, "%u.%03ums",
1526                       (unsigned)(ts / 1000),
1527                       (unsigned)(ts % 1000));
1528       else
1529         {
1530           ts /= 1000;
1531           if (ts < BIG_INT_C(60000))
1532             sz = sprintf (buf,
1533                           "%u.%03us",
1534                           (unsigned)(ts / 1000),
1535                           (unsigned)(ts % 1000));
1536           else
1537             sz = sprintf (buf,
1538                           "%um%u.%03us",
1539                           (unsigned)( ts / BIG_INT_C(60000)),
1540                           (unsigned)((ts % BIG_INT_C(60000)) / 1000),
1541                           (unsigned)((ts % BIG_INT_C(60000)) % 1000));
1542         }
1543     }
1544   if (sz >= size)
1545     fatal (NILF, _("format_elapsed_nano buffer overflow: %u written, %lu buffer"),
1546            sz, (unsigned long)size);
1547   return sz;
1548 }
1549 #endif /* CONFIG_WITH_PRINT_TIME_SWITCH */
1550