Annotation of binutils/make.c, revision 1.1

1.1     ! root        1: /* `make' - recompile files as needed.
        !             2:    Copyright (C) 1988 Free Software Foundation, Inc.
        !             3:    written by Richard Stallman and Roland McGrath.
        !             4: 
        !             5:                       NO WARRANTY
        !             6: 
        !             7:   BECAUSE GNU MAKE IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
        !             8: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
        !             9: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
        !            10: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE GNU MAKE "AS IS"
        !            11: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
        !            12: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
        !            13: FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
        !            14: AND PERFORMANCE OF GNU MAKE IS WITH YOU.  SHOULD GNU MAKE PROVE
        !            15: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
        !            16: CORRECTION.
        !            17: 
        !            18:  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
        !            19: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
        !            20: WHO MAY MODIFY AND REDISTRIBUTE GNU MAKE AS PERMITTED BELOW, BE
        !            21: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
        !            22: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
        !            23: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
        !            24: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
        !            25: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GNU MAKE,
        !            26: EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
        !            27: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
        !            28: 
        !            29:                GENERAL PUBLIC LICENSE TO COPY
        !            30: 
        !            31:   1. You may copy and distribute verbatim copies of GNU Make source
        !            32: code as you receive it, in any medium, provided that you conspicuously
        !            33: and appropriately publish on each copy a valid copyright notice
        !            34: "Copyright (C) 1988 Free Software Foundation, Inc." (or with whatever
        !            35: year is appropriate), and include following the copyright notice a
        !            36: verbatim copy of the above disclaimer of warranty and of this License.
        !            37: You may charge a distribution fee for the physical act of transferring
        !            38: a copy.
        !            39: 
        !            40:   2. You may modify your copy or copies of GNU Make or
        !            41: any portion of it, and copy and distribute such modifications under
        !            42: the terms of Paragraph 1 above, provided that you also do the following:
        !            43: 
        !            44:     a) cause the modified files to carry prominent notices stating
        !            45:     that you changed the files and the date of any change; and
        !            46: 
        !            47:     b) cause the whole of any work that you distribute or publish,
        !            48:     that in whole or in part contains or is a derivative of GNU Make
        !            49:     or any part thereof, to be licensed at no charge to all
        !            50:     third parties on terms identical to those contained in this
        !            51:     License Agreement (except that you may choose to grant more extensive
        !            52:     warranty protection to some or all third parties, at your option).
        !            53: 
        !            54:     c) You may charge a distribution fee for the physical act of
        !            55:     transferring a copy, and you may at your option offer warranty
        !            56:     protection in exchange for a fee.
        !            57: 
        !            58: Mere aggregation of another unrelated program with this program (or its
        !            59: derivative) on a volume of a storage or distribution medium does not bring
        !            60: the other program under the scope of these terms.
        !            61: 
        !            62:   3. You may copy and distribute GNU Make (or a portion or derivative
        !            63: of it, under Paragraph 2) in object code or executable form under the terms
        !            64: of Paragraphs 1 and 2 above provided that you also do one of the following:
        !            65: 
        !            66:     a) accompany it with the complete corresponding machine-readable
        !            67:     source code, which must be distributed under the terms of
        !            68:     Paragraphs 1 and 2 above; or,
        !            69: 
        !            70:     b) accompany it with a written offer, valid for at least three
        !            71:     years, to give any third party free (except for a nominal
        !            72:     shipping charge) a complete machine-readable copy of the
        !            73:     corresponding source code, to be distributed under the terms of
        !            74:     Paragraphs 1 and 2 above; or,
        !            75: 
        !            76:     c) accompany it with the information you received as to where the
        !            77:     corresponding source code may be obtained.  (This alternative is
        !            78:     allowed only for noncommercial distribution and only if you
        !            79:     received the program in object code or executable form alone.)
        !            80: 
        !            81: For an executable file, complete source code means all the source code for
        !            82: all modules it contains; but, as a special exception, it need not include
        !            83: source code for modules which are standard libraries that accompany the
        !            84: operating system on which the executable file runs.
        !            85: 
        !            86:   4. You may not copy, sublicense, distribute or transfer GNU Make
        !            87: except as expressly provided under this License Agreement.  Any attempt
        !            88: otherwise to copy, sublicense, distribute or transfer GNU Make is void and
        !            89: your rights to use the program under this License agreement shall be
        !            90: automatically terminated.  However, parties who have received computer
        !            91: software programs from you with this License Agreement will not have
        !            92: their licenses terminated so long as such parties remain in full compliance.
        !            93: 
        !            94:   5. If you wish to incorporate parts of GNU Make into other free
        !            95: programs whose distribution conditions are different, write to the Free
        !            96: Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
        !            97: worked out a simple rule that can be stated here, but we will often permit
        !            98: this.  We will be guided by the two goals of preserving the free status of
        !            99: all derivatives of our free software and of promoting the sharing and reuse of
        !           100: software.
        !           101: 
        !           102:  In other words, you are welcome to use, share and improve this program.
        !           103:  You are forbidden to forbid anyone else to use, share and improve
        !           104:  what you give them.   Help stamp out software-hoarding!  */
        !           105: 
        !           106: #if 0  /* dummy tags for etags */
        !           107: endcopyr (){}
        !           108: endcopyright (){}
        !           109: endlicense (){}
        !           110: #endif
        !           111: 
        !           112: #if 0  /* dummy tags for etags */
        !           113: rcs (){}
        !           114: log (){}
        !           115: #endif
        !           116: 
        !           117: /*
        !           118:  * $Header: make.c,v 2.9 88/07/10 17:40:53 mcgrath Rel $
        !           119:  *
        !           120:  $Log: make.c,v $
        !           121:  * Revision 2.9  88/07/10  17:40:53  mcgrath
        !           122:  * Fixed a really stupid bug in command execution.
        !           123:  * This was really DUMB!  Somebody hit me for being so dumb.
        !           124:  * 
        !           125:  * Revision 2.8  88/07/10  15:53:55  mcgrath
        !           126:  * Fixed a debug message that needed a newline.
        !           127:  * 
        !           128:  * Revision 2.7  88/07/09  23:15:05  mcgrath
        !           129:  * * Fixed bug in comment handling.
        !           130:  * * Misc cleanup.
        !           131:  * * Made -p output distinguish flavors of variables by using = or :=.
        !           132:  * 
        !           133:  * Revision 2.6  88/07/03  20:10:58  mcgrath
        !           134:  * * Made $* be set to % stem for static pattern rules.
        !           135:  * * Added `word' and `words' functions.
        !           136:  * 
        !           137:  * Revision 2.5  88/07/03  12:42:55  mcgrath
        !           138:  * Fixed bug in recursive variable expansion.
        !           139:  * 
        !           140:  * Revision 2.4  88/07/02  12:12:45  mcgrath
        !           141:  * * Added System V support; #define USG.
        !           142:  * * Fixed a bug in ifeq.
        !           143:  * (From RMS.)
        !           144:  * 
        !           145:  * Revision 2.3  88/07/01  21:06:45  mcgrath
        !           146:  * Made it flush stderr after printing a "*** Error N (ignored)" message.
        !           147:  * 
        !           148:  * Revision 2.2  88/06/29  23:59:39  mcgrath
        !           149:  * Declared some functions to prevent GCC warnings.
        !           150:  * 
        !           151:  * Revision 2.1  88/06/29  23:50:28  mcgrath
        !           152:  * Made default variable values (CC = cc, etc.) not override
        !           153:  * definitions from the environment.
        !           154:  * 
        !           155:  * Revision 2.0  88/06/28  21:57:40  mcgrath
        !           156:  * Second release.
        !           157:  * 
        !           158:  * Revision 1.66  88/06/19  16:34:15  mcgrath
        !           159:  * Made it continue after ignored errors.
        !           160:  * 
        !           161:  * Revision 1.65  88/06/19  15:36:13  mcgrath
        !           162:  * Added variable references inside variable references.
        !           163:  * E.g.: $($(x)) ==> $(y) when x = y.  They are recursive so that
        !           164:  * if x = $(y) and y = z (notice recursive variable definitions),
        !           165:  * then $($(x)) goes -> $($(y)) -> $(z) -> value of z.
        !           166:  * 
        !           167:  * Revision 1.64  88/06/18  21:21:11  mcgrath
        !           168:  * Fixed an error message.
        !           169:  * 
        !           170:  * Revision 1.63  88/06/18  13:59:47  mcgrath
        !           171:  * Made error messages use the name of invokation instead
        !           172:  * of always using `make'.
        !           173:  * 
        !           174:  * Revision 1.62  88/06/18  13:35:05  mcgrath
        !           175:  * * Fixed up some error messages.
        !           176:  * * Made it say "*** Error n (ignored)" rather than nothing under -i.
        !           177:  * * Put run_shell_command inside execute_command_line.
        !           178:  * 
        !           179:  * Revision 1.61  88/06/17  20:59:49  mcgrath
        !           180:  * * Removed Bourne shell $(a-b), etc. variable reference constructs.
        !           181:  * * It is not longer a fatal error if Make doesn't know how to make
        !           182:  *   a file when -k is in effect.
        !           183:  * 
        !           184:  * Revision 1.60  88/06/15  01:33:29  mcgrath
        !           185:  * Made `foreach' control variables always be nonrecursive.
        !           186:  * They are restored to whatever recursiveness and value they
        !           187:  * had before the `foreach' call when it is done.
        !           188:  * 
        !           189:  * Revision 1.59  88/06/14  21:33:18  mcgrath
        !           190:  * Moved .s to the end of the default suffix list.
        !           191:  * 
        !           192:  * Revision 1.59  88/06/12  03:00:00  rms
        !           193:  * Move .s to end of default suffix list.
        !           194:  *
        !           195:  * Revision 1.58  88/06/10  11:01:41  mcgrath
        !           196:  * Removed an unused variable.
        !           197:  * 
        !           198:  * Revision 1.57  88/06/09  21:31:13  mcgrath
        !           199:  * Fixed a bug in dealing with double-colon files.
        !           200:  * 
        !           201:  * Revision 1.56  88/06/02  15:22:18  mcgrath
        !           202:  * Changed RCS rules to give both the RCS filename and the working
        !           203:  * filename to `co' so the workfile will go in the right place if they
        !           204:  * have different paths for some weird reason.
        !           205:  * 
        !           206:  * Revision 1.55  88/06/02  14:52:47  mcgrath
        !           207:  * Made pattern_search and selective_vpath_search consider files
        !           208:  * mentioned in makefiles to be existent even if they are not targets.
        !           209:  * 
        !           210:  * Revision 1.54  88/05/31  00:40:34  mcgrath
        !           211:  * Made recursive variables referenced with $X work right.
        !           212:  * 
        !           213:  * Revision 1.53  88/05/30  20:31:20  mcgrath
        !           214:  * * Made converted single-suffix (".o:", etc.) rules nonterminal.
        !           215:  * * Added `foreach' and `sort' functions.
        !           216:  * 
        !           217:  * Revision 1.52  88/05/29  19:19:15  mcgrath
        !           218:  * Doubled-up a `%' in a printf format.
        !           219:  * 
        !           220:  * Revision 1.51  88/05/26  18:31:37  mcgrath
        !           221:  * * Removed built-in suffix rules for .? -> .s
        !           222:  * * Rewrote precious intermediate file pattern stuff to work right.
        !           223:  * 
        !           224:  * Revision 1.50  88/05/22  14:48:17  mcgrath
        !           225:  * Major Beta release before release 2.0.
        !           226:  * 
        !           227:  * Revision 1.25  88/05/22  14:29:21  mcgrath
        !           228:  * Fixed minor bug
        !           229:  * 
        !           230:  * Revision 1.24  88/05/21  16:39:54  mcgrath
        !           231:  * Fixed idiotic (really; I'm losing it) bug in -w stuff.  (sigh)
        !           232:  * 
        !           233:  * Revision 1.23  88/05/20  21:38:59  mcgrath
        !           234:  * Changed to use new globbing function `glob_filename'.
        !           235:  * 
        !           236:  * Revision 1.22  88/05/18  23:26:15  mcgrath
        !           237:  * Fixed stupid incorrect lengths for `filter' and `filter-out'
        !           238:  * in `function_table'.
        !           239:  * 
        !           240:  * Revision 1.21  88/05/18  20:56:55  mcgrath
        !           241:  * Removed the `struct ruleset' stuff; did extended static rules
        !           242:  * in a much simpler way.  The new syntax is for example,
        !           243:  * `*.o: %.o: %.c'.  It is a non-fatal error for the rule target (*.o)
        !           244:  * not to match the pattern target (%.o).
        !           245:  * 
        !           246:  * Revision 1.20  88/05/17  23:10:28  mcgrath
        !           247:  * Made it a fatal error to use the `LIB((NAME))' syntax.
        !           248:  * 
        !           249:  * Revision 1.19  88/05/17  22:30:37  mcgrath
        !           250:  * Fixed some bugs introduced by the bugfix in the last version (sigh).
        !           251:  * 
        !           252:  * Revision 1.18  88/05/16  17:47:01  mcgrath
        !           253:  * * Changed touching back to reading and writing rather than using utimes.
        !           254:  * * Changed nonwarranty notice.
        !           255:  * * Changed the way RCS keywords are handled for version information.
        !           256:  * 
        !           257:  * Revision 1.17  88/05/15  17:50:11  mcgrath
        !           258:  * Made most references to the `name' field of a `struct dep' use
        !           259:  * the macro `dep_name (d)' which uses `d->name' if it is not nil and
        !           260:  * `d->file->name' if it is.  This is so that when `snap_deps' makes
        !           261:  * `struct file's for all the dependencies, further references to their
        !           262:  * names will use those in the `struct file's which may be changed by
        !           263:  * VPATH search.
        !           264:  * 
        !           265:  * Revision 1.16  88/05/14  15:27:42  mcgrath
        !           266:  * * Added Emacs c-mode local variables.
        !           267:  * * A file's modtime is now looked at before implicit rule
        !           268:  *   search because finding its modtime may change its name via VPATH.
        !           269:  * * Fixed bug in VPATH pattern recognition that made `%'
        !           270:  *   matching one char not work.
        !           271:  * 
        !           272:  * Revision 1.15  88/05/11  21:29:04  mcgrath
        !           273:  * Made `$<' be the first dependency of any rule, not just implicit rules.
        !           274:  * 
        !           275:  * Revision 1.14  88/05/07  20:32:39  mcgrath
        !           276:  * * Made all internal functions `static'.
        !           277:  * * Changed to use new globbing function I added
        !           278:  *   to glob.c to make it work right.
        !           279:  * 
        !           280:  * Revision 1.13  88/05/07  13:44:06  mcgrath
        !           281:  * Made `touch' use utimes(2) rather than reading and writing.
        !           282:  * 
        !           283:  * Revision 1.12  88/05/06  17:13:06  mcgrath
        !           284:  * Removed SHFLAGS.
        !           285:  * 
        !           286:  * Revision 1.11  88/05/04  18:33:34  mcgrath
        !           287:  * Fixed Fixed bug which caused core dumps when $< was used
        !           288:  * in a pattern rule with no deps.
        !           289:  * 
        !           290:  * Revision 1.10  88/05/04  17:52:40  mcgrath
        !           291:  * * Made `define' directives make recursive (`='-style) variables.
        !           292:  * * Removed the `expand' function, since the above change makes in unnecessary.
        !           293:  * 
        !           294:  * Revision 1.9  88/05/03  22:27:39  mcgrath
        !           295:  * * Fixed bug which made recursive expansion not quite work (ack!!).
        !           296:  * * Made `MAKE' and `MAKEOVERRIDES' be figured out after environment
        !           297:  *   variables are read in so they will have the right values.
        !           298:  * * Miscellaneous cosmetic cleanup.
        !           299:  * 
        !           300:  * Revision 1.8  88/05/03  16:53:35  mcgrath
        !           301:  * * Fixed bug in expansion functions code.
        !           302:  * * Cosmetic changes.
        !           303:  * 
        !           304:  * Revision 1.7  88/04/30  15:27:16  mcgrath
        !           305:  * * Fixed bug which made `ifeq "x" "y"' conditionals fail.
        !           306:  * * Minor cleanup in conditional_line.
        !           307:  * 
        !           308:  * Revision 1.6  88/04/24  00:56:44  roland
        !           309:  * Removed $($@) automatic macro.
        !           310:  * 
        !           311:  * Revision 1.5  88/04/23  21:36:12  roland
        !           312:  * * Added -v switch the print version information.
        !           313:  * * Made -w switch be passed in MAKEFLAGS.
        !           314:  * * Made `main' use exit rather than return (more portable).
        !           315:  * * Made `pattern_search' and `vpath_search' consider files
        !           316:  *   mentioned in the makefile but that don't really exist to
        !           317:  *   be existent only if they are targets in the makefile.
        !           318:  *   This is the way Unix Make (Sun at least) does it and
        !           319:  *   it makes more sense.
        !           320:  * * Given to RMS for beta-testing.
        !           321:  * 
        !           322:  Revision 1.4  88/04/23  18:22:28  roland
        !           323:  * Fixed a minor bug which caused core dumps every time Make ran.
        !           324:  * Changed all messages to use `...' rather than "...".
        !           325:  * Given to RMS for beta-testing.
        !           326:  
        !           327:  Revision 1.3  88/04/23  17:37:24  roland
        !           328:  * Changed RCS header stuff slightly (added a keyword).
        !           329:  * Added support for $(a:-b), etc. as in Sun sh.
        !           330:  * Fixed bug fix making :: still not work right.
        !           331:  * Changed format of the message given for -w.
        !           332:  * Miscellaneous cosmetic cleanup.
        !           333:  * Added `struct ruleset': contains a chain of rules,
        !           334:    a pointer to the last rule in the chain, and info about
        !           335:    the implicit rule limits (which were previously global
        !           336:    variables).  Pattern rules are put in the ruleset in
        !           337:    the global variable `global_ruleset'.  There is a chain
        !           338:    of rulesets which will be listed by -p (if it exists).
        !           339:    Nothing adds to the chain of rulesets yet.
        !           340:    The `struct file' has a `ruleset' entry for the set of
        !           341:    implicit rules that should be used for that file (it should
        !           342:    be one in the `rulesets' chain) and `pattern_search' will
        !           343:    honor this entry.
        !           344:    All of this is the groundwork for `extended static rules' which
        !           345:    are sets of implicit rules which apply to a given set of files.
        !           346:    This has not yet been fully implemented because it will need
        !           347:    a complex design to read in extended static rules (as well as
        !           348:    a decision of a syntax; `files: %-target: %-deps' is a possibility)
        !           349:    and put them into rulesets associated with the right files.
        !           350:    This will be fully implemented sometime in the near future.
        !           351:  
        !           352:  *
        !           353:  */
        !           354: 
        !           355: #if 0  /* dummy tags for etags */
        !           356: endrcs (){}
        !           357: endlog (){}
        !           358: #endif
        !           359: 
        !           360: #if 0  /* dummy tag for etags  */
        !           361: flags (){}
        !           362: #endif
        !           363: 
        !           364: /* Flags:
        !           365:  *     -b ignored for compatability with System V Make
        !           366:  *     -c change directory
        !           367:  *     -d debug
        !           368:  *     -e env_overrides
        !           369:  *     -f makefile
        !           370:  *     -i ignore_errors
        !           371:  *     -k keep_going
        !           372:  *     -m ignored for compatibility with something or other
        !           373:  *     -n just_print
        !           374:  *     -o consider file old
        !           375:  *     -p print_data_base
        !           376:  *     -q question
        !           377:  *     -r no_builtin_rules
        !           378:  *     -s silent
        !           379:  *     -S turn off -k
        !           380:  *     -t touch
        !           381:  *     -v print version information
        !           382:  *     -w log working directory
        !           383:  */
        !           384: 
        !           385: #if 0  /* dummy tags for etags */
        !           386: definitions (){}
        !           387: defs (){}
        !           388: #endif
        !           389: 
        !           390: #include <signal.h>
        !           391: #include <stdio.h>
        !           392: #include <sys/types.h>
        !           393: #include <sys/param.h>
        !           394: #include <sys/stat.h>
        !           395: #include <sys/wait.h>
        !           396: 
        !           397: #ifdef USG
        !           398: #include "ndir.h"   /* Get ndir.h from the Emacs distribution.  */
        !           399: #include <fcntl.h>
        !           400: #define vfork fork
        !           401: #include <string.h>
        !           402: #define index strchr
        !           403: #define rindex strrchr
        !           404: #include <memory.h>
        !           405: #define bcmp(s1,s2,n) memcmp ((s1), (s2), (n))
        !           406: #define bzero(s,n) memset ((s), 0, (n))
        !           407: #define bcopy(s,d,n) memcpy ((d), (s), (n))
        !           408: #include <time.h>
        !           409: 
        !           410: #ifndef MAXPATHLEN
        !           411: #define MAXPATHLEN 1024
        !           412: #endif /* no MAXPATHLEN */
        !           413: 
        !           414: extern char *getcwd ();
        !           415: #define getwd(buf) getcwd (buf, MAXPATHLEN - 2)
        !           416: 
        !           417: #else /* not USG */
        !           418: 
        !           419: #include <strings.h>
        !           420: #include <sys/dir.h>
        !           421: #include <sys/file.h>
        !           422: #include <sys/time.h>
        !           423: 
        !           424: extern char *getwd ();
        !           425: 
        !           426: #endif /* not USG */
        !           427: 
        !           428: /* Somebody sent this in.  I assume machines that
        !           429:    pre-define `sparc' will need it.  */
        !           430: #ifdef sparc
        !           431: #include <alloca.h>
        !           432: #endif /* sparc        */
        !           433: 
        !           434: /* We record the status of a command that got a signal
        !           435:    as the signal number | 0200 (| 0400 if it got a coredump).  */
        !           436: #define SIGNAL_STATUS 0200
        !           437: #define SIGNAL_COREDUMP 0400
        !           438: 
        !           439: #define max(a, b) ((a) > (b) ? (a) : (b))
        !           440: #define min(a, b) ((a) < (b) ? (a) : (b))
        !           441: #define streq(a, b) \
        !           442:   ((a) == (b) || \
        !           443:    (*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1))))
        !           444: #define file_mtime(f) ((f)->last_mtime != 0 ? (f)->last_mtime : f_mtime (f))
        !           445: #define initbuffer(lb) (lb)->buffer = (char *) xmalloc ((lb)->size = 200)
        !           446: #define freebuffer(lb) free ((lb)->buffer)
        !           447: #define dep_name(d) ((d)->name == 0 ? (d)->file->name : (d)->name)
        !           448: 
        !           449: /* The name we were invoked with.  */
        !           450: 
        !           451: static char *program;
        !           452: 
        !           453: /* A `struct linebuffer' is a structure which holds a line of text.
        !           454:    `readline' reads a line from a stream into a linebuffer
        !           455:    and works regardless of the length of the line.  */
        !           456: 
        !           457: struct linebuffer
        !           458:   {
        !           459:     /* Note:  This is the number of bytes malloc'ed for `buffer'
        !           460:        It does not indicate `buffer's real length.
        !           461:        Instead, a losing C asciz null-byte indicates end-of-string */
        !           462:     unsigned size;
        !           463:     char *buffer;
        !           464:   };
        !           465: 
        !           466: /* Nonzero => file to delete if fatal signal happens.
        !           467:    While actually running shell commands, this is their target.  */
        !           468: 
        !           469: char *signal_delete_file;
        !           470: 
        !           471: /* But only delete the file if it has been changed;
        !           472:    that is, its mtime is not the same as this.  */
        !           473: 
        !           474: long signal_delete_mtime;
        !           475: 
        !           476: /* The filename and pointer to line number of the
        !           477:    makefile currently being read in.  */
        !           478: 
        !           479: char *reading_filename;
        !           480: long *reading_lineno_ptr;
        !           481: 
        !           482: /* Structure that gives the commands to make a file
        !           483:    and information about where these commands came from.  */
        !           484: 
        !           485: struct commands
        !           486:   {
        !           487:     char *filename;            /* file that contains commands */
        !           488:     long lineno;               /* line number in file */
        !           489:     char *commands;            /* commands text */
        !           490:   };
        !           491: 
        !           492: /* Structure that represents the info on one file
        !           493:    that the makefile says how to make.
        !           494:    All of these are chained together through `next'.  */
        !           495: 
        !           496: struct file
        !           497:   {
        !           498:     struct file *next;
        !           499:     char *name;
        !           500:     struct dep *deps;
        !           501:     struct commands *cmds;     /* Commands to execute for this target */
        !           502:     char *stem;                        /* common stem, if an implicit
        !           503:                                   rule has been used */
        !           504:     int update_status;         /* Status of the last attempt to update,
        !           505:                                   or -1 if none has been made.  */
        !           506:     long last_mtime;           /* File's modtime, if already known.  */
        !           507:     struct file *prev;         /* Previous entry for same file name;
        !           508:                                   used when there are multiple double-colon
        !           509:                                   entries for the same file.  */
        !           510:     char double_colon;         /* Nonzero for double-colon entry */
        !           511:     char precious;             /* Non-0 means don't delete this file on quit */
        !           512:     char recursive;            /* Non-0 means do this file's commands
        !           513:                                   even if -q, -t or -n.  */
        !           514:     char tried_implicit;       /* Nonzero if have searched for implicit rule
        !           515:                                   for making this file; don't search again */
        !           516:     char updating;             /* Nonzero while updating deps of this file */
        !           517:     char updated;              /* Nonzero if this file has been remade.  */
        !           518:     char is_target;            /* Nonzero if file is described as target */
        !           519:     char phony;                        /* Nonzero if this is a phony file
        !           520:                                   ie, a dependent of .PHONY.  */
        !           521:     char intermediate;         /* Nonzero if this is an intermediate file.  */
        !           522:   };
        !           523: 
        !           524: /* Number of intermediate files entered.  */
        !           525: 
        !           526: int num_intermediates;
        !           527: 
        !           528: /* Hash table of files the makefile knows how to make.  */
        !           529: 
        !           530: #define FILE_BUCKETS   53
        !           531: struct file *files[FILE_BUCKETS];
        !           532: 
        !           533: /* Hash table of files in the various directories.
        !           534:    This makes file_exists_p faster for files in these directories.  */
        !           535: 
        !           536: struct dirdata
        !           537: {
        !           538:   struct dirdata *next;
        !           539:   char *dir;                   /* Name of directory */
        !           540:   char *name;                  /* Name of file in the directory */
        !           541:   int impossible;              /* This file is impossible */
        !           542: };
        !           543: 
        !           544: #define DIR_HASH_SIZE 1007
        !           545: 
        !           546: struct dirdata *dir_hash_table[DIR_HASH_SIZE];
        !           547: 
        !           548: /* Structure used for pattern rules.  */
        !           549: 
        !           550: struct rule
        !           551:   {
        !           552:     struct rule *next;
        !           553:     char *name;                        /* Name (target) of the rule  */
        !           554:     int namelen;               /* Length of that string; to save time */
        !           555:     char *patsuffix;           /* Pointer to char after %  */
        !           556:     struct dep *deps;          /* Dependents of the rule  */
        !           557:     struct commands *cmds;     /* Commands to execute  */
        !           558:     char recursive;            /* If commands contain "$(MAKE)"  */
        !           559:     char terminal;             /* If terminal (double colon)  */
        !           560:     char subdir;               /* If references nonexistent subdirectory  */
        !           561:     char in_use;               /* If in use by a parent pattern_search  */
        !           562:   };
        !           563: 
        !           564: 
        !           565: /* Chain of all pattern rules  */
        !           566: 
        !           567: struct rule *pattern_rules;
        !           568: 
        !           569: /* Pointer to last rule in the chain, so we can add onto the end  */
        !           570: 
        !           571: struct rule *last_pattern_rule;
        !           572: 
        !           573: /* Number of rules in the chain  */
        !           574: 
        !           575: int num_pattern_rules;
        !           576: 
        !           577: /* Maximum number of dependencies of any pattern rule  */
        !           578: 
        !           579: int max_pattern_deps;
        !           580: 
        !           581: /* Maximum length of the name of a dependencies of any pattern rule  */
        !           582: 
        !           583: int max_pattern_dep_length;
        !           584: 
        !           585: /* Structure used to represent a selective VPATH searchpath.  */
        !           586: 
        !           587: struct vpath
        !           588:   {
        !           589:     struct vpath *next;        /* Pointer to next struct in the linked list.  */
        !           590:     char *pattern;     /* The pattern to match.  */
        !           591:     int patlen;                /* Length of the pattern.  */
        !           592:     char *patsuffix;   /* Pointer to the char after `%' in pattern.  */
        !           593:     char **searchpath; /* Null-terminated list of directories.  */
        !           594:     int maxlen;                /* Maximum length of any entry in the list.  */
        !           595:   };
        !           596: 
        !           597: /* Linked-list of all selective VPATHs.  */
        !           598: 
        !           599: struct vpath *vpaths;
        !           600: 
        !           601: /* Structure for the general VPATH given in the macro.  */
        !           602: 
        !           603: struct vpath *general_vpath;
        !           604: 
        !           605: /* Incremented when we find a file needs to be remade,
        !           606:    even if it has no commands or if we are not really executing commands.  */
        !           607: 
        !           608: int files_remade;
        !           609: 
        !           610: /* Structure representing one dependency of a file.
        !           611:    Each struct file's `deps' points to a chain of these,
        !           612:    chained through the `next'.
        !           613: 
        !           614:    Note that the first three words of this match a struct nameseq.  */
        !           615: 
        !           616: struct dep
        !           617:   {
        !           618:     struct dep *next;
        !           619:     char *name;
        !           620:     int quotedparen;
        !           621:     struct file *file;
        !           622:     int changed;
        !           623:   };
        !           624: 
        !           625: /* Structure used in chains of names, for parsing and globbing */
        !           626: 
        !           627: struct nameseq
        !           628:   {
        !           629:     struct nameseq *next;
        !           630:     char *name;
        !           631:     int quotedparen;
        !           632:   };
        !           633: 
        !           634: /* First file defined in the makefile whose name does not
        !           635:    start with `.'.  This is the default to remake if the
        !           636:    command line does not specify.  */
        !           637: 
        !           638: struct file *default_goal_file;
        !           639: 
        !           640: /* Pointer to structure for the file .SUFFIXES
        !           641:    whose dependencies are the suffixes to be searched.  */
        !           642: 
        !           643: struct file *suffix_file;
        !           644: 
        !           645: /* Maximum length of a suffix.  */
        !           646: 
        !           647: int maxsuffix;
        !           648: 
        !           649: /* Pointer to structure for the file .DEFAULT
        !           650:    whose commands are used for any file that has none of its own.
        !           651:    This is zero if the makefiles do not define .DEFAULT.  */
        !           652: 
        !           653: struct file *default_file;
        !           654: 
        !           655: /* Codes in a macro definition saying where the definition came from.
        !           656:    Increasing numeric values signify less-overridable definitions.  */
        !           657: enum macro_origin
        !           658:   {
        !           659:     o_env,             /* Macro from environment.  */
        !           660:     o_file,            /* Macro given in a makefile.  */
        !           661:     o_env_override,    /* Macro from environment, if -e.  */
        !           662:     o_command,         /* Macro given by user.  */
        !           663:     o_override,        /* Macro from an `override' directive in a makefile.  */
        !           664:   };
        !           665: 
        !           666: /* Structure that represents one macro definition.
        !           667:    Each bucket of the hash table `macros' is a chain of these,
        !           668:    chained through `next'.  */
        !           669: 
        !           670: struct macro
        !           671:   {
        !           672:     struct macro *next;                /* Link the chain  */
        !           673:     char *name;                        /* Macro name  */
        !           674:     char *value;               /* Macro value  */
        !           675:     enum macro_origin origin;  /* Macro origin  */
        !           676:     char recursive;            /* Gets recursively re-evaluated  */
        !           677:     char expanding;            /* Is currently expanding  */
        !           678:   };
        !           679: 
        !           680: /* Hash table of all macro definitions.  */
        !           681: 
        !           682: #define MACRO_BUCKETS  43
        !           683: struct macro *macros[MACRO_BUCKETS];
        !           684: 
        !           685: /* Pointers to struct macro's for the built-in macros,
        !           686:    $*, $@, $<, $% and their F and D pairs, $^ and $?, and $($/).   */
        !           687: 
        !           688: struct macro *star_macro, *starF_macro, *starD_macro;
        !           689: struct macro *at_macro, *atF_macro, *atD_macro;
        !           690: struct macro *less_macro, *lessF_macro, *lessD_macro;
        !           691: struct macro *percent_macro, *percentF_macro, *percentD_macro;
        !           692: struct macro *caret_macro, *qmark_macro;
        !           693: struct macro *dollar_slash_macro;
        !           694: 
        !           695: /* Pointer to struct macro for SHELL.  So we can look up the value fast.  */
        !           696: 
        !           697: struct macro *shell_macro;
        !           698: 
        !           699: /* Pointer to struct macro for IFS (sh internal field separator).  */
        !           700: 
        !           701: struct macro *ifs_macro;
        !           702: 
        !           703: /* Value of the MAKELEVEL macro at startup (or 0).  */
        !           704: 
        !           705: int makelevel;
        !           706: 
        !           707: /* The next two describe the macro output buffer.
        !           708:    This buffer is used to hold the macro-expansion of a line of the makefile.
        !           709:    It is made bigger with realloc whenever it is too small.
        !           710:    macro_buffer_length is the size currently allocated.
        !           711:    macro_buffer is the address of the buffer.  */
        !           712: 
        !           713: unsigned macro_buffer_length;
        !           714: char *macro_buffer;
        !           715: 
        !           716: /* Values of command-line options.  */
        !           717: 
        !           718: /* Nonzero means do not print commands to be executed (-s).  */
        !           719: 
        !           720: int silent_flag;
        !           721: 
        !           722: /* Nonzero means just touch the files
        !           723:    that would appear to need remaking (-t)  */
        !           724: 
        !           725: int touch_flag;
        !           726: 
        !           727: /* Nonzero means just print what commands would need to be executed,
        !           728:    don't actually execute them (-n).  */
        !           729: 
        !           730: int just_print_flag;
        !           731: 
        !           732: /* Print debugging trace info (-d).  */
        !           733: 
        !           734: int debug_flag;
        !           735: 
        !           736: /* Environment macros override makefile definitions.  */
        !           737: 
        !           738: int env_overrides;
        !           739: 
        !           740: /* Nonzero means ignore status codes returned by commands
        !           741:    executed to remake files.  Just treat them all as successful (-i).  */
        !           742: 
        !           743: int ignore_errors_flag;
        !           744: 
        !           745: /* Nonzero means don't remake anything, just print the data base
        !           746:    that results from reading the makefile (-p).  */
        !           747: 
        !           748: int print_data_base_flag;
        !           749: 
        !           750: /* Nonzero means don't remake anything; just return a nonzero status
        !           751:    if the specified targets are not up to date (-q).  */
        !           752: 
        !           753: int question_flag;
        !           754: 
        !           755: /* Nonzero means do not use any of the builtin rules (-r).  */
        !           756: 
        !           757: int no_builtin_rules_flag;
        !           758: 
        !           759: /* Nonzero means keep going even if remaking some file fails (-k).  */
        !           760: 
        !           761: int keep_going_flag;
        !           762: 
        !           763: /* Nonzero means print working directory before starting and after
        !           764:    finishing make. */
        !           765: 
        !           766: int print_directory_flag;
        !           767: 
        !           768: /* Nonzero means print version information.  */
        !           769: 
        !           770: int print_version_flag;
        !           771: 
        !           772: #if 0  /* dummy tags for etags */
        !           773: declarations (){}
        !           774: decls (){}
        !           775: #endif
        !           776: 
        !           777: /* Forward declarations */
        !           778: 
        !           779: static void decode_env_switches ();
        !           780: static int check_dep (), remake_file ();
        !           781: static int file_exists_p (), dir_file_exists_p ();
        !           782: static struct macro *define_macro ();
        !           783: static struct macro *lookup_macro ();
        !           784: static char *macro_expand ();
        !           785: static char *macro_buffer_output ();
        !           786: static int try_macro_definition ();
        !           787: static long do_define ();
        !           788: static struct file *enter_file ();
        !           789: static struct file *lookup_file ();
        !           790: static int update_file ();
        !           791: static long readline ();
        !           792: static void print_spaces ();
        !           793: static long f_mtime (), name_mtime (), library_file_mtime ();
        !           794: static int vpath_search ();
        !           795: static char *savestring (), *concat ();
        !           796: static char *xmalloc (), *xrealloc ();
        !           797: static char *alloca ();
        !           798: static char *sindex (), *lindex (), *wstok ();
        !           799: static char *string_glob ();
        !           800: static char *end_of_token (), *next_token (), *find_next_token ();
        !           801: static void new_environ ();
        !           802: static void fatal (), error (), perror_with_name (), pfatal_with_name ();
        !           803: static struct nameseq *parse_file_seq ();
        !           804: static struct nameseq *multi_glob ();
        !           805: static void decode_switches ();
        !           806: static void define_automatic_macros ();
        !           807: static void print_data_base ();
        !           808: static void read_all_makefiles ();
        !           809: static struct dep *copy_dep_chain ();
        !           810: static int conditional_line ();
        !           811: static void snap_deps ();
        !           812: static struct vpath *construct_vpath_list ();
        !           813: static void build_vpath_lists ();
        !           814: static void construct_include_path ();
        !           815: static void dir_load ();
        !           816: static void file_impossible ();
        !           817: static int file_impossible_p ();
        !           818: static void convert_to_pattern ();
        !           819: static void new_pattern_rule ();
        !           820: static void install_pattern_rule ();
        !           821: static void count_implicit_rule_limits ();
        !           822: static int pattern_search ();
        !           823: 
        !           824: static int update_file_1 (), execute_file_commands (), try_implicit_rule ();
        !           825: static int execute_command_line ();
        !           826: static void collapse_line ();
        !           827: 
        !           828: static void log_working_directory ();
        !           829: static void print_version ();
        !           830: 
        !           831: static int alpha_compare ();
        !           832: static int ar_name ();
        !           833: static int ar_touch (), ar_scan_1 ();
        !           834: extern int ar_scan (), ar_member_touch ();
        !           835: 
        !           836: extern char **glob_filename ();
        !           837: 
        !           838: extern long time ();
        !           839: extern long lseek ();
        !           840: 
        !           841: /* Data base of implicit rules */
        !           842: 
        !           843: /* For calling install_pattern_rule.  */
        !           844: struct pspec {char *target, *dep, *commands;};
        !           845: 
        !           846: /* This is the default list of suffixes for suffix rules.
        !           847:    `.s' must come last, so that a `.o' file will be made from
        !           848:    a `.c' or `.p' or ... file rather than from a .s file.  */
        !           849: 
        !           850: char *default_suffixes = ".out .a .o .c .y .ye .yr .l .F .e .r .f .p .h .s";
        !           851: 
        !           852: struct pspec default_pattern_rules[] =
        !           853:   {
        !           854:     "(%)", "%",
        !           855:     "ar r $@ $<",
        !           856: 
        !           857:     /* The X.out rules are only in BSD's default set because
        !           858:        BSD Make has no null-suffix rules, so `foo.out' and
        !           859:        `foo' are the same thing.  */
        !           860:     "%.out", "%",
        !           861:     "@rm -f $@ \n cp $< $@",
        !           862: 
        !           863:     /* For libraries, so they won't get ranlib'd unnecessarily.  */
        !           864:     "%(__.SYMDEF)", "%",
        !           865:     "$(RANLIB) $<",
        !           866: 
        !           867:     0, 0, 0
        !           868:   };
        !           869: 
        !           870: struct pspec default_terminal_rules[] =
        !           871:   {
        !           872:     /* RCS  */
        !           873:     "%", "%,v",
        !           874:     "$(CO) $(COFLAGS) $< $@",
        !           875:     "%", "RCS/%,v",
        !           876:     "$(CO) $(COFLAGS) $< $@",
        !           877: 
        !           878:     /* SCCS  */
        !           879:     "%", "s.%",
        !           880:     "$(GET) $(GFLAGS) $<",
        !           881:     "%", "SCCS/s.%",
        !           882:     "$(GET) $(GFLAGS) $<",
        !           883: 
        !           884:     0, 0, 0
        !           885:   };
        !           886: 
        !           887: char *default_suffix_rules[] =
        !           888:   {
        !           889:     ".o",
        !           890:     "$(CC) $(LDFLAGS) $^ $(LOADLIBES) -o $@",
        !           891:     ".s",
        !           892:     "$(CC) $(ASFLAGS) $(LDFLAGS) $^ $(LOADLIBES) -o $@",
        !           893:     ".c",
        !           894:     "$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LOADLIBES) -o $@",
        !           895:     ".f",
        !           896:     "$(FC) $(FFLAGS) $(LDFLAGS) $^ $(LOADLIBES) -o $@",
        !           897:     ".p",
        !           898:     "$(PC) $(PFLAGS) $(LDFLAGS) $^ $(LOADLIBES) -o $@",
        !           899:     ".F",
        !           900:     "$(FC) $(FFLAGS) $(LDFLAGS) $^ $(LOADLIBES) -o $@",
        !           901:     ".e",
        !           902:     "$(FC) $(FFLAGS) $(LDFLAGS) $^ $(LOADLIBES) -o $@",
        !           903:     ".r",
        !           904:     "$(FC) $(FFLAGS) $(LDFLAGS) $^ $(LOADLIBES) -o $@",
        !           905: 
        !           906:     ".s.o",
        !           907:     "$(AS) $(ASFLAGS) $< -o $@",
        !           908:     ".c.o",
        !           909:     "$(CC) $(CFLAGS) -c $< -o $@",
        !           910:     ".f.o",
        !           911:     "$(FC) $(FFLAGS) -c $< -o $@",
        !           912:     ".p.o",
        !           913:     "$(PC) $(PFLAGS) -c $< -o $@",
        !           914:     ".F.o",
        !           915:     "$(FC) $(FFLAGS) -c $< -o $@",
        !           916:     ".e.o",
        !           917:     "$(EC) $(EFLAGS) -c $< -o $@",
        !           918:     ".r.o",
        !           919:     "$(RC) $(RFLAGS) -c $< -o $@",
        !           920: 
        !           921:     ".y.c",
        !           922:     "$(YACC) $(YFLAGS) $< \n mv -f y.tab.c $@",
        !           923:     ".l.c",
        !           924:     "$(LEX) $(LFLAGS) $< \n mv -f lex.yy.c $@",
        !           925: 
        !           926:     ".F.f",
        !           927:     "$(FC) $(FFLAGS) -F $< -o $@",
        !           928:     ".e.f",
        !           929:     "$(EC) $(EFLAGS) -F $< -o $@",
        !           930:     ".r.f",
        !           931:     "$(RC) $(RFLAGS) -F $< -o $@",
        !           932: 
        !           933:     ".ye.e",
        !           934:     "$(YACCE) $(YFLAGS) $< \n mv -f y.tab.e $@",
        !           935: 
        !           936:     ".yr.r",
        !           937:     "$(YACCR) $(YFLAGS) $< \n mv -f y.tab.r $@",
        !           938:     /* This might actually make lex.yy.c if there's no %R%
        !           939:        directive in $*.l, but in that case why were you
        !           940:        trying to make $*.r anyway?  */
        !           941:     ".l.r",
        !           942:     "$(LEX) $(LFLAGS) $< \n mv -f lex.yy.r $@",
        !           943: 
        !           944:     0
        !           945:   };
        !           946: 
        !           947: char *default_macros[] =
        !           948:   {
        !           949:     "AS", "as",
        !           950:     "CC", "cc",
        !           951:     "CO", "co",
        !           952:     "EC", "f77",
        !           953:     "FC", "f77",
        !           954:     "GET", "get",
        !           955:     "LEX", "lex",
        !           956:     "RANLIB", "ranlib",
        !           957:     "RC", "f77",
        !           958:     "PC", "pc",
        !           959:     "YACC", "yacc",    /* Or "bison -y"  */
        !           960:     "YACCE", "yacc -e",
        !           961:     "YACCR", "yacc -r",
        !           962:     0
        !           963:   };
        !           964: 
        !           965: /* Default directories to search for include files in  */
        !           966: 
        !           967: char *default_include_directories[] =
        !           968:   {
        !           969:     "/usr/gnu/include",
        !           970:     "/usr/local/include",
        !           971:     "/usr/include",
        !           972:     0
        !           973:   };
        !           974: 
        !           975: /* List of directories to search for include files in  */
        !           976: 
        !           977: char **include_directories;
        !           978: 
        !           979: /* Maximum length of an element of the above.  */
        !           980: 
        !           981: int max_incl_len;
        !           982: 
        !           983: #if 0  /* dummy tag for etags  */
        !           984: code (){}
        !           985: #endif
        !           986: 
        !           987: #ifdef USG
        !           988: char *sys_siglist[NSIG] = {
        !           989: /*0 */ "(no signal 0)",
        !           990: /*1 */ "Hangup",
        !           991: /*2 */ "Interrupt",
        !           992: /*3 */ "Quit",
        !           993: /*4 */ "Illegal Instruction",
        !           994: /*5 */ "Trace Trap",
        !           995: /*6 */ "IOT Instruction",
        !           996: /*7 */ "EMT Instruction",
        !           997: /*8 */ "Floating Point Exception",
        !           998: /*9 */ "Kill",
        !           999: /*10*/ "Bus Error",
        !          1000: /*11*/ "Segmentation Error",
        !          1001: /*12*/ "Bad Argument to System Call",
        !          1002: /*13*/ "Write on pipe with no reader",
        !          1003: /*14*/ "Alarm Clock",
        !          1004: /*15*/ "Software Termination",
        !          1005: /*16*/ "User-defined signal 1",
        !          1006: /*17*/ "User-defined signal 2",
        !          1007: /*18*/ "Child Process Exited",
        !          1008: /*19*/ "Power Fail"
        !          1009:        };
        !          1010: #endif /* USG */
        !          1011: 
        !          1012: /* Handle bus errors, illegal instruction, etc. */
        !          1013: static
        !          1014: fatal_error_signal (sig)
        !          1015:      int sig;
        !          1016: {
        !          1017:   struct stat st;
        !          1018: 
        !          1019:   signal (sig, SIG_DFL);
        !          1020: #ifndef USG
        !          1021:   (void) sigsetmask (0);
        !          1022: #endif /* USG */
        !          1023: 
        !          1024:   /* Don't die until our children have finished dying.  */
        !          1025:   while (wait ((union wait *) 0) != -1)
        !          1026:     ;
        !          1027: 
        !          1028:   /* If we have specified a file to delete for this moment,
        !          1029:      and it exists and is not a directory, delete it.  */
        !          1030: 
        !          1031:   if (signal_delete_file
        !          1032:       && stat (signal_delete_file, &st) >= 0
        !          1033:       && (st.st_mode & S_IFMT) != S_IFDIR
        !          1034:       && st.st_mtime != signal_delete_mtime)
        !          1035:     {
        !          1036:       fprintf (stderr, "\n%s: Deleting file %s\n",
        !          1037:               program, signal_delete_file);
        !          1038:       fflush (stderr);
        !          1039:       if (unlink (signal_delete_file) < 0)
        !          1040:        perror_with_name ("unlink: ", signal_delete_file);
        !          1041:     }
        !          1042: 
        !          1043:   /* Delete any non-precious intermediate files that were made.  */
        !          1044: 
        !          1045:   if (num_intermediates > 0)
        !          1046:     {
        !          1047:       register int i;
        !          1048:       register struct file *f;
        !          1049: 
        !          1050:       /* Examine each `struct file' in the hash table.  */
        !          1051:       for (i = 0; i < FILE_BUCKETS; ++i)
        !          1052:        for (f = files[i]; f != 0; f = f->next)
        !          1053:          if (f->intermediate && !f->precious && f->updated)
        !          1054:            {
        !          1055:              fprintf (stderr, "%s: Deleting file %s\n", program, f->name);
        !          1056:              fflush (stderr);
        !          1057:              if (!just_print_flag && unlink (f->name) < 0)
        !          1058:                perror_with_name ("unlink: ", f->name);
        !          1059:            }
        !          1060:     }
        !          1061: 
        !          1062:   /* Signal the same code; this time it will really be fatal.  */
        !          1063:   if (kill (getpid (), sig) < 0)
        !          1064:     /* It shouldn't return, but if it does, die anyway.  */
        !          1065:     pfatal_with_name ("kill");
        !          1066: }
        !          1067: 
        !          1068: int
        !          1069: main (argc, argv, envp)
        !          1070:      int argc;
        !          1071:      char **argv;
        !          1072:      char **envp;
        !          1073: {
        !          1074:   register struct file *f;
        !          1075:   register int i;
        !          1076:   int num_remade = 0;
        !          1077:   int status = 0;
        !          1078:   int this_status;
        !          1079:   register char *cmd_defs;
        !          1080:   register unsigned cmd_defs_len, cmd_defs_idx;
        !          1081: 
        !          1082:   bzero ((char *) files, sizeof files);
        !          1083:   bzero ((char *) macros, sizeof macros);
        !          1084:   bzero ((char *) dir_hash_table, sizeof dir_hash_table);
        !          1085: 
        !          1086:   files_remade = 0;
        !          1087:   macro_buffer = 0;
        !          1088:   default_goal_file = 0;
        !          1089:   signal_delete_file = 0;
        !          1090:   signal_delete_mtime = 0;
        !          1091:   reading_filename = 0;
        !          1092:   reading_lineno_ptr = 0;
        !          1093:   num_intermediates = 0;
        !          1094:   vpaths = 0;
        !          1095:   general_vpath = 0;
        !          1096:   pattern_rules = last_pattern_rule = 0;
        !          1097:   
        !          1098:   signal (SIGHUP, fatal_error_signal);
        !          1099:   signal (SIGQUIT, fatal_error_signal);
        !          1100:   signal (SIGINT, fatal_error_signal);
        !          1101:   signal (SIGILL, fatal_error_signal);
        !          1102:   signal (SIGTRAP, fatal_error_signal);
        !          1103:   signal (SIGIOT, fatal_error_signal);
        !          1104:   signal (SIGEMT, fatal_error_signal);
        !          1105:   signal (SIGFPE, fatal_error_signal);
        !          1106:   signal (SIGBUS, fatal_error_signal);
        !          1107:   signal (SIGSEGV, fatal_error_signal);
        !          1108:   signal (SIGSYS, fatal_error_signal);
        !          1109:   signal (SIGTERM, fatal_error_signal);
        !          1110: #ifdef SIGXCPU
        !          1111:   signal (SIGXCPU, fatal_error_signal);
        !          1112: #endif
        !          1113: #ifdef SIGXFSZ
        !          1114:   signal (SIGXFSZ, fatal_error_signal);
        !          1115: #endif
        !          1116: 
        !          1117:   if (argv[0] == 0)
        !          1118:     program = "make";
        !          1119:   else 
        !          1120:     {
        !          1121:       program = rindex (argv[0], '/');
        !          1122:       if (program == 0)
        !          1123:        program = argv[0];
        !          1124:       else
        !          1125:        ++program;
        !          1126:     }
        !          1127: 
        !          1128:   /* Read in macros from the environment.  It is important that this be
        !          1129:      done before `MAKE' and `MAKEOVERRIDES' are figured out so their
        !          1130:      definitions will not be ones from the environment.  */
        !          1131: 
        !          1132:   for (i = 0; envp[i] != 0; ++i)
        !          1133:     {
        !          1134:       register char *ep = envp[i];
        !          1135:       while (*ep++ != '=')
        !          1136:        ;
        !          1137:       (void) define_macro (envp[i], ep - envp[i] - 1, ep,
        !          1138:                           env_overrides ? o_env_override : o_env, 1);
        !          1139:     }
        !          1140: 
        !          1141:   /* Search for command line arguments that define macros,
        !          1142:      and do the definitions.  Also save up the text of these
        !          1143:      arguments in CMD_DEFS so we can put them into the values
        !          1144:      of $(MAKEOVERRIDES) and $(MAKE).  */
        !          1145: 
        !          1146:   cmd_defs_len = 100;
        !          1147:   cmd_defs = (char *) xmalloc (cmd_defs_len);
        !          1148:   cmd_defs_idx = 0;
        !          1149: 
        !          1150:   for (i = 1; i < argc; i++)
        !          1151:     {
        !          1152:       /* Don't even try an arg that is a switch.  */
        !          1153:       if (!strcmp (argv[i], "-f") || !strcmp (argv[i], "-o"))
        !          1154:        i++;
        !          1155:       else if (argv[i][0] != '-')
        !          1156:        {
        !          1157:          /* It's not a switch; try it as a macro definition.  */
        !          1158:          if (try_macro_definition (argv[i], o_command))
        !          1159:            {
        !          1160:              /* It succeeded.  The macro is already defined.
        !          1161:                 Backslash-quotify it and append it to CMD_DEFS,
        !          1162:                 then clobber it to `-' in ARGV
        !          1163:                 so that it won't be taken for a goal target.  */
        !          1164:              register char *p = argv[i];
        !          1165:              int l = strlen (p);
        !          1166:              if (((int) (cmd_defs_len - ((l * 2) + 1))) < 0)
        !          1167:                {
        !          1168:                  cmd_defs_len += l * 2;
        !          1169:                  cmd_defs = (char *) xrealloc (cmd_defs, cmd_defs_len);
        !          1170:                }
        !          1171:              while (*p)
        !          1172:                {
        !          1173:                  if (index ("'\"*?[]$<>(){}|&~`\\ \t\r\n\f\v", *p) != 0)
        !          1174:                    cmd_defs[cmd_defs_idx++] = '\\';
        !          1175:                  cmd_defs[cmd_defs_idx++] = *p++;
        !          1176:                }
        !          1177:              cmd_defs[cmd_defs_idx++] = ' ';
        !          1178:              argv[i] = "-";
        !          1179:            }
        !          1180:        }
        !          1181:     }
        !          1182: 
        !          1183:   if (cmd_defs_idx > 0)
        !          1184:     {
        !          1185:       cmd_defs[cmd_defs_idx] = '\0';
        !          1186:       (void) define_macro ("MAKEOVERRIDES", 13, cmd_defs, o_override, 0);
        !          1187:     }
        !          1188: 
        !          1189:   /* Set the "MAKE" macro to the name we were invoked with.
        !          1190:      (If it is a relative pathname with a slash, prepend our directory name
        !          1191:      so the result will run the same program regardless of current dir.
        !          1192:      If it is a name with no slash, we can only hope that PATH did not
        !          1193:      find it in the current directory.)
        !          1194: 
        !          1195:      Append at the end the command-line macro definitions gathered above
        !          1196:      so sub-makes get them as command-line definitions.  */
        !          1197: 
        !          1198:   if (argv[0] != 0 && argv[0][0] != '/' && index (argv[0], '/') != 0)
        !          1199:     {
        !          1200:       char dir[MAXPATHLEN];
        !          1201:       char *str;
        !          1202:       if (getwd (dir) == 0)
        !          1203:        {
        !          1204:          error ("getwd: %s", dir);
        !          1205:          dir[0] = '\0';
        !          1206:        }
        !          1207:       str = concat (dir, "/", argv[0]);
        !          1208:       if (cmd_defs_idx > 0)
        !          1209:        {
        !          1210:          char *s = concat (str, " ", cmd_defs);
        !          1211:          free (str);
        !          1212:          str = s;
        !          1213:        }
        !          1214:       (void) define_macro ("MAKE", 4, str, o_env, 0);
        !          1215:       free (str);
        !          1216:     }
        !          1217:   else if (cmd_defs_idx > 0)
        !          1218:     {
        !          1219:       char *str = concat (argv[0], " ", cmd_defs);
        !          1220:       (void) define_macro ("MAKE", 4, str, o_env, 0);
        !          1221:       free (str);
        !          1222:     }
        !          1223:   else
        !          1224:     (void) define_macro ("MAKE", 4, argv[0], o_env, 0);
        !          1225: 
        !          1226:   free (cmd_defs);
        !          1227: 
        !          1228:   /* Decode the switches now */
        !          1229: 
        !          1230:   decode_switches (argc, argv);
        !          1231: 
        !          1232:   /* Parse any -c flags and move ourselves about.  */
        !          1233: 
        !          1234:   for (i = 1; i < argc; ++i)
        !          1235:     if (!strcmp (argv[i], "-c"))
        !          1236:       {
        !          1237:        ++i;
        !          1238:        if (i >= argc)
        !          1239:          fatal ("no directory given after -c command switch");
        !          1240:        if (chdir (argv[i]) < 0)
        !          1241:          pfatal_with_name (argv[i]);
        !          1242:       }
        !          1243: 
        !          1244:   /* Now that we know the default directory, hash its contents.  */
        !          1245: 
        !          1246:   if (print_directory_flag)
        !          1247:     log_working_directory (1);
        !          1248: 
        !          1249:   dir_load (".");
        !          1250: 
        !          1251:   /* Define the initial list of suffixes for old-style rules.  */
        !          1252: 
        !          1253:   suffix_file = enter_file (".SUFFIXES");
        !          1254: 
        !          1255:   if (!no_builtin_rules_flag)
        !          1256:     {
        !          1257:       char *ptr;
        !          1258:       char **p1;
        !          1259: 
        !          1260:       ptr = default_suffixes;
        !          1261:       /* Why do multi-glob here?  None of the suffixes contains *.
        !          1262:         But multi-glob is easiest way of reversing the chain.  */
        !          1263:       suffix_file->deps
        !          1264:        = (struct dep *) multi_glob (parse_file_seq (&ptr, '\0',
        !          1265:                                                     sizeof (struct dep)),
        !          1266:                                     sizeof (struct dep));
        !          1267: 
        !          1268:       /* Enter the suffix rules as files.  */
        !          1269:       for (p1 = default_suffix_rules; *p1;)
        !          1270:        {
        !          1271:          f = enter_file (*p1++);
        !          1272:          f->cmds = (struct commands *) xmalloc (sizeof (struct commands));
        !          1273:          f->cmds->commands = *p1++;
        !          1274:          f->cmds->filename = 0;
        !          1275:          f->cmds->lineno = 0;
        !          1276:        }
        !          1277: 
        !          1278:       /* Install the default macro definitions (CC, etc.)  */
        !          1279:       for (p1 = default_macros; *p1; ++p1)
        !          1280:        {
        !          1281:          char *name = *p1++;
        !          1282:          int len = strlen (name);
        !          1283:          if (lookup_macro (name, len) == 0)
        !          1284:            (void) define_macro (name, len, *p1, o_file, 0);
        !          1285:        }
        !          1286:     }
        !          1287: 
        !          1288:   /* Define some internal and special macros.  */
        !          1289: 
        !          1290:   define_automatic_macros ();
        !          1291: 
        !          1292:   /* Read all the specified or default makefiles */
        !          1293: 
        !          1294:   read_all_makefiles (argc, argv);
        !          1295: 
        !          1296:   ignore_errors_flag = ignore_errors_flag || lookup_file (".IGNORE");
        !          1297: 
        !          1298:   silent_flag = silent_flag || lookup_file (".SILENT");
        !          1299: 
        !          1300:   default_file = lookup_file (".DEFAULT");
        !          1301: 
        !          1302:   /* Mark files given with -o flags as very old (00:00:01.00 Jan 1, 1970)
        !          1303:      and as having been updated already.  */
        !          1304: 
        !          1305:   for (i = 1; i < argc; ++i)
        !          1306:     if (argv[i][0] == '-' && argv[i][1] == 'o' && argv[i][2] == '\0')
        !          1307:       {
        !          1308:        ++i;
        !          1309:        if (i >= argc)
        !          1310:          fatal ("no file name given after -o flag");
        !          1311:        f = enter_file (argv[i]);
        !          1312:        f->last_mtime = 1L;
        !          1313:        f->updated = 1;
        !          1314:        f->update_status = 0;
        !          1315:       }
        !          1316: 
        !          1317:   /* Make each `struct dep' point at the `struct file'
        !          1318:      for the file depended on.  */
        !          1319: 
        !          1320:   snap_deps ();
        !          1321: 
        !          1322:   /* Install the default pattern rules.  */
        !          1323: 
        !          1324:   if (!no_builtin_rules_flag)
        !          1325:     {
        !          1326:       struct pspec *p;
        !          1327:       /* Install the default pattern rules.  */
        !          1328:       for (p = default_pattern_rules; p->target != 0; ++p)
        !          1329:        install_pattern_rule (p, 0);
        !          1330:       /* Install the default terminal (RCS and SCCS) rules.  */
        !          1331:       for (p = default_terminal_rules; p->target != 0; ++p)
        !          1332:        install_pattern_rule (p, 1);
        !          1333:     }
        !          1334: 
        !          1335:   /* Convert old-style suffix rules to pattern rules.  */
        !          1336: 
        !          1337:   convert_to_pattern ();
        !          1338: 
        !          1339:   /* Compute max dep length and max # deps of any implicit rule.  */
        !          1340: 
        !          1341:   count_implicit_rule_limits ();
        !          1342: 
        !          1343:   /* Construct the listings of directories in VPATH lists.  */
        !          1344: 
        !          1345:   build_vpath_lists ();
        !          1346: 
        !          1347:   /* Construct the list of include directories to search.  */
        !          1348: 
        !          1349:   construct_include_path (argc, argv);
        !          1350: 
        !          1351:   if (print_data_base_flag)
        !          1352:     print_data_base ();
        !          1353:   else if (print_version_flag)
        !          1354:     /* We don't print the version under -p
        !          1355:        because print_data_base does it.  */
        !          1356:     print_version ();
        !          1357: 
        !          1358:   /* Search command line for files to remake.  */
        !          1359: 
        !          1360:   for (i = 1; i < argc; i++)
        !          1361:     {
        !          1362:       /* Anything not a switch or an argument of a switch
        !          1363:         is a file to be remade.
        !          1364:         Note that macro definition args were replaced with
        !          1365:         dummies that look like switches.  */
        !          1366:       if (!strcmp (argv[i], "-f") || !strcmp (argv[i], "-c")
        !          1367:           || !strcmp (argv[i], "-o") || !strcmp (argv[i], "-I"))
        !          1368:        ++i;
        !          1369:       else if (argv[i][0] != '-')
        !          1370:        {
        !          1371:          f = enter_file (argv[i]);
        !          1372:          num_remade++;
        !          1373:          this_status = update_file (f, 0);
        !          1374:          if (this_status)
        !          1375:            {
        !          1376:              status = this_status;
        !          1377:              if (!keep_going_flag)
        !          1378:                break;
        !          1379:            }
        !          1380:        }
        !          1381:     }
        !          1382: 
        !          1383:   /* Command line did not specify any file to remake => use default.  */
        !          1384: 
        !          1385:   if (num_remade == 0)
        !          1386:     {
        !          1387:       if (default_goal_file)
        !          1388:        status = update_file (default_goal_file, 0);
        !          1389:       else
        !          1390:        fatal ("no target");
        !          1391:     }
        !          1392: 
        !          1393:   /* Remove the intermediate files.  */
        !          1394: 
        !          1395:   if (num_intermediates > 0)
        !          1396:     for (i = 0; i < FILE_BUCKETS; ++i)
        !          1397:       for (f = files[i]; f != 0; f = f->next)
        !          1398:        if (f->intermediate && !f->precious && f->updated)
        !          1399:          {
        !          1400:            if (!silent_flag)
        !          1401:              printf ("rm -f %s\n", f->name);
        !          1402:            if (!just_print_flag && unlink (f->name) < 0)
        !          1403:              perror_with_name ("unlink: ", f->name);
        !          1404:          }
        !          1405: 
        !          1406:   if (print_directory_flag)
        !          1407:     log_working_directory (0);
        !          1408: 
        !          1409:   exit (status);
        !          1410:   /* NOTREACHED */
        !          1411: }
        !          1412: 
        !          1413: static void
        !          1414: decode_switches (argc, argv)
        !          1415:      int argc;
        !          1416:      char **argv;
        !          1417: {
        !          1418:   register int i;
        !          1419:   register char *sw;
        !          1420:   char keptflag;
        !          1421:   void decode_env_switches ();
        !          1422: 
        !          1423:   debug_flag = 0;
        !          1424:   env_overrides = 0;
        !          1425:   ignore_errors_flag = 0;
        !          1426:   keep_going_flag = 0;
        !          1427:   just_print_flag = 0;
        !          1428:   print_data_base_flag = 0;
        !          1429:   question_flag = 0;
        !          1430:   no_builtin_rules_flag = 0;
        !          1431:   silent_flag = 0;
        !          1432:   touch_flag = 0;
        !          1433:   print_directory_flag = 0;
        !          1434:   print_version_flag = 0;
        !          1435: 
        !          1436:   decode_env_switches ("MAKEFLAGS", 9);
        !          1437:   decode_env_switches ("MFLAGS", 5);
        !          1438: 
        !          1439:   for (i = 1; i < argc; i++)
        !          1440:     {
        !          1441:       keptflag = '\0';
        !          1442:       sw = argv[i];
        !          1443:       if (*sw++ == '-')
        !          1444:        while (*sw)
        !          1445:          switch (*sw++)
        !          1446:            {
        !          1447:            case 'b':
        !          1448:            case 'm':
        !          1449:              break;
        !          1450:            case 'c':
        !          1451:              keptflag = 'c';
        !          1452:              break;
        !          1453:            case 'd':
        !          1454:              debug_flag = 1;
        !          1455:              break;
        !          1456:            case 'e':
        !          1457:              env_overrides = 1;
        !          1458:              break;
        !          1459:            case 'f':
        !          1460:              keptflag = 'f';
        !          1461:              break;
        !          1462:            case 'I':
        !          1463:              keptflag = 'I';
        !          1464:              break;
        !          1465:            case 'i':
        !          1466:              ignore_errors_flag = 1;
        !          1467:              break;
        !          1468:            case 'k':
        !          1469:              keep_going_flag = 1;
        !          1470:              break;
        !          1471:            case 'n':
        !          1472:              just_print_flag = 1;
        !          1473:              break;
        !          1474:            case 'o':
        !          1475:              keptflag = 'o';
        !          1476:              break;
        !          1477:            case 'p':
        !          1478:              print_data_base_flag = 1;
        !          1479:              break;
        !          1480:            case 'q':
        !          1481:              question_flag = 1;
        !          1482:              break;
        !          1483:            case 'r':
        !          1484:              no_builtin_rules_flag = 1;
        !          1485:              break;
        !          1486:            case 's':
        !          1487:              silent_flag = 1;
        !          1488:              break;
        !          1489:            case 'S':
        !          1490:              keep_going_flag = 0;
        !          1491:              break;
        !          1492:            case 't':
        !          1493:              touch_flag = 1;
        !          1494:              break;
        !          1495:            case 'v':
        !          1496:              print_version_flag = 1;
        !          1497:              break;
        !          1498:            case 'w':
        !          1499:              print_directory_flag = 1;
        !          1500:              break;
        !          1501:            default:
        !          1502:              fatal ("unknown switch: %c", sw[-1]);
        !          1503:            }
        !          1504:       if (keptflag != '\0')
        !          1505:        {
        !          1506:          argv[i][1] = keptflag;
        !          1507:          argv[i][2] = '\0';
        !          1508:        }
        !          1509:     }
        !          1510: }
        !          1511: 
        !          1512: static void
        !          1513: decode_env_switches (envar, len)
        !          1514:      char *envar;
        !          1515:      int len;
        !          1516: {
        !          1517:   struct macro *m;
        !          1518:   register char *args;
        !          1519: 
        !          1520:   m = lookup_macro (envar, len);
        !          1521:   if (m == 0 || *m->value == '\0')
        !          1522:     return;
        !          1523: 
        !          1524:   args = m->value;
        !          1525:   while (*args)
        !          1526:     switch (*args++)
        !          1527:       {
        !          1528:       case 'e':
        !          1529:        env_overrides = 1;
        !          1530:         break;
        !          1531:       case 'i':
        !          1532:        ignore_errors_flag = 1;
        !          1533:         break;
        !          1534:       case 'k':
        !          1535:        keep_going_flag = 1;
        !          1536:         break;
        !          1537:       case 'n':
        !          1538:        just_print_flag = 1;
        !          1539:         break;
        !          1540:       case 'q':
        !          1541:        question_flag = 1;
        !          1542:         break;
        !          1543:       case 'r':
        !          1544:        no_builtin_rules_flag = 1;
        !          1545:         break;
        !          1546:       case 's':
        !          1547:        silent_flag = 1;
        !          1548:         break;
        !          1549:       case 't':
        !          1550:        touch_flag = 1;
        !          1551:         break;
        !          1552:       case 'v':
        !          1553:        print_version_flag = 1;
        !          1554:        break;
        !          1555:       case 'w':
        !          1556:        print_directory_flag = 1;
        !          1557:        break;
        !          1558:       }
        !          1559: 
        !          1560:   return;
        !          1561: }
        !          1562: 
        !          1563: /* Implement macros.  */
        !          1564: 
        !          1565: /* Define macro named NAME with value VALUE.  VALUE is copied.
        !          1566:    LENGTH is the length of NAME, which does not
        !          1567:    need to be null-terminated.
        !          1568:    ORIGIN specifies the origin of the macro (makefile, command line
        !          1569:    or environment).
        !          1570:    If RECURSIVE is nonzero a flag is set in the macro saying
        !          1571:    that it should be recursively re-evaluated.  */
        !          1572: 
        !          1573: static struct macro *
        !          1574: define_macro (name, length, value, origin, recursive)
        !          1575:      char *name, *value;
        !          1576:      int length;
        !          1577:      enum macro_origin origin;
        !          1578:      char recursive;
        !          1579: {
        !          1580:   register struct macro *m;
        !          1581:   register int i;
        !          1582:   register int hashval = 0;
        !          1583: 
        !          1584:   for (i = 0; i < length; ++i)
        !          1585:     hashval += name[i];
        !          1586:   hashval %= MACRO_BUCKETS;
        !          1587: 
        !          1588:   for (m = macros[hashval]; m != 0; m = m->next)
        !          1589:     if (*m->name == *name
        !          1590:         && !strncmp (m->name + 1, name + 1, length - 1)
        !          1591:        && m->name[length] == '\0')
        !          1592:       break;
        !          1593: 
        !          1594:   if (m != 0)
        !          1595:     {
        !          1596:       /* A macro of this name is already defined.
        !          1597:         If the old definition is from a stronger source than this one,
        !          1598:         don't redefine.  */
        !          1599:       if ((int) origin >= (int) m->origin)
        !          1600:        {
        !          1601:          m->value = savestring (value, strlen (value));
        !          1602:          m->origin = origin;
        !          1603:          m->recursive = recursive;
        !          1604:        }
        !          1605:       return m;
        !          1606:     }
        !          1607: 
        !          1608:   /* Create a new macro definition and add to hash table.  */
        !          1609: 
        !          1610:   m = (struct macro *) xmalloc (sizeof (struct macro));
        !          1611:   m->name = savestring (name, length);
        !          1612:   m->value = savestring (value, strlen (value));
        !          1613:   m->origin = origin;
        !          1614:   m->recursive = recursive;
        !          1615:   m->expanding = 0;
        !          1616:   m->next = macros[hashval];
        !          1617:   return (macros[hashval] = m);
        !          1618: }
        !          1619: 
        !          1620: /* Lookup a macro whose name is a string starting at NAME
        !          1621:    and with LENGTH chars.  NAME need not be null-terminated.
        !          1622:    Returns address of the `struct macro' containing all info on the macro,
        !          1623:    or nil if no such macro is defined.  */
        !          1624: 
        !          1625: static struct macro *
        !          1626: lookup_macro (name, length)
        !          1627:      char *name;
        !          1628:      int length;
        !          1629: {
        !          1630:   register struct macro *m;
        !          1631:   register int i;
        !          1632:   register int hashval = 0;
        !          1633: 
        !          1634:   for (i = 0; i < length; ++i)
        !          1635:     hashval += name[i];
        !          1636:   hashval %= MACRO_BUCKETS;
        !          1637: 
        !          1638:   for (m = macros[hashval]; m != 0; m = m->next)
        !          1639:     if (*m->name == *name
        !          1640:         && !strncmp (m->name + 1, name + 1, length - 1)
        !          1641:        && m->name[length] == 0)
        !          1642:       return m;
        !          1643: 
        !          1644:   return 0;
        !          1645: }
        !          1646: 
        !          1647: /* Define the automatic macros, and record the addresses
        !          1648:    of their structures so we can change their values quickly.  */
        !          1649: 
        !          1650: static void
        !          1651: define_automatic_macros ()
        !          1652: {
        !          1653:   char mflags[100];    /* 100 is more than # of distinct option letters */
        !          1654:   register int i;
        !          1655:   register struct macro *m;
        !          1656: 
        !          1657:   star_macro = define_macro ("*", 1, "", o_override, 0);
        !          1658:   starF_macro = define_macro ("*F", 2, "", o_override, 0);
        !          1659:   starD_macro = define_macro ("*D", 2, "", o_override, 0);
        !          1660:   at_macro = define_macro ("@", 1, "", o_override, 0);
        !          1661:   atF_macro = define_macro ("@F", 2, "", o_override, 0);
        !          1662:   atD_macro = define_macro ("@D", 2, "", o_override, 0);
        !          1663:   less_macro = define_macro ("<", 1, "", o_override, 0);
        !          1664:   lessF_macro = define_macro ("<F", 2, "", o_override, 0);
        !          1665:   lessD_macro = define_macro ("<D", 2, "", o_override, 0);
        !          1666:   percent_macro = define_macro ("%", 1, "", o_override, 0);
        !          1667:   percentF_macro = define_macro ("%F", 2, "", o_override, 0);
        !          1668:   percentD_macro = define_macro ("%D", 2, "", o_override, 0);
        !          1669:   qmark_macro = define_macro ("?", 1, "", o_override, 0);
        !          1670:   caret_macro = define_macro ("^", 1, "", o_override, 0);
        !          1671:   dollar_slash_macro = define_macro ("$/", 1, "", o_override, 0);
        !          1672: 
        !          1673:   m = lookup_macro ("MAKELEVEL", 9);
        !          1674:   if (m && m->value)
        !          1675:     makelevel = atoi (m->value);
        !          1676:   else
        !          1677:     makelevel = 0;
        !          1678: 
        !          1679:   shell_macro = lookup_macro ("SHELL", 5);
        !          1680:   if (shell_macro == 0)
        !          1681:     shell_macro = define_macro ("SHELL", 5, "/bin/sh", o_file, 0);
        !          1682: 
        !          1683:   /* Don't let SHELL come from the environment
        !          1684:      if MAKELEVEL is 0.  Also, SHELL must not be empty.  */
        !          1685:   if (*shell_macro->value == '\0'
        !          1686:       || (shell_macro->origin == o_env && makelevel == 0))
        !          1687:     {
        !          1688:       shell_macro->origin = o_file;
        !          1689:       shell_macro->value = savestring ("/bin/sh", 7);
        !          1690:     }
        !          1691: 
        !          1692:   ifs_macro = lookup_macro ("IFS", 3);
        !          1693: 
        !          1694:   /* Define the built-in macro MAKEFLAGS to contain the command line switches.
        !          1695:      We can ignore here those switches that cause commands from the
        !          1696:      makefile not to be run.  */
        !          1697: 
        !          1698:   i = 0;
        !          1699:   mflags[i++] = '-';
        !          1700:   if (env_overrides) mflags[i++] = 'e';
        !          1701:   if (ignore_errors_flag) mflags[i++] = 'i';
        !          1702:   if (keep_going_flag) mflags[i++] = 'k';
        !          1703:   if (just_print_flag) mflags[i++] = 'n';
        !          1704:   if (question_flag) mflags[i++] = 'q';
        !          1705:   if (no_builtin_rules_flag) mflags[i++] = 'r';
        !          1706:   if (silent_flag) mflags[i++] = 's';
        !          1707:   if (touch_flag) mflags[i++] = 't';
        !          1708:   if (print_version_flag) mflags[i++] = 'v';
        !          1709:   if (print_directory_flag) mflags[i++] = 'w';
        !          1710:   mflags[i] = '\0';
        !          1711:   if (i == 1)
        !          1712:     mflags[0] = '\0';
        !          1713:   /* On Sun, value of MFLAGS starts with a `-'
        !          1714:      but value of MAKEFLAGS lacks the `-'.  Be compatible.  */
        !          1715:   (void) define_macro ("MAKEFLAGS", 9, &mflags[1], o_env, 0);
        !          1716:   (void) define_macro ("MFLAGS", 6, mflags, o_env, 0);
        !          1717: }
        !          1718: 
        !          1719: /* Try to interpret LINE (a null-terminated string)
        !          1720:    as a macro definition.  If it is one, define the macro and return 1.
        !          1721:    Otherwise return 0.
        !          1722: 
        !          1723:    ORIGIN be o_file, o_override, o_env, o_env_override, or o_command
        !          1724:    specifying that the macro definition comes from a makefile,
        !          1725:    an override directive, the environment with or without the -e switch,
        !          1726:    or the command line.
        !          1727: 
        !          1728:    A macro definition has the form "name = value" or "name := value".
        !          1729:    Any whitespace around the "=" or ":=" is removed.  The first
        !          1730:    form defines a macro that is recursively re-evaluated.  The second
        !          1731:    form defines a macro whose value is macro-expanded at the time
        !          1732:    of definition and then is evaluated only once at the time of expansion.  */
        !          1733: 
        !          1734: static int
        !          1735: try_macro_definition (line, origin)
        !          1736:      char *line;
        !          1737:      enum macro_origin origin;
        !          1738: {
        !          1739:   register int c;
        !          1740:   register char *p = line;
        !          1741:   register char *beg;
        !          1742:   register char *end;
        !          1743:   register int recursive;
        !          1744: 
        !          1745:   if (*p == '\t')
        !          1746:     return 0;
        !          1747:   while (1)
        !          1748:     {
        !          1749:       c = *p++;
        !          1750:       if (c == '\0' || c == '#')
        !          1751:        return 0;
        !          1752:       if (c == '=')
        !          1753:        {
        !          1754:          end = p - 1;
        !          1755:          recursive = 1;
        !          1756:          break;
        !          1757:        }
        !          1758:       else if (c == ':')
        !          1759:        if (*p == '=')
        !          1760:          {
        !          1761:            end = p - 1;
        !          1762:            c = *p++;
        !          1763:            recursive = 0;
        !          1764:            break;
        !          1765:          }
        !          1766:        else
        !          1767:          return 0;
        !          1768:     }
        !          1769:   beg = line;
        !          1770:   while (beg[0] == ' ' || beg[0] == '\t') beg++;
        !          1771:   while (end[-1] == ' ' || end[-1] == '\t') end--;
        !          1772: 
        !          1773:   while (*p == ' ' || *p == '\t') p++;
        !          1774: 
        !          1775:   (void) define_macro (beg, end - beg, recursive ? p : macro_expand (p),
        !          1776:                       origin, recursive);
        !          1777: 
        !          1778:   return 1;
        !          1779: }
        !          1780: 
        !          1781: /* Store into MACRO_BUFFER at O the result of scanning TEXT
        !          1782:    and replacing each occurrence of SUBST with REPLACE.
        !          1783:    TEXT is null-terminated.
        !          1784:    SLEN is the length of SUBST and RLEN is the length of REPLACE.
        !          1785:    If SUFFIX_ONLY is nonzero, the substitutions are only done
        !          1786:    at the ends of whitespace-delimited words.  */
        !          1787: 
        !          1788: static char *
        !          1789: subst_expand (o, text, subst, replace, slen, rlen, suffix_only)
        !          1790:      char *o;
        !          1791:      char *text;
        !          1792:      char *subst, *replace;
        !          1793:      int slen, rlen;
        !          1794:      int suffix_only;
        !          1795: {
        !          1796:   register char *t = text;
        !          1797:   register char *p;
        !          1798: 
        !          1799: 
        !          1800:   if (slen == 0)
        !          1801:     {
        !          1802:       /* The first occurance of "" in any string is its end.  */
        !          1803:       register int len = strlen (t);
        !          1804:       o = macro_buffer_output (o, t, len);
        !          1805:       t += len;
        !          1806:       if (rlen > 0)
        !          1807:        o = macro_buffer_output (o, replace, rlen);
        !          1808:     }
        !          1809: 
        !          1810:   while (p = sindex (t, 0, subst, slen))
        !          1811:     {
        !          1812:       /* Output everything before this occurance of the string to replace.  */
        !          1813:       if (p > t)
        !          1814:        o = macro_buffer_output (o, t, p - t);
        !          1815:       /* Advance T past the string to be replaced.  */
        !          1816:       t = p + slen;
        !          1817: 
        !          1818:       /* If we're substituting only at the end of whitespace-delimited
        !          1819:         words, check if we're at the end of one.  */
        !          1820:       if (suffix_only && (*t != '\0' && *t != ' ' && *t != '\t'))
        !          1821:        /* Struck out.  Output the rest of the string that is
        !          1822:           no longer to be replaced.  */
        !          1823:        o = macro_buffer_output (o, subst, slen);
        !          1824:       else if (rlen > 0)
        !          1825:        /* Output the replacement string.  */
        !          1826:        o = macro_buffer_output (o, replace, rlen);
        !          1827:     }
        !          1828: 
        !          1829:   /* Output everything left on the end.  */
        !          1830:   if (*t != '\0')
        !          1831:     o = macro_buffer_output (o, t, strlen (t));
        !          1832: 
        !          1833:   return o;
        !          1834: }
        !          1835: 
        !          1836: /* Store into MACRO_BUFFER at O the result of scanning TEXT
        !          1837:    and replacing strings matching PATTERN with REPLACE.  */
        !          1838: 
        !          1839: static char *
        !          1840: patsubst_expand (o, text, pattern, replace)
        !          1841:      char *o;
        !          1842:      char *text;
        !          1843:      register char *pattern, *replace;
        !          1844: {
        !          1845:   register char *pattern_percent = index (pattern, '%');
        !          1846:   register int pattern_prepercent_len, pattern_postpercent_len;
        !          1847:   register char *replace_percent = index (replace, '%');
        !          1848:   register int replace_prepercent_len, replace_postpercent_len;
        !          1849:   register char *t;
        !          1850:   int len;
        !          1851:   int doneany = 0;
        !          1852: 
        !          1853: 
        !          1854:   if (pattern_percent == 0)
        !          1855:     /* With no % in the pattern, this is just a simple substitution.  */
        !          1856:     return subst_expand (o, text, pattern, replace,
        !          1857:                         strlen (pattern), strlen (replace), 0);
        !          1858: 
        !          1859: 
        !          1860:   /* We store the length of the part of the pattern before
        !          1861:      the % in PATTERN_PREPERCENT_LEN so we don't have to do
        !          1862:      the pointer arithmetic to compute it more than once.  */
        !          1863:   pattern_prepercent_len = pattern_percent - pattern;
        !          1864:   /* We store the length of the part of the pattern after
        !          1865:      the pattern in PATTERN_POSTPERCENT_LEN so we don't have
        !          1866:      to compute it more than once.  */
        !          1867:   pattern_postpercent_len = strlen (pattern_percent + 1);
        !          1868: 
        !          1869:   if (replace_percent == 0)
        !          1870:     /* We store the length of the replacement so we only
        !          1871:        need to compute it once.  */
        !          1872:     replace_prepercent_len = strlen (replace);
        !          1873:   else
        !          1874:     {
        !          1875:       /* We store the length of the part of the replacement before
        !          1876:         the % in REPLACE_PREPERCENT_LEN so we don't have to do
        !          1877:         the pointer arithmetic to compute it more than once.  */
        !          1878:       replace_prepercent_len = replace_percent - replace;
        !          1879:       /* We store the length of the part of the replacement after
        !          1880:         the pattern in REPLACE_POSTPERCENT_LEN so we don't have
        !          1881:         to compute it more than once.  */
        !          1882:       replace_postpercent_len = strlen (replace_percent + 1);
        !          1883:     }
        !          1884: 
        !          1885: 
        !          1886:   while (t = find_next_token (&text, &len))
        !          1887:     {
        !          1888:       int fail = 0;
        !          1889: 
        !          1890:       /* Is it big enough to match?  */
        !          1891:       if (len < pattern_prepercent_len + pattern_postpercent_len)
        !          1892:        fail = 1;
        !          1893: 
        !          1894:       /* Does the prefix match?  */
        !          1895:       if (!fail && pattern_prepercent_len > 0
        !          1896:          && (*t != *pattern
        !          1897:              || t[pattern_prepercent_len - 1] != pattern_percent[-1])
        !          1898:              || strncmp (t + 1, pattern + 1, pattern_prepercent_len - 1))
        !          1899:        fail = 1;
        !          1900: 
        !          1901:       /* Does the suffix match?  */
        !          1902:       if (!fail && pattern_postpercent_len > 0
        !          1903:          && (t[len - 1] != pattern_percent[pattern_postpercent_len]
        !          1904:              || t[len - pattern_postpercent_len] != pattern_percent[1]
        !          1905:              || strncmp (&t[len - pattern_postpercent_len],
        !          1906:                          &pattern_percent[1], pattern_postpercent_len - 1)))
        !          1907:        fail = 1;
        !          1908: 
        !          1909:       if (fail)
        !          1910:        /* It didn't match.  Output the string.  */
        !          1911:        o = macro_buffer_output (o, t, len);
        !          1912:       else
        !          1913:        {
        !          1914:          /* It matched.  Output the replacement.  */
        !          1915: 
        !          1916:          /* Output the part of the replacement before the %.  */
        !          1917:          o = macro_buffer_output (o, replace, replace_prepercent_len);
        !          1918: 
        !          1919:          if (replace_percent != 0)
        !          1920:            {
        !          1921:              /* Output the part of the matched string that
        !          1922:                 matched the % in the pattern.  */
        !          1923:              o = macro_buffer_output (o, t + pattern_prepercent_len,
        !          1924:                                       len - (pattern_prepercent_len
        !          1925:                                              + pattern_postpercent_len));
        !          1926:              /* Output the part of the replacement after the %.  */
        !          1927:              o = macro_buffer_output (o, replace_percent + 1,
        !          1928:                                       replace_postpercent_len);
        !          1929:            }
        !          1930:        }
        !          1931: 
        !          1932:       /* Output a space, but not if the replacement is "".  */
        !          1933:       if (!(!fail && replace_percent == 0 && replace_postpercent_len == 0))
        !          1934:        {
        !          1935:          o = macro_buffer_output (o, " ", 1);
        !          1936:          doneany = 1;
        !          1937:        }
        !          1938:     }
        !          1939:   if (doneany)
        !          1940:     /* Kill the last space.  */
        !          1941:     --o;
        !          1942: 
        !          1943:   return o;
        !          1944: }
        !          1945: 
        !          1946: /* Handle macro-expansion-time functions such as $(dir foo/bar) ==> foo/  */
        !          1947: 
        !          1948: /* These enumeration constants distinguish the various expansion-time
        !          1949:    built-in functions.  */
        !          1950: 
        !          1951: enum function
        !          1952:   {
        !          1953:     function_subst,
        !          1954:     function_addsuffix,
        !          1955:     function_addprefix,
        !          1956:     function_dir,
        !          1957:     function_notdir,
        !          1958:     function_suffix,
        !          1959:     function_basename,
        !          1960:     function_wildcard,
        !          1961:     function_firstword,
        !          1962:     function_word,
        !          1963:     function_words,
        !          1964:     function_findstring,
        !          1965:     function_strip,
        !          1966:     function_join,
        !          1967:     function_patsubst,
        !          1968:     function_filter,
        !          1969:     function_filter_out,
        !          1970:     function_foreach,
        !          1971:     function_sort,
        !          1972:     function_invalid
        !          1973:   };
        !          1974: 
        !          1975: /* Greater than the length of any function name.  */
        !          1976: #define MAXFUNCTIONLEN 17
        !          1977: 
        !          1978: /* The function names and lengths of names, for looking them up.  */
        !          1979: 
        !          1980: struct { char *name; int len; enum function function; } function_table[] =
        !          1981:   {
        !          1982:     { "subst", 5, function_subst },
        !          1983:     { "addsuffix", 9, function_addsuffix },
        !          1984:     { "addprefix", 9, function_addprefix },
        !          1985:     { "dir", 3, function_dir },
        !          1986:     { "notdir", 6, function_notdir },
        !          1987:     { "suffix", 6, function_suffix },
        !          1988:     { "basename", 8, function_basename },
        !          1989:     { "wildcard", 8, function_wildcard },
        !          1990:     { "firstword", 9, function_firstword },
        !          1991:     { "word", 4, function_word },
        !          1992:     { "words", 5, function_words },
        !          1993:     { "findstring", 10, function_findstring },
        !          1994:     { "strip", 5, function_strip },
        !          1995:     { "join", 4, function_join },
        !          1996:     { "patsubst", 8, function_patsubst },
        !          1997:     { "filter", 6, function_filter },
        !          1998:     { "filter-out", 10, function_filter_out },
        !          1999:     { "foreach", 7, function_foreach },
        !          2000:     { "sort", 4, function_sort },
        !          2001:     { 0, 0, function_invalid }
        !          2002:   };
        !          2003: 
        !          2004: /* Return 1 if PATTERN matches WORD, 0 if not.  */
        !          2005: static int
        !          2006: pattern_matches (pattern, word)
        !          2007:      register char *pattern, *word;
        !          2008: {
        !          2009:   char *percent = index (pattern, '%');
        !          2010:   int len;
        !          2011: 
        !          2012:   if (percent == 0)
        !          2013:     return !strcmp (pattern, word);
        !          2014: 
        !          2015:   len = strlen (pattern + 1);
        !          2016: 
        !          2017:   if (strlen (word) < (percent - pattern) + len
        !          2018:       || strncmp (pattern, word, percent - pattern))
        !          2019:     return 0;
        !          2020: 
        !          2021:   return !strcmp (percent + 1, word + (strlen (word) - len));
        !          2022: }
        !          2023: 
        !          2024: 
        !          2025: /* Expand an argument for an expansion function.
        !          2026:    The text starting at STR and ending at END is macro-expanded
        !          2027:    into a null-terminated string that is returned as the value.
        !          2028:    This is done without clobbering `macro_buffer' or the current
        !          2029:    macro-expansion that is in progress.  */
        !          2030: 
        !          2031: static char *
        !          2032: expand_argument (str, end)
        !          2033:      char *str, *end;
        !          2034: {
        !          2035:   char *save_macro_buffer = macro_buffer;
        !          2036:   unsigned save_length = macro_buffer_length;
        !          2037:   char *tmp;
        !          2038:   char *value;
        !          2039: 
        !          2040:   macro_buffer = 0;
        !          2041:   tmp = savestring (str, end - str);
        !          2042:   value = macro_expand (tmp);
        !          2043:   free (tmp);
        !          2044: 
        !          2045:   macro_buffer = save_macro_buffer;
        !          2046:   macro_buffer_length = save_length;
        !          2047: 
        !          2048:   return value;
        !          2049: }
        !          2050: 
        !          2051: 
        !          2052: /* Perform the function specified by FUNCTION on the text at TEXT.
        !          2053:    END is points to the end of the argument text (exclusive).
        !          2054:    The output is written into MACRO_BUFFER starting at O.  */
        !          2055: 
        !          2056: static char *
        !          2057: expand_function (o, function, text, end)
        !          2058:      char *o;
        !          2059:      enum function function;
        !          2060:      char *text;
        !          2061:      char *end;
        !          2062: {
        !          2063:   char *p, *p2;
        !          2064:   int i;
        !          2065:   int doneany = 0;
        !          2066: 
        !          2067: /* Note this absorbs a semicolon and is safe to use in conditionals.  */
        !          2068: #define BADARGS(func)  \
        !          2069:   if (reading_filename)                                                \
        !          2070:     fatal ("%s:%ld: Insufficient arguments to function `%s'",  \
        !          2071:           reading_filename, *reading_lineno_ptr, func);        \
        !          2072:   else fatal ("insufficient arguments to function `%s'", func)
        !          2073: 
        !          2074:   switch (function)
        !          2075:     {
        !          2076:     default:
        !          2077:       abort ();
        !          2078:       break;
        !          2079:       
        !          2080:     case function_sort:
        !          2081:       /* Expand the argument.  */
        !          2082:       text = expand_argument (text, end);
        !          2083: 
        !          2084:       {
        !          2085:        char **words = (char **) xmalloc (10 * sizeof (char *));
        !          2086:        unsigned nwords = 10;
        !          2087:        register int wordi = 0;
        !          2088: 
        !          2089:        /* Chop TEXT into words and put them in WORDS.  */
        !          2090:        for (p = wstok(text); p != 0; p = wstok((char *) 0))
        !          2091:          {
        !          2092:            if (wordi >= nwords - 1)
        !          2093:              {
        !          2094:                nwords += 5;
        !          2095:                words = (char **) xrealloc ((char *) words,
        !          2096:                                            nwords * sizeof (char *));
        !          2097:              }
        !          2098:            words[wordi++] = savestring (p, strlen (p));
        !          2099:          }
        !          2100:        words[wordi] = 0;
        !          2101: 
        !          2102:        /* Now sort the list of words.  */
        !          2103:        qsort ((char *) words, wordi, sizeof (char *), alpha_compare);
        !          2104: 
        !          2105:        /* Now write the sorted list.  */
        !          2106:        for (wordi = 0; words[wordi] != 0; ++wordi)
        !          2107:          {
        !          2108:            i = strlen (words[wordi]);
        !          2109:            if (words[wordi + 1] == 0 || strlen (words[wordi + 1]) != i
        !          2110:                || *words[wordi] != *words[wordi + 1]
        !          2111:                || strcmp (words[wordi], words[wordi + 1]))
        !          2112:              {
        !          2113:                o = macro_buffer_output (o, words[wordi], i);
        !          2114:                o = macro_buffer_output (o, " ", 1);
        !          2115:              }
        !          2116:            free (words[wordi]);
        !          2117:          }
        !          2118:        /* Kill the last space.  */
        !          2119:        --o;
        !          2120: 
        !          2121:        free ((char *) words);
        !          2122:       }
        !          2123: 
        !          2124:       free (text);
        !          2125:       break;
        !          2126:       
        !          2127:     case function_foreach:
        !          2128:       {
        !          2129:        /* Get three comma-separated arguments but
        !          2130:           expand only the first two.  */
        !          2131:        char *var, *list;
        !          2132:        register struct macro *m;
        !          2133:        char *saved_value;
        !          2134:        int saved_recursive;
        !          2135:        
        !          2136:        p = lindex (text, end, ',');
        !          2137:        if (p == 0)
        !          2138:          BADARGS ("foreach");
        !          2139:        var = expand_argument (text, p);
        !          2140:        ++p;
        !          2141:        p2 = lindex (p, end, ',');
        !          2142:        if (p2 == 0)
        !          2143:          BADARGS ("foreach");
        !          2144:        list = expand_argument (p, p2);
        !          2145:        ++p2;
        !          2146:        text = savestring (p2, end - p2);
        !          2147: 
        !          2148:        p2 = text + strlen (text);
        !          2149:        i = strlen (var);
        !          2150:        m = lookup_macro (var, i);
        !          2151:        if (m == 0)
        !          2152:          {
        !          2153:            saved_value = "";
        !          2154:            saved_recursive = 0;
        !          2155:            m = define_macro (var, i, saved_value, o_file, 0);
        !          2156:          }
        !          2157:        else
        !          2158:          {
        !          2159:            saved_value = m->value;
        !          2160:            saved_recursive = m->recursive;
        !          2161:            m->recursive = 0;
        !          2162:          }
        !          2163:        for (p = wstok(list); p != 0; p = wstok((char *) 0)) 
        !          2164:          {
        !          2165:            char *result;
        !          2166:            m->value = p;
        !          2167:            result = expand_argument (text, p2);
        !          2168:            o = macro_buffer_output (o, result, strlen (result));
        !          2169:          }
        !          2170:        m->value = saved_value;
        !          2171:        m->recursive = saved_recursive;
        !          2172: 
        !          2173:        free (var);
        !          2174:        free (list);
        !          2175:        free (text);
        !          2176:       }
        !          2177:       break;
        !          2178: 
        !          2179:     case function_filter:
        !          2180:     case function_filter_out:
        !          2181:       /* Get two comma-separated arguments and expand each one.  */
        !          2182:       p = lindex (text, end, ',');
        !          2183:       if (p == 0)
        !          2184:        BADARGS (function == function_filter ? "filter" : "filter-out");
        !          2185:       text = expand_argument (text, p);
        !          2186:       p = expand_argument (p + 1, end);
        !          2187:       
        !          2188:       /* Match the %-style pattern TEXT in P and output words
        !          2189:         that match (for filter) or ones that don't (for
        !          2190:         filter-out).  */
        !          2191:       if (function == function_filter_out)
        !          2192:        /* For filter-out it's simple: just use the patsubst
        !          2193:           function to replace matching words with nothing.  */
        !          2194:        o = patsubst_expand (o, p, text, "");
        !          2195:       else
        !          2196:        /* For filter we must do it ourselves.  */
        !          2197:        for (p2 = wstok (p); p2 != 0; p2 = wstok ((char *) 0))
        !          2198:          if (pattern_matches (text, p2))
        !          2199:            {
        !          2200:              o = macro_buffer_output (o, p2, strlen (p2));
        !          2201:              o = macro_buffer_output (o, " ", 1);
        !          2202:              /* Give us a little marker.  */
        !          2203:              p = 0;
        !          2204:            }
        !          2205:       if (p == 0)
        !          2206:        /* Kill the last space.  */
        !          2207:        --o;
        !          2208:       
        !          2209:       free (p);
        !          2210:       free (text);
        !          2211:       break;
        !          2212:       
        !          2213:     case function_patsubst:
        !          2214:       /* Get three comma-separated arguments and expand each one.  */
        !          2215:       p = lindex (text, end, ',');
        !          2216:       if (p == 0)
        !          2217:        BADARGS ("patsubst");
        !          2218:       p2 = lindex (p + 1, end, ',');
        !          2219:       if (p2 == 0)
        !          2220:        BADARGS ("patsubst");
        !          2221:       text = expand_argument (text, p);
        !          2222:       ++p;
        !          2223:       p = expand_argument (p, p2);
        !          2224:       ++p2;
        !          2225:       p2 = expand_argument (p2, end);
        !          2226:       
        !          2227:       o = patsubst_expand (o, p2, text, p);
        !          2228:       
        !          2229:       free (text);
        !          2230:       free (p);
        !          2231:       free (p2);
        !          2232:       break;
        !          2233:     case function_join:
        !          2234:       /* Get two comma-separated arguments and expand each one.  */
        !          2235:       p = lindex (text, end, ',');
        !          2236:       if (p == 0)
        !          2237:        BADARGS ("join");
        !          2238:       text = expand_argument (text, p);
        !          2239:       ++p;
        !          2240:       p = expand_argument (p, end);
        !          2241:       
        !          2242:       {
        !          2243:        /* Write each word of the first argument directly followed
        !          2244:           by the corresponding word of the second argument.
        !          2245:           If the two arguments have a different number of words,
        !          2246:           the excess words are just output separated by blanks.  */
        !          2247:        register char *tp, *pp;
        !          2248:        int tlen, plen;
        !          2249:        i = 0;
        !          2250:        do
        !          2251:          {
        !          2252:            tp = find_next_token (&text, &tlen);
        !          2253:            if (tp != 0)
        !          2254:              o = macro_buffer_output (o, tp, tlen);
        !          2255:            
        !          2256:            pp = find_next_token (&p, &plen);
        !          2257:            if (pp != 0)
        !          2258:              o = macro_buffer_output (o, pp, plen);
        !          2259:            
        !          2260:            if (tp != 0 || pp != 0)
        !          2261:              {
        !          2262:                o = macro_buffer_output (o, " ", 1);
        !          2263:                doneany = 1;
        !          2264:              }
        !          2265:          }
        !          2266:        while (tp != 0 || pp != 0);
        !          2267:        if (doneany)
        !          2268:          /* Kill the last blank.  */
        !          2269:          --o;
        !          2270:       }
        !          2271:       
        !          2272:       free (text);
        !          2273:       free (p);
        !          2274:       break;
        !          2275:       
        !          2276:     case function_strip:
        !          2277:       text = expand_argument (text, end);
        !          2278:       p = text;
        !          2279:       i = 0;
        !          2280:       while (*p)
        !          2281:        {
        !          2282:          while (*p == ' ' || *p == '\t' || *p == '\n')
        !          2283:            ++p;
        !          2284:          
        !          2285:          p2 = p;
        !          2286:          while (*p && *p != ' ' && *p != '\t' && *p != '\n')
        !          2287:            ++p;
        !          2288:          
        !          2289:          o = macro_buffer_output (o, p2, p - p2);
        !          2290:          o = macro_buffer_output (o, " ", 1);
        !          2291:          doneany = 1;
        !          2292:        }
        !          2293:       if (doneany)
        !          2294:        /* Kill the last space.  */
        !          2295:        --o;
        !          2296:       
        !          2297:       free (text);
        !          2298:       free (p);
        !          2299:       break;
        !          2300:       
        !          2301:     case function_wildcard:
        !          2302:       text = expand_argument (text, end);
        !          2303:       
        !          2304:       p = string_glob (text, 0);
        !          2305:       o = macro_buffer_output (o, p, strlen (p));
        !          2306:       
        !          2307:       free (text);
        !          2308:       break;
        !          2309:       
        !          2310:     case function_subst:
        !          2311:       /* Get three comma-separated arguments and expand each one.  */
        !          2312:       p = lindex (text, end, ',');
        !          2313:       if (p == 0)
        !          2314:        BADARGS ("subst");
        !          2315:       p2 = lindex (p + 1, end, ',');
        !          2316:       if (p2 == 0)
        !          2317:        BADARGS ("subst");
        !          2318:       text = expand_argument (text, p);
        !          2319:       ++p;
        !          2320:       p = expand_argument (p, p2);
        !          2321:       ++p2;
        !          2322:       p2 = expand_argument (p2, end);
        !          2323:       
        !          2324:       o = subst_expand (o, p2, text, p, strlen (text), strlen (p), 0);
        !          2325:       
        !          2326:       free (text);
        !          2327:       free (p);
        !          2328:       free (p2);
        !          2329:       break;
        !          2330:       
        !          2331:     case function_firstword:
        !          2332:       text = expand_argument (text, end);
        !          2333:       /* Find the first word in TEXT.  */
        !          2334:       
        !          2335:       p = wstok (text);
        !          2336:       o = macro_buffer_output (o, p, strlen (p));
        !          2337:       
        !          2338:       free (text);
        !          2339:       break;
        !          2340:       
        !          2341:     case function_word:
        !          2342:       /* Get two comma-separated arguments and expand each one.  */
        !          2343:       p = lindex (text, end, ',');
        !          2344:       if (p == 0)
        !          2345:        BADARGS ("word");
        !          2346:       text = expand_argument (text, p);
        !          2347:       ++p;
        !          2348:       p = expand_argument (p, end);
        !          2349: 
        !          2350:       /* Check the first argument.  */
        !          2351:       for (p2 = text; *p2 != '\0'; ++p2)
        !          2352:        if (*p2 < '0' || *p2 > '9')
        !          2353:          fatal ("%s:%ld: non-numeric first argument to `word' function",
        !          2354:                 reading_filename, *reading_lineno_ptr);
        !          2355: 
        !          2356:       i = atoi (text);
        !          2357:       if (i == 0)
        !          2358:        fatal ("%s:%ld: the `word' function takes a one-origin index argument",
        !          2359:               reading_filename, *reading_lineno_ptr);
        !          2360:       
        !          2361:       for (p2 = wstok (p); p2 != 0; p2 = wstok ((char *) 0))
        !          2362:        if (--i == 0)
        !          2363:          break;
        !          2364:       if (i == 0)
        !          2365:        o = macro_buffer_output (o, p2, strlen (p2));
        !          2366: 
        !          2367:       free (text);
        !          2368:       free (p);
        !          2369:       break;
        !          2370: 
        !          2371:     case function_words:
        !          2372:       /* Expand the argument.  */
        !          2373:       text = expand_argument (text, end);
        !          2374: 
        !          2375:       i = 0;
        !          2376:       for (p = wstok (text); p != 0; p = wstok ((char *) 0))
        !          2377:        ++i;
        !          2378: 
        !          2379:       {
        !          2380:        char buf[20];
        !          2381:        sprintf (buf, "%d", i);
        !          2382:        o = macro_buffer_output (o, buf, strlen (buf));
        !          2383:       }
        !          2384: 
        !          2385:       free (text);
        !          2386:       break;
        !          2387: 
        !          2388:     case function_findstring:
        !          2389:       /* Get two comma-separated arguments and expand each one.  */
        !          2390:       p = lindex (text, end, ',');
        !          2391:       if (p == 0)
        !          2392:        BADARGS ("findstring");
        !          2393:       text = expand_argument (text, p);
        !          2394:       ++p;
        !          2395:       p = expand_argument (p, end);
        !          2396:       
        !          2397:       /* Find the first occurence of the first string in the second.  */
        !          2398:       i = strlen (text);
        !          2399:       if (sindex (p, 0, text, i) != 0)
        !          2400:        o = macro_buffer_output (o, text, i);
        !          2401:       
        !          2402:       free (p);
        !          2403:       free (text);
        !          2404:       break;
        !          2405:       
        !          2406:     case function_addsuffix:
        !          2407:     case function_addprefix:
        !          2408:       /* Get two comma-separated arguments and expand each one.  */
        !          2409:       p2 = lindex (text, end, ',');
        !          2410:       if (p2 == 0)
        !          2411:        BADARGS (function == function_addsuffix ? "addsuffix" : "addprefix");
        !          2412:       text = expand_argument (text, p2);
        !          2413:       i = strlen (text);
        !          2414:       ++p2;
        !          2415:       p2 = expand_argument (p2, end);
        !          2416:       
        !          2417:       for (p = wstok (p2); p != 0; p = wstok ((char *) 0))
        !          2418:        {
        !          2419:          if (function == function_addprefix)
        !          2420:            o = macro_buffer_output (o, text, i);
        !          2421:          o = macro_buffer_output (o, p, strlen (p));
        !          2422:          if (function == function_addsuffix)
        !          2423:            o = macro_buffer_output (o, text, i);
        !          2424:          o = macro_buffer_output (o, " ", 1);
        !          2425:          doneany = 1;
        !          2426:        }
        !          2427:       if (doneany)
        !          2428:        /* Kill last space.  */
        !          2429:        --o;
        !          2430:       
        !          2431:       free (p2);
        !          2432:       free (text);
        !          2433:       break;
        !          2434:       
        !          2435:     case function_dir:
        !          2436:     case function_basename:
        !          2437:       text = expand_argument (text, end);
        !          2438:       for (p2 = wstok (text); p2; p2 = wstok ((char *) 0))
        !          2439:        {
        !          2440:          p = rindex (p2, function == function_dir ? '/' : '.');
        !          2441:          if (p != 0)
        !          2442:            {
        !          2443:              if (function == function_dir)
        !          2444:                ++p;
        !          2445:              o = macro_buffer_output (o, p2, p - p2);
        !          2446:            }
        !          2447:          else if (function == function_dir)
        !          2448:            o = macro_buffer_output (o, "./", 2);
        !          2449:          else  /* The entire name is the basename.  */
        !          2450:            o = macro_buffer_output (o, p2, strlen (p2));
        !          2451:          o = macro_buffer_output (o, " ", 1);
        !          2452:          doneany = 1;
        !          2453:        }
        !          2454:       if (doneany)
        !          2455:        /* Kill last space.  */
        !          2456:        --o;
        !          2457:       
        !          2458:       free (text);
        !          2459:       break;
        !          2460:       
        !          2461:     case function_notdir:
        !          2462:     case function_suffix:
        !          2463:       text = expand_argument (text, end);
        !          2464:       for (p2 = wstok (text); p2; p2 = wstok ((char *) 0))
        !          2465:        {
        !          2466:          p = rindex (p2, function == function_notdir ? '/' : '.');
        !          2467:          if (p != 0)
        !          2468:            {
        !          2469:              ++p;
        !          2470:              o = macro_buffer_output (o, p, strlen (p));
        !          2471:            }
        !          2472:          else if (function == function_notdir)
        !          2473:            o = macro_buffer_output (o, p2, strlen (p2));
        !          2474:          if ((p && *p) || function == function_notdir)
        !          2475:            o = macro_buffer_output (o, " ", 1);
        !          2476:          doneany = 1;
        !          2477:        }
        !          2478:       if (doneany)
        !          2479:        /* Kill last space.  */
        !          2480:        --o;
        !          2481:       free (text);
        !          2482:       break;
        !          2483:     }
        !          2484: 
        !          2485:   return o;
        !          2486: }
        !          2487: 
        !          2488: /* Scan LINE for macro references and expansion-function calls.
        !          2489:    Build in `macro_buffer' the result of expanding those references and calls.
        !          2490:    Return the address of the resulting string, which is null-terminated
        !          2491:    and is valid only until the next time this function is called.  */
        !          2492: 
        !          2493: static char *
        !          2494: macro_expand (line)
        !          2495:      register char *line;
        !          2496: {
        !          2497:   register struct macro *m;
        !          2498:   register char *p, *o, *p1;
        !          2499: 
        !          2500: 
        !          2501:   /* If we don't have a macro output buffer yet, get one.
        !          2502:      The same buffer is reused each time macro_expand is called,
        !          2503:      and made bigger whenever necessary.  */
        !          2504: 
        !          2505:   if (macro_buffer == 0)
        !          2506:     {
        !          2507:       macro_buffer_length = 200;
        !          2508:       macro_buffer = (char *) xmalloc (macro_buffer_length);
        !          2509:     }
        !          2510: 
        !          2511:   p = line;
        !          2512:   o = macro_buffer;
        !          2513:   *o = '\0';
        !          2514: 
        !          2515:   while (1)
        !          2516:     {
        !          2517:       /* Copy all following uninteresting chars all at once to the
        !          2518:          macro output buffer, and skip them.  Uninteresting chars end
        !          2519:         at the next $ or the end of the input.  */
        !          2520: 
        !          2521:       p1 = index (p, '$');
        !          2522:       o = macro_buffer_output (o, p, p1 ? p1 - p : strlen (p) + 1);
        !          2523: 
        !          2524:       if (p1 == 0)
        !          2525:        break;
        !          2526:       p = p1 + 1;
        !          2527: 
        !          2528:       /* Dispatch on the char that follows the $.  */
        !          2529: 
        !          2530:       switch (*p)
        !          2531:        {
        !          2532:        case '$':
        !          2533:          /* $$ seen means output one $ to the output buffer.  */
        !          2534: 
        !          2535:          o = macro_buffer_output (o, p, 1);
        !          2536:          break;
        !          2537: 
        !          2538:        case '(':
        !          2539:        case '{':
        !          2540:          /* $(...) or ${...} is the general case of substitution.  */
        !          2541: 
        !          2542:          {
        !          2543:            char openparen = *p;
        !          2544:            char closeparen = (openparen == '(') ? ')' : '}';
        !          2545:            register char *beg = p + 1;
        !          2546:            char *end;
        !          2547:            register int code;
        !          2548:            int maxlen;
        !          2549: 
        !          2550:            /* First, see if this is a reference to a built-in function.
        !          2551:               That is so if the text inside the parens starts with
        !          2552:               the name of a function ended by a space or tab.  */
        !          2553: 
        !          2554:            p1 = lindex (beg, beg + MAXFUNCTIONLEN, '\0');
        !          2555:            maxlen = p1 ? p1 - beg : MAXFUNCTIONLEN;
        !          2556: 
        !          2557:            for (code = 0; function_table[code].name; ++code)
        !          2558:              {
        !          2559:                if (maxlen < function_table[code].len)
        !          2560:                  continue;
        !          2561:                p1 = beg + function_table[code].len;
        !          2562:                if ((*p1 == ' ' || *p1 == '\t')
        !          2563:                    && !strncmp (function_table[code].name, beg,
        !          2564:                                 function_table[code].len))
        !          2565:                  break;
        !          2566:              }
        !          2567:            if (function_table[code].name)
        !          2568:              {
        !          2569:                /* We have found a call to an expansion-time function.
        !          2570:                   Find the end of the arguments, and do the function.  */
        !          2571: 
        !          2572:                int count = 0;
        !          2573:                char *argbeg;
        !          2574: 
        !          2575:                /* Space after function name isn't part of the args.  */
        !          2576:                p = p1;
        !          2577:                while (*p == ' ' || *p == '\t')
        !          2578:                  ++p;
        !          2579:                argbeg = p;
        !          2580: 
        !          2581:                /* Count nested use of whichever kind of parens we use,
        !          2582:                   so that nested calls and macro refs work.  */
        !          2583: 
        !          2584:                for (; *p; ++p)
        !          2585:                  {
        !          2586:                    if (*p == openparen)
        !          2587:                      ++count;
        !          2588:                    else if (*p == closeparen && --count < 0)
        !          2589:                      break;
        !          2590:                  }
        !          2591: 
        !          2592:                /* We found the end; expand the function call.  */
        !          2593: 
        !          2594:                o = expand_function (o, function_table[code].function,
        !          2595:                                     argbeg, p);
        !          2596:                break;
        !          2597:              }
        !          2598: 
        !          2599:            /* Is there a macro reference inside the parens or braces?
        !          2600:               If so, expand it before expanding the entire reference.  */
        !          2601: 
        !          2602:            p1 = index (beg, '$');
        !          2603:            if (p1 != 0)
        !          2604:              {
        !          2605:                /* BEG now points past the opening paren or brace.
        !          2606:                   Count parens or braces until it is matched.  */
        !          2607:                int count = 0;
        !          2608:                for (p = beg; *p != '\0'; ++p)
        !          2609:                  {
        !          2610:                    if (*p == openparen)
        !          2611:                      ++count;
        !          2612:                    else if (*p == closeparen && --count < 0)
        !          2613:                      break;
        !          2614:                  }
        !          2615:                /* If count is >= 0, there were unmatched opening parens
        !          2616:                   or braces, so we go to the simple case of a macro name
        !          2617:                   such as "$($(a)".  */
        !          2618:                if (count < 0)
        !          2619:                  {
        !          2620:                    char *name = expand_argument (beg, p);
        !          2621:                    p1 = concat ("$(", name, ")");
        !          2622:                    free (name);
        !          2623:                    name = expand_argument (p1, p1 + strlen (p1));
        !          2624:                    o = macro_buffer_output (o, name, strlen (name));
        !          2625:                    free (name);
        !          2626:                    break;
        !          2627:                  }
        !          2628:              }
        !          2629: 
        !          2630:            /* This is not a reference to a built-in function and
        !          2631:               it does not contain any macro references inside.
        !          2632:               There are several things it could be.  In any case,
        !          2633:               find the end of it, which is the first close-paren
        !          2634:               of the appropriate type.  (We do not count them.)  */
        !          2635: 
        !          2636:            end = index (beg, closeparen);
        !          2637:            if (end == 0)
        !          2638:              /* There was no ending ) or } !!
        !          2639:                 Swallow the line (and screw the hook and sinker).  */
        !          2640:              return macro_buffer;
        !          2641: 
        !          2642:            /* This is not a reference to a built-in function.  Is it
        !          2643:               an old-fashioned substitution spec, $(FOO:BAR=UGH)?  */
        !          2644: 
        !          2645:            if ((p = lindex (beg, end, ':')) && (p1 = lindex (p, end, '=')))
        !          2646:              {
        !          2647:                int slen = p1 - p - 1;
        !          2648:                int rlen = end - p1 - 1;
        !          2649:                m = lookup_macro (beg, p - beg);
        !          2650:                if (m != 0 && *m->value != '\0')
        !          2651:                  o = subst_expand (o, m->value, p+1, p1+1, slen, rlen, 1);
        !          2652:              }
        !          2653: 
        !          2654:            /* No, this must be an ordinary macro reference.  */
        !          2655:            else
        !          2656:              {
        !          2657:                /* Look up the value of the macro.  */
        !          2658:                m = lookup_macro (beg, end - beg);
        !          2659: 
        !          2660:                if (m != 0 && *m->value != '\0')
        !          2661:                  if (m->expanding)
        !          2662:                    fatal ("Recursive variable `%s' references \
        !          2663: itself (eventually)",
        !          2664:                           m->name);
        !          2665:                  else if (m->recursive)
        !          2666:                    {
        !          2667:                      /* Re-expand the macro value.  */
        !          2668:                      m->expanding = 1;
        !          2669:                      p = expand_argument (m->value,
        !          2670:                                           m->value + strlen (m->value));
        !          2671:                      m->expanding = 0;
        !          2672: 
        !          2673:                      /* Output the re-expanded value.  */
        !          2674:                      o = macro_buffer_output (o, p, strlen (p));
        !          2675:                    }
        !          2676:                  else
        !          2677:                    o = macro_buffer_output (o, m->value, strlen (m->value));
        !          2678:              }
        !          2679: 
        !          2680:            /* Advance p past the macro reference to resume scan.  */
        !          2681:            p = end;
        !          2682:          }
        !          2683:          break;
        !          2684: 
        !          2685:        case '\0':
        !          2686:        case '\t':
        !          2687:        case ' ':
        !          2688:          break;
        !          2689: 
        !          2690:        default:
        !          2691:          /* A $ followed by a random char is a macro reference:
        !          2692:             $a is equivalent to $(a).  */
        !          2693: 
        !          2694:          m = lookup_macro (p, 1);
        !          2695:          if (m != 0 && *m->value != '\0')
        !          2696:            if (m->expanding)
        !          2697:              fatal ("Recursive variable `%s' references itself (eventually)",
        !          2698:                     m->name);
        !          2699:            else if (m->recursive)
        !          2700:              {
        !          2701:                /* Re-expand the macro value.  */
        !          2702:                m->expanding = 1;
        !          2703:                p1 = expand_argument (m->value,
        !          2704:                                      m->value + strlen (m->value));
        !          2705:                m->expanding = 0;
        !          2706:                
        !          2707:                /* Output the re-expanded value.  */
        !          2708:                o = macro_buffer_output (o, p1, strlen (p1));
        !          2709:              }
        !          2710:            else
        !          2711:              o = macro_buffer_output (o, m->value, strlen (m->value));
        !          2712: 
        !          2713:          break;
        !          2714:        }      
        !          2715:       ++p;
        !          2716:     }
        !          2717:   return macro_buffer;
        !          2718: }
        !          2719: 
        !          2720: /* Subroutine of macro_expand and friends:
        !          2721:    The text to add is LENGTH chars starting at STRING to the macro_buffer.
        !          2722:    The text is added to the buffer at PTR, and the updated pointer into
        !          2723:    the buffer is returned as the value.  Thus, the value returned by
        !          2724:    each call to macro_buffer_output should be the first argument to
        !          2725:    the following call.  */
        !          2726: 
        !          2727: static char *
        !          2728: macro_buffer_output (ptr, string, length)
        !          2729:      char *ptr, *string;
        !          2730:      int length;
        !          2731: {
        !          2732:   register int newlen = length + (ptr - macro_buffer);
        !          2733:   register char *new;
        !          2734: 
        !          2735:   if (newlen > macro_buffer_length)
        !          2736:     {
        !          2737:       macro_buffer_length = max (2 * macro_buffer_length, newlen + 100);
        !          2738:       new = (char *) xrealloc (macro_buffer, macro_buffer_length);
        !          2739:       ptr += new - macro_buffer;
        !          2740:       macro_buffer = new;
        !          2741:     }
        !          2742: 
        !          2743:   bcopy (string, ptr, (int) length);
        !          2744:   return (ptr + length);
        !          2745: }
        !          2746: 
        !          2747: /* Access the hash table of all file records.
        !          2748:    lookup_file  given a name, return the struct file * for that name,
        !          2749:            or nil if there is none.
        !          2750:    enter_file   similar, but create one if there is none.  */
        !          2751: 
        !          2752: static struct file *
        !          2753: lookup_file (name)
        !          2754:      char *name;
        !          2755: {
        !          2756:   register struct file *f;
        !          2757:   register char *n;
        !          2758:   register int hashval = 0;
        !          2759: 
        !          2760:   while (name[0] == '.' && name[1] == '/' && name[2])
        !          2761:     name += 2;
        !          2762: 
        !          2763:   if (*name == '\0')
        !          2764:     abort ();
        !          2765: 
        !          2766:   for (n = name; *n; ++n)
        !          2767:     hashval += *n;
        !          2768:   hashval %= FILE_BUCKETS;
        !          2769: 
        !          2770:   for (f = files[hashval]; f != 0; f = f->next)
        !          2771:     if (streq (f->name, name))
        !          2772:       return (f);
        !          2773:   return (0);
        !          2774: }
        !          2775: 
        !          2776: static struct file *
        !          2777: enter_file (name)
        !          2778:      char *name;
        !          2779: {
        !          2780:   register struct file *f, *lastf;
        !          2781:   register char *n;
        !          2782:   register int hashval = 0;
        !          2783: 
        !          2784:   while (name[0] == '.' && name[1] == '/' && name[2])
        !          2785:     name += 2;
        !          2786: 
        !          2787:   if (*name == '\0')
        !          2788:     abort ();
        !          2789: 
        !          2790:   for (n = name; *n; ++n)
        !          2791:     hashval += *n;
        !          2792:   hashval %= FILE_BUCKETS;
        !          2793: 
        !          2794:   for (lastf = f = files[hashval]; f != 0; lastf = f, f = f->next)
        !          2795:     if (streq (f->name, name))
        !          2796:       break;
        !          2797: 
        !          2798:   if (f != 0)
        !          2799:     if (f->double_colon)
        !          2800:       {
        !          2801:        /* If there is a double-colon entry for NAME, we want to
        !          2802:           add another entry, but make it so the original one,
        !          2803:           now pointed to by F, will always be the first found.  */
        !          2804:        /* Remove F from the chain.  */
        !          2805:        if (f == lastf)
        !          2806:          /* If F and LASTF are the same, we are at the beginning
        !          2807:             of the chain and must change the head pointer.  */
        !          2808:          files[hashval] = f->next;
        !          2809:        else
        !          2810:          lastf->next = f->next;
        !          2811:       }
        !          2812:     else
        !          2813:       return f;
        !          2814: 
        !          2815:   lastf = (struct file *) xmalloc (sizeof (struct file));
        !          2816:   bzero ((char *) lastf, sizeof (struct file));
        !          2817:   lastf->name = name;
        !          2818:   lastf->update_status = -1;
        !          2819: 
        !          2820:   lastf->next = files[hashval];
        !          2821:   files[hashval] = lastf;
        !          2822:   if (f != 0)
        !          2823:     {
        !          2824:       /* Put F in front of the newly created LASTF.  */
        !          2825:       f->next = files[hashval];
        !          2826:       files[hashval] = f;
        !          2827:     }
        !          2828: 
        !          2829:   return lastf;
        !          2830: }
        !          2831: 
        !          2832: /* Print version information.
        !          2833:    This prints:
        !          2834: 
        !          2835:      GNU Make version X.Y (Rel), by Richard Stallman and Roland McGrath.
        !          2836:      Copyright (C) 1988 Free Software Foundation, Inc.
        !          2837:      This is free software; see the source file for copying conditions.
        !          2838:      There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
        !          2839:      PARTICULAR PURPOSE.
        !          2840: 
        !          2841:    where X.Y is the second word of `$Revision: 2.9 $' and Rel is
        !          2842:    the second word of `$State: Rel $'.  */
        !          2843: 
        !          2844: static void
        !          2845: print_version ()
        !          2846: {
        !          2847:   char *revision = &"$Revision: 2.9 $"[11];
        !          2848:   char *state = &"$State: Rel $"[8];
        !          2849:   int rlen, slen;
        !          2850:   
        !          2851: 
        !          2852:   /* If this was compiled from a checked-out and locked version
        !          2853:      of the source, the RCS keywords have no values.  */
        !          2854:   if (revision[-2] == '$' || state[-2] == '$')
        !          2855:     {
        !          2856:       revision = "(New)";
        !          2857:       state = "in progess";
        !          2858:       rlen = 5;
        !          2859:       slen = 10;
        !          2860:     }
        !          2861:   else
        !          2862:     {
        !          2863:       rlen = index (revision, ' ') - revision;
        !          2864:       slen = index (state, ' ') - state;
        !          2865:     }
        !          2866:   
        !          2867: 
        !          2868:   printf ("GNU Make version %.*s (%.*s), ", rlen, revision, slen, state);
        !          2869: 
        !          2870:   puts ("by Richard Stallman and Roland McGrath.\n\
        !          2871: Copyright (C) 1988 Free Software Foundation, Inc.\n\
        !          2872: This is free software; see the source file for copying conditions.\n\
        !          2873: There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\
        !          2874: PARTICULAR PURPOSE.\n");
        !          2875: 
        !          2876:   /* Flush stdout so the user doesn't have to wait to see the
        !          2877:      version information while things are thought about.  */
        !          2878:   fflush (stdout);
        !          2879: }
        !          2880: 
        !          2881: /* Print the contents of the files and macros hash tables.  */
        !          2882: 
        !          2883: static void
        !          2884: print_data_base ()
        !          2885: {
        !          2886:   register struct macro *m;
        !          2887:   register struct file *f;
        !          2888:   register struct dep *d;
        !          2889:   register struct rule *r;
        !          2890:   register struct dirdata *dir;
        !          2891:   register int i, j, k;
        !          2892: 
        !          2893:   print_version ();
        !          2894: 
        !          2895:   puts ("\nMacros\n");
        !          2896: 
        !          2897:   j = 0;
        !          2898:   for (i = 0; i < MACRO_BUCKETS; ++i)
        !          2899:     for (m = macros[i]; m != 0; m = m->next)
        !          2900:       {
        !          2901:        ++j;
        !          2902:        printf ("%s %s= %s\n", m->name, m->recursive ? "" : ":", m->value);
        !          2903:       }
        !          2904: 
        !          2905:   printf ("\n%d macros in %d hash buckets, average %f macros per bucket.\n",
        !          2906:          j, MACRO_BUCKETS, ((float) j) / MACRO_BUCKETS);
        !          2907: 
        !          2908:   puts ("\nImplicit rules\n");
        !          2909: 
        !          2910:   j = k = 0;
        !          2911:   for (r = pattern_rules; r != 0; r = r->next)
        !          2912:     {
        !          2913:       ++j;
        !          2914:       printf ("%s:", r->name);
        !          2915:       if (r->terminal)
        !          2916:        {
        !          2917:          ++k;
        !          2918:          puts ("   (terminal)");
        !          2919:        }
        !          2920:       else
        !          2921:        putchar ('\n');
        !          2922:       for (d = r->deps; d != 0; d = d->next)
        !          2923:        printf (" depends on %s\n", dep_name (d));
        !          2924:       if (r->cmds)
        !          2925:        {
        !          2926:          struct commands *c = r->cmds;
        !          2927:          if (c->filename)
        !          2928:            printf (" commands to execute (from `%s', line %ld):\n  %s",
        !          2929:                    c->filename, c->lineno, c->commands);
        !          2930:          else
        !          2931:            printf (" commands to execute:\n  %s\n", c->commands);
        !          2932:        }
        !          2933:     }
        !          2934: 
        !          2935:   printf ("\n%d implicit rules, %d (%f%%) terminal.\n", j, k, 100 * k / j);
        !          2936: 
        !          2937:   puts ("\nDirectories\n");
        !          2938: 
        !          2939:   j = k = 0;
        !          2940:   for (i = 0; i < DIR_HASH_SIZE; ++i)
        !          2941:     for (dir = dir_hash_table[i]; dir != 0; dir = dir->next)
        !          2942:       {
        !          2943:        ++k;
        !          2944:        if (dir->name[0] == '.' && dir->name[1] == '\0')
        !          2945:          {
        !          2946:            ++j;
        !          2947:            puts (dir->dir);
        !          2948:          }
        !          2949:       }
        !          2950: 
        !          2951:   printf ("\n%d directories with a total of %d files in %d hash buckets,\n",
        !          2952:           j, k, DIR_HASH_SIZE);
        !          2953:   printf ("average of %f files per bucket.\n", ((float) k) / DIR_HASH_SIZE);
        !          2954: 
        !          2955:   puts ("\nFiles\n");
        !          2956: 
        !          2957:   j = 0;
        !          2958:   for (i = 0; i < FILE_BUCKETS; ++i)
        !          2959:     for (f = files[i]; f != 0; f = f->next)
        !          2960:       {
        !          2961:        ++j;
        !          2962:        fputs (f->name, stdout);
        !          2963:        if (f->is_target)
        !          2964:          putchar (':');
        !          2965:        if (f->double_colon)
        !          2966:          putchar (':');
        !          2967:        if (f->stem != 0)
        !          2968:          printf ("   (pattern rule stem `%s')", f->stem);
        !          2969:        putchar ('\n');
        !          2970:        for (d = f->deps; d != 0; d = d->next)
        !          2971:          printf (" depends on %s\n", dep_name (d));
        !          2972:        if (f->cmds)
        !          2973:          {
        !          2974:            struct commands *c = f->cmds;
        !          2975:            if (c->filename)
        !          2976:              printf (" commands to execute (from `%s', line %ld):\n  %s",
        !          2977:                      c->filename, c->lineno, c->commands);
        !          2978:            else
        !          2979:              printf (" commands to execute:\n  %s\n", c->commands);
        !          2980:          }
        !          2981:       }
        !          2982: 
        !          2983:   printf ("\n%d files in %d hash buckets, average %f files per bucket.\n",
        !          2984:          j, FILE_BUCKETS, ((float) j) / FILE_BUCKETS);
        !          2985: 
        !          2986:   puts ("\nDone");
        !          2987:   fflush (stdout);
        !          2988: }
        !          2989: 
        !          2990: void read_makefile (), record_files ();
        !          2991: 
        !          2992: /* Look at out command args to determine the names of the makefiles
        !          2993:    and read all those files, adding their macro definitions and rules
        !          2994:    to the macro and file hash tables.  */
        !          2995: 
        !          2996: static void
        !          2997: read_all_makefiles (argc, argv)
        !          2998:      int argc;
        !          2999:      char **argv;
        !          3000: {
        !          3001:   struct macro *m;
        !          3002:   register int i;
        !          3003:   int num_makefiles = 0;
        !          3004: 
        !          3005:   /* If there's a non-null macro MAKEFILES,
        !          3006:      its value a list of files to read first thing.
        !          3007:      But don't let it prevent reading the default makefiles
        !          3008:      and don't let the default goal come from there.  */
        !          3009: 
        !          3010:   m = lookup_macro ("MAKEFILES", 9);
        !          3011:   if (m && *m->value)
        !          3012:     {
        !          3013:       char *rest = m->value;
        !          3014:       char *name;
        !          3015:       int length;
        !          3016:       /* Set NAME to start of next token and LENGTH to its length.
        !          3017:         REST is updated for finding remaining tokens.  */
        !          3018:       while (name = find_next_token (&rest, &length))
        !          3019:        {
        !          3020:          name = savestring (name, length);
        !          3021:          if (file_exists_p (name))
        !          3022:            read_makefile (name, 1, 0);
        !          3023:          else
        !          3024:            free (name);
        !          3025:        }
        !          3026:     }
        !          3027: 
        !          3028:   /* Read makefiles specified with -f switches.  */
        !          3029: 
        !          3030:   for (i = 1; i < argc; i++)
        !          3031:     if (!strcmp (argv[i], "-f"))
        !          3032:       {
        !          3033:        ++i;
        !          3034:        if (i >= argc)
        !          3035:          fatal ("no description argument after -f command option");
        !          3036:        read_makefile (argv[i], 0, 2);
        !          3037:        ++num_makefiles;
        !          3038:       }
        !          3039: 
        !          3040:   /* If there were no -f switches, try the default names.  */
        !          3041: 
        !          3042:   if (num_makefiles == 0)
        !          3043:     {
        !          3044:       if (file_exists_p ("makefile"))
        !          3045:        read_makefile ("makefile", 0, 2);
        !          3046:       else if (file_exists_p ("Makefile"))
        !          3047:        read_makefile ("Makefile", 0, 2);
        !          3048:       else if (argc <= 1)
        !          3049:        fatal ("no target arguments or description file");
        !          3050:     }
        !          3051: }
        !          3052: 
        !          3053: /* Read file FILENAME as a makefile and add its contents to the data base.
        !          3054:    NODEFAULT means don't take the default goal target from this makefile.
        !          3055:    ERRORLEVEL determines the behavior if the file is not found.
        !          3056:    If it is <= 0, nothing happens.  If it is 1, a message is issued.
        !          3057:    If it is > 1, a message is issued and the program exits.  */
        !          3058: 
        !          3059: static void
        !          3060: read_makefile (filename, nodefault, errorlevel)
        !          3061:      char *filename;
        !          3062:      int nodefault;
        !          3063:      int errorlevel;
        !          3064: {
        !          3065:   static char *collapsed = 0;
        !          3066:   static unsigned collapsed_length = 0;
        !          3067:   register FILE *infile;
        !          3068:   struct linebuffer lb;
        !          3069:   unsigned commands_len = 200;
        !          3070:   char *commands = (char *) xmalloc (200);
        !          3071:   int commands_idx = 0;
        !          3072:   long commands_started;
        !          3073:   register char *p;
        !          3074:   char *p2;
        !          3075:   int ignoring = 0;
        !          3076: 
        !          3077:   struct nameseq *filenames = 0;
        !          3078:   struct dep *deps = 0;
        !          3079:   long lineno = 1;
        !          3080:   long nlines = 0;
        !          3081:   int two_colon;
        !          3082:   char *cmdleft;
        !          3083:   char *pattern = 0;
        !          3084:   
        !          3085: #ifdef lint    /* Suppress `used before set' messages.  */
        !          3086:   two_colon = 0;
        !          3087: #endif
        !          3088: 
        !          3089:   /* First, get a stream to read.  */
        !          3090: 
        !          3091:   if (!strcmp (filename, "-"))
        !          3092:     infile = stdin;
        !          3093:   else
        !          3094:     infile = fopen (filename, "r");
        !          3095: 
        !          3096:   if (infile == 0 && nodefault && *filename != '/' && include_directories)
        !          3097:     {
        !          3098:       register int i;
        !          3099:       char *name = (char *) alloca (max_incl_len + 1 + strlen (filename) + 1);
        !          3100:       for (i = 0; include_directories[i] != 0; ++i)
        !          3101:        {
        !          3102:          sprintf (name, "%s/%s", include_directories[i], filename);
        !          3103:          infile = fopen (name, "r");
        !          3104:          if (infile != 0)
        !          3105:            {
        !          3106:              filename = name;
        !          3107:              break;
        !          3108:            }
        !          3109:        }
        !          3110:     }
        !          3111: 
        !          3112:   /* If file can't be found at all, either ignore it or give up entirely.  */
        !          3113: 
        !          3114:   if (infile == 0)
        !          3115:     {
        !          3116:       if (errorlevel > 1)
        !          3117:        pfatal_with_name (filename);
        !          3118:       else if (errorlevel > 0)
        !          3119:        perror_with_name ("", filename);
        !          3120:       return;
        !          3121:     }
        !          3122: 
        !          3123:   reading_filename = filename;
        !          3124:   reading_lineno_ptr = &lineno;
        !          3125: 
        !          3126:   /* Loop over lines in the file.
        !          3127:      The strategy is to accumulate target names in FILENAMES,
        !          3128:      dependencies in DEPS and commands in COMMANDS.
        !          3129:      These are used to define a rule
        !          3130:      when the start of the next rule (or eof) is encountered.  */
        !          3131: 
        !          3132:   initbuffer (&lb);
        !          3133: 
        !          3134:   while (!feof (infile))
        !          3135:     {
        !          3136:       lineno += nlines;
        !          3137:       nlines = readline (&lb, infile, filename);
        !          3138:       if (nlines == 0)
        !          3139:        break;
        !          3140: 
        !          3141:       if (collapsed_length < lb.size)
        !          3142:        {
        !          3143:          collapsed_length = lb.size;
        !          3144:          if (collapsed == 0)
        !          3145:            collapsed = (char *) xmalloc (collapsed_length);
        !          3146:          else
        !          3147:            collapsed = (char *) xrealloc (collapsed, collapsed_length);
        !          3148:        }
        !          3149:       strcpy (collapsed, lb.buffer);
        !          3150:       collapse_line (collapsed);
        !          3151:       
        !          3152:       p = collapsed;
        !          3153:       while (*p == ' ' || *p == '\t')
        !          3154:        ++p;
        !          3155:       if (*p == '\0')
        !          3156:        continue;
        !          3157: 
        !          3158: #define        word1eq(s, l)   ((p[l] == '\0' || p[l] == ' ' || p[l] == '\t') && \
        !          3159:                         !strncmp (s, p, l))
        !          3160:       p = lb.buffer;
        !          3161:       if (word1eq ("ifdef", 5) || word1eq ("ifndef", 6)
        !          3162:          || word1eq ("ifeq", 4) || word1eq ("ifneq", 5)
        !          3163:          || word1eq ("else", 4) || word1eq ("endif", 5))
        !          3164:        {
        !          3165:          int i = conditional_line (collapsed, filename, lineno);
        !          3166:          if (i >= 0)
        !          3167:            {
        !          3168:              ignoring = i;
        !          3169:              continue;
        !          3170:            }
        !          3171:          else
        !          3172:            fatal ("%s:%ld: invalid syntax in conditional", filename, lineno);
        !          3173:        }
        !          3174:       if (ignoring)
        !          3175:        continue;
        !          3176:       else if (word1eq ("define", 6))
        !          3177:        {
        !          3178:          p = collapsed;
        !          3179:          p += 6;
        !          3180:          p2 = next_token (p);
        !          3181:          p = end_of_token (p2);
        !          3182:          lineno = do_define (&lb, savestring (p2, p - p2),
        !          3183:                              lineno, infile, filename);
        !          3184:          continue;
        !          3185:        }
        !          3186:       else if (word1eq ("endef", 5))
        !          3187:        fatal ("%s:%ld: extraneous `endef'", filename, lineno);
        !          3188:       else if (word1eq ("override", 8))
        !          3189:        {
        !          3190:          p = collapsed;
        !          3191:          p += 8;
        !          3192:          p2 = next_token (p);
        !          3193:          if (p2 == 0 || !try_macro_definition (p2, o_override))
        !          3194:            fatal ("%s:%ld: Empty `override' directive", filename, lineno);
        !          3195:        }
        !          3196:       else if (word1eq ("include", 7))
        !          3197:        {
        !          3198:          /* We have found an `include' line specifying a nested
        !          3199:             makefile to be read at this point.  */
        !          3200:          p = collapsed;
        !          3201:          p += 8;
        !          3202:          p2 = next_token (p);
        !          3203:          if (p2 == 0)
        !          3204:            fatal ("%s:%ld: no filename for `include'", filename, lineno);
        !          3205:          p = end_of_token (p2);
        !          3206:          p = savestring (p2, p - p2);
        !          3207:          read_makefile (p, 1, 1);
        !          3208:          continue;
        !          3209:        }
        !          3210:       else if (word1eq ("vpath", 5))
        !          3211:        {
        !          3212:          p = collapsed;
        !          3213:          p += 5;
        !          3214:          p2 = macro_expand (p);
        !          3215:          p = next_token (p2);
        !          3216:          if (p != 0)
        !          3217:            {
        !          3218:            p2 = end_of_token (p);
        !          3219:            pattern = savestring (p, p2 - p);
        !          3220:            p = next_token (p2);
        !          3221:            if (p != 0)
        !          3222:              {
        !          3223:                p2 = end_of_token (p);
        !          3224:                p = savestring (p, p2 - p);
        !          3225:              }
        !          3226:              /* No searchpath means remove all previous selective VPATH's
        !          3227:                 with the same pattern.  */
        !          3228:            }
        !          3229:          else
        !          3230:            /* No pattern means remove all previous selective VPATH's.  */
        !          3231:            pattern = 0;
        !          3232:          (void) construct_vpath_list (pattern, p);
        !          3233:          if (pattern != 0)
        !          3234:            free (pattern);
        !          3235:          if (p != 0)
        !          3236:            free (p);
        !          3237:          continue;
        !          3238:        }
        !          3239: #undef word1eq
        !          3240:       else if (try_macro_definition (collapsed, o_file))
        !          3241:        continue;
        !          3242:       else if (*p == '\t')
        !          3243:        {
        !          3244:          /* This line is a shell command */
        !          3245:          int len;
        !          3246: 
        !          3247:          if (filenames == 0)
        !          3248:            fatal ("%s:%ld: commands commence before first target",
        !          3249:                   filename, lineno);
        !          3250: 
        !          3251:          /* Add this command line to end of the line being accumulated.  */
        !          3252:          if (commands_idx == 0)
        !          3253:            commands_started = lineno;
        !          3254:          len = strlen (p);
        !          3255:          if (len + 1 + commands_idx > commands_len)
        !          3256:            {
        !          3257:              commands_len = (len + 1 + commands_idx) * 2;
        !          3258:              commands = (char *) xrealloc (commands, commands_len);
        !          3259:            }
        !          3260:          bcopy (p, &commands[commands_idx], len);
        !          3261:          commands_idx += len;
        !          3262:          commands[commands_idx++] = '\n';
        !          3263:        }
        !          3264:       else
        !          3265:        {
        !          3266:          /* This line describes some target files.
        !          3267:             Record the previous rule.  */
        !          3268: 
        !          3269:          struct commands *cmds;
        !          3270: 
        !          3271:          if (commands_idx > 0)
        !          3272:            {
        !          3273:              register int i = 0;
        !          3274:              while (i < commands_idx
        !          3275:                     && (commands[i] == ' ' || commands[i] == '\t'
        !          3276:                         || commands[i] == '\n'))
        !          3277:                ++i;
        !          3278:              if (i < commands_idx)
        !          3279:                {
        !          3280:                  cmds = (struct commands *)
        !          3281:                    xmalloc (sizeof (struct commands));
        !          3282:                  cmds->filename = filename;
        !          3283:                  cmds->lineno = commands_started;
        !          3284:                  cmds->commands = savestring (commands, commands_idx);
        !          3285:                }
        !          3286:              else
        !          3287:                cmds = 0;
        !          3288:            }
        !          3289:          else
        !          3290:            cmds = 0;
        !          3291:          record_files (filenames, pattern, deps, cmds, two_colon,
        !          3292:                        filename, lineno, !nodefault);
        !          3293: 
        !          3294: 
        !          3295:          /* Does this line contain a semicolon (that isn't quoted with \)?
        !          3296:             If so, find the first such.  */
        !          3297:          cmdleft = index (collapsed, ';');
        !          3298:          while (cmdleft != 0 && cmdleft[-1] == '\\')
        !          3299:            {
        !          3300:              register char *q = &cmdleft[-1];
        !          3301:              register int backslash = 0;
        !          3302:              while (*q-- == '\\')
        !          3303:                backslash = !backslash;
        !          3304:              if (backslash)
        !          3305:                cmdleft = index (cmdleft + 1, ';');
        !          3306:              else
        !          3307:                break;
        !          3308:            }
        !          3309:          if (cmdleft != 0)
        !          3310:            {
        !          3311:              commands_started = lineno;
        !          3312:              *cmdleft = '\0';
        !          3313:              p2 = macro_expand (collapsed);
        !          3314:            }
        !          3315:          else
        !          3316:            p2 = macro_expand (collapsed);
        !          3317: 
        !          3318:          if (*p2 == '\0' || *p2 == ':')
        !          3319:            fatal ("%s:%ld: missing target name", filename, lineno);
        !          3320:          filenames = multi_glob (parse_file_seq (&p2, ':',
        !          3321:                                                  sizeof (struct nameseq)),
        !          3322:                                  sizeof (struct nameseq));
        !          3323:          if (*p2++ == '\0')
        !          3324:            fatal ("%s:%ld: missing separator", filename, lineno);
        !          3325:          /* Is this a one-colon or two-colon entry?  */
        !          3326:          two_colon = *p2 == ':';
        !          3327:          if (two_colon) p2++;
        !          3328: 
        !          3329:          /* Is this an extended static rule: `target: %targ: %dep; ...'?  */
        !          3330:          p = index (p2, ':');
        !          3331:          while (p != 0 && p[-1] == '\\')
        !          3332:            {
        !          3333:              register char *q = &p[-1];
        !          3334:              register int backslash = 0;
        !          3335:              while (*q-- == '\\')
        !          3336:                backslash = !backslash;
        !          3337:              if (backslash)
        !          3338:                p = index (p + 1, ';');
        !          3339:              else
        !          3340:                break;
        !          3341:            }
        !          3342:          if (p != 0)
        !          3343:            {
        !          3344:              struct nameseq *target;
        !          3345:              target = parse_file_seq (&p2, ':', sizeof (struct nameseq));
        !          3346:              ++p2;
        !          3347:              if (target == 0)
        !          3348:                fatal ("%s:%ld: missing target pattern", filename, lineno);
        !          3349:              else if (target->next != 0)
        !          3350:                fatal ("%s:%ld: multiple target patterns", filename, lineno);
        !          3351:              pattern = target->name;
        !          3352:              if (index (pattern, '%') == 0)
        !          3353:                fatal ("%s:%ld: target pattern contains no `%%'",
        !          3354:                       filename, lineno);
        !          3355:            }
        !          3356:          else
        !          3357:            pattern = 0;
        !          3358:          
        !          3359:          /* Parse the dependencies.  */
        !          3360:          deps = (struct dep *)
        !          3361:            multi_glob (parse_file_seq (&p2, ';', sizeof (struct dep)),
        !          3362:                        sizeof (struct dep));
        !          3363: 
        !          3364:          commands_idx = 0;
        !          3365:          /* Did we stop at end of line, or at a semicolon?  */
        !          3366:          if (cmdleft != 0)
        !          3367:            {
        !          3368:              /* Semicolon means rest of line is a command */
        !          3369:              int len = strlen (cmdleft + 1);
        !          3370: 
        !          3371:              /* Add this command line to the buffer.  */
        !          3372:              if (len + 2 > commands_len)
        !          3373:                {
        !          3374:                  commands_len = (len + 2) * 2;
        !          3375:                  commands = (char *) xrealloc (commands, commands_len);
        !          3376:                }
        !          3377:              bcopy (cmdleft + 1, commands, len);
        !          3378:              commands_idx += len;
        !          3379:              commands[commands_idx++] = '\n';
        !          3380:            }
        !          3381:        }
        !          3382:     }
        !          3383: 
        !          3384:   if (ignoring)
        !          3385:     fatal ("missing endif");
        !          3386: 
        !          3387:   /* At eof, record the last rule.  */
        !          3388:   {
        !          3389:     struct commands *cmds;
        !          3390: 
        !          3391:     if (commands_idx > 0)
        !          3392:       {
        !          3393:        register int i = 0;
        !          3394:        while (i < commands_idx
        !          3395:               && (commands[i] == ' ' || commands[i] == '\t'
        !          3396:                   || commands[i] == '\n'))
        !          3397:          ++i;
        !          3398:        if (i < commands_idx)
        !          3399:          {
        !          3400:            cmds = (struct commands *) xmalloc (sizeof (struct commands));
        !          3401:            cmds->filename = filename;
        !          3402:            cmds->lineno = commands_started;
        !          3403:            cmds->commands = savestring (commands, commands_idx);
        !          3404:          }
        !          3405:        else
        !          3406:          cmds = 0;
        !          3407:       }
        !          3408:     else
        !          3409:       cmds = 0;
        !          3410:     record_files (filenames, pattern, deps, cmds, two_colon,
        !          3411:                  filename, lineno, !nodefault);
        !          3412:   }
        !          3413: 
        !          3414:   freebuffer (&lb);
        !          3415:   free ((char *) commands);
        !          3416:   if (infile != stdin)
        !          3417:     fclose (infile);
        !          3418: 
        !          3419:   reading_filename = 0;
        !          3420:   reading_lineno_ptr = 0;
        !          3421: }
        !          3422: 
        !          3423: /* Execute a `define' directive.
        !          3424:    The first line has already been read, and NAME is the name of
        !          3425:    the variable to be defined.  The following lines remain to be read.
        !          3426:    LINENO, INFILE and FILENAME refer to the makefile being read.
        !          3427:    The value returned is LINENO, updated for lines read here.  */
        !          3428: 
        !          3429: static long
        !          3430: do_define (lbp, name, lineno, infile, filename)
        !          3431:      struct linebuffer *lbp;
        !          3432:      char *name;
        !          3433:      long lineno;
        !          3434:      FILE *infile;
        !          3435:      char *filename;
        !          3436: {
        !          3437:   unsigned length = 0;
        !          3438:   long nlines = 0L;
        !          3439:   char *definition = (char *) xmalloc (1);
        !          3440:   register char *p;
        !          3441: 
        !          3442:   while (!feof (infile))
        !          3443:     {
        !          3444:       lineno += nlines;
        !          3445:       nlines = readline (lbp, infile, filename);
        !          3446:       p = lbp->buffer;
        !          3447: 
        !          3448:       if ((p[5] == '\0' || p[5] == ' ' || p[5] == '\t')
        !          3449:          && !strncmp (p, "endef", 5))
        !          3450:        {
        !          3451:          /* Define the macro.  */
        !          3452:          (void) define_macro (name, strlen (name), definition, o_file, 1);
        !          3453:          break;
        !          3454:        }
        !          3455:       else
        !          3456:        {
        !          3457:          int len = strlen (p);
        !          3458:          unsigned olength = length;
        !          3459: 
        !          3460:          /* Increase the buffer if necessary.  */
        !          3461:          length += len + (olength != 0);
        !          3462:          if (olength == 0)
        !          3463:            definition = (char *) xmalloc (length + 1);
        !          3464:          else
        !          3465:            definition = (char *) xrealloc (definition, length + 1);
        !          3466: 
        !          3467:          /* Separate lines with a newline.  */
        !          3468:          if (olength > 0)
        !          3469:            definition[olength++] = '\n';
        !          3470:          bcopy (p, &definition[olength], len);
        !          3471:          definition[length] = '\0';
        !          3472:        }
        !          3473:     }
        !          3474: 
        !          3475:   return lineno;
        !          3476: }
        !          3477: 
        !          3478: /* Glob-expand LINE.
        !          3479:    The returned pointer is only good until the next call to this
        !          3480:    routine.
        !          3481: 
        !          3482:    The RECURSIVE flag is only used internally.  */
        !          3483: 
        !          3484: static char *
        !          3485: string_glob (line, recursive)
        !          3486:      char *line;
        !          3487:      int recursive;
        !          3488: {
        !          3489:   static char *result, *result_end;
        !          3490:   static unsigned result_length = 0;
        !          3491:   char **globbed;
        !          3492:   register int i, d, len;
        !          3493:   register char *p, *s;
        !          3494: 
        !          3495:   s = line;
        !          3496:   while (*s && *s != ' ' && *s != '\t')
        !          3497:     ++s;
        !          3498: 
        !          3499:   p = savestring (line, s - line);
        !          3500:   globbed = glob_filename (p);
        !          3501:   free (p);
        !          3502: 
        !          3503:   while (*s == ' ' || *s == '\t')
        !          3504:     ++s;
        !          3505: 
        !          3506:   /* NOSTRICT */
        !          3507:   if (globbed == (char **) 0)
        !          3508:     fatal ("virtual memory exhausted");
        !          3509:   /* NOSTRICT */
        !          3510:   else if (globbed == (char **) -1)
        !          3511:     pfatal_with_name (".");
        !          3512: 
        !          3513:   if (result_length == 0)
        !          3514:     {
        !          3515:       result_length = 200;
        !          3516:       result = xmalloc (200);
        !          3517:     }
        !          3518: 
        !          3519:   p = recursive ? result_end : result;
        !          3520:   *p = '\0';
        !          3521:   for (i = 0; globbed[i] != 0; ++i)
        !          3522:     {
        !          3523:       len = strlen (globbed[i]) + 1;
        !          3524:       d = p - result;
        !          3525:       if (d > 0)
        !          3526:        ++d;
        !          3527:       d += len;
        !          3528:       if (d > result_length)
        !          3529:        {
        !          3530:          result_length = d + (globbed[i + 1] ? 20 : 0);
        !          3531:          result = xrealloc (result, result_length);
        !          3532:           p = result + (d - len - (d > len ? 1 : 0));
        !          3533:        }
        !          3534:       if (d > len)
        !          3535:        *p++ = ' ';
        !          3536:       bcopy (globbed[i], p, len);
        !          3537:       free (globbed[i]);
        !          3538:       p += len - 1;
        !          3539:     }
        !          3540:   result_end = p;
        !          3541:   free ((char *) globbed);
        !          3542: 
        !          3543:   if (*s != '\0')
        !          3544:     (void) string_glob (s, 1);
        !          3545: 
        !          3546:   return (result);
        !          3547: }
        !          3548: 
        !          3549: /* Interpret conditional commands "ifdef", "ifndef", "ifeq",
        !          3550:    "ifneq", "else" and "endif".
        !          3551:    LINE is the input line, with the command as its first word.
        !          3552: 
        !          3553:    FILENAME and LINENO are the filename and line number in the
        !          3554:    current makefile.  They are used for error messages.
        !          3555: 
        !          3556:    Value is -1 if the line is invalid,
        !          3557:    0 if following text should be interpreted,
        !          3558:    1 if following text should be ignored.  */
        !          3559: 
        !          3560: static int
        !          3561: conditional_line (line, filename, lineno)
        !          3562:      char *line;
        !          3563:      char *filename;
        !          3564:      long lineno;
        !          3565: {
        !          3566:   static int if_cmds = 0;
        !          3567:   static char *ignoring = 0;
        !          3568:   static unsigned max_ignoring = 0;
        !          3569:   int notdef;
        !          3570:   char *cmdname;
        !          3571:   register int i;
        !          3572: 
        !          3573:   if (*line == 'i')
        !          3574:     {
        !          3575:       /* It's an "if..." command.  */
        !          3576:       notdef = line[2] == 'n';
        !          3577:       if (notdef)
        !          3578:        {
        !          3579:          cmdname = line[3] == 'd' ? "ifndef" : "ifneq";
        !          3580:          line += cmdname[3] == 'd' ? 7 : 6;
        !          3581:        }
        !          3582:       else
        !          3583:        {
        !          3584:          cmdname = line[2] == 'd' ? "ifdef" : "ifeq";
        !          3585:          line += cmdname[2] == 'd' ? 6 : 5;
        !          3586:        }
        !          3587:     }
        !          3588:   else
        !          3589:     {
        !          3590:       /* It's an "else" or "endif" command.  */
        !          3591:       notdef = line[1] == 'n';
        !          3592:       cmdname = notdef ? "endif" : "else";
        !          3593:       line += notdef ? 5 : 4;
        !          3594:     }
        !          3595: 
        !          3596:   while (*line == ' ' || *line == '\t')
        !          3597:     ++line;
        !          3598: 
        !          3599:   if (*cmdname == 'e')
        !          3600:     {
        !          3601:       if (*line != '\0')
        !          3602:        return -1;
        !          3603:       /* "Else" or "endif".  */
        !          3604:       if (if_cmds == 0)
        !          3605:        fatal ("%s:%ld: extraneous `%s'\n", filename, lineno, cmdname);
        !          3606:       /* NOTDEF indicates an "endif" command.  */
        !          3607:       if (notdef)
        !          3608:        --if_cmds;
        !          3609:       else
        !          3610:        ignoring[if_cmds - 1] = !ignoring[if_cmds - 1];
        !          3611:       for (i = 0; i < if_cmds; ++i)
        !          3612:        if (ignoring[i]) return 1;
        !          3613:       return 0;
        !          3614:     }
        !          3615: 
        !          3616:   ++if_cmds;
        !          3617: 
        !          3618:   if (if_cmds > (max_ignoring - 1))
        !          3619:     {
        !          3620:       max_ignoring += 5;
        !          3621:       if (ignoring)
        !          3622:        ignoring = xrealloc (ignoring, max_ignoring);
        !          3623:       else
        !          3624:        ignoring = xmalloc (max_ignoring);
        !          3625:     }
        !          3626: 
        !          3627:   if (cmdname[notdef ? 3 : 2] == 'd')
        !          3628:     {
        !          3629:       /* "Ifdef" or "ifndef".  */
        !          3630:       struct macro *m;
        !          3631:       register char *p = line;
        !          3632: 
        !          3633:       while (*p != '\0' && *p != ' ' && *p != '\t')
        !          3634:        ++p;
        !          3635:       i = p - line;
        !          3636:       while (*p == ' ' || *p == '\t')
        !          3637:        ++p;
        !          3638:       if (*p != '\0')
        !          3639:        return -1;
        !          3640:       m = lookup_macro (line, i);
        !          3641:       ignoring[if_cmds - 1] = (m && *m->value) == notdef;
        !          3642:       for (i = 0; i < if_cmds; ++i)
        !          3643:        if (ignoring[i]) return 1;
        !          3644:       return 0;
        !          3645:     }
        !          3646:   else
        !          3647:     {
        !          3648:       /* "Ifeq" or "ifneq".  */
        !          3649:       char *s1, *s2;
        !          3650:       int len;
        !          3651:       char termin = *line == '(' ? ',' : *line;
        !          3652: 
        !          3653:       if (termin != ',' && termin != '"' && termin != '\'')
        !          3654:        return -1;
        !          3655: 
        !          3656:       s1 = ++line;
        !          3657:       /* Find the end of the first string.  */
        !          3658:       if (termin == ',')
        !          3659:        {
        !          3660:          register int count = 0;
        !          3661:          for (; *line != '\0'; ++line)
        !          3662:              {
        !          3663:                if (*line == '(')
        !          3664:                  ++count;
        !          3665:                else if (*line == ')')
        !          3666:                  --count;
        !          3667:                else if (*line == ',' && count <= 0)
        !          3668:                  break;
        !          3669:              }
        !          3670:        }
        !          3671:       else
        !          3672:        while (*line != '\0' && *line != termin)
        !          3673:          ++line;
        !          3674: 
        !          3675:       if (*line == '\0')
        !          3676:        return -1;
        !          3677: 
        !          3678:       *line++ = '\0';
        !          3679: 
        !          3680:       s2 = macro_expand (s1);
        !          3681:       /* We must allocate a new copy of the expanded string because
        !          3682:         macro_expand re-uses the same buffer.  */
        !          3683:       len = strlen (s2);
        !          3684:       s1 = (char *) alloca (len + 1);
        !          3685:       bcopy (s2, s1, len + 1);
        !          3686: 
        !          3687:       /* Find the start of the second string.  */
        !          3688:       while (*line == ' ' || *line == '\t')
        !          3689:        ++line;
        !          3690: 
        !          3691:       termin = termin == ',' ? ')' : *line;
        !          3692:       if (termin != ')' && termin != '"' && termin != '\'')
        !          3693:        return -1;
        !          3694:       s2 = line;
        !          3695: 
        !          3696:       /* Find the end of the second string.  */
        !          3697:       if (termin == ')')
        !          3698:        {
        !          3699:          register int count = 0;
        !          3700:          for (; *line != '\0'; ++line)
        !          3701:              if (*line == '(')
        !          3702:                ++count;
        !          3703:              else if (*line == ')')
        !          3704:                if (count <= 0)
        !          3705:                  break;
        !          3706:                else
        !          3707:                  --count;
        !          3708:        }
        !          3709:       else
        !          3710:        {
        !          3711:          ++line;
        !          3712:          s2 = line;
        !          3713:          while (*line != '\0' && *line != termin)
        !          3714:            ++line;
        !          3715:        }
        !          3716: 
        !          3717:       if (*line == '\0')
        !          3718:        return -1;
        !          3719: 
        !          3720:       if (*line != '\0')
        !          3721:        {
        !          3722:          *line = '\0';
        !          3723:          ++line;
        !          3724:          while (*line == ' ' || *line == '\t')
        !          3725:            ++line;
        !          3726:          if (*line != '\0')
        !          3727:            return -1;
        !          3728:        }
        !          3729:       s2 = macro_expand (s2);
        !          3730:       ignoring[if_cmds - 1] = streq (s1, s2) == notdef;
        !          3731:       for (i = 0; i < if_cmds; ++i)
        !          3732:        if (ignoring[i]) return 1;
        !          3733:       return 0;
        !          3734:     }
        !          3735: }
        !          3736: 
        !          3737: /* Record a description line for files FILENAMES,
        !          3738:    with dependencies DEPS, commands to execute COMMANDS.
        !          3739:    TWO_COLON is nonzero if a double colon was used.
        !          3740:    If not nil, PATTERN is the `%' pattern to make this
        !          3741:    an extended static rule.
        !          3742: 
        !          3743:    The links of FILENAMES are freed, and so are any names in it
        !          3744:    that are not incorporated into other data structures.
        !          3745: 
        !          3746:    If any of the command lines for a file contain "$(MAKE)"
        !          3747:    or "${MAKE}" then the file's recursive flag is set.  */
        !          3748: 
        !          3749: static void
        !          3750: record_files (filenames, pattern, deps, commands, two_colon,
        !          3751:              filename, lineno, set_default)
        !          3752:      struct nameseq *filenames;
        !          3753:      char *pattern;
        !          3754:      struct dep *deps;
        !          3755:      struct commands *commands;
        !          3756:      int two_colon;
        !          3757:      char *filename;
        !          3758:      long lineno;
        !          3759:      int set_default;
        !          3760: {
        !          3761:   struct nameseq *nextf;
        !          3762: 
        !          3763:   for (; filenames != 0; filenames = nextf)
        !          3764:     {
        !          3765:       register char *name = filenames->name;
        !          3766:       char *p = index (name, '%');
        !          3767:       register struct file *f, *f1;
        !          3768:       register struct rule *r;
        !          3769:       register struct dep *d;
        !          3770:       struct dep *this;
        !          3771: 
        !          3772:       nextf = filenames->next;
        !          3773:       free ((char *) filenames);
        !          3774: 
        !          3775:       if (p != 0 && pattern != 0)
        !          3776:        fatal ("%s:%ld: mixed implicit and static pattern rules",
        !          3777:               filename, lineno);
        !          3778: 
        !          3779:       /* If there are multiple filenames, copy the chain DEPS
        !          3780:         for all but the last one.  It is not safe for the same deps
        !          3781:         to go in more than one place in the data base.  */
        !          3782:       this = nextf != 0 ? copy_dep_chain (deps) : deps;
        !          3783: 
        !          3784:       if (pattern != 0)
        !          3785:        /* If this is an extended static rule:
        !          3786:           `targets: target%pattern: dep%pattern; cmds',
        !          3787:           Translate each dependency pattern into a plain filename
        !          3788:           using the target pattern and this target's filename.  */
        !          3789:        if (!pattern_matches (pattern, name))
        !          3790:          {
        !          3791:            /* Give a warning if the rule is meaningless.  */
        !          3792:            error ("%s:%ld: target `%s' doesn't match the target pattern",
        !          3793:                   filename, lineno, name);
        !          3794:            this = 0;
        !          3795:          }
        !          3796:        else
        !          3797:          {
        !          3798:            /* We use patsubst_expand to do the work of translating
        !          3799:               the target pattern, the target's name and the dependencies'
        !          3800:               patterns into plain dependency filenames.  */
        !          3801: 
        !          3802:            /* Allocate MACRO_BUFFER if it doesn't exist.  */
        !          3803:            if (macro_buffer == 0)
        !          3804:              (void) macro_expand ("");
        !          3805: 
        !          3806:            for (d = this; d != 0; d = d->next)
        !          3807:              {
        !          3808:                char *o;
        !          3809:                if (index (d->name, '%') == 0)
        !          3810:                  continue;
        !          3811:                o = patsubst_expand (macro_buffer, name, pattern, d->name);
        !          3812:                free (d->name);
        !          3813:                d->name = savestring (macro_buffer, o - macro_buffer);
        !          3814:              }
        !          3815:          }
        !          3816:       
        !          3817:       /* Check for a pattern rule.  */
        !          3818:       if (p != 0)
        !          3819:        {
        !          3820:          r = (struct rule *) xmalloc (sizeof (struct rule));
        !          3821:          r->name = name;
        !          3822:          r->namelen = strlen (name);
        !          3823:          r->patsuffix = p + 1;
        !          3824:          r->terminal = two_colon;
        !          3825:          r->deps = this;
        !          3826:          r->cmds = commands;
        !          3827:          /* If the new rule duplicates an old one, delete the old one. */
        !          3828:          new_pattern_rule (r, 1);
        !          3829:          f = 0;
        !          3830:        }
        !          3831:       else if (!two_colon)
        !          3832:        {
        !          3833:          /* Single-colon.  Combine these dependencies
        !          3834:             with any others in file's existing record, if any.  */
        !          3835:          f = enter_file (name);
        !          3836:          if (f->double_colon)
        !          3837:            fatal ("target file `%s' has both : and :: entries", f->name);
        !          3838:          /* Check for two single-colon entries both with commands.
        !          3839:             Check is_target so that we don't lose on files such as .c.o
        !          3840:             whose commands were preinitialized.  */
        !          3841:          if (commands != 0 && f->cmds != 0 && f->is_target)
        !          3842:            fatal ("target file `%s' has commands specified twice", f->name);
        !          3843:          f->is_target = 1;
        !          3844:          if (commands != 0)
        !          3845:            f->cmds = commands;
        !          3846:          /* Defining .SUFFIXES with no dependencies
        !          3847:             clears out the list of suffixes.  */
        !          3848:          if (f == suffix_file && this == 0)
        !          3849:            f->deps = 0;
        !          3850:          else if (f->deps)
        !          3851:            {
        !          3852:              d = f->deps;
        !          3853:              while (d->next != 0)
        !          3854:                d = d->next;
        !          3855:              d->next = this;
        !          3856:            }
        !          3857:          else
        !          3858:            f->deps = this;
        !          3859:          /* If this is a static pattern rule and it has commands,
        !          3860:             set the file's stem to the part of its name that matches
        !          3861:             the `%' in the pattern, so you can use $* in the commands.  */
        !          3862:          if (pattern != 0 && commands != 0)
        !          3863:            {
        !          3864:              char *o = patsubst_expand (macro_buffer, name, pattern, "%");
        !          3865:              f->stem = savestring (macro_buffer, o - macro_buffer);
        !          3866:            }
        !          3867:        }
        !          3868:       else
        !          3869:        {
        !          3870:          /* Double-colon.  Make a new record even if file has one.  */
        !          3871:          f1 = lookup_file (name);
        !          3872:          if (f1 != 0 && !f1->double_colon)
        !          3873:            fatal ("target file `%s' has both : and :: entries", f->name);
        !          3874:          f = enter_file (name);
        !          3875:          f->deps = this;
        !          3876:          f->cmds = commands;
        !          3877:          f->double_colon = 1;
        !          3878:          f->is_target = 1;
        !          3879:          f->prev = f1;
        !          3880:        }
        !          3881: 
        !          3882:       /* Check for $(MAKE) or ${MAKE} in the commands.  */
        !          3883:       if (commands != 0
        !          3884:           && (sindex (commands->commands, 0, "${MAKE}", 7) != 0
        !          3885:              || sindex (commands->commands, 0, "$(MAKE)", 7) != 0))
        !          3886:        {
        !          3887:          if (f != 0)
        !          3888:            f->recursive = 1;
        !          3889:          else
        !          3890:            r->recursive = 1;
        !          3891:        }
        !          3892: 
        !          3893:       /* Free name if not needed further.  */
        !          3894:       if (f != 0 && name != f->name)
        !          3895:        free (name);
        !          3896: 
        !          3897:       /* See if this is first file seen in a top-level makefile
        !          3898:         whose name does not start with a `.'.  */
        !          3899:       if (default_goal_file == 0 && set_default && f && *name != '.')
        !          3900:        {
        !          3901:          int reject = 0;
        !          3902: 
        !          3903:          /* If this file is a suffix, don't
        !          3904:             let it be the default goal file.  */
        !          3905: 
        !          3906:          for (d = suffix_file->deps; d != 0; d = d->next)
        !          3907:            if (streq (name, dep_name (d)))
        !          3908:              {
        !          3909:                reject = 1;
        !          3910:                break;
        !          3911:              }
        !          3912: 
        !          3913:          if (!reject)
        !          3914:            default_goal_file = f;
        !          3915:        }
        !          3916:     }
        !          3917: }
        !          3918: 
        !          3919: /* Copy a chain of `struct dep', making a new chain
        !          3920:    with the same contents as the old one.  */
        !          3921: 
        !          3922: static struct dep *
        !          3923: copy_dep_chain (d)
        !          3924:      struct dep *d;
        !          3925: {
        !          3926:   register struct dep *c;
        !          3927:   struct dep *firstnew = 0;
        !          3928:   struct dep *lastnew;
        !          3929: 
        !          3930:   while (d)
        !          3931:     {
        !          3932:       c = (struct dep *) xmalloc (sizeof (struct dep));
        !          3933:       bcopy ((char *) d, (char *) c, sizeof (struct dep));
        !          3934:       c->next = 0;
        !          3935:       if (firstnew == 0)
        !          3936:        firstnew = lastnew = c;
        !          3937:       else
        !          3938:        lastnew = lastnew->next = c;
        !          3939: 
        !          3940:       d = d->next;
        !          3941:     }
        !          3942: 
        !          3943:   return firstnew;
        !          3944: }
        !          3945: 
        !          3946: /* Parse a string into a sequence of filenames
        !          3947:    represented as a chain of struct nameseq's in reverse order.
        !          3948:    Return that chain.
        !          3949: 
        !          3950:    The string is passed as STRINGP, the address of a string pointer.
        !          3951:    The string pointer is updated to point at the first character
        !          3952:    not parsed, which either is a null char or equals STOPCHAR.
        !          3953: 
        !          3954:    SIZE is how big to construct chain elements.
        !          3955:    This is useful if we want them actually to be other structures
        !          3956:    that have room for additional info.  */
        !          3957: 
        !          3958: static struct nameseq *
        !          3959: parse_file_seq (stringp, stopchar, size)
        !          3960:      char **stringp;
        !          3961:      char stopchar;
        !          3962:      unsigned size;
        !          3963: {
        !          3964:   register struct nameseq *new = 0;
        !          3965:   register struct nameseq *new1;
        !          3966:   register char *p = *stringp;
        !          3967:   char *q;
        !          3968:   char *name;
        !          3969:   register int c;
        !          3970: 
        !          3971:   while (1)
        !          3972:     {
        !          3973:       /* Skip whitespace; see if any more names are left.  */
        !          3974:       while (*p == ' ' || *p == '\t')
        !          3975:        ++p;
        !          3976:       if (*p == '\0')
        !          3977:        break;
        !          3978:       if (*p == stopchar)
        !          3979:        break;
        !          3980:       /* Yes, find end of next name.  */
        !          3981:       q = p;
        !          3982:       while (1)
        !          3983:        {
        !          3984:          c = *p++;
        !          3985:          if (c == '\0')
        !          3986:            break;
        !          3987:          else if (c == '\\' &&
        !          3988:                   (*p == '\\' || *p == ' ' || *p == '\t' || *p == stopchar))
        !          3989:            ++p;
        !          3990:          else if (c == ' ' || c == '\t' || c == stopchar)
        !          3991:            break;
        !          3992:        }
        !          3993:       p--;
        !          3994: 
        !          3995:       /* Extract the filename just found, and skip it.  */
        !          3996:       name = savestring (q, p - q);
        !          3997: 
        !          3998:       /* Add it to the front of the chain.  */
        !          3999:       new1 = (struct nameseq *) xmalloc (size);
        !          4000:       new1->name = name;
        !          4001:       new1->next = new;
        !          4002:       new = new1;
        !          4003:     }
        !          4004: 
        !          4005:   *stringp = p;
        !          4006:   return (new);
        !          4007: }
        !          4008: 
        !          4009: /* Compare strings *S1 and *S2.
        !          4010:    Return negative if the first is less, positive if it is greater,
        !          4011:    zero if they are equal.  */
        !          4012: 
        !          4013: static int
        !          4014: alpha_compare (s1, s2)
        !          4015:      char **s1, **s2;
        !          4016: {
        !          4017:   if (**s1 != **s2)
        !          4018:     return **s1 - **s2;
        !          4019:   return strcmp (*s1, *s2);
        !          4020: }
        !          4021: 
        !          4022: /* Remove quoting backslashes from a string
        !          4023:    by compacting the string down into itself.
        !          4024:    Backslashes quoted by other backslashes are not removed.  */
        !          4025: 
        !          4026: static void
        !          4027: dequote (string)
        !          4028:      char *string;
        !          4029: {
        !          4030:   register char *in, *out;
        !          4031:   register int c;
        !          4032: 
        !          4033:   in = string;
        !          4034:   out = string;
        !          4035: 
        !          4036:   while (c = *in++)
        !          4037:     {
        !          4038:       if (c != '\\')
        !          4039:        *out++ = c;
        !          4040:       else if (c = *in++)
        !          4041:        *out++ = c;
        !          4042:     }
        !          4043: 
        !          4044:   *out = '\0';
        !          4045: }
        !          4046: 
        !          4047: /* Given a chain of struct nameseq's describing a sequence of filenames,
        !          4048:    in reverse of the intended order,
        !          4049:    return a new chain describing the result of globbing the filenames.
        !          4050:    The new chain is in forward order.
        !          4051:    The links of the old chain are freed or used in the new chain.
        !          4052:    Likewise for the names in the old chain.
        !          4053: 
        !          4054:    SIZE is how big to construct chain elements.
        !          4055:    This is useful if we want them actually to be other structures
        !          4056:    that have room for additional info.  */
        !          4057: 
        !          4058: static struct nameseq *
        !          4059: multi_glob (chain, size)
        !          4060:      struct nameseq *chain;
        !          4061:      unsigned size;
        !          4062: {
        !          4063:   register struct nameseq *new = 0;
        !          4064:   register struct nameseq *tem;
        !          4065:   register struct nameseq *old;
        !          4066:   register char **vector;
        !          4067:   register int i;
        !          4068:   int length;
        !          4069:   struct nameseq *nexto;
        !          4070: 
        !          4071: 
        !          4072:   for (old = chain; old != 0; old = nexto)
        !          4073:     {
        !          4074:       nexto = old->next;
        !          4075: 
        !          4076:       if (glob_pattern_p (old->name))
        !          4077:        {
        !          4078:          vector = glob_filename (old->name);
        !          4079:          /* NOSTRICT */
        !          4080:          if (vector == (char **) 0)
        !          4081:            fatal ("virtual memory exhausted");
        !          4082:          /* NOSTRICT */
        !          4083:          else if (vector == (char **) -1)
        !          4084:            pfatal_with_name (old->name);
        !          4085:          free (old->name);
        !          4086:          for (i = 0; vector[i]; i++);
        !          4087:          length = i;
        !          4088:          qsort ((char *) vector, length, sizeof (char *), alpha_compare);
        !          4089:          for (i = length - 1; i >= 0; i--)
        !          4090:            {
        !          4091:              tem = (struct nameseq *) xmalloc (size);
        !          4092:              tem->name = vector[i];
        !          4093:              tem->next = new;
        !          4094:              tem->quotedparen = 1;
        !          4095:              new = tem;
        !          4096:            }
        !          4097:          free ((char *) vector);
        !          4098:          free ((char *) old);
        !          4099:        }
        !          4100:       else
        !          4101:        {
        !          4102:          old->quotedparen = !strcmp (old->name + strlen (old->name) - 2,
        !          4103:                                      "\\)");
        !          4104:          dequote (old->name);
        !          4105:          old->next = new;
        !          4106:          new = old;
        !          4107:        }
        !          4108:     }
        !          4109: 
        !          4110:   return (new);
        !          4111: }
        !          4112: 
        !          4113: 
        !          4114: /* For each dependency of each file, make it point at the
        !          4115:    file that it depends on.
        !          4116: 
        !          4117:    Also mark the files depended on by .PRECIOUS and .PHONY.  */
        !          4118: 
        !          4119: static void
        !          4120: snap_deps ()
        !          4121: {
        !          4122:   register struct file *f;
        !          4123:   register struct dep *d;
        !          4124:   register int i;
        !          4125: 
        !          4126:   /* Enter each dependency name as a file.  */
        !          4127:   for (i = 0; i < FILE_BUCKETS; ++i)
        !          4128:     for (f = files[i]; f != 0; f = f->next)
        !          4129:       for (d = f->deps; d != 0; d = d->next)
        !          4130:        {
        !          4131:          d->file = enter_file (dep_name (d));
        !          4132:          d->name = 0;
        !          4133:        }
        !          4134:   
        !          4135: 
        !          4136:   /* Compute maximum length of all the suffixes.  */
        !          4137:   maxsuffix = 0;
        !          4138:   for (d = suffix_file->deps; d != 0; d = d->next)
        !          4139:     {
        !          4140:       maxsuffix = max (maxsuffix, strlen (dep_name (d)));
        !          4141:     }
        !          4142: 
        !          4143:   f = lookup_file (".PRECIOUS");
        !          4144:   if (f != 0)
        !          4145:     for (d = f->deps; d != 0; d = d->next)
        !          4146:       for (f = d->file; f != 0; f = f->prev)
        !          4147:        f->precious = 1;
        !          4148: 
        !          4149:   f = lookup_file (".PHONY");
        !          4150:   if (f != 0)
        !          4151:     for (d = f->deps; d != 0; d = d->next)
        !          4152:       for (f = d->file; f != 0; f = f->prev)
        !          4153:        {
        !          4154:          /* Mark this file as phony and non-existent.  */
        !          4155:          f->phony = 1;
        !          4156:          f->last_mtime = -1L;
        !          4157:        }
        !          4158: }
        !          4159: 
        !          4160: /* If FILE is not up to date, execute the commands for it.
        !          4161:    Return 0 if successful, 1 if unsuccessful;
        !          4162:    but with some flag settings, just call `exit' if unsuccessful.
        !          4163: 
        !          4164:    DEPTH is the depth in recursions of this function.
        !          4165:    We increment it during the consideration of our dependencies,
        !          4166:    then decrement it again after finding out whether this file
        !          4167:    is out of date.
        !          4168: 
        !          4169:    If there are multiple entries for FILE, consider each in turn.  */
        !          4170: 
        !          4171: static int
        !          4172: update_file (file, depth)
        !          4173:      struct file *file;
        !          4174:      int depth;
        !          4175: {
        !          4176:   register int status;
        !          4177:   register struct file *f = file;
        !          4178:   int ofiles_remade = files_remade;
        !          4179: 
        !          4180:   while (f)
        !          4181:     {
        !          4182:       status = update_file_1 (f, depth);
        !          4183:       if (status && !keep_going_flag)
        !          4184:        return (status);
        !          4185:       f = f->prev;
        !          4186:     }
        !          4187: 
        !          4188:   /* For a top level target, if we have found nothing whatever to do for it,
        !          4189:      print a message saying nothing needs doing.  */
        !          4190: 
        !          4191:   if (ofiles_remade == files_remade
        !          4192:       && !print_data_base_flag
        !          4193:       && depth == 0 && !silent_flag && !question_flag)
        !          4194:     {
        !          4195:       printf ("%s: File `%s' is up to date.\n", program, file->name);
        !          4196:       fflush (stdout);
        !          4197:     }
        !          4198: 
        !          4199:   return (status);
        !          4200: }
        !          4201: 
        !          4202: /* Consider a single `struct file' and update it as appropriate.  */
        !          4203: 
        !          4204: #define DEBUGPR(msg) \
        !          4205:   if (debug_flag) \
        !          4206:     {  print_spaces (depth);  printf (msg, file->name); fflush (stdout);  }
        !          4207: 
        !          4208: static int
        !          4209: update_file_1 (file, depth)
        !          4210:      struct file *file;
        !          4211:      int depth;
        !          4212: {
        !          4213:   register long this_mtime;
        !          4214:   int must_make;
        !          4215:   int dep_status = 0;
        !          4216:   register struct dep *d;
        !          4217: 
        !          4218:   DEBUGPR ("Considering target file `%s'.\n");
        !          4219:   depth++;
        !          4220: 
        !          4221:   if (file->updated)
        !          4222:     {
        !          4223:       depth--;
        !          4224:       if (file->update_status > 0)
        !          4225:        {
        !          4226:          DEBUGPR ("Recently tried and failed to update file `%s'.\n");
        !          4227:          return (file->update_status);
        !          4228:        }
        !          4229: 
        !          4230:       DEBUGPR ("File `%s' was considered already.\n");
        !          4231:       return 0;
        !          4232:     }
        !          4233:   else
        !          4234:     {
        !          4235:       file->updating = 1;      /* Notice recursive update of same file.  */
        !          4236: 
        !          4237:       /* Looking at the file's modtime beforehand allows the possibility
        !          4238:         that its name may be changed by a VPATH search, and thus it may
        !          4239:         not need an implicit rule.  If this were not done, the file
        !          4240:         might get implicit commands that apply to its initial name, only
        !          4241:         to have that name replaced with another found by VPATH search.  */
        !          4242: 
        !          4243:       this_mtime = file_mtime (file);
        !          4244:       must_make = this_mtime == -1L;
        !          4245:       if (must_make)
        !          4246:        DEBUGPR ("File `%s' does not exist.\n");
        !          4247: 
        !          4248:       /* If file was specified as a target with no commands,
        !          4249:         come up with some default commands */
        !          4250: 
        !          4251:       if (!file->phony && file->cmds == 0 && !file->tried_implicit)
        !          4252:        {
        !          4253:          if (try_implicit_rule (file, depth))
        !          4254:            {
        !          4255:              DEBUGPR ("An implicit rule found for `%s'.\n");
        !          4256:            }
        !          4257:          else
        !          4258:            {
        !          4259:              DEBUGPR ("No implicit rule found for `%s'.\n");
        !          4260:              if (default_file)
        !          4261:                file->cmds = default_file->cmds;
        !          4262:            }
        !          4263:          file->tried_implicit = 1;
        !          4264:        }
        !          4265: 
        !          4266:       /* Update all non-intermediate files we depend on, if necessary,
        !          4267:         and see whether any of them is more recent than this file.  */
        !          4268: 
        !          4269:       for (d = file->deps; d != 0; d = d->next)
        !          4270:        {
        !          4271:          if (d->file->updating)
        !          4272:            fatal ("dependency loop involving `%s' and `%s'",
        !          4273:                   dep_name (d), file->name);
        !          4274: 
        !          4275:          dep_status |= check_dep (d->file, depth, this_mtime, &must_make);
        !          4276:          if (dep_status && !keep_going_flag)
        !          4277:            break;
        !          4278:        }
        !          4279: 
        !          4280:       /* Now we know whether this target needs updating.
        !          4281:         If it does, update all the intermediate files we depend on.  */
        !          4282: 
        !          4283:       if (must_make)
        !          4284:        {
        !          4285:          for (d = file->deps; d != 0; d = d->next)
        !          4286:            if (d->file->intermediate)
        !          4287:              {
        !          4288:                dep_status |= update_file (d->file, depth);
        !          4289:                if (dep_status && !keep_going_flag)
        !          4290:                  break;
        !          4291:              }
        !          4292:        }
        !          4293: 
        !          4294:       file->updating = 0;
        !          4295: 
        !          4296:       DEBUGPR ("Finished dependencies of target file `%s'.\n");
        !          4297: 
        !          4298:       if (print_data_base_flag)
        !          4299:        {
        !          4300:          depth--;
        !          4301:          DEBUGPR ("Would now consider updating `%s'.\n");
        !          4302:          return (0);
        !          4303:        }
        !          4304: 
        !          4305:       /* If any dependency failed, give up now.  */
        !          4306: 
        !          4307:       if (dep_status)
        !          4308:        {
        !          4309:          depth--;
        !          4310:          if (depth == 0 && keep_going_flag)
        !          4311:            {
        !          4312:              printf ("%s: Target `%s' not remade because of errors.\n",
        !          4313:                      program, file->name);
        !          4314:              fflush (stdout);
        !          4315:            }
        !          4316:          DEBUGPR ("Giving up on target file `%s'.\n");
        !          4317:          return (dep_status);
        !          4318:        }
        !          4319: 
        !          4320:       /* Now record which dependencies are more recent than this file,
        !          4321:         so we can create $@.  */
        !          4322: 
        !          4323:       for (d = file->deps; d != 0; d = d->next)
        !          4324:        {
        !          4325:          d->changed = this_mtime == -1L || this_mtime < file_mtime (d->file);
        !          4326: 
        !          4327:          if (debug_flag && this_mtime != -1L)
        !          4328:            {
        !          4329:              print_spaces (depth);
        !          4330:              printf ("File `%s' is %s than file `%s'.\n",
        !          4331:                      file->name, d->changed ? "older" : "newer",
        !          4332:                      dep_name (d));
        !          4333:              fflush (stdout);
        !          4334:            }
        !          4335:        }
        !          4336:     }
        !          4337: 
        !          4338:   /* Here depth returns to the value it had when we were called */
        !          4339:   depth--;
        !          4340: 
        !          4341:   if (!must_make)
        !          4342:     {
        !          4343:       DEBUGPR ("No need to remake target file `%s'.\n");
        !          4344:       file->update_status = 0;
        !          4345:       file->updated = 1;
        !          4346:       return (0);
        !          4347:     }
        !          4348: 
        !          4349:   DEBUGPR ("Must remake target file `%s'.\n");
        !          4350: 
        !          4351:   /* Now, take appropriate actions to remake the file.  */
        !          4352:   return remake_file (file);
        !          4353: }
        !          4354: 
        !          4355: /* Check whether another file (whose mtime is THIS_MTIME)
        !          4356:    needs updating on account of a dependency which is file FILE.
        !          4357:    If it does, store 1 in *MUST_MAKE_PTR.
        !          4358:    In the process, update any non-intermediate files
        !          4359:    that FILE depends on (including FILE itself).
        !          4360:    Return nonzero if any updating failed.  */
        !          4361: 
        !          4362: static int
        !          4363: check_dep (file, depth, this_mtime, must_make_ptr)
        !          4364:      struct file *file;
        !          4365:      int depth;
        !          4366:      long this_mtime;
        !          4367:      int *must_make_ptr;
        !          4368: {
        !          4369:   register struct dep *d;
        !          4370:   int dep_status = 0;
        !          4371: 
        !          4372:   ++depth;
        !          4373:   file->updating = 1;
        !          4374: 
        !          4375:   if (!file->intermediate)
        !          4376:     /* If this is a non-intermediate file, update it
        !          4377:        and record whether it is newer than THIS_MTIME.  */
        !          4378:     {
        !          4379:       dep_status = update_file (file, depth);
        !          4380:       if (file_mtime (file) > this_mtime)
        !          4381:        *must_make_ptr = 1;
        !          4382:     }
        !          4383:   else
        !          4384:     /* FILE is an intermediate file.
        !          4385:        Update all non-intermediate files we depend on, if necessary,
        !          4386:        and see whether any of them is more recent than the file
        !          4387:        on whose behalf we are checking.  */
        !          4388:     for (d = file->deps; d != 0; d = d->next)
        !          4389:       {
        !          4390:        if (d->file->updating)
        !          4391:          fatal ("dependency loop involving `%s' and `%s'",
        !          4392:                 dep_name (d), file->name);
        !          4393: 
        !          4394:        dep_status |= check_dep (d->file, depth, this_mtime, must_make_ptr);
        !          4395:        if (dep_status && !keep_going_flag)
        !          4396:          break;
        !          4397:       }
        !          4398: 
        !          4399:   file->updating = 0;
        !          4400:   return dep_status;
        !          4401: }
        !          4402: 
        !          4403: /* Having checked and updated the dependencies of FILE,
        !          4404:    do whatever is appropriate to remake FILE itself.
        !          4405:    Return the status from executing FILE's commands.  */
        !          4406: 
        !          4407: static int
        !          4408: remake_file (file)
        !          4409:      struct file *file;
        !          4410: {
        !          4411:   int status;
        !          4412: 
        !          4413:   file->update_status = 0;
        !          4414:   files_remade++;
        !          4415: 
        !          4416:   /* If file is a recursive submake, ignore -t and -q for this file.  */
        !          4417: 
        !          4418:   if (!file->is_target && !file->phony && file->cmds == 0)
        !          4419:     {
        !          4420:       fprintf (stderr, "%s: *** No specificaton for making file `%s'.",
        !          4421:               program, file->name);
        !          4422:       if (keep_going_flag)
        !          4423:        {
        !          4424:          fputs ("  Continuing.\n", stderr);
        !          4425:          status = 1;
        !          4426:        }
        !          4427:       else
        !          4428:        {
        !          4429:          fputs ("  Stop.\n", stderr);
        !          4430:          exit (1);
        !          4431:        }
        !          4432:     }
        !          4433:   else if (question_flag && !file->recursive)
        !          4434:     /* pretend that updating "failed".  */
        !          4435:     status = 1;
        !          4436:   else if (file->cmds == 0)
        !          4437:     /* The only effect of this if statement
        !          4438:        is that files with no commands (not even implicit ones)
        !          4439:        and files marked as phony do not get touched with -t.  */
        !          4440:     status = 0;
        !          4441:   else if (touch_flag && !file->phony && !file->recursive)
        !          4442:     {
        !          4443:       /* Should set file's modification date and do nothing else.  */
        !          4444:       if (!silent_flag)
        !          4445:        {
        !          4446:          printf ("touch %s\n", file->name);
        !          4447:          fflush (stdout);
        !          4448:        }
        !          4449: 
        !          4450:       if (ar_name (file->name))
        !          4451:        status = ar_touch (file->name);
        !          4452:       else
        !          4453:        {
        !          4454:          int fd = open (file->name, O_RDWR | O_CREAT, 0666);
        !          4455: 
        !          4456: #define        TOUCH_ERROR(call) \
        !          4457:   do { perror_with_name (call, file->name); goto end_touch; } while (0)
        !          4458: 
        !          4459:          status = fd < 0;
        !          4460:          if (status)
        !          4461:            TOUCH_ERROR ("touch: open: ");
        !          4462:          else
        !          4463:            {
        !          4464:              struct stat statbuf;
        !          4465:              char buf;
        !          4466: 
        !          4467:              if (fstat (fd, &statbuf) < 0)
        !          4468:                TOUCH_ERROR ("touch: fstat: ");
        !          4469:              /* Rewrite character 0 same as it already is.  */
        !          4470:              if (read (fd, &buf, 1) < 0)
        !          4471:                TOUCH_ERROR ("touch: read: ");
        !          4472:              if (lseek (fd, 0L, 0) < 0L)
        !          4473:                TOUCH_ERROR ("touch: lseek: ");
        !          4474:              if (write (fd, &buf, 1) < 0)
        !          4475:                TOUCH_ERROR ("touch: write: ");
        !          4476:              /* If file length was 0, we just changed it.
        !          4477:                 So change it back.  */
        !          4478:              if (statbuf.st_size == 0)
        !          4479:                {
        !          4480:                  close (fd);
        !          4481:                  fd = open (file->name, O_RDWR | O_TRUNC, 0666);
        !          4482:                  if (fd < 0)
        !          4483:                    TOUCH_ERROR ("touch: ftruncate: ");
        !          4484:                }
        !          4485:              close (fd);
        !          4486:            }
        !          4487:          end_touch:;
        !          4488:        }
        !          4489:     }
        !          4490:   else
        !          4491:     status = execute_file_commands (file);
        !          4492: 
        !          4493:   file->update_status = status;
        !          4494:   file->last_mtime = just_print_flag
        !          4495:                      ? time ((long *) 0) : name_mtime (file->name);
        !          4496:   file->updated = 1;
        !          4497: 
        !          4498:   return (status);
        !          4499: }
        !          4500: 
        !          4501: /* Discard each backslash-newline combination from LINE.
        !          4502:    Backslash-backslash-newline combinations become backslash-newlines.
        !          4503:    This is done by copying the text at LINE into itself.  */
        !          4504: 
        !          4505: static void
        !          4506: collapse_continuations (line)
        !          4507:      char *line;
        !          4508: {
        !          4509:   register char *in, *out, *p;
        !          4510:   int backslash, bs_write;
        !          4511: 
        !          4512:   in = index (line, '\n');
        !          4513:   if (in == 0)
        !          4514:     return;
        !          4515: 
        !          4516:   out = in;
        !          4517:   while (*in != '\0')
        !          4518:     {
        !          4519:       backslash = 0;
        !          4520:       bs_write = 0;
        !          4521:       for (p = in - 1; p >= line && *p == '\\'; --p)
        !          4522:        {
        !          4523:          if (backslash)
        !          4524:            ++bs_write;
        !          4525:          backslash = !backslash;
        !          4526:        }
        !          4527: 
        !          4528:       out -= in - p;
        !          4529:       if (*p != '\\')
        !          4530:        ++out;
        !          4531: 
        !          4532:       while (bs_write-- > 0)
        !          4533:        *out++ = '\\';
        !          4534: 
        !          4535:       ++in;
        !          4536:       if (backslash)
        !          4537:        {
        !          4538:          while (*in == ' ' || *in == '\t')
        !          4539:            ++in;
        !          4540:          *out++ = ' ';
        !          4541:        }
        !          4542:       else
        !          4543:        *out++ = '\n';
        !          4544: 
        !          4545:       while (*in != '\0' && *in != '\n')
        !          4546:        *out++ = *in++;
        !          4547:     }
        !          4548: 
        !          4549:   *out = '\0';
        !          4550: }
        !          4551: 
        !          4552: /* Remove comments, backslash-newline combinations and whitespace
        !          4553:    following such combinations from LINE.
        !          4554:    This is done by copying the text at LINE into itself.  */
        !          4555: 
        !          4556: static void
        !          4557: collapse_line (line)
        !          4558:      char *line;
        !          4559: {
        !          4560:   register char *p, *p2;
        !          4561:   int backslash;
        !          4562:   int bs_write;
        !          4563: 
        !          4564:   /* Collapse backslash-newline continuations.  */
        !          4565:   collapse_continuations (line);
        !          4566: 
        !          4567:   while (1)
        !          4568:     {
        !          4569:       p = index (line, '#');
        !          4570:       if (p == 0)
        !          4571:        break;
        !          4572: 
        !          4573:       backslash = 0;
        !          4574:       bs_write = 0;
        !          4575:       for (p2 = p - 1; p2 > line && *p2 == '\\'; --p2)
        !          4576:        {
        !          4577:          if (backslash)
        !          4578:            ++bs_write;
        !          4579:          backslash = !backslash;
        !          4580:        }
        !          4581: 
        !          4582:       if (!backslash)
        !          4583:        {
        !          4584:          /* Cut off the line at the #.  */
        !          4585:          *p = '\0';
        !          4586:          break;
        !          4587:        }
        !          4588: 
        !          4589:       /* strcpy better copy left to right.  */
        !          4590:       line = p + 1;
        !          4591:       strcpy (p2 + 1 + bs_write, line);
        !          4592:     }
        !          4593: }
        !          4594: 
        !          4595: /* Execute the commands associated with FILE.
        !          4596:    Returns nonzero if some command got an unignored error.
        !          4597:    Returns zero if have successfully executed the commands.  */
        !          4598: 
        !          4599: static int
        !          4600: execute_file_commands (file)
        !          4601:      struct file *file;
        !          4602: {
        !          4603:   register char *line, *p, *next;
        !          4604:   int status = 0;
        !          4605:   char *expansion;
        !          4606:   struct commands *cmds = file->cmds;
        !          4607: 
        !          4608:   /* Don't go through all the preparations if the
        !          4609:      command is nothing but whitespace.  */
        !          4610: 
        !          4611:   for (p = cmds->commands; *p; ++p)
        !          4612:     if (*p != ' ' && *p != '\t' && *p != '\n')
        !          4613:       break;
        !          4614:   if (*p == '\0')
        !          4615:     return 0;
        !          4616: 
        !          4617:   /* First set the automatic macros according to this file */
        !          4618: 
        !          4619:   free (atD_macro->value);
        !          4620:   free (starD_macro->value);
        !          4621:   free (lessD_macro->value);
        !          4622:   free (percentD_macro->value);
        !          4623:   free (at_macro->value);
        !          4624:   free (percent_macro->value);
        !          4625: 
        !          4626: #define        LASTSLASH(m)    rindex (m->value, '/')
        !          4627: #define        FILEONLY(m)     line ? line + 1 : m->value
        !          4628: #define        DIRONLY(m)      line == 0 ? savestring ("./", 2) :              \
        !          4629:                        ((line == m->value) ? savestring ("/", 1) :     \
        !          4630:                        savestring (m->value, line - m->value + 1))
        !          4631: 
        !          4632: 
        !          4633:   if (ar_name (file->name))
        !          4634:     {
        !          4635:       line = index (file->name, '(');
        !          4636:       at_macro->value = savestring (file->name, line - file->name);
        !          4637:       ++line;
        !          4638:       percent_macro->value = savestring (line, strlen (line) - 1);
        !          4639:     }
        !          4640:   else
        !          4641:     {
        !          4642:       at_macro->value = savestring (file->name, strlen (file->name));
        !          4643:       percent_macro->value = savestring ((char *) 0, 0);
        !          4644:     }
        !          4645:   star_macro->value = file->stem != 0 ? file->stem : "";
        !          4646:   less_macro->value = file->deps != 0 ? dep_name (file->deps) : "";
        !          4647:   line = LASTSLASH (at_macro);
        !          4648:   atF_macro->value = FILEONLY (at_macro);
        !          4649:   atD_macro->value = DIRONLY (at_macro);
        !          4650:   dollar_slash_macro->value = atF_macro->value;
        !          4651:   line = LASTSLASH (star_macro);
        !          4652:   starF_macro->value = FILEONLY (star_macro);
        !          4653:   starD_macro->value = DIRONLY (star_macro);
        !          4654:   line = LASTSLASH (less_macro);
        !          4655:   lessF_macro->value = FILEONLY (less_macro);
        !          4656:   lessD_macro->value = DIRONLY (less_macro);
        !          4657:   line = LASTSLASH (percent_macro);
        !          4658:   percentF_macro->value = FILEONLY (percent_macro);
        !          4659:   percentD_macro->value = DIRONLY (percent_macro);
        !          4660: #undef LASTSLASH
        !          4661: #undef FILEONLY
        !          4662: #undef DIRONLY
        !          4663: 
        !          4664:   /* Compute the values for $^ and $?.  */
        !          4665: 
        !          4666:   {
        !          4667:     register unsigned dep_size = 0, c_size = 0;
        !          4668:     register char *cline;
        !          4669:     register struct dep *d;
        !          4670: 
        !          4671:     for (d = file->deps; d != 0; d = d->next)
        !          4672:       {
        !          4673:        register int i = strlen (dep_name (d)) + 1;
        !          4674:        c_size += i;
        !          4675:        if (d->changed)
        !          4676:          dep_size += i;
        !          4677:       }
        !          4678: 
        !          4679:     /* Add 1 to size here to make room for the null that
        !          4680:        `strcat' inserts after the final space.  */
        !          4681:     line = (char *) xmalloc (dep_size + 1);
        !          4682:     cline = (char *) xmalloc (c_size + 1);
        !          4683:     *line = *cline = '\0';
        !          4684: 
        !          4685:     if (c_size > 0)
        !          4686:       {
        !          4687:        for (d = file->deps; d != 0; d = d->next)
        !          4688:          {
        !          4689:            strcat (cline, dep_name (d));
        !          4690:            strcat (cline, " ");
        !          4691:            if (d->changed)
        !          4692:              {
        !          4693:                strcat (line, dep_name (d));
        !          4694:                strcat (line, " ");
        !          4695:              }
        !          4696:          }
        !          4697:        /* remove final space */
        !          4698:        line[dep_size - 1] = cline[c_size - 1] = '\0';
        !          4699:       }
        !          4700:     caret_macro->value = cline;
        !          4701:     qmark_macro->value = line;
        !          4702:   }
        !          4703: 
        !          4704:   /* Arrange for fatal signals to delete this target
        !          4705:      unless it is a dependency of .PRECIOUS.  */
        !          4706: 
        !          4707:   if (!file->precious)
        !          4708:     {
        !          4709:       signal_delete_file = file->name;
        !          4710:       signal_delete_mtime = file->last_mtime;
        !          4711:     }
        !          4712: 
        !          4713:   /* Expand macros and functions.  Error messages refer to
        !          4714:      the file and line where these commands were found.  */
        !          4715:   reading_filename = cmds->filename;
        !          4716:   reading_lineno_ptr = &(cmds->lineno);
        !          4717:   next = expansion = macro_expand (cmds->commands);
        !          4718:   reading_filename = 0;
        !          4719:   reading_lineno_ptr = 0;
        !          4720: 
        !          4721:   /* Now execute the command lines */
        !          4722: 
        !          4723:   line = (char *) alloca (strlen (expansion) + 1);
        !          4724:   while (next != 0 && *next != '\0')
        !          4725:     {
        !          4726:       int noprint = 0;
        !          4727:       int noerror = 0;
        !          4728:       char *end;
        !          4729:       register char *p;
        !          4730:       int backslash;
        !          4731: 
        !          4732:       /* Find the end of this line.  Backslash-newlines don't
        !          4733:         mean the end.  */
        !          4734: 
        !          4735:       end = next;
        !          4736:       while (*end != '\0')
        !          4737:        {
        !          4738:          p = index (end, '\n');
        !          4739:          if (p == 0)
        !          4740:            {
        !          4741:              end += strlen (end);
        !          4742:              break;
        !          4743:            }
        !          4744: 
        !          4745:          end = p;
        !          4746:          backslash = 0;
        !          4747:          while (*--p == '\\')
        !          4748:            backslash = !backslash;
        !          4749: 
        !          4750:          if (backslash)
        !          4751:            {
        !          4752:              ++end;
        !          4753:              /* If there is a tab after a backslash-newline,
        !          4754:                 remove it, since it was most likely used to line
        !          4755:                 up the continued line with the previous one.  */
        !          4756:              if (*end == '\t')
        !          4757:                strcpy (end, end + 1);
        !          4758:            }
        !          4759:          else
        !          4760:            break;
        !          4761:        }
        !          4762: 
        !          4763:       strncpy (line, next, end - next);
        !          4764:       line[end - next] = '\0';
        !          4765:       next = *end == '\0' ? 0 : end + 1;
        !          4766: 
        !          4767:       /* Print each line that does not start with `@',
        !          4768:         unless -s was specified.  */
        !          4769:       while (*line != '\0')
        !          4770:        {
        !          4771:          if (*line == '@')
        !          4772:            noprint = 1;
        !          4773:          else if (*line == '-')
        !          4774:            noerror = 1;
        !          4775:          else if (*line != ' ' && *line != '\t')
        !          4776:            break;
        !          4777:          line++;
        !          4778:        }
        !          4779: 
        !          4780:       if (just_print_flag || (!silent_flag && !noprint))
        !          4781:        {
        !          4782:          puts (line);
        !          4783:          fflush (stdout);
        !          4784:        }
        !          4785: 
        !          4786:       /* If -n was specified, don't really execute, unless file
        !          4787:         is a recursive submake.
        !          4788:         But do pretend we changed this file's date.  */
        !          4789:       if (just_print_flag && !file->recursive)
        !          4790:        continue;
        !          4791: 
        !          4792:       /* Delete backslash-newlines from this line.  */
        !          4793: 
        !          4794:       collapse_continuations (line);
        !          4795: 
        !          4796:       /* Execute the command line.  */
        !          4797: 
        !          4798:       status = execute_command_line (line);
        !          4799: 
        !          4800:       if (status)
        !          4801:        {
        !          4802:          fprintf (stderr, "%s: *** ", program);
        !          4803:          if (status & SIGNAL_STATUS)
        !          4804:            {
        !          4805:              extern char *sys_siglist[];
        !          4806:              int sig = status & ~(SIGNAL_STATUS|SIGNAL_COREDUMP);
        !          4807:              if (sig < NSIG)
        !          4808:                fputs (sys_siglist[sig], stderr);
        !          4809:              else
        !          4810:                fprintf (stderr, "Signal %d", sig);
        !          4811:              if (status & SIGNAL_COREDUMP)
        !          4812:                fputs (" (core dumped)", stderr);
        !          4813:            }
        !          4814:          else
        !          4815:            fprintf (stderr, "Error %d", status);
        !          4816: 
        !          4817:          if (ignore_errors_flag || noerror)
        !          4818:            {
        !          4819:              fputs (" (ignored)\n", stderr);
        !          4820:              fflush (stderr);
        !          4821:              /* We say it succeeded anyway so other things
        !          4822:                 that depend on this target will still be made.  */
        !          4823:              status = 0;
        !          4824:            }
        !          4825:          else
        !          4826:            {
        !          4827:              putc ('\n', stderr);
        !          4828:              fflush (stderr);
        !          4829:              break;
        !          4830:            }
        !          4831:        }
        !          4832:     }
        !          4833: 
        !          4834:   /* Target is final; no further reason to delete it.  */
        !          4835:   signal_delete_file = 0;
        !          4836:   signal_delete_mtime = 0;
        !          4837: 
        !          4838:   /* Now free the macro values made above.  */
        !          4839:   free (caret_macro->value);
        !          4840:   free (qmark_macro->value);
        !          4841:   caret_macro->value = qmark_macro->value = "";
        !          4842: 
        !          4843:   return (status);
        !          4844: }
        !          4845: 
        !          4846: /* For a FILE which has no commands specified, try to figure out some
        !          4847:    from the implicit pattern rules.
        !          4848:    Returns 1 if a suitable implicit rule was found,
        !          4849:    after modifying FILE to contain the appropriate commands and deps,
        !          4850:    or returns 0 if no implicit rule was found.  */
        !          4851: 
        !          4852: static int
        !          4853: try_implicit_rule (file, depth)
        !          4854:      struct file *file;
        !          4855:      int depth;
        !          4856: {
        !          4857:   register char *filename;
        !          4858: 
        !          4859:   DEBUGPR ("Looking for an implicit rule for `%s'.\n");
        !          4860: 
        !          4861:   /* If this is an archive member reference,
        !          4862:      use just the archive member name to search for implicit rules.  */
        !          4863:   if (ar_name (file->name))
        !          4864:     {
        !          4865:       filename = index (file->name, '(');
        !          4866:       DEBUGPR ("Looking for archive-member implicit rule for `%s'.\n");
        !          4867:       if (pattern_search (file, filename, depth, 0))
        !          4868:        return 1;
        !          4869:     }
        !          4870: 
        !          4871:   return pattern_search (file, (char *) 0, depth, 0);
        !          4872: }
        !          4873: 
        !          4874: #define DEBUGP2(msg, a1, a2) \
        !          4875:   if (debug_flag) \
        !          4876:     { print_spaces (depth); printf (msg, a1, a2); fflush (stdout);  }
        !          4877: 
        !          4878: /* Search the pattern rules for a rule with an existing
        !          4879:    dependent to make NAME.  If NAME is nil,
        !          4880:    FILE->name is used.  If a rule is found, the
        !          4881:    appropriate commands and deps are put in FILE
        !          4882:    and 1 is returned.  If not, 0 is returned.
        !          4883: 
        !          4884:    If an intermediate file is found by pattern search,
        !          4885:    the intermediate file is set up as a target by the recursive call
        !          4886:    and is also made a dependency of FILE.
        !          4887: 
        !          4888:    DEPTH is used for debugging messages.  */
        !          4889: 
        !          4890: static int
        !          4891: pattern_search (file, name, depth, recursions)
        !          4892:      struct file *file;
        !          4893:      char *name;
        !          4894:      int depth;
        !          4895:      int recursions;
        !          4896: {
        !          4897:   /* Filename we are searching for a rule for.  */
        !          4898:   char *filename = name != 0 ? name : file->name;
        !          4899: 
        !          4900:   /* Length of FILENAME.  */
        !          4901:   int namelen = strlen (filename);
        !          4902: 
        !          4903:   /* The last slash in FILENAME (or nil if there is none).  */
        !          4904:   char *lastslash;
        !          4905: 
        !          4906:   /* This is a file-object used as an argument in
        !          4907:      recursive calls.  It never contains any data
        !          4908:      except during a recursive call.  */
        !          4909:   struct file *intermediate_file = 0;
        !          4910: 
        !          4911:   /* Number of dependencies of the current rule that
        !          4912:      have been found using a recursive pattern_search.  */
        !          4913:   int intermediate_files_found = 0;
        !          4914: 
        !          4915:   /* List of dependencies found recursively.  */
        !          4916:   struct file **intermediate_files
        !          4917:     = (struct file **) alloca (max_pattern_deps * sizeof (struct file *));
        !          4918: 
        !          4919:   /* List of patterns used to find intermediate targets.  */
        !          4920:   char **intermediate_patterns
        !          4921:     = (char **) alloca (max_pattern_deps * sizeof (char *));
        !          4922: 
        !          4923:   /* This buffer records all the dependencies actually found for a rule.  */
        !          4924:   char **found_files = (char **) alloca (max_pattern_deps * sizeof (char *));
        !          4925:   /* Number of dep names now in FOUND_FILES.  */
        !          4926:   int deps_found;
        !          4927: 
        !          4928:   /* Names of possible dependencies are constructed in this buffer.  */
        !          4929:   register char *depname = (char *) alloca (namelen + max_pattern_dep_length);
        !          4930: 
        !          4931:   /* The start and length of the stem of FILENAME for the current rule.  */
        !          4932:   register char *stem;
        !          4933:   register int stemlen;
        !          4934: 
        !          4935:   /* Buffer in which we store all the rules that are possibly applicable.  */
        !          4936:   struct rule **tryrules
        !          4937:     = (struct rule **) alloca (num_pattern_rules * sizeof (struct rule *));
        !          4938: 
        !          4939:   /* Number of valid elements in tryrules.  */
        !          4940:   int nrules = 0;
        !          4941: 
        !          4942:   /* Nonzero if should consider intermediate files as dependencies.  */
        !          4943:   int intermed_ok;
        !          4944: 
        !          4945:   /* Nonzero if we have matched a pattern-rule target
        !          4946:      that is not just `%'.  */
        !          4947:   int specific_rule_matched = 0;
        !          4948: 
        !          4949:   register int i;
        !          4950:   register struct rule *rule;
        !          4951:   register struct dep *dep;
        !          4952: 
        !          4953:   char *p;
        !          4954: 
        !          4955:   /* Set LASTSLASH to point at the last slash in FILENAME
        !          4956:      but not counting any slash at the end.  (foo/bar/ counts as
        !          4957:      bar/ in directory foo/, not empty in directory foo/bar/.)  */
        !          4958: 
        !          4959:   lastslash = 0;
        !          4960:   p = filename;
        !          4961:   while (*p && p[1])
        !          4962:     {
        !          4963:       if (*p == '/')
        !          4964:        lastslash = p;
        !          4965:       p++;
        !          4966:     }
        !          4967: 
        !          4968:   /* First see which pattern rules match this target
        !          4969:      and may be considered.  Put them in TRYRULES.  */
        !          4970: 
        !          4971:   for (rule = pattern_rules; rule != 0; rule = rule->next)
        !          4972:     {
        !          4973:       int check_lastslash;
        !          4974:       /* If the pattern rule has no commands, ignore it.
        !          4975:         Users cancel built-in rules by redefining them without commands.  */
        !          4976:       if (rule->deps != 0 && rule->cmds == 0)
        !          4977:        continue;
        !          4978: 
        !          4979:       /* If this rule is in use by a parent pattern_search,
        !          4980:         don't use it here.  */
        !          4981:       if (rule->in_use)
        !          4982:        {
        !          4983:          DEBUGP2 ("Avoiding implicit rule recursion.\n", 0, 0);
        !          4984:          continue;
        !          4985:        }
        !          4986: 
        !          4987:       /* Don't try rules whose dependents are guaranteed
        !          4988:         to be non-existent.  */
        !          4989:       if (lastslash == 0 && rule->subdir)
        !          4990:        continue;
        !          4991: 
        !          4992:       /* From the lengths of the filename and the pattern parts,
        !          4993:         find the stem: the part of the filename that matches the %.  */
        !          4994:       stem = filename + (rule->patsuffix - rule->name - 1);
        !          4995:       stemlen = namelen - rule->namelen + 1;
        !          4996: 
        !          4997:       /* Set CHECK_LASTSLASH if FILENAME contains a directory prefix
        !          4998:         and the target pattern does not contain a slash.  */
        !          4999: 
        !          5000:       check_lastslash = lastslash && index (rule->name, '/') == 0;
        !          5001:       if (check_lastslash)
        !          5002:        {
        !          5003:          /* In that case, don't include the directory prefix in STEM here.  */
        !          5004:          stem += lastslash - filename + 1;
        !          5005:          stemlen -= (lastslash - filename) + 1;
        !          5006:        }
        !          5007: 
        !          5008:       /* Check that filename is long enough to match the whole pattern.  */
        !          5009:       if (stemlen <= 0)
        !          5010:        continue;
        !          5011: 
        !          5012:       /* Check that the rule pattern matches the text before the stem.  */
        !          5013:       if (check_lastslash)
        !          5014:        {
        !          5015:          if (stem > (lastslash + 1)
        !          5016:              && strncmp (rule->name, lastslash + 1, stem - lastslash - 1))
        !          5017:            continue;
        !          5018:        }
        !          5019:       else if (stem > filename
        !          5020:                && strncmp (rule->name, filename, stem - filename))
        !          5021:        continue;
        !          5022: 
        !          5023:       /* Check that the rule pattern matches the text after the stem.
        !          5024:         We could test simply !streq (rule->patsuffix, stem + stemlen)
        !          5025:         but this way we compare the first two characters immediately.
        !          5026:         This saves time in the very common case where the first
        !          5027:         character matches because it is a period.  */
        !          5028:       if (*rule->patsuffix != stem[stemlen]
        !          5029:          || (*rule->patsuffix != 0
        !          5030:              && !streq (&rule->patsuffix[1], &stem[stemlen + 1])))
        !          5031:        continue;
        !          5032: 
        !          5033:       /* Record if we match some rule that not all filenames will match.  */
        !          5034:       if (rule->name[1] != '\0')
        !          5035:        specific_rule_matched = 1;
        !          5036: 
        !          5037:       /* A rule with no dependencies and no commands exists solely to set
        !          5038:         specific_rule_matched when it matches.  Don't try to use it.  */
        !          5039:       if (rule->deps != 0 || rule->cmds != 0)
        !          5040:        tryrules[nrules++] = rule;
        !          5041:     }
        !          5042: 
        !          5043:   /* If we have found a matching rule that won't match all filenames,
        !          5044:      retroactively reject any "terminal" rules that do always match.  */
        !          5045:   if (specific_rule_matched)
        !          5046:     for (i = 0; i < nrules; ++i)
        !          5047:       if (tryrules[i]->terminal && tryrules[i]->name[1] == '\0')
        !          5048:        tryrules[i] = 0;
        !          5049: 
        !          5050:   /* Try each rule once without intermediate files,
        !          5051:      then once with them.  */
        !          5052:   for (intermed_ok = 0; intermed_ok < 2; intermed_ok++)
        !          5053:     {
        !          5054:       /* Try each pattern rule till we find one that applies.
        !          5055:         If it does, copy the names of its dependencies (as substituted)
        !          5056:         and store them in FOUND_FILES.  DEPS_FOUND is the number of them.  */
        !          5057:       for (i = 0; i < nrules; i++)
        !          5058:        {
        !          5059:          int check_lastslash;
        !          5060: 
        !          5061:          rule = tryrules[i];
        !          5062: 
        !          5063:          /* RULE is nil when we discovered that a rule, already placed
        !          5064:             in TRYRULES, should not be applied.  */
        !          5065:          if (rule == 0)
        !          5066:            continue;
        !          5067: 
        !          5068:          /* Rules that can match any filename and are not terminal
        !          5069:             should be ignored on the second pass, so that they
        !          5070:             cannot accept an intermediate file.
        !          5071:             These rules can only be the end of a chain.  */
        !          5072:          if (intermed_ok && rule->name[1] == '\0' && !rule->terminal)
        !          5073:            continue;
        !          5074: 
        !          5075:          /* Mark this rule as in use so a recursive
        !          5076:             pattern_search won't try to use it.  */
        !          5077:          rule->in_use = 1;
        !          5078: 
        !          5079:          /* From the lengths of the filename and the pattern parts,
        !          5080:             find the stem: the part of the filename that matches the %.  */
        !          5081:          stem = filename + (rule->patsuffix - rule->name) - 1;
        !          5082:          stemlen = namelen - rule->namelen + 1;
        !          5083:          check_lastslash = lastslash && index (rule->name, '/') == 0;
        !          5084:          if (check_lastslash)
        !          5085:            {
        !          5086:              stem += lastslash - filename + 1;
        !          5087:              stemlen -= (lastslash - filename) + 1;
        !          5088:            }
        !          5089: 
        !          5090:          DEBUGP2 ("Trying pattern rule with stem `%.*s'.\n",
        !          5091:                   stemlen, stem);
        !          5092: 
        !          5093:          /* Try each dependency; see if it "exists".  */
        !          5094: 
        !          5095:          intermediate_files_found = 0;
        !          5096:          deps_found = 0;
        !          5097:          for (dep = rule->deps; dep != 0; dep = dep->next)
        !          5098:            {
        !          5099:              /* If the dependency name has a %, substitute the stem.  */
        !          5100:              p = index (dep_name (dep), '%');
        !          5101:              if (p != 0)
        !          5102:                {
        !          5103:                  register int i;
        !          5104:                  if (check_lastslash)
        !          5105:                    {
        !          5106:                      i = lastslash - filename + 1;
        !          5107:                      bcopy (filename, depname, i);
        !          5108:                    }
        !          5109:                  else
        !          5110:                    i = 0;
        !          5111:                  bcopy (dep_name (dep), depname + i, p - dep_name (dep));
        !          5112:                  i += p - dep_name (dep);
        !          5113:                  bcopy (stem, depname + i, stemlen);
        !          5114:                  i += stemlen;
        !          5115:                  strcpy (depname + i, p + 1);
        !          5116:                  p = depname;
        !          5117:                }
        !          5118:              else
        !          5119:                p = dep_name (dep);
        !          5120:              
        !          5121:              /* P is now the actual dependency name as substituted.  */
        !          5122: 
        !          5123:              if (file_impossible_p (p))
        !          5124:                {
        !          5125:                  /* If this dependency has already been ruled
        !          5126:                     "impossible", then the rule fails
        !          5127:                     and don't bother trying it on the second pass either
        !          5128:                     since we know that will fail too.  */
        !          5129:                  DEBUGP2 ("Rejecting impossible %s dependent `%s'.\n",
        !          5130:                       p == depname ? "implicit" : "rule", p);
        !          5131:                  tryrules[i] = 0;
        !          5132:                  break;
        !          5133:                }
        !          5134: 
        !          5135:              DEBUGP2 ("Trying %s dependent `%s'.\n",
        !          5136:                       p == depname ? "implicit" : "rule", p);
        !          5137:              if (lookup_file (p) != 0 || file_exists_p (p))
        !          5138:                {
        !          5139:                  found_files[deps_found++] = savestring (p, strlen (p));
        !          5140:                  continue;
        !          5141:                }
        !          5142:              /* This code, given FILENAME = "lib/foo.o",
        !          5143:                 dependency name "lib/foo.c", and VPATH=src,
        !          5144:                 searches for "src/lib/foo.c".  */
        !          5145:              if (vpath_search (&p, (char *) 0, 0))
        !          5146:                {
        !          5147:                  DEBUGP2 ("Found dependent as `%s'.\n", p, 0);
        !          5148:                  found_files[deps_found++] = p;
        !          5149:                  continue;
        !          5150:                }
        !          5151: 
        !          5152:              /* We could not find the file in any place we should look.  */
        !          5153:              /* Try to make this dependency as an intermediate file,
        !          5154:                 but only on the second pass.  */
        !          5155: 
        !          5156:              if (intermed_ok && p == depname)
        !          5157:                {
        !          5158:                  int status;
        !          5159: 
        !          5160:                  if (intermediate_file == 0)
        !          5161:                    intermediate_file
        !          5162:                      = (struct file *) alloca (sizeof (struct file));
        !          5163: 
        !          5164:                  DEBUGP2 ("Looking for rule with intermediate file `%s'.\n",
        !          5165:                           p, 0);
        !          5166: 
        !          5167:                  bzero ((char *) intermediate_file, sizeof (struct file));
        !          5168:                  intermediate_file->name = p;
        !          5169:                  status = pattern_search (intermediate_file, (char *) 0,
        !          5170:                                      depth + 1, recursions + 1);
        !          5171:                  if (status)
        !          5172:                    {
        !          5173:                      p = savestring (p, strlen (p));
        !          5174:                      intermediate_patterns[deps_found]
        !          5175:                        = intermediate_file->name;
        !          5176:                      found_files[deps_found++] = p;
        !          5177:                      intermediate_file->name = p;
        !          5178:                      intermediate_files[intermediate_files_found++]
        !          5179:                        = intermediate_file;
        !          5180:                      intermediate_file = 0;
        !          5181:                      continue;
        !          5182:                    }
        !          5183:                  /* If we have tried to find P as an intermediate file
        !          5184:                     and failed, mark that name as impossible
        !          5185:                     so we won't go through the search again later.  */
        !          5186:                  file_impossible (p);
        !          5187:                }
        !          5188:              
        !          5189:              /* A dependency of this rule does not exist.
        !          5190:                 Therefore, this rule fails.  */
        !          5191:              break;
        !          5192:            }
        !          5193: 
        !          5194:          /* This rule is no longer "in use" for recursive searches.  */
        !          5195:          rule->in_use = 0;
        !          5196: 
        !          5197:          if (dep != 0)
        !          5198:            {
        !          5199:              /* This pattern rule does not apply.
        !          5200:                 If some of its dependents succeeded,
        !          5201:                 free the data structure describing them.  */
        !          5202:              while (deps_found-- > 0)
        !          5203:                free (found_files[deps_found]);
        !          5204:              while (intermediate_files_found-- > 0)
        !          5205:                {
        !          5206:                  register struct file *f
        !          5207:                    = intermediate_files[intermediate_files_found];
        !          5208:                  if (f->stem < f->name
        !          5209:                      || (f->stem > f->name
        !          5210:                          && (f->stem - f->name) <= strlen (f->name)))
        !          5211:                    free (f->stem);
        !          5212:                }
        !          5213:            }
        !          5214:          else
        !          5215:            /* This pattern rule does apply.  Stop looking for one.  */
        !          5216:            break;
        !          5217:        }
        !          5218: 
        !          5219:       /* If we found an applicable rule with intermed_ok == 0,
        !          5220:         don't try intermed_ok == 1.  */
        !          5221:       if (i < nrules)
        !          5222:        break;
        !          5223: 
        !          5224:       rule = 0;
        !          5225:     }
        !          5226: 
        !          5227:   /* RULE is nil if the loop went all the way through
        !          5228:      the list and everything failed.  */
        !          5229:   if (rule == 0)
        !          5230:     return 0;
        !          5231: 
        !          5232:   /* If we are recursing, store the pattern that matched
        !          5233:      FILENAME in FILE->name for use in upper levels.  */
        !          5234: 
        !          5235:   if (recursions > 0)
        !          5236:     /* Kludge-o-matic */
        !          5237:     file->name = rule->name;
        !          5238:   
        !          5239:   /* FOUND_FILES lists the dependencies for the rule we found.
        !          5240:      This includes the intermediate file, if any.
        !          5241:      Convert them into entries on the deps-chain of FILE.  */
        !          5242: 
        !          5243:   while (deps_found-- > 0)
        !          5244:     {
        !          5245:       register char *s;
        !          5246: 
        !          5247:       dep = (struct dep *) xmalloc (sizeof (struct dep));
        !          5248:       s = found_files[deps_found];
        !          5249:       if (recursions == 0)
        !          5250:        {
        !          5251:          dep->name = 0;
        !          5252:          dep->file = enter_file (s);
        !          5253:        }
        !          5254:       else
        !          5255:        dep->name = s;
        !          5256:       dep->next = file->deps;
        !          5257:       file->deps = dep;
        !          5258: 
        !          5259:       /* If the new dependency duplicates an old one, delete the old one. */
        !          5260:       while (dep)
        !          5261:        {
        !          5262:          if (dep->next && streq (dep_name (dep->next), s))
        !          5263:            dep->next = dep->next->next;
        !          5264:          else
        !          5265:            dep = dep->next;
        !          5266:        }
        !          5267:     }
        !          5268: 
        !          5269:   file->stem = stem[stemlen] == '\0' ? stem : savestring (stem, stemlen);
        !          5270:   file->cmds = rule->cmds;
        !          5271:   file->recursive = file->recursive || rule->recursive;
        !          5272: 
        !          5273:   /* If we need to use an intermediate file,
        !          5274:      make sure it is entered as a target, with the info that was
        !          5275:      found for it in the recursive pattern_search call.
        !          5276:      We know that the intermediate file did not already exist as
        !          5277:      a target; therefore we can assume that the deps and cmds
        !          5278:      of F below are null before we change them.  */
        !          5279: 
        !          5280:   while (intermediate_files_found-- > 0)
        !          5281:     {
        !          5282:       struct file *imf = intermediate_files[intermediate_files_found];
        !          5283:       register struct file *f = enter_file (imf->name);
        !          5284:       f->deps = imf->deps;
        !          5285:       f->cmds = imf->cmds;
        !          5286:       f->stem = imf->stem;
        !          5287:       imf = lookup_file (intermediate_patterns[intermediate_files_found]);
        !          5288:       if (imf != 0 && imf->precious)
        !          5289:        f->precious = 1;
        !          5290:       f->intermediate = 1;
        !          5291:       f->tried_implicit = 1;
        !          5292:       for (dep = f->deps; dep != 0; dep = dep->next)
        !          5293:        {
        !          5294:          dep->file = enter_file (dep->name);
        !          5295:          dep->name = 0;
        !          5296:        }
        !          5297:       num_intermediates++;
        !          5298:     }
        !          5299: 
        !          5300:   return 1;
        !          5301: }
        !          5302: 
        !          5303: /* Compute the maximum dependency length and maximum number of
        !          5304:    dependencies of all implicit rules.  Also sets the subdir
        !          5305:    flag for a rule when appropriate.  */
        !          5306: 
        !          5307: static void
        !          5308: count_implicit_rule_limits ()
        !          5309: {
        !          5310:   char *name = 0;
        !          5311:   unsigned namelen = 0;
        !          5312:   register struct rule *rule, *lastrule;
        !          5313:   
        !          5314:   num_pattern_rules = 0;
        !          5315:   
        !          5316:   lastrule = pattern_rules;
        !          5317:   for (rule = lastrule; rule != 0; lastrule = rule, rule = rule->next)
        !          5318:     {
        !          5319:       int ndeps = 0;
        !          5320:       register struct dep *dep;
        !          5321:       
        !          5322:       ++num_pattern_rules;
        !          5323:       
        !          5324:       for (dep = rule->deps; dep != 0; dep = dep->next)
        !          5325:        {
        !          5326:          int len = strlen (dep->name);
        !          5327:          char *p = rindex (dep->name, '/');
        !          5328:          char *p2 = p != 0 ? index (dep->name, '%') : 0;
        !          5329:          if (len > max_pattern_dep_length)
        !          5330:            max_pattern_dep_length = len;
        !          5331:          ndeps++;
        !          5332:          if (p != 0 && p2 > p)
        !          5333:            {
        !          5334:              if ((p - dep->name) > namelen)
        !          5335:                {
        !          5336:                  if (name != 0)
        !          5337:                    free (name);
        !          5338:                  namelen = p - dep->name;
        !          5339:                  name = (char *) xmalloc (namelen + 1);
        !          5340:                }
        !          5341:              bcopy (dep->name, name, p - dep->name);
        !          5342:              name[p - dep->name] = '\0';
        !          5343:              if (dir_file_exists_p (name, "."))
        !          5344:                rule->subdir = 0;
        !          5345:              else
        !          5346:                {
        !          5347:                  struct stat buf;
        !          5348:                  if (stat (name, &buf) < 0
        !          5349:                      || (buf.st_mode & S_IFMT) != S_IFDIR)
        !          5350:                    {
        !          5351:                      if (*name == '/')
        !          5352:                        {
        !          5353:                          if (rule == pattern_rules)
        !          5354:                            pattern_rules = rule->next;
        !          5355:                          else
        !          5356:                            last_pattern_rule->next = rule->next;
        !          5357:                          free (rule->name);
        !          5358:                          free ((char *) rule);
        !          5359:                        }
        !          5360:                      else
        !          5361:                        rule->subdir = 1;
        !          5362:                    }
        !          5363:                  else
        !          5364:                    {
        !          5365:                      dir_load (name);
        !          5366:                      rule->subdir = 0;
        !          5367:                    }
        !          5368:                }
        !          5369:            }
        !          5370:        }
        !          5371:       if (ndeps > max_pattern_deps)
        !          5372:        max_pattern_deps = ndeps;
        !          5373:     }
        !          5374:   
        !          5375:   if (name != 0)
        !          5376:     free (name);
        !          5377: }
        !          5378: 
        !          5379: /* Read a line of text from `stream' into `linebuffer'.
        !          5380:    Combine continuation lines into one line.
        !          5381:    Return the number of actual lines read. (> 1 if hacked continuation lines)
        !          5382:  */
        !          5383: 
        !          5384: static long
        !          5385: readline (linebuffer, stream, filename)
        !          5386:      struct linebuffer *linebuffer;
        !          5387:      FILE *stream;
        !          5388:      char *filename;
        !          5389: {
        !          5390:   char *buffer = linebuffer->buffer;
        !          5391:   register char *p = linebuffer->buffer;
        !          5392:   register char *end = p + linebuffer->size;
        !          5393:   register int len;
        !          5394:   register char *p2;
        !          5395:   register long nlines = 0L;
        !          5396:   int backslash;
        !          5397: 
        !          5398:   while (1)
        !          5399:     {
        !          5400:       if (fgets (p, end - p, stream) == 0)
        !          5401:        {
        !          5402:          if (feof (stream))
        !          5403:            return nlines;
        !          5404:          else
        !          5405:            pfatal_with_name (filename);
        !          5406:        }
        !          5407: 
        !          5408:       len = strlen (p);
        !          5409:       if (len == 0 || (p += len)[-1] != '\n')
        !          5410:        {
        !          5411:          /* Ran out of buffer space.  */
        !          5412:          register int delta = linebuffer->size;
        !          5413:          end += delta;
        !          5414:          buffer = (char *) xrealloc (buffer, linebuffer->size += delta);
        !          5415:          delta = buffer - linebuffer->buffer;
        !          5416:          p += delta;
        !          5417:          end += delta;
        !          5418:          linebuffer->buffer = buffer;
        !          5419:          continue;
        !          5420:        }
        !          5421: 
        !          5422:       ++nlines;
        !          5423: 
        !          5424:       backslash = 0;
        !          5425:       for (p2 = p - 2; --len > 0; --p2)
        !          5426:        {
        !          5427:          if (*p2 == '\\')
        !          5428:            backslash = !backslash;
        !          5429:          else
        !          5430:            break;
        !          5431:        }
        !          5432:       
        !          5433:       if (!backslash)
        !          5434:        {
        !          5435:          p[-1] = '\0';
        !          5436:          return nlines;
        !          5437:        }
        !          5438:     }
        !          5439: }
        !          5440: 
        !          5441: static int
        !          5442: ar_name (name)
        !          5443:      char *name;
        !          5444: {
        !          5445:   char *p = index (name, '('), *end = name + strlen (name) - 1;
        !          5446:   
        !          5447:   if (p == 0 || *end != ')')
        !          5448:     return 0;
        !          5449: 
        !          5450:   if (p[1] == '(' && end[-1] == ')')
        !          5451:     fatal ("attempt to use unsupported feature: `%s'", name);
        !          5452: 
        !          5453:   return 1;
        !          5454: }
        !          5455: 
        !          5456: static int
        !          5457: ar_scan_1 (name, function)
        !          5458:      char *name;
        !          5459:      int (*function) ();
        !          5460: {
        !          5461:   char *arname;
        !          5462:   char *memname;
        !          5463:   char *p;
        !          5464:   int val;
        !          5465: 
        !          5466:   /* This "file" is an archive member */
        !          5467:   p = index (name, '(');
        !          5468:   arname = savestring (name, p - name);
        !          5469:   memname = savestring (p + 1, strlen (p) - 2);
        !          5470: 
        !          5471:   val = ar_scan (arname, function, memname);
        !          5472:   free (arname);
        !          5473:   free (memname);
        !          5474:   return (val);
        !          5475: }
        !          5476: 
        !          5477: /* ARGSUSED */
        !          5478: static int
        !          5479: ar_member_date_1 (desc, name, hdrpos, datapos, size, date, uid, gid, mode, mem)
        !          5480:      int desc;
        !          5481:      char *name;
        !          5482:      int hdrpos, datapos, size, date, uid, gid, mode;
        !          5483:      char *mem;
        !          5484: {
        !          5485:   if (streq (name, mem))
        !          5486:     return (date);
        !          5487:   else
        !          5488:     return (0);
        !          5489: }
        !          5490: 
        !          5491: static int
        !          5492: ar_member_date (name)
        !          5493:      char *name;
        !          5494: {
        !          5495:   return (ar_scan_1 (name, ar_member_date_1));
        !          5496: }
        !          5497: 
        !          5498: static int
        !          5499: ar_touch (name)
        !          5500:      char *name;
        !          5501: {
        !          5502:   register char *p, *arname, *memname;
        !          5503:   register int val;
        !          5504: 
        !          5505:   p = index (name, '(');
        !          5506:   arname = savestring (name, p - name);
        !          5507:   memname = savestring (p + 1, strlen (p) - 2);
        !          5508: 
        !          5509:   val = ar_member_touch (arname, memname);
        !          5510:   if (val == -2)
        !          5511:     fatal ("Invalid archive %s", arname);
        !          5512:   if (val < 0)
        !          5513:     pfatal_with_name (arname);
        !          5514:   if (val > 0)
        !          5515:     error ("touch: No such archive member %s", name);
        !          5516: 
        !          5517:   free (arname);
        !          5518:   free (memname);
        !          5519: 
        !          5520:   return (val);
        !          5521: }
        !          5522: 
        !          5523: /* Execute LINE as a command.  Try to avoid forking a shell.
        !          5524:    This routine handles only ' quoting.  Starting quotes may be
        !          5525:    escaped with a backslash.  If any of the characters ;"*?[]&|<>(){}=
        !          5526:    is seen, or any of the builtin commands listed in sh_cmds[]
        !          5527:    is the first word of a line, the shell is used.  */
        !          5528: 
        !          5529: static int
        !          5530: execute_command_line (line)
        !          5531:      char *line;
        !          5532: {
        !          5533:   static char *sh_cmds[] = { "cd", "eval", "exec", "exit", "login",
        !          5534:                             "logout", "set", "umask", "wait", "while", "for",
        !          5535:                             "case", "if", ":", ".", "break", "continue",
        !          5536:                             "export", "read", "readonly", "shift", "times",
        !          5537:                             "trap", "switch", 0 };
        !          5538:   register int i;
        !          5539:   register char *p;
        !          5540:   register char *ap;
        !          5541:   char *end;
        !          5542:   int instring;
        !          5543:   union wait status;
        !          5544:   int pid;
        !          5545:   char **new_argv;
        !          5546: 
        !          5547:   new_environ ();
        !          5548: 
        !          5549:   /* See if it is safe to parse commands internally.  */
        !          5550:   if (strcmp (shell_macro->value, "/bin/sh"))
        !          5551:        goto slow;
        !          5552:   else if (ifs_macro != 0)
        !          5553:     for (line = ifs_macro->value; *line != '\0'; ++line)
        !          5554:       if (*line != ' ' && *line != '\t' && *line != '\n')
        !          5555:        goto slow;
        !          5556: 
        !          5557:   i = strlen (line) + 1;
        !          5558: 
        !          5559:   /* More than 1 arg per character is impossible.  */
        !          5560:   new_argv = (char **) alloca (i * sizeof (char *));
        !          5561: 
        !          5562:   /* All the args can fit in a buffer as big as LINE is.   */
        !          5563:   ap = new_argv[0] = (char *) alloca (i);
        !          5564:   end = ap + i;
        !          5565: 
        !          5566:   /* I is how many complete arguments have been found.  */
        !          5567:   i = 0;
        !          5568:   instring = 0;
        !          5569:   for (p = line; *p; ++p)
        !          5570:     {
        !          5571:       if (ap > end)
        !          5572:        {
        !          5573:          fflush (stdout);
        !          5574:          fflush (stderr);
        !          5575:          abort ();
        !          5576:        }
        !          5577: 
        !          5578:       if (instring)
        !          5579:        {
        !          5580:          /* Inside a string, just copy any char except a closing quote.  */
        !          5581:          if (*p == '\'')
        !          5582:            instring = 0;
        !          5583:          else
        !          5584:            *ap++ = *p;
        !          5585:        }
        !          5586:       else
        !          5587:        /* Not inside a string.  */
        !          5588:        switch (*p)
        !          5589:          {
        !          5590:          case '\\':
        !          5591:            if (p[1] && p[1] != '\n')
        !          5592:              /* Copy and skip the following char.  */
        !          5593:              *ap++ = *++p;
        !          5594:            break;
        !          5595: 
        !          5596:          case '\'':
        !          5597:            instring = 1;
        !          5598:            break;
        !          5599: 
        !          5600:          case ';':
        !          5601:          case '"':
        !          5602:          case '*':
        !          5603:          case '?':
        !          5604:          case '[':
        !          5605:          case ']':
        !          5606:          case '$':
        !          5607:          case '<':
        !          5608:          case '>':
        !          5609:          case '|':
        !          5610:          case '&':
        !          5611:          case '=':
        !          5612:          case '~':
        !          5613:          case '`':
        !          5614:          case '(':
        !          5615:          case ')':
        !          5616:          case '{':
        !          5617:          case '}':
        !          5618:            goto slow;
        !          5619: 
        !          5620:          case '\n':
        !          5621:          case ' ':
        !          5622:          case '\t':
        !          5623:            /* We have the end of an argument.
        !          5624:               Terminate the text of the argument.  */
        !          5625:            *ap++ = '\0';
        !          5626:            new_argv[++i] = ap;
        !          5627:            /* If this argument is the command name,
        !          5628:               see if it is a built-in shell command.
        !          5629:               If so, have the shell handle it.  */
        !          5630:            if (i == 1)
        !          5631:              {
        !          5632:                register int j;
        !          5633:                for (j = 0; sh_cmds[j] != 0; ++j)
        !          5634:                  if (streq (sh_cmds[j], new_argv[0]))
        !          5635:                    goto slow;
        !          5636:              }
        !          5637:            /* Ignore multiple whitespace.  */
        !          5638:            while (*p == ' ' || *p == '\t')
        !          5639:              ++p;
        !          5640:            /* Next iteration should examine the first nonwhite char.  */
        !          5641:            --p;
        !          5642:            break;
        !          5643: 
        !          5644:          case '#':
        !          5645:            /* # starts a comment, at beginning of word.  */
        !          5646:            if (p == line || p[-1] == ' ' || p[-1] == '\t')
        !          5647:              goto endloop;
        !          5648: 
        !          5649:            /* Drops in */
        !          5650:          default:
        !          5651:            *ap++ = *p;
        !          5652:            break;
        !          5653:          }
        !          5654:     }
        !          5655: 
        !          5656:  endloop:
        !          5657: 
        !          5658:   /* Terminate the last argument and the argument list.  */
        !          5659: 
        !          5660:   *ap = '\0';
        !          5661:   if (new_argv[i][0] != '\0')
        !          5662:     ++i;
        !          5663:   new_argv[i] = 0;
        !          5664: 
        !          5665:   if (new_argv[0] == 0)
        !          5666:     /* Line was empty */
        !          5667:     return 0;
        !          5668: 
        !          5669:   line = new_argv[0];
        !          5670:   
        !          5671:   if (0)
        !          5672:     {
        !          5673:     slow:;
        !          5674:       new_argv = (char **) alloca (4 * sizeof (char *));
        !          5675:       ap = rindex (shell_macro->value, '/');
        !          5676:       new_argv[0] = ap == 0 ? shell_macro->value : ap + 1;
        !          5677:       new_argv[1] = "-c";
        !          5678:       new_argv[2] = line;
        !          5679:       new_argv[3] = 0;
        !          5680:       line = shell_macro->value;
        !          5681:     }
        !          5682:   
        !          5683:   /* Run the command.  */
        !          5684: 
        !          5685:   pid = vfork ();
        !          5686:   if (pid == 0)
        !          5687:     {
        !          5688:       execvp (line, new_argv);
        !          5689:       perror_with_name ("execvp: ", line);
        !          5690:       _exit (127);
        !          5691:     }
        !          5692: 
        !          5693:   if (pid < 0)
        !          5694:     return (127);
        !          5695: 
        !          5696:   /* Wait for termination and report the results.  */
        !          5697: 
        !          5698:   while (1)
        !          5699:     {
        !          5700:       int wpid;
        !          5701:       wpid = wait (&status);
        !          5702:       if (wpid < 0)
        !          5703:        return (127);
        !          5704:       else if (wpid != pid)
        !          5705:        continue;
        !          5706:       else if (WIFEXITED (status))
        !          5707:        return (status.w_retcode);
        !          5708:       else if (WIFSIGNALED (status))
        !          5709:        {
        !          5710:          int s;
        !          5711:          struct stat st;
        !          5712: 
        !          5713:          /* Delete the output file that the command was supposed to make.  */
        !          5714: 
        !          5715:          if (signal_delete_file
        !          5716:              && stat (signal_delete_file, &st) >= 0
        !          5717:              && (st.st_mode & S_IFMT) != S_IFDIR
        !          5718:              && st.st_mtime != signal_delete_mtime)
        !          5719:            {
        !          5720:              fprintf (stderr, "\n%s: Deleting file %s\n",
        !          5721:                       program, signal_delete_file);
        !          5722:              fflush (stderr);
        !          5723:              if (unlink (signal_delete_file) < 0)
        !          5724:                perror_with_name ("unlink: ", signal_delete_file);
        !          5725:            }
        !          5726: 
        !          5727:          /* Treat this as failure.  */
        !          5728: 
        !          5729:          s = status.w_termsig | SIGNAL_STATUS;
        !          5730:          if (status.w_coredump)
        !          5731:            s |= SIGNAL_COREDUMP;
        !          5732:          return s;
        !          5733:        }
        !          5734:     }
        !          5735: }
        !          5736: 
        !          5737: /* New_environ () sets environ with a new environment for child
        !          5738:    processes.  The storage is freed at the next call to this routine.
        !          5739:    The child's MAKELEVEL variable is incremented.  */
        !          5740: 
        !          5741: static void
        !          5742: new_environ ()
        !          5743: {
        !          5744:   extern char **environ;
        !          5745:   register unsigned macro_count, i, mcnt;
        !          5746:   register struct macro *m;
        !          5747: 
        !          5748:   static int free_env = 0;
        !          5749: 
        !          5750:   if (free_env)
        !          5751:     {
        !          5752:       for (i = 0; environ[i] != 0; ++i)
        !          5753:        free (environ[i]);
        !          5754:       free ((char *) environ);
        !          5755:     }
        !          5756: 
        !          5757: #define        identifier_char(c) \
        !          5758:   (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') \
        !          5759:    || ((c) >= '0' && (c) <= '9') || (c) == '_')
        !          5760: 
        !          5761:   macro_count = 0;
        !          5762:   for (i = 0; i < MACRO_BUCKETS; ++i)
        !          5763:     for (m = macros[i]; m != 0; m = m->next)
        !          5764:       {
        !          5765:        register char *p;
        !          5766:        for (p = m->name; *p; ++p)
        !          5767:          if (!identifier_char (*p))
        !          5768:            break;
        !          5769:        if (*p == 0)
        !          5770:          ++macro_count;
        !          5771:       }
        !          5772: 
        !          5773:   environ = (char **) xmalloc ((macro_count + 2) * sizeof (char *));
        !          5774: 
        !          5775:   mcnt = 0;
        !          5776:   for (i = 0; i < MACRO_BUCKETS; ++i)
        !          5777:     for (m = macros[i]; m != 0; m = m->next)
        !          5778:       {
        !          5779:        register char *p;
        !          5780: 
        !          5781:        for (p = m->name; *p; ++p)
        !          5782:          if (!identifier_char (*p))
        !          5783:            break;
        !          5784:        if (*p == '\0')
        !          5785:          {
        !          5786:            /* 663 mod MACRO_BUCKETS is "MAKELEVEL"s hash bucket number.  */
        !          5787:            if (i != (663 % MACRO_BUCKETS) || strcmp ("MAKELEVEL", m->name))
        !          5788:              {
        !          5789:                environ[mcnt] = xmalloc ((unsigned) (strlen (m->name)
        !          5790:                                         + strlen (m->value) + 2));
        !          5791:                sprintf (environ[mcnt], "%s=%s", m->name, m->value);
        !          5792:              }
        !          5793:            ++mcnt;
        !          5794:          }
        !          5795:       }
        !          5796: 
        !          5797:   environ[mcnt] = xmalloc (50);
        !          5798:   sprintf (environ[mcnt], "MAKELEVEL=%d", makelevel + 1);
        !          5799: 
        !          5800:   environ[mcnt + 1] = 0;
        !          5801: 
        !          5802:   free_env = 1;
        !          5803: 
        !          5804:   return;
        !          5805: }
        !          5806: 
        !          5807: /* Print N spaces.  */
        !          5808: 
        !          5809: static void
        !          5810: print_spaces (n)
        !          5811:      register int n;
        !          5812: {
        !          5813:   while (n-- > 0)
        !          5814:     putchar (' ');
        !          5815: }
        !          5816: 
        !          5817: /* Return the mtime of a file, given a struct file.
        !          5818:    Caches the time in the struct file to avoid excess stat calls.
        !          5819:    If the file is not found, VPATH searching and replacement
        !          5820:    is done.  If that fails, a library (-lLIBNAME) is tried but
        !          5821:    the library's actual name (/lib/libLIBNAME.a, etc.) is not
        !          5822:    substituted in.  */
        !          5823: 
        !          5824: static long
        !          5825: f_mtime (file)
        !          5826:      register struct file *file;
        !          5827: {
        !          5828:   register long mtime;
        !          5829: 
        !          5830:   if (file->last_mtime != 0L)
        !          5831:     return (file->last_mtime);
        !          5832: 
        !          5833:   /* File's mtime is not known; must get it now from system.  */
        !          5834: 
        !          5835:   mtime = name_mtime (file->name);
        !          5836: 
        !          5837:   if (mtime == -1L)
        !          5838:     {
        !          5839:       /* If the stat failed, search VPATH.  */
        !          5840:       if (vpath_search (&(file->name), (char *) 0, 0))
        !          5841:        mtime = name_mtime (file->name);
        !          5842:       else
        !          5843:        /* Last resort, is it a library (-lxxx)?  */
        !          5844:        if (file->name[0] == '-' && file->name[1] == 'l')
        !          5845:          mtime = library_file_mtime (&file->name[2]);
        !          5846:     }
        !          5847: 
        !          5848:   /* Store the mtime into all the entries for this file.  */
        !          5849: 
        !          5850:   while (file)
        !          5851:     {
        !          5852:       file->last_mtime = mtime;
        !          5853:       file = file->prev;
        !          5854:     }
        !          5855:   return (mtime);
        !          5856: }
        !          5857: 
        !          5858: static long
        !          5859: name_mtime (name)
        !          5860:      register char *name;
        !          5861: {
        !          5862:   struct stat st;
        !          5863: 
        !          5864:   if (ar_name (name))
        !          5865:     return (ar_member_date (name));
        !          5866: 
        !          5867:   if (stat (name, &st) < 0)
        !          5868:     return (-1L);
        !          5869:   return (st.st_mtime);
        !          5870: }
        !          5871: 
        !          5872: /* Read the directory named DIRNAME and enter all of its files
        !          5873:    in the dir_hash_table.
        !          5874: 
        !          5875:    Once a directory's files have been entered,
        !          5876:    `dir_file_exists_p' may be used to check the existence
        !          5877:    of any file in that directory.  */
        !          5878: 
        !          5879: static void
        !          5880: dir_load (dirname)
        !          5881:      char *dirname;
        !          5882: {
        !          5883:   register DIR *reading;
        !          5884:   register struct direct *next;
        !          5885:   int dirhash;
        !          5886:   register char *ptr;
        !          5887: 
        !          5888:   /* Copy dirname so we can make the hash table entries
        !          5889:      point at something that will never be freed.  */
        !          5890:   dirname = savestring (dirname, strlen (dirname));
        !          5891: 
        !          5892:   /* Compute hash code of the dir name.
        !          5893:      This is the starting point for hashing each file name.  */
        !          5894: 
        !          5895:   dirhash = 0;
        !          5896:   ptr = dirname;
        !          5897:   while (*ptr)
        !          5898:     {
        !          5899:       dirhash += *ptr++;
        !          5900:       dirhash = (dirhash << 7) + (dirhash >> 20);
        !          5901:     }
        !          5902: 
        !          5903:   /* Make a hash table entry for this dir name and no filename,
        !          5904:      to indicate that `dir_load' has been called for this dir.  */
        !          5905:   {
        !          5906:     register int hash;
        !          5907:     register struct dirdata *new;
        !          5908: 
        !          5909:     /* Compute hash code of this dir name.  */
        !          5910:     hash = dirhash;
        !          5911:     hash &= 0xffffff;
        !          5912:     hash %= DIR_HASH_SIZE;
        !          5913: 
        !          5914:     /* Add an entry to the hash table.  */
        !          5915: 
        !          5916:     new = (struct dirdata *) xmalloc (sizeof (struct dirdata));
        !          5917:     new->next = dir_hash_table[hash];
        !          5918:     dir_hash_table[hash] = new;
        !          5919:     new->dir = dirname;
        !          5920:     new->name = "";
        !          5921:     new->impossible = 0;
        !          5922:   }
        !          5923: 
        !          5924:   /* Open the directory and check for errors.  */
        !          5925:   reading = opendir (dirname);
        !          5926:   if (reading == 0)
        !          5927:     return;
        !          5928: 
        !          5929:   /* Read the directory entries, and insert the subfiles
        !          5930:      into the `files' table.  */
        !          5931: 
        !          5932:   while (next = readdir (reading))
        !          5933:     {
        !          5934:       register int hash;
        !          5935:       register struct dirdata *new;
        !          5936: 
        !          5937:       /* Compute hash code of this file name and dir name.  */
        !          5938:       hash = dirhash;
        !          5939:       ptr = next->d_name;
        !          5940:       while (*ptr)
        !          5941:        {
        !          5942:          hash += *ptr++;
        !          5943:          hash = (hash << 7) + (hash >> 20);
        !          5944:        }
        !          5945: 
        !          5946:       hash &= 0xffffff;
        !          5947:       hash %= DIR_HASH_SIZE;
        !          5948: 
        !          5949:       /* Add an entry to the hash table.  */
        !          5950: 
        !          5951:       new = (struct dirdata *) xmalloc (sizeof (struct dirdata));
        !          5952:       new->next = dir_hash_table[hash];
        !          5953:       dir_hash_table[hash] = new;
        !          5954:       new->dir = dirname;
        !          5955:       new->name = savestring (next->d_name, strlen (next->d_name));
        !          5956:       new->impossible = 0;
        !          5957:     }
        !          5958: 
        !          5959:   closedir (reading);
        !          5960: }
        !          5961: 
        !          5962: /* Return 1 if the file named NAME exists.
        !          5963:    This could work simply by using `access' or
        !          5964:    by calling `name_mtime', but those ways are too slow.
        !          5965:    Instead, the first inquiry about any particular directory
        !          5966:    records the entire contents of that directory in `dir_hash_table'
        !          5967:    and all inquiries work by checking the table.  */
        !          5968: 
        !          5969: static int
        !          5970: file_exists_p (name)
        !          5971:      register char *name;
        !          5972: {
        !          5973:   char *dirend;
        !          5974:   char *dirname;
        !          5975: 
        !          5976:   if (ar_name (name))
        !          5977:     return (ar_member_date (name) > 0);
        !          5978: 
        !          5979:   dirend = (char *) rindex (name, '/');
        !          5980:   if (dirend == 0)
        !          5981:     return dir_file_exists_p (".", name);
        !          5982: 
        !          5983:   dirname = (char *) alloca (dirend - name + 1);
        !          5984:   bcopy (name, dirname, dirend - name);
        !          5985:   dirname[dirend - name] = '\0';
        !          5986:   if (!dir_file_exists_p (dirname, ""))
        !          5987:     dir_load (dirname);
        !          5988:   return dir_file_exists_p (dirname, dirend + 1);
        !          5989: }
        !          5990: 
        !          5991: char *dir_name ();
        !          5992: 
        !          5993: /* Marks FILENAME as `impossible' for `file_impossible_p'.
        !          5994:    This means an attempt has been made to search for FILENAME
        !          5995:    as an intermediate file, and it has failed.  */
        !          5996: 
        !          5997: static void
        !          5998: file_impossible (filename)
        !          5999:      char *filename;
        !          6000: {
        !          6001:   register char *name = filename;
        !          6002:   register int hash = 0;
        !          6003:   char *dirend;
        !          6004:   register struct dirdata *new;
        !          6005: 
        !          6006:   dirend = (char *) rindex (name, '/');
        !          6007: 
        !          6008:   while (dirend ? name < dirend : *name)
        !          6009:     {
        !          6010:       hash += *name++;
        !          6011:       hash = (hash << 7) + (hash >> 20);
        !          6012:     }
        !          6013: 
        !          6014:   if (dirend != 0)
        !          6015:     for (name = ++dirend; *name; ++name)
        !          6016:       {
        !          6017:        hash += *name;
        !          6018:        hash = (hash << 7) + (hash >> 20);
        !          6019:       }
        !          6020: 
        !          6021:   hash &= 0xffffff;
        !          6022:   hash %= DIR_HASH_SIZE;
        !          6023: 
        !          6024:   new = (struct dirdata *) xmalloc (sizeof (struct dirdata));
        !          6025:   if (dirend != 0)
        !          6026:     {
        !          6027:       --dirend;
        !          6028:       *dirend = '\0';
        !          6029:       new->dir = dir_name (filename);
        !          6030:       *dirend = '/';
        !          6031:       ++dirend;
        !          6032:       new->name = savestring (dirend, strlen (dirend));
        !          6033:     }
        !          6034:   else
        !          6035:     {
        !          6036:       new->dir = dir_name (".");
        !          6037:       new->name = savestring (filename, strlen (filename));
        !          6038:     }
        !          6039:   new->impossible = 1;
        !          6040: 
        !          6041:   /* Now put this entry in the table.  */
        !          6042: 
        !          6043:   new->next = dir_hash_table[hash];
        !          6044:   dir_hash_table[hash] = new;
        !          6045: }
        !          6046: 
        !          6047: /* Returns 1 if FILENAME has been marked impossible.  */
        !          6048: 
        !          6049: static int
        !          6050: file_impossible_p (filename)
        !          6051:      char *filename;
        !          6052: {
        !          6053:   register char *name = filename;
        !          6054:   register int hash = 0;
        !          6055:   char *dirend;
        !          6056:   register struct dirdata *next;
        !          6057: 
        !          6058:   dirend = (char *) rindex (name, '/');
        !          6059: 
        !          6060:   while (dirend ? name < dirend : *name)
        !          6061:     {
        !          6062:       hash += *name++;
        !          6063:       hash = (hash << 7) + (hash >> 20);
        !          6064:     }
        !          6065: 
        !          6066:   if (dirend != 0)
        !          6067:     for (name = ++dirend; *name; ++name)
        !          6068:       {
        !          6069:        hash += *name;
        !          6070:        hash = (hash << 7) + (hash >> 20);
        !          6071:       }
        !          6072: 
        !          6073:   hash &= 0xffffff;
        !          6074:   hash %= DIR_HASH_SIZE;
        !          6075: 
        !          6076:   for (next = dir_hash_table[hash]; next != 0; next = next->next)
        !          6077:     if (dirend != 0)
        !          6078:       {
        !          6079:        if (streq (next->name, dirend)
        !          6080:            && !strncmp (next->dir, filename, dirend - filename - 1))
        !          6081:          return (next->impossible);
        !          6082:       }
        !          6083:     else if (next->dir[0] == '.' && next->dir[1] == '\0'
        !          6084:              && streq (filename, next->name))
        !          6085:       return (next->impossible);
        !          6086: 
        !          6087:   return (0);
        !          6088: }
        !          6089: 
        !          6090: /* Return 1 if the name FILENAME in directory DIRNAME
        !          6091:    is entered in the dir hash table.
        !          6092:    FILENAME must contain no slashes.
        !          6093: 
        !          6094:    If the directory has been loaded and the value is 0,
        !          6095:    then the file did not exist.
        !          6096: 
        !          6097:    To see if a directory is described by the table,
        !          6098:    call with "." for FILENAME.  */
        !          6099: 
        !          6100: static int
        !          6101: dir_file_exists_p (dirname, filename)
        !          6102:      register char *dirname;
        !          6103:      register char *filename;
        !          6104: {
        !          6105:   register int hash;
        !          6106:   register char *ptr;
        !          6107:   register struct dirdata *next;
        !          6108: 
        !          6109:   hash = 0;
        !          6110:   ptr = dirname;
        !          6111:   while (*ptr)
        !          6112:     {
        !          6113:       hash += *ptr++;
        !          6114:       hash = (hash << 7) + (hash >> 20);
        !          6115:     }
        !          6116:   ptr = filename;
        !          6117:   while (*ptr)
        !          6118:     {
        !          6119:       hash += *ptr++;
        !          6120:       hash = (hash << 7) + (hash >> 20);
        !          6121:     }
        !          6122: 
        !          6123:   hash &= 0xffffff;
        !          6124:   hash %= DIR_HASH_SIZE;
        !          6125: 
        !          6126:   for (next = dir_hash_table[hash]; next != 0; next = next->next)
        !          6127:     if (streq (next->name, filename) && streq (next->dir, dirname))
        !          6128:       return !next->impossible;
        !          6129:   return 0;
        !          6130: }
        !          6131: 
        !          6132: /* Return the already allocated name in the directory hash table
        !          6133:    that matches DIR.  The lookup should be fast and never fail
        !          6134:    because this routine is called after a dir_load () or
        !          6135:    dir_file_exists_p () call.  */
        !          6136: 
        !          6137: static char *
        !          6138: dir_name (dir)
        !          6139:      char *dir;
        !          6140: {
        !          6141:   register int hash;
        !          6142:   register char *ptr;
        !          6143:   register struct dirdata *next;
        !          6144: 
        !          6145:   hash = 0;
        !          6146:   ptr = dir;
        !          6147:   while (*ptr)
        !          6148:     {
        !          6149:       hash += *ptr++;
        !          6150:       hash = (hash << 7) + (hash >> 20);
        !          6151:     }
        !          6152: 
        !          6153:   hash &= 0xffffff;
        !          6154:   hash %= DIR_HASH_SIZE;
        !          6155: 
        !          6156:   for (next = dir_hash_table[hash]; next != 0; next = next->next)
        !          6157:     if (streq (next->dir, dir))
        !          6158:       return (next->dir);
        !          6159: 
        !          6160:   /* "Things are getting strange.  Perhaps you'd better quit --More--"  */
        !          6161:   fflush (stdout);
        !          6162:   fflush (stderr);
        !          6163:   abort ();
        !          6164:   return (0);
        !          6165: }
        !          6166: 
        !          6167: int selective_vpath_search ();
        !          6168: 
        !          6169: /* Reverse the chain of selective VPATH lists so they
        !          6170:    will be searched in the order given in the makefiles
        !          6171:    and construct the list from the VPATH macro.  */
        !          6172: 
        !          6173: static void
        !          6174: build_vpath_lists ()
        !          6175: {
        !          6176:   register struct vpath *new = 0;
        !          6177:   register struct vpath *old, *nexto;
        !          6178:   register struct macro *m;
        !          6179: 
        !          6180:   /* Reverse the chain.  */
        !          6181:   for (old = vpaths; old != 0; old = nexto)
        !          6182:     {
        !          6183:       nexto = old->next;
        !          6184:       old->next = new;
        !          6185:       new = old;
        !          6186:     }
        !          6187: 
        !          6188:   vpaths = new;
        !          6189: 
        !          6190:   /* If there is a VPATH macro with a nonnull value,
        !          6191:      construct the general VPATH list from it.  */
        !          6192:   m = lookup_macro ("VPATH", 5);
        !          6193:   if (m != 0 && *m->value != '\0')
        !          6194:     {
        !          6195:       general_vpath = construct_vpath_list ("%", m->value);
        !          6196:       /* It was just put into the linked list,
        !          6197:         but we don't want it there, so we must remove it.  */
        !          6198:       if (general_vpath)
        !          6199:         vpaths = general_vpath->next;
        !          6200:     }
        !          6201: }
        !          6202: 
        !          6203: 
        !          6204: /* Construct the VPATH listing for the pattern and searchpath given.
        !          6205: 
        !          6206:    This function is called to generate selective VPATH lists and also for
        !          6207:    the general VPATH list (which is in fact just a selective VPATH that
        !          6208:    is applied to everything).  The returned pointer is either put in the
        !          6209:    linked list of all selective VPATH lists or in the GENERAL_VPATH
        !          6210:    variable.
        !          6211: 
        !          6212:    If SEARCHPATH is nil, remove all previous listings with the same
        !          6213:    pattern.  If PATTERN is nil, remove all VPATH listings.
        !          6214:    Existing and readable directories that are not "." given in the
        !          6215:    searchpath separated by colons are loaded into the directory hash
        !          6216:    table if they are not there already and put in the VPATH searchpath
        !          6217:    for the given pattern with trailing slashes stripped off if present
        !          6218:    (and if the directory is not the root, "/").
        !          6219:    The length of the longest entry in the list is put in the structure as well.
        !          6220:    The address of an malloc'd structure containing the result is returned.  */
        !          6221: 
        !          6222: static struct vpath *
        !          6223: construct_vpath_list (pattern, dirpath)
        !          6224:      char *pattern, *dirpath;
        !          6225: {
        !          6226:   register unsigned elem;
        !          6227:   register char *p;
        !          6228:   register char **vpath;
        !          6229:   register unsigned maxvpath;
        !          6230:   unsigned maxelem;
        !          6231: 
        !          6232: 
        !          6233:   if (dirpath == 0)
        !          6234:     {
        !          6235:       /* Remove matching listings.  */
        !          6236:       register struct vpath *path, *lastpath;
        !          6237: 
        !          6238:       lastpath = vpaths;
        !          6239:       for (path = vpaths; path != 0; lastpath = path, path = path->next)
        !          6240:        if (pattern == 0 || streq (pattern, path->pattern))
        !          6241:          {
        !          6242:            /* Remove it from the linked list.  */
        !          6243:            if (lastpath == vpaths)
        !          6244:              vpaths = path->next;
        !          6245:            else
        !          6246:              lastpath->next = path->next;
        !          6247: 
        !          6248:            /* Free its unused storage.  */
        !          6249:            free ((char *) path->searchpath);
        !          6250:            free ((char *) path);
        !          6251:          }
        !          6252:     }
        !          6253: 
        !          6254:   /* Skip over any initial colons.  */
        !          6255:   p = dirpath;
        !          6256:   while (*p == ':')
        !          6257:     ++p;
        !          6258: 
        !          6259:   /* Figure out the maximum number of VPATH entries and
        !          6260:      put it in MAXELEM.  We start with 2, one before the
        !          6261:      first colon and one nil, the list terminator and
        !          6262:      increment our estimated number for each colon we find.  */
        !          6263:   maxelem = 2;
        !          6264:   while (*p)
        !          6265:     if (*p++ == ':')
        !          6266:       ++maxelem;
        !          6267: 
        !          6268:   vpath = (char **) xmalloc (maxelem * sizeof (char *));
        !          6269:   maxvpath = 0;
        !          6270: 
        !          6271:   elem = 0;
        !          6272:   p = dirpath;
        !          6273:   while (*p)
        !          6274:     {
        !          6275:       char *v;
        !          6276:       int len;
        !          6277: 
        !          6278:       /* Find the next entry.  */
        !          6279:       while (*p && *p == ':')
        !          6280:        ++p;
        !          6281:       if (*p == '\0')
        !          6282:        break;
        !          6283: 
        !          6284:       /* Find the end of this entry.  */
        !          6285:       v = p;
        !          6286:       while (*p && *p != ':')
        !          6287:        ++p;
        !          6288: 
        !          6289:       len = p - v;
        !          6290:       /* Make sure there's no trailing slash,
        !          6291:         but still allow "/" as a directory.  */
        !          6292:       if (len > 1 && p[-1] == '/')
        !          6293:        --len;
        !          6294: 
        !          6295:       if (len == 1 && *v == '.')
        !          6296:        continue;
        !          6297: 
        !          6298:       v = savestring (v, len);
        !          6299:       if (dir_file_exists_p (v, "."))
        !          6300:        {
        !          6301:          /* The directory is already in the directory hash table.  */
        !          6302:          vpath[elem] = dir_name (v);
        !          6303:          maxvpath = max (maxvpath, len);
        !          6304:          free (v);
        !          6305:          ++elem;
        !          6306:        }
        !          6307:       else
        !          6308:        {
        !          6309:          struct stat st;
        !          6310:          if (stat (v, &st) < 0 || (st.st_mode & S_IFMT) != S_IFDIR)
        !          6311:            /* Doesn't exist or isn't a directory.  */
        !          6312:            free (v);
        !          6313:          else
        !          6314:            {
        !          6315:              /* Exists and is a directory, so put it in the directory
        !          6316:                 hash table and the VPATH list.  */
        !          6317:              dir_load (v);
        !          6318:              vpath[elem] = dir_name (v);
        !          6319:              maxvpath = max (maxvpath, len);
        !          6320:              free (v);
        !          6321:              ++elem;
        !          6322:            }
        !          6323:        }
        !          6324:     }
        !          6325: 
        !          6326:   if (elem > 0)
        !          6327:     {
        !          6328:       struct vpath *path;
        !          6329:       /* ELEM is now incremented one element past the last
        !          6330:         entry, to where the nil-pointer terminator goes.
        !          6331:         Usually this is maxelem - 1.  If not, shrink vpath down.  */
        !          6332:       if (elem < (maxelem - 1))
        !          6333:        vpath = (char **) xrealloc ((char *) vpath,
        !          6334:                                    (elem + 1) * sizeof (char *));
        !          6335: 
        !          6336:       /* Put the nil-pointer terminator on the end of the VPATH list.  */
        !          6337:       vpath[elem] = 0;
        !          6338: 
        !          6339:       /* Construct the vpath structure and put it into the linked list.  */
        !          6340:       path = (struct vpath *) xmalloc (sizeof (struct vpath));
        !          6341:       path->searchpath = vpath;
        !          6342:       path->maxlen = maxvpath;
        !          6343:       path->next = vpaths;
        !          6344:       vpaths = path;
        !          6345: 
        !          6346:       /* Set up the members.  */
        !          6347:       path->patlen = strlen (pattern);
        !          6348:       path->pattern = savestring (pattern, path->patlen);
        !          6349:       p = index (path->pattern, '%');
        !          6350:       path->patsuffix = p == 0 ? 0 : p + 1;
        !          6351: 
        !          6352:       return path;
        !          6353:     }
        !          6354:   else
        !          6355:     {
        !          6356:       /* There were no entries, so free whatever space we allocated.  */
        !          6357:       free ((char *) vpath);
        !          6358:       return 0;
        !          6359:     }
        !          6360: }
        !          6361: 
        !          6362: 
        !          6363: /* Search the VPATH list whose pattern matches *FILE for a directory
        !          6364:    where the name pointed to by FILE exists.  If it is found, the pointer
        !          6365:    in FILE is set to the newly malloc'd name of the existing file and
        !          6366:    we return 1.  Otherwise we return 0.
        !          6367: 
        !          6368:    If DIRPREFIX is non-null, it specifies a directory prefix to be
        !          6369:    prepended to the name with VPATH directory and DPLEN
        !          6370:    is the length of this prefix.  */
        !          6371: 
        !          6372: static int
        !          6373: vpath_search (file, dirprefix, dplen)
        !          6374:      char **file;
        !          6375:      char *dirprefix;
        !          6376:      int dplen;
        !          6377: {
        !          6378:   register struct vpath *v;
        !          6379:   register int flen;
        !          6380: 
        !          6381:   /* If there are no VPATH entries or FILENAME starts at the root,
        !          6382:      there is nothing we can do.  */
        !          6383: 
        !          6384:   if (**file == '/' || (vpaths == 0 && general_vpath == 0))
        !          6385:     return 0;
        !          6386: 
        !          6387:   flen = strlen (*file);
        !          6388: 
        !          6389:   for (v = vpaths; v != 0; v = v->next)
        !          6390:     {
        !          6391:       register int i;
        !          6392: 
        !          6393:       if (v->patsuffix == 0)
        !          6394:        {
        !          6395:          if (*v->pattern != **file || !streq (v->pattern, *file))
        !          6396:            continue;
        !          6397:          else if (selective_vpath_search (v, file, dirprefix, dplen))
        !          6398:            return 1;
        !          6399:          else
        !          6400:            continue;
        !          6401:        }
        !          6402: 
        !          6403:       i = (v->patsuffix - v->pattern) - 1;
        !          6404:       if (i > 0 && i <= flen && (**file != *v->pattern
        !          6405:                                  || strncmp (*file + 1, v->pattern + 1, i - 1)))
        !          6406:        continue;
        !          6407: 
        !          6408:       i = v->patlen - i - 1;
        !          6409:       if (i > 0 && strcmp (v->patsuffix, *file + flen - i))
        !          6410:        continue;
        !          6411: 
        !          6412:       if (selective_vpath_search (v, file, dirprefix, dplen))
        !          6413:        return 1;
        !          6414:     }
        !          6415: 
        !          6416:   if (general_vpath != 0)
        !          6417:     return selective_vpath_search (general_vpath, file, dirprefix, dplen);
        !          6418:   else
        !          6419:     return 0;
        !          6420: }
        !          6421: 
        !          6422: 
        !          6423: /* Search the given VPATH list for a directory where the name pointed
        !          6424:    to by FILE exists.  If it is found, the pointer in FILE
        !          6425:    is set to the newly malloc'd name of the existing file and we return 1.
        !          6426:    Otherwise we return 0.
        !          6427: 
        !          6428:    If DIRPREFIX is non-null, it specifies a directory prefix to be
        !          6429:    prepended to the name with VPATH directory and DPLEN
        !          6430:    is the length of this prefix.  */
        !          6431: 
        !          6432: static int
        !          6433: selective_vpath_search (path, file, dirprefix, dplen)
        !          6434:      struct vpath *path;
        !          6435:      char **file;
        !          6436:      char *dirprefix;
        !          6437:      int dplen;
        !          6438: {
        !          6439:   char *name, *n;
        !          6440:   char *filename;
        !          6441:   register char **vpath = path->searchpath;
        !          6442:   int maxvpath = path->maxlen;
        !          6443:   register int i;
        !          6444:   int flen, vlen;
        !          6445:   int name_dplen;
        !          6446:   int exists;
        !          6447: 
        !          6448:   flen = strlen (*file);
        !          6449: 
        !          6450:   /* Split *FILE into a directory prefix and a name-within-directory.
        !          6451:      NAME_DPLEN gets the length of the prefix; FILENAME gets the
        !          6452:      pointer to the name-within-directory and FLEN is its length.  */
        !          6453: 
        !          6454:   n = rindex (*file, '/');
        !          6455:   name_dplen = n ? n - *file : 0;
        !          6456:   filename = name_dplen > 0 ? n + 1 : *file;
        !          6457:   if (name_dplen > 0)
        !          6458:     flen -= name_dplen + 1;
        !          6459: 
        !          6460:   /* Allocate enough space for the directory prefix, the biggest
        !          6461:      VPATH entry, a slash, the directory prefix that came with *FILE,
        !          6462:      another slash (although this one may not always be necessary),
        !          6463:      the filename, and a null terminator.  */
        !          6464:   name = (char *) alloca (dplen + maxvpath + 1 + name_dplen + 1 + flen + 1);
        !          6465: 
        !          6466:   /* Try each VPATH entry.  */
        !          6467:   for (i = 0; vpath[i] != 0; ++i)
        !          6468:     {
        !          6469:       /* Start with the directory prefix, if any,
        !          6470:         unless this VPATH element is absolute.  */
        !          6471:       if (*vpath[i] != '/' && dirprefix != 0)
        !          6472:        {
        !          6473:          bcopy (dirprefix, name, dplen);
        !          6474:          n = name + dplen;
        !          6475:        }
        !          6476:       else
        !          6477:        n = name;
        !          6478: 
        !          6479:       /* Put the next VPATH entry into NAME at N and increment N past it.  */
        !          6480:       vlen = strlen (vpath[i]);
        !          6481:       bcopy (vpath[i], n, vlen);
        !          6482:       n += vlen;
        !          6483: 
        !          6484:       /* Add the directory prefix already in *FILE.  */
        !          6485:       if (name_dplen > 0)
        !          6486:        {
        !          6487:          *n++ = '/';
        !          6488:          bcopy (*file, n, name_dplen);
        !          6489:          n += name_dplen;
        !          6490:        }
        !          6491: 
        !          6492:       /* Null-terminate the string.
        !          6493:         Now NAME is the name of the directory to look in.  */
        !          6494:       *n = '\0';
        !          6495: 
        !          6496:       /* Make sure the directory exists and we know its contents.  */
        !          6497:       if ((dirprefix != 0 || name_dplen > 0) && !dir_file_exists_p (name, "."))
        !          6498:        {
        !          6499:          struct stat st;
        !          6500:          if (stat (name, &st) < 0 || (st.st_mode & S_IFMT) != S_IFDIR)
        !          6501:            /* Doesn't exist or isn't a directory.  */
        !          6502:            continue;   /* for I  */
        !          6503:          else
        !          6504:            dir_load (name);
        !          6505:        }
        !          6506: 
        !          6507:       /* We know the directory is in the hash table now because either
        !          6508:          construct_vpath_list or the code just above put it there.
        !          6509:         Does the file we seek exist in it?  */
        !          6510: 
        !          6511:       exists = dir_file_exists_p (name, filename);
        !          6512: 
        !          6513:       /* Now add the name-within-directory at the end of NAME.  */
        !          6514: 
        !          6515:       if (n != name && n[-1] != '/')
        !          6516:        *n++ = '/';
        !          6517:       bcopy (filename, n, flen + 1);
        !          6518: 
        !          6519:       /* Is the file mentioned in the makefile?
        !          6520:         That counts as almost existing.  */
        !          6521: 
        !          6522:       if (!exists)
        !          6523:        exists = lookup_file (name) != 0;
        !          6524: 
        !          6525:       if (exists)
        !          6526:        {
        !          6527:          /* We have found a file.  */
        !          6528:          /* Store the name we found into *FILE for the caller.  */
        !          6529: 
        !          6530:          *file = savestring (name, (n - name) + flen);
        !          6531: 
        !          6532:          return 1;
        !          6533:        }
        !          6534:     }
        !          6535: 
        !          6536:   return 0;
        !          6537: }
        !          6538: 
        !          6539: /* Return the mtime of a library file specified as -lLIBNAME,
        !          6540:    searching for a suitable library file in the system library directories
        !          6541:    and the VPATH directories.  */
        !          6542: 
        !          6543: static long
        !          6544: library_file_mtime (lib)
        !          6545:      char *lib;
        !          6546: {
        !          6547:   long mtime;
        !          6548:   char *name;
        !          6549: 
        !          6550:   if (!dir_file_exists_p ("/usr/lib", "."))
        !          6551:     dir_load ("/usr/lib");
        !          6552:   if (!dir_file_exists_p ("/lib", "."))
        !          6553:     dir_load ("/lib");
        !          6554: 
        !          6555:   lib = concat ("lib", lib, ".a");
        !          6556:   name = concat ("/usr/lib/", lib, "");
        !          6557:   if (dir_file_exists_p ("/usr/lib", lib))
        !          6558:     mtime = name_mtime (name);
        !          6559:   else if (dir_file_exists_p ("/lib", lib))
        !          6560:     mtime = name_mtime (name + 4);
        !          6561:   else if (vpath_search (&lib, (char *) 0, 0))
        !          6562:     mtime = name_mtime (lib);
        !          6563: 
        !          6564:   free (lib);
        !          6565:   free (name);
        !          6566: 
        !          6567:   return (mtime);
        !          6568: }
        !          6569: 
        !          6570: /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3.  */
        !          6571: 
        !          6572: static char *
        !          6573: concat (s1, s2, s3)
        !          6574:      char *s1, *s2, *s3;
        !          6575: {
        !          6576:   register unsigned len1, len2, len3;
        !          6577:   register char *result;
        !          6578: 
        !          6579:   len1 = *s1 != '\0' ? strlen (s1) : 0;
        !          6580:   len2 = *s2 != '\0' ? strlen (s2) : 0;
        !          6581:   len3 = *s3 != '\0' ? strlen (s3) : 0;
        !          6582: 
        !          6583:   result = xmalloc (len1 + len2 + len3 + 1);
        !          6584: 
        !          6585:   if (*s1 != '\0')
        !          6586:     bcopy (s1, result, len1);
        !          6587:   if (*s2 != '\0')
        !          6588:     bcopy (s2, result + len1, len2);
        !          6589:   if (*s3 != '\0')
        !          6590:     bcopy (s3, result + len1 + len2, len3);
        !          6591:   *(result + len1 + len2 + len3) = '\0';
        !          6592: 
        !          6593:   return (result);
        !          6594: }
        !          6595: 
        !          6596: /* Print error message and exit.  */
        !          6597: 
        !          6598: /* VARARGS1 */
        !          6599: static void
        !          6600: fatal (s1, s2, s3, s4, s5)
        !          6601:      char *s1, *s2, *s3, *s4, *s5;
        !          6602: {
        !          6603:   fprintf (stderr, "%s: ", program);
        !          6604:   fprintf (stderr, s1, s2, s3, s4, s5);
        !          6605:   fputs (".  Stop.\n", stderr);
        !          6606: 
        !          6607:   if (print_directory_flag)
        !          6608:     log_working_directory (0);
        !          6609: 
        !          6610:   exit (1);
        !          6611: }
        !          6612: 
        !          6613: /* Print error message.  `s1' is printf control string, `s2' is arg for it. */
        !          6614: 
        !          6615: /* VARARGS1 */
        !          6616: 
        !          6617: static void
        !          6618: error (s1, s2)
        !          6619:      char *s1, *s2;
        !          6620: {
        !          6621:   fprintf (stderr, "%s: ", program);
        !          6622:   fprintf (stderr, s1, s2);
        !          6623:   putc ('\n', stderr);
        !          6624:   fflush (stderr);
        !          6625: }
        !          6626: 
        !          6627: static void
        !          6628: perror_with_name (str, name)
        !          6629:      char *str, *name;
        !          6630: {
        !          6631:   extern int errno, sys_nerr;
        !          6632:   extern char *sys_errlist[];
        !          6633: 
        !          6634:   fprintf (stderr, "%s: %s%s: ", program, str, name);
        !          6635:   if (errno < sys_nerr)
        !          6636:     fprintf (stderr, "%s\n", sys_errlist[errno]);
        !          6637:   else
        !          6638:     fprintf (stderr, "Unknown error %d\n", errno);
        !          6639:   fflush (stderr);
        !          6640: }
        !          6641: 
        !          6642: static void
        !          6643: pfatal_with_name (name)
        !          6644:      char *name;
        !          6645: {
        !          6646:   extern int errno, sys_nerr;
        !          6647:   extern char *sys_errlist[];
        !          6648: 
        !          6649:   if (errno < sys_nerr)
        !          6650:     fprintf (stderr, "%s: %s: %s\n", program, name, sys_errlist[errno]);
        !          6651:   else
        !          6652:     fprintf (stderr, "%s: %s: Unknown error %d\n", program, name, errno);
        !          6653: 
        !          6654:   exit (1);
        !          6655: }
        !          6656: 
        !          6657: 
        !          6658: /* Like malloc but get fatal error if memory is exhausted.  */
        !          6659: extern char *malloc (), *realloc ();
        !          6660: 
        !          6661: static char *
        !          6662: xmalloc (size)
        !          6663:      unsigned size;
        !          6664: {
        !          6665:   char *result = malloc (size);
        !          6666:   if (result == 0)
        !          6667:     fatal ("virtual memory exhausted");
        !          6668:   return (result);
        !          6669: }
        !          6670: 
        !          6671: 
        !          6672: static char *
        !          6673: xrealloc (ptr, size)
        !          6674:      char *ptr;
        !          6675:      unsigned size;
        !          6676: {
        !          6677:   char *result = realloc (ptr, size);
        !          6678:   if (result == 0)
        !          6679:     fatal ("virtual memory exhausted");
        !          6680:   return (result);
        !          6681: }
        !          6682: 
        !          6683: static char *
        !          6684: savestring (string, length)
        !          6685:      char *string;
        !          6686:      int length;
        !          6687: {
        !          6688:   register char *out = (char *) xmalloc ((unsigned) length + 1);
        !          6689:   if (length > 0) bcopy (string, out, length);
        !          6690:   out[length] = '\0';
        !          6691:   return (out);
        !          6692: }
        !          6693: 
        !          6694: /* Search string BIG (length BLEN) for an occurrence of
        !          6695:    string SMALL (length SLEN).  Return a pointer to the
        !          6696:    beginning of the first occurrence, or return nil if none found.  */
        !          6697: 
        !          6698: static char *
        !          6699: sindex (big, blen, small, slen)
        !          6700:      char *big, *small;
        !          6701:      int blen, slen;
        !          6702: {
        !          6703:   register int b;
        !          6704: 
        !          6705:   if (blen < 1)
        !          6706:     blen = strlen (big);
        !          6707:   if (slen < 1)
        !          6708:     slen = strlen (small);
        !          6709: 
        !          6710:   for (b = 0; b < blen; ++b)
        !          6711:     if (big[b] == *small && !strncmp (&big[b + 1], small + 1, slen - 1))
        !          6712:       return (&big[b]);
        !          6713: 
        !          6714:   return (0);
        !          6715: }
        !          6716: 
        !          6717: /* Limited INDEX:
        !          6718:    Search through the string STRING, which ends at LIMIT, for the character C.
        !          6719:    Returns a pointer to the first occurrence, or nil if none is found.
        !          6720:    Like INDEX except that the string searched ends where specified
        !          6721:    instead of at the first null.  */
        !          6722: 
        !          6723: static char *
        !          6724: lindex (string, limit, c)
        !          6725:      register char *string, *limit;
        !          6726:      char c;
        !          6727: {
        !          6728:   while (string != limit)
        !          6729:     if (*string++ == c)
        !          6730:       return string - 1;
        !          6731: 
        !          6732:   return 0;
        !          6733: }
        !          6734: 
        !          6735: /* Convert old-style suffix rules to pattern rules.
        !          6736:    All rules for the suffixes on the .SUFFIXES list
        !          6737:    are converted and added to the chain of pattern rules.  */
        !          6738: 
        !          6739: static void
        !          6740: convert_to_pattern ()
        !          6741: {
        !          6742:   register struct dep *d, *d2, *newd;
        !          6743:   register struct file *f;
        !          6744:   register struct rule *r;
        !          6745:   register char *rulename = (char *) alloca (maxsuffix * 2 + 1);
        !          6746:   register int slen, s2len;
        !          6747: 
        !          6748:   for (d = suffix_file->deps; d != 0; d = d->next)
        !          6749:     {
        !          6750:       slen = strlen (dep_name (d));
        !          6751:       r = (struct rule *) xmalloc (sizeof (struct rule));
        !          6752:       r->name = savestring ("%", 1 + slen);
        !          6753:       r->patsuffix = r->name + 1;
        !          6754:       bcopy (dep_name (d), r->patsuffix, slen + 1);
        !          6755:       r->namelen = strlen (r->name);
        !          6756:       r->deps = 0;
        !          6757:       r->cmds = 0;
        !          6758:       f = d->file;
        !          6759:       new_pattern_rule (r, 0);
        !          6760:       if (f->cmds && f->deps == 0)
        !          6761:        {
        !          6762:          for (r = pattern_rules; r != 0; r = r->next)
        !          6763:            if (r->name[1] == '\0' && r->deps != 0 && r->deps->next == 0
        !          6764:                && r->deps->name[0] == '%'
        !          6765:                && streq (r->deps->name + 1, dep_name (d)))
        !          6766:              break;
        !          6767:          if (r == 0)
        !          6768:            {
        !          6769:              /* Record a pattern for this suffix's null-suffix rule.  */
        !          6770:              r = (struct rule *) xmalloc (sizeof (struct rule));
        !          6771:              r->cmds = f->cmds;
        !          6772:              r->recursive = f->recursive;
        !          6773:              r->name = savestring ("%", 1);
        !          6774:              r->namelen = 1;
        !          6775:              r->patsuffix = r->name + 1;
        !          6776:              r->terminal = 0;
        !          6777:              newd = (struct dep *) xmalloc (sizeof (struct dep));
        !          6778:              newd->name = savestring ("%", 1 + slen);
        !          6779:              bcopy (dep_name (d), newd->name + 1, slen + 1);
        !          6780:              newd->next = f->deps;
        !          6781:              r->deps = newd;
        !          6782:              /* Install this rule.  */
        !          6783:              new_pattern_rule (r, 0);
        !          6784:            }
        !          6785:        }
        !          6786: 
        !          6787:       bcopy (dep_name (d), rulename, slen);
        !          6788:       /* Record a pattern for each of this suffix's
        !          6789:         two-suffix rules.  */
        !          6790:       for (d2 = suffix_file->deps; d2; d2 = d2->next)
        !          6791:        {
        !          6792:          if (streq (dep_name (d), dep_name (d2)))
        !          6793:            continue;
        !          6794: 
        !          6795:          s2len = strlen (dep_name (d2));
        !          6796:          bcopy (dep_name (d2), rulename + slen, s2len + 1);
        !          6797:          f = lookup_file (rulename);
        !          6798:          if (f == 0 || f->deps != 0)
        !          6799:            continue;
        !          6800: 
        !          6801:          for (r = pattern_rules; r != 0; r = r->next)
        !          6802:            if (r->deps && r->deps->next == 0
        !          6803:                && r->name[0] == '%' && streq (r->name + 1, dep_name (d2))
        !          6804:                && r->deps->name[0] == '%'
        !          6805:                && streq (r->deps->name + 1, dep_name (d)))
        !          6806:               break;
        !          6807:          if (r != 0)
        !          6808:            continue;
        !          6809: 
        !          6810:          r = (struct rule *) xmalloc (sizeof (struct rule));
        !          6811:          r->cmds = f->cmds;
        !          6812:          r->recursive = f->recursive;
        !          6813:          newd = (struct dep *) xmalloc (sizeof (struct dep));
        !          6814:          if (s2len == 2 && !strcmp (dep_name (d2), ".a"))
        !          6815:            {
        !          6816:              /* A suffix rule `.X.a:' is converted into
        !          6817:                 the pattern rule `(%.o): %.X'.  */
        !          6818:              r->namelen = 4;
        !          6819:              r->name = savestring ("(%.o)", 4);
        !          6820:              r->patsuffix = r->name + 2;
        !          6821:              newd->name = savestring ("%", 1 + s2len);
        !          6822:              bcopy (dep_name (d2), newd->name, s2len + 1);
        !          6823:            }
        !          6824:          else
        !          6825:            {
        !          6826:              r->namelen = 1 + s2len;
        !          6827:              r->name = savestring ("%", 1 + s2len);
        !          6828:              r->patsuffix = r->name + 1;
        !          6829:              bcopy (dep_name (d2), r->patsuffix, s2len + 1);
        !          6830:              newd->name = savestring ("%", 1 + slen);
        !          6831:              bcopy (dep_name (d), newd->name + 1, slen + 1);
        !          6832:            }
        !          6833:          newd->next = f->deps;
        !          6834:          r->deps = newd;
        !          6835:          new_pattern_rule (r, 0);
        !          6836:        }
        !          6837:     }
        !          6838: }
        !          6839: 
        !          6840: /* Install the pattern rule RULE (whose fields have been filled in)
        !          6841:    at the end of the list (so that any rules previously defined
        !          6842:    will take precedence).  If this rule duplicates a previous one
        !          6843:    (identical target and dependents), the old one is replaced
        !          6844:    if OVERRIDE is nonzero, otherwise this new one is thrown out.
        !          6845:    When an old rule is replaced, the new one is put at the end of the
        !          6846:    list.  */
        !          6847: 
        !          6848: static void
        !          6849: new_pattern_rule (rule, override)
        !          6850:      register struct rule *rule;
        !          6851:      int override;
        !          6852: {
        !          6853:   register struct rule *r, *lastrule;
        !          6854: 
        !          6855:   rule->subdir = 0;
        !          6856:   rule->in_use = 0;
        !          6857:   rule->recursive = 0;
        !          6858:   rule->terminal = 0;
        !          6859: 
        !          6860:   rule->next = 0;
        !          6861: 
        !          6862:   /* Search for an identical rule.  */
        !          6863:   lastrule = pattern_rules;
        !          6864:   for (r = pattern_rules; r != 0; lastrule = r, r = r->next)
        !          6865:     if (streq (rule->name, r->name))
        !          6866:       {
        !          6867:        register struct dep *d, *d2;
        !          6868:        for (d = rule->deps, d2 = r->deps; d && d2; d = d->next, d2 = d2->next)
        !          6869:          if (!streq (dep_name (d), dep_name (d2)))
        !          6870:            break;
        !          6871:        if (d == 0 && d2 == 0)
        !          6872:          {
        !          6873:            /* All the dependents matched.  */
        !          6874:            if (override)
        !          6875:              {
        !          6876:                /* Remove the old rule.  */
        !          6877:                if (lastrule == pattern_rules)
        !          6878:                  pattern_rules = r->next;
        !          6879:                else
        !          6880:                  lastrule->next = r->next;
        !          6881:                /* Install the new one.  */
        !          6882:                if (pattern_rules == 0)
        !          6883:                  pattern_rules = rule;
        !          6884:                else
        !          6885:                  last_pattern_rule->next = rule;
        !          6886:                last_pattern_rule = rule;
        !          6887:              }
        !          6888:            else
        !          6889:              /* The old rule stays intact.  Destroy the new one.  */
        !          6890:              r = rule;
        !          6891: 
        !          6892:            /* Free all the storage allocated for the rule being
        !          6893:               destroyed that will not be used elsewhere.  */
        !          6894:            free (r->name);
        !          6895:            if (r->deps)
        !          6896:              free ((char *) r->deps);
        !          6897:            if (r->cmds)
        !          6898:              {
        !          6899:                free (r->cmds->commands);
        !          6900:                free ((char *) r->cmds);
        !          6901:              }
        !          6902:            break;
        !          6903:          }
        !          6904:       }
        !          6905: 
        !          6906:   if (r == 0)
        !          6907:     {
        !          6908:       /* There was no rule to replace.  */
        !          6909:       if (pattern_rules == 0)
        !          6910:        pattern_rules = rule;
        !          6911:       else
        !          6912:        last_pattern_rule->next = rule;
        !          6913:       last_pattern_rule = rule;
        !          6914:     }
        !          6915: }
        !          6916: 
        !          6917: /* Install an implicit pattern rule based on the three text strings
        !          6918:    in the structure P points to.  These strings come from one of
        !          6919:    the arrays on the preceding page.
        !          6920:    TERMINAL specifies what the `terminal' field of the rule should be.  */
        !          6921: 
        !          6922: static void
        !          6923: install_pattern_rule (p, terminal)
        !          6924:      struct pspec *p;
        !          6925:      int terminal;
        !          6926: {
        !          6927:   struct rule *r;
        !          6928:   char *ptr;
        !          6929:   int cmdlen;
        !          6930: 
        !          6931:   r = (struct rule *) xmalloc (sizeof (struct rule));
        !          6932:   r->namelen = strlen (p->target);
        !          6933:   /* These will all be string literals, but we malloc space for them
        !          6934:      anyway because somebody might want to free them later.  */
        !          6935:   r->name = savestring (p->target, r->namelen);
        !          6936:   r->patsuffix = index (r->name, '%') + 1;
        !          6937: 
        !          6938:   r->terminal = terminal;
        !          6939:   ptr = p->dep;
        !          6940:   r->deps = (struct dep *) multi_glob (parse_file_seq (&ptr, '\0',
        !          6941:                                                        sizeof (struct dep)),
        !          6942:                                       sizeof (struct dep));
        !          6943:   r->cmds = (struct commands *) xmalloc (sizeof (struct commands));
        !          6944:   r->cmds->filename = 0;
        !          6945:   r->cmds->lineno = 0;
        !          6946:   cmdlen = strlen (p->commands);
        !          6947:   /* These will all be string literals, but we malloc space for them
        !          6948:      anyway because somebody might want to free them later.  */
        !          6949:   r->cmds->commands = savestring (p->commands, cmdlen);
        !          6950:   r->recursive = sindex (p->commands, cmdlen, "$(MAKE)", 7)
        !          6951:                  || sindex (p->commands, cmdlen, "${MAKE}", 7);
        !          6952: 
        !          6953:   new_pattern_rule (r, 0);
        !          6954: }
        !          6955: 
        !          6956: /* Construct the list of include directories from the
        !          6957:    arguments and the default list.  */
        !          6958: 
        !          6959: static void
        !          6960: construct_include_path (argc, argv)
        !          6961:      int argc;
        !          6962:      char **argv;
        !          6963: {
        !          6964:   register int i;
        !          6965:   struct stat stbuf;
        !          6966: 
        !          6967:   /* Table to hold the dirs, long enough for the worst case
        !          6968:      plus a null pointer at the end.  */
        !          6969: 
        !          6970:   register char **dirs
        !          6971:     = (char **) xmalloc ((unsigned) (argc
        !          6972:                          + (sizeof (default_include_directories)
        !          6973:                             / sizeof (char *)) - 1)
        !          6974:                         * sizeof (char *));
        !          6975:   /* Number of elements in DIRS currently in use.  */
        !          6976:   register int count = 0;
        !          6977: 
        !          6978:   include_directories = dirs;
        !          6979: 
        !          6980:   /* First consider any dirs specified with -I switches.
        !          6981:      Ignore dirs that don't exist.  */
        !          6982: 
        !          6983:   for (i = 0; i < argc; ++i)
        !          6984:     if (!strcmp (argv[i], "-I"))
        !          6985:       {
        !          6986:        ++i;
        !          6987:        if (argv[i] == 0)
        !          6988:          fatal ("no directory given after -I switch");
        !          6989:        if (stat (argv[i], &stbuf) == 0
        !          6990:            && (stbuf.st_mode & S_IFMT) == S_IFDIR)
        !          6991:          dirs[count++] = argv[i];
        !          6992:       }
        !          6993:     else if (!strcmp (argv[i], "-f") || !strcmp (argv[i], "-o"))
        !          6994:       ++i;
        !          6995: 
        !          6996:   /* Now add at the end the standard default dirs.  */
        !          6997: 
        !          6998:   for (i = 0; default_include_directories[i] != 0; ++i)
        !          6999:     if (stat (default_include_directories[i], &stbuf) == 0
        !          7000:        && (stbuf.st_mode & S_IFMT) == S_IFDIR)
        !          7001:       dirs[count++] = default_include_directories[i];
        !          7002: 
        !          7003:   dirs[count] = 0;
        !          7004: 
        !          7005:   /* Now compute the maximum length of any name in it.  */
        !          7006: 
        !          7007:   max_incl_len = 0;
        !          7008:   for (i = 0; i < count; ++i)
        !          7009:     {
        !          7010:       int len = strlen (dirs[i]);
        !          7011:       /* If dir name is written with a trailing slash, discard it.  */
        !          7012:       if (dirs[i][len - 1] == '/')
        !          7013:        dirs[i] = savestring (dirs[i], len - 1);
        !          7014:       max_incl_len = max (max_incl_len, len);
        !          7015:     }
        !          7016: }
        !          7017: 
        !          7018: /* Return the address of the first whitespace or null in the string S.  */
        !          7019: 
        !          7020: static char *
        !          7021: end_of_token (s)
        !          7022:      char *s;
        !          7023: {
        !          7024:   register char *p = s;
        !          7025:   register int backslash = 0;
        !          7026: 
        !          7027:   while (*p && (!backslash && (*p != ' ' && *p != '\t')))
        !          7028:     {
        !          7029:       if (*p++ == '\\')
        !          7030:        {
        !          7031:          backslash = !backslash;
        !          7032:          while (*p == '/')
        !          7033:            {
        !          7034:              backslash = !backslash;
        !          7035:              ++p;
        !          7036:            }
        !          7037:        }
        !          7038:       else
        !          7039:        backslash = 0;
        !          7040:     }
        !          7041: 
        !          7042:   return p;
        !          7043: }
        !          7044: 
        !          7045: /* Return the address of the first nonwhitespace or null in the string S.  */
        !          7046: 
        !          7047: static char *
        !          7048: next_token (s)
        !          7049:      char *s;
        !          7050: {
        !          7051:   register char *p = s;
        !          7052: 
        !          7053:   while (*p == ' ' || *p == '\t') ++p;
        !          7054:   return p;
        !          7055: }
        !          7056: 
        !          7057: /* Find the next token in PTR; return the address of it,
        !          7058:    and store the length of the token into *LENGTHPTR.  */
        !          7059: 
        !          7060: static char *
        !          7061: find_next_token (ptr, lengthptr)
        !          7062:      char **ptr;
        !          7063:      int *lengthptr;
        !          7064: {
        !          7065:   char *p = next_token (*ptr);
        !          7066:   char *end;
        !          7067: 
        !          7068:   if (*p == '\0')
        !          7069:     return 0;
        !          7070: 
        !          7071:   *ptr = end = end_of_token (p);
        !          7072:   *lengthptr = end - p;
        !          7073:   return p;
        !          7074: }
        !          7075: 
        !          7076: /* Scan a string and find the whitespace-separated tokens composing it.
        !          7077:    wstok (S) specifies the string to scan, and returns the address of the
        !          7078:    first token.  wstok (0) gets the next token.  Repeat wstok (0) until
        !          7079:    the tokens are exhausted, which is indicated by a value of zero.
        !          7080: 
        !          7081:    The token that is returned is made into a null-terminated string
        !          7082:    by storing a zero at the end of it.  The following call to wstok
        !          7083:    restores the original contents of that character.  */
        !          7084: 
        !          7085: char *wstok_last_token_end;    /* Address of end of last token, now a null */
        !          7086: char wstok_saved_end_char;     /* Previous contents of that char */
        !          7087: 
        !          7088: static char *
        !          7089: wstok (s)
        !          7090:      char *s;
        !          7091: {
        !          7092:   char *beg;
        !          7093:   int length;
        !          7094: 
        !          7095:   if (s != 0)
        !          7096:     wstok_last_token_end = s;
        !          7097:   else
        !          7098:     *wstok_last_token_end = wstok_saved_end_char;
        !          7099: 
        !          7100:   beg = find_next_token (&wstok_last_token_end, &length);
        !          7101:   wstok_saved_end_char = *wstok_last_token_end;
        !          7102:   *wstok_last_token_end = '\0';
        !          7103: 
        !          7104:   return beg;
        !          7105: }
        !          7106: 
        !          7107: /* Write a message indicating that we've just entered or
        !          7108:    left (according to ENTERING) the current directory.  */
        !          7109: 
        !          7110: static void
        !          7111: log_working_directory (entering)
        !          7112:      int entering;
        !          7113: {
        !          7114:   char pwdbuf[MAXPATHLEN];
        !          7115:   char *message = entering ? "Entering" : "Leaving";
        !          7116: 
        !          7117:   if (getwd (pwdbuf) == 0)
        !          7118:     printf ("%s: %s an unknown directory (getwd: %s)\n",
        !          7119:            program, message, pwdbuf);
        !          7120:   else
        !          7121:     printf ("%s: %s directory `%s'\n", program, message, pwdbuf);
        !          7122: }
        !          7123: 
        !          7124: #if 0  /* dummy tags for etags */
        !          7125: fmt (){}
        !          7126: formatting (){}
        !          7127: #endif
        !          7128: 
        !          7129: /* Emacs C-mode formatting variables.
        !          7130:    These are actually the defaults, but they're not what the maintainer uses.
        !          7131:    Local Variables:
        !          7132:    c-argdecl-indent: 5
        !          7133:    c-brace-imaginary-offset: 0
        !          7134:    c-brace-offset: 0
        !          7135:    c-continued-brace-offset: 0
        !          7136:    c-continued-statement-offset: 2
        !          7137:    c-indent-level: 2
        !          7138:    c-label-offset: -2
        !          7139:    End:
        !          7140:  */

unix.superglobalmegacorp.com