1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman * *
3*b30d1939SAndy Fiddaman * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1990-2011 AT&T Intellectual Property *
5*b30d1939SAndy Fiddaman * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
7*b30d1939SAndy Fiddaman * by AT&T Intellectual Property *
8*b30d1939SAndy Fiddaman * *
9*b30d1939SAndy Fiddaman * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12*b30d1939SAndy Fiddaman * *
13*b30d1939SAndy Fiddaman * Information and Software Systems Research *
14*b30d1939SAndy Fiddaman * AT&T Research *
15*b30d1939SAndy Fiddaman * Florham Park NJ *
16*b30d1939SAndy Fiddaman * *
17*b30d1939SAndy Fiddaman * Glenn Fowler <gsf@research.att.com> *
18*b30d1939SAndy Fiddaman * *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman
22*b30d1939SAndy Fiddaman /*
23*b30d1939SAndy Fiddaman * mamake -- MAM make
24*b30d1939SAndy Fiddaman *
25*b30d1939SAndy Fiddaman * coded for portability
26*b30d1939SAndy Fiddaman */
27*b30d1939SAndy Fiddaman
28*b30d1939SAndy Fiddaman static char id[] = "\n@(#)$Id: mamake (AT&T Research) 2011-08-31 $\0\n";
29*b30d1939SAndy Fiddaman
30*b30d1939SAndy Fiddaman #if _PACKAGE_ast
31*b30d1939SAndy Fiddaman
32*b30d1939SAndy Fiddaman #include <ast.h>
33*b30d1939SAndy Fiddaman #include <error.h>
34*b30d1939SAndy Fiddaman
35*b30d1939SAndy Fiddaman static const char usage[] =
36*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: mamake (AT&T Research) 2011-08-31 $\n]"
37*b30d1939SAndy Fiddaman USAGE_LICENSE
38*b30d1939SAndy Fiddaman "[+NAME?mamake - make abstract machine make]"
39*b30d1939SAndy Fiddaman "[+DESCRIPTION?\bmamake\b reads \amake abstract machine\a target and"
40*b30d1939SAndy Fiddaman " prerequisite file descriptions from a mamfile (see \b-f\b) and executes"
41*b30d1939SAndy Fiddaman " actions to update targets that are older than their prerequisites."
42*b30d1939SAndy Fiddaman " Mamfiles are generated by the \b--mam\b option of \bnmake\b(1) and"
43*b30d1939SAndy Fiddaman " \bgmake\b(1) and are portable to environments that only have"
44*b30d1939SAndy Fiddaman " \bsh\b(1) and \bcc\b(1).]"
45*b30d1939SAndy Fiddaman "[+?In practice \bmamake\b is used to bootstrap build \bnmake\b(1) and"
46*b30d1939SAndy Fiddaman " \bksh\b(1) in new environments. Mamfiles are used rather than"
47*b30d1939SAndy Fiddaman " old-\bmake\b makefiles because some features are not reliably supported"
48*b30d1939SAndy Fiddaman " across all \bmake\b variants:]{"
49*b30d1939SAndy Fiddaman " [+action execution?Multi-line actions are executed as a"
50*b30d1939SAndy Fiddaman " unit by \b$SHELL\b. There are some shell constructs"
51*b30d1939SAndy Fiddaman " that cannot be expressed in an old-\bmake\b makefile.]"
52*b30d1939SAndy Fiddaman " [+viewpathing?\bVPATH\b is properly interpreted. This allows"
53*b30d1939SAndy Fiddaman " source to be separate from generated files.]"
54*b30d1939SAndy Fiddaman " [+recursion?Ordered subdirectory recursion over unrelated"
55*b30d1939SAndy Fiddaman " makefiles.]"
56*b30d1939SAndy Fiddaman " }"
57*b30d1939SAndy Fiddaman "[+?\bmamprobe\b(1) is called to probe and generate system specific variable"
58*b30d1939SAndy Fiddaman " definitions. The probe information is regenerated when it is older"
59*b30d1939SAndy Fiddaman " than the \bmamprobe\b command.]"
60*b30d1939SAndy Fiddaman "[+?For compatibility with \bnmake\b(1) the \b-K\b option and the"
61*b30d1939SAndy Fiddaman " \brecurse\b and \bcc-*\b command line targets are ignored.]"
62*b30d1939SAndy Fiddaman "[e:?Explain reason for triggering action. Ignored if -F is on.]"
63*b30d1939SAndy Fiddaman "[f:?Read \afile\a instead of the default.]:[file:=Mamfile]"
64*b30d1939SAndy Fiddaman "[i:?Ignore action errors.]"
65*b30d1939SAndy Fiddaman "[k:?Continue after error with sibling prerequisites.]"
66*b30d1939SAndy Fiddaman "[n:?Print actions but do not execute. Recursion actions (see \b-r\b) are still"
67*b30d1939SAndy Fiddaman " executed. Use \b-N\b to disable recursion actions too.]"
68*b30d1939SAndy Fiddaman "[r:?Recursively make leaf directories matching \apattern\a. Only leaf"
69*b30d1939SAndy Fiddaman " directories containing a makefile named \bNmakefile\b, \bnmakefile\b,"
70*b30d1939SAndy Fiddaman " \bMakefile\b or \bmakefile\b are considered. The first makefile"
71*b30d1939SAndy Fiddaman " found in each leaf directory is scanned for leaf directory"
72*b30d1939SAndy Fiddaman " prerequisites; the recusion order is determined by a topological sort"
73*b30d1939SAndy Fiddaman " of these prerequisites.]:[pattern]"
74*b30d1939SAndy Fiddaman "[C:?Do all work in \adirectory\a. All messages will mention"
75*b30d1939SAndy Fiddaman " \adirectory\a.]:[directory]"
76*b30d1939SAndy Fiddaman "[D:?Set the debug trace level to \alevel\a. Higher levels produce more"
77*b30d1939SAndy Fiddaman " output.]#[level]"
78*b30d1939SAndy Fiddaman "[F:?Force all targets to be out of date.]"
79*b30d1939SAndy Fiddaman "[K:?Ignored.]"
80*b30d1939SAndy Fiddaman "[N:?Like \b-n\b but recursion actions (see \b-r\b) are also disabled.]"
81*b30d1939SAndy Fiddaman "[V:?Print the program version and exit.]"
82*b30d1939SAndy Fiddaman "[G:debug-symbols?Compile and link with debugging symbol options enabled.]"
83*b30d1939SAndy Fiddaman "[S:strip-symbols?Strip link-time static symbols from executables.]"
84*b30d1939SAndy Fiddaman
85*b30d1939SAndy Fiddaman "\n"
86*b30d1939SAndy Fiddaman "\n[ target ... ] [ name=value ... ]\n"
87*b30d1939SAndy Fiddaman "\n"
88*b30d1939SAndy Fiddaman
89*b30d1939SAndy Fiddaman "[+SEE ALSO?\bgmake\b(1), \bmake\b(1), \bmamprobe\b(1),"
90*b30d1939SAndy Fiddaman " \bnmake\b(1), \bsh\b(1)]"
91*b30d1939SAndy Fiddaman ;
92*b30d1939SAndy Fiddaman
93*b30d1939SAndy Fiddaman #else
94*b30d1939SAndy Fiddaman
95*b30d1939SAndy Fiddaman #define elementsof(x) (sizeof(x)/sizeof(x[0]))
96*b30d1939SAndy Fiddaman #define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
97*b30d1939SAndy Fiddaman
98*b30d1939SAndy Fiddaman #define NiL ((char*)0)
99*b30d1939SAndy Fiddaman
100*b30d1939SAndy Fiddaman #endif
101*b30d1939SAndy Fiddaman
102*b30d1939SAndy Fiddaman #include <stdio.h>
103*b30d1939SAndy Fiddaman #include <unistd.h>
104*b30d1939SAndy Fiddaman #include <ctype.h>
105*b30d1939SAndy Fiddaman #include <sys/types.h>
106*b30d1939SAndy Fiddaman #include <sys/stat.h>
107*b30d1939SAndy Fiddaman #include <time.h>
108*b30d1939SAndy Fiddaman
109*b30d1939SAndy Fiddaman #if !_PACKAGE_ast && defined(__STDC__)
110*b30d1939SAndy Fiddaman #include <stdlib.h>
111*b30d1939SAndy Fiddaman #include <string.h>
112*b30d1939SAndy Fiddaman #endif
113*b30d1939SAndy Fiddaman
114*b30d1939SAndy Fiddaman #define delimiter(c) ((c)==' '||(c)=='\t'||(c)=='\n'||(c)==';'||(c)=='('||(c)==')'||(c)=='`'||(c)=='|'||(c)=='&'||(c)=='=')
115*b30d1939SAndy Fiddaman
116*b30d1939SAndy Fiddaman #define add(b,c) (((b)->nxt >= (b)->end) ? append(b, "") : NiL, *(b)->nxt++ = (c))
117*b30d1939SAndy Fiddaman #define get(b) ((b)->nxt-(b)->buf)
118*b30d1939SAndy Fiddaman #define set(b,o) ((b)->nxt=(b)->buf+(o))
119*b30d1939SAndy Fiddaman #define use(b) (*(b)->nxt=0,(b)->nxt=(b)->buf)
120*b30d1939SAndy Fiddaman
121*b30d1939SAndy Fiddaman #define CHUNK 1024
122*b30d1939SAndy Fiddaman #define KEY(a,b,c,d) ((((unsigned long)(a))<<15)|(((unsigned long)(b))<<10)|(((unsigned long)(c))<<5)|(((unsigned long)(d))))
123*b30d1939SAndy Fiddaman #define NOW ((unsigned long)time((time_t*)0))
124*b30d1939SAndy Fiddaman #define ROTATE(p,l,r,t) ((t)=(p)->l,(p)->l=(t)->r,(t)->r=(p),(p)=(t))
125*b30d1939SAndy Fiddaman
126*b30d1939SAndy Fiddaman #define RULE_active 0x0001 /* active target */
127*b30d1939SAndy Fiddaman #define RULE_dontcare 0x0002 /* ok if not found */
128*b30d1939SAndy Fiddaman #define RULE_error 0x0004 /* not found or not generated */
129*b30d1939SAndy Fiddaman #define RULE_exists 0x0008 /* target file exists */
130*b30d1939SAndy Fiddaman #define RULE_generated 0x0010 /* generated target */
131*b30d1939SAndy Fiddaman #define RULE_ignore 0x0020 /* ignore time */
132*b30d1939SAndy Fiddaman #define RULE_implicit 0x0040 /* implicit prerequisite */
133*b30d1939SAndy Fiddaman #define RULE_made 0x0080 /* already made */
134*b30d1939SAndy Fiddaman #define RULE_virtual 0x0100 /* not a file */
135*b30d1939SAndy Fiddaman
136*b30d1939SAndy Fiddaman #define STREAM_KEEP 0x0001 /* don't fclose() on pop() */
137*b30d1939SAndy Fiddaman #define STREAM_MUST 0x0002 /* push() file must exist */
138*b30d1939SAndy Fiddaman #define STREAM_PIPE 0x0004 /* pclose() on pop() */
139*b30d1939SAndy Fiddaman
140*b30d1939SAndy Fiddaman #ifndef S_IXUSR
141*b30d1939SAndy Fiddaman #define S_IXUSR 0100 /* owner execute permission */
142*b30d1939SAndy Fiddaman #endif
143*b30d1939SAndy Fiddaman #ifndef S_IXGRP
144*b30d1939SAndy Fiddaman #define S_IXGRP 0010 /* group execute permission */
145*b30d1939SAndy Fiddaman #endif
146*b30d1939SAndy Fiddaman #ifndef S_IXOTH
147*b30d1939SAndy Fiddaman #define S_IXOTH 0001 /* other execute permission */
148*b30d1939SAndy Fiddaman #endif
149*b30d1939SAndy Fiddaman
150*b30d1939SAndy Fiddaman struct Rule_s;
151*b30d1939SAndy Fiddaman
152*b30d1939SAndy Fiddaman typedef struct stat Stat_t;
153*b30d1939SAndy Fiddaman typedef FILE Stdio_t;
154*b30d1939SAndy Fiddaman
155*b30d1939SAndy Fiddaman typedef struct Buf_s /* buffer stream */
156*b30d1939SAndy Fiddaman {
157*b30d1939SAndy Fiddaman struct Buf_s* old; /* next dropped buffer */
158*b30d1939SAndy Fiddaman char* end; /* 1 past end of buffer */
159*b30d1939SAndy Fiddaman char* nxt; /* next char to add */
160*b30d1939SAndy Fiddaman char* buf; /* buffer space */
161*b30d1939SAndy Fiddaman } Buf_t;
162*b30d1939SAndy Fiddaman
163*b30d1939SAndy Fiddaman typedef struct Dict_item_s /* dictionary item */
164*b30d1939SAndy Fiddaman {
165*b30d1939SAndy Fiddaman struct Dict_item_s* left; /* left child */
166*b30d1939SAndy Fiddaman struct Dict_item_s* right; /* right child */
167*b30d1939SAndy Fiddaman void* value; /* user defined value */
168*b30d1939SAndy Fiddaman char name[1];/* 0 terminated name */
169*b30d1939SAndy Fiddaman } Dict_item_t;
170*b30d1939SAndy Fiddaman
171*b30d1939SAndy Fiddaman typedef struct Dict_s /* dictionary handle */
172*b30d1939SAndy Fiddaman {
173*b30d1939SAndy Fiddaman Dict_item_t* root; /* root item */
174*b30d1939SAndy Fiddaman } Dict_t;
175*b30d1939SAndy Fiddaman
176*b30d1939SAndy Fiddaman typedef struct List_s /* Rule_t list */
177*b30d1939SAndy Fiddaman {
178*b30d1939SAndy Fiddaman struct List_s* next; /* next in list */
179*b30d1939SAndy Fiddaman struct Rule_s* rule; /* list item */
180*b30d1939SAndy Fiddaman } List_t;
181*b30d1939SAndy Fiddaman
182*b30d1939SAndy Fiddaman typedef struct Rule_s /* rule item */
183*b30d1939SAndy Fiddaman {
184*b30d1939SAndy Fiddaman char* name; /* unbound name */
185*b30d1939SAndy Fiddaman char* path; /* bound path */
186*b30d1939SAndy Fiddaman List_t* prereqs; /* prerequisites */
187*b30d1939SAndy Fiddaman struct Rule_s* leaf; /* recursion leaf alias */
188*b30d1939SAndy Fiddaman int flags; /* RULE_* flags */
189*b30d1939SAndy Fiddaman int making; /* currently make()ing */
190*b30d1939SAndy Fiddaman unsigned long time; /* modification time */
191*b30d1939SAndy Fiddaman } Rule_t;
192*b30d1939SAndy Fiddaman
193*b30d1939SAndy Fiddaman typedef struct Stream_s /* input file stream stack */
194*b30d1939SAndy Fiddaman {
195*b30d1939SAndy Fiddaman Stdio_t* fp; /* read stream */
196*b30d1939SAndy Fiddaman char* file; /* stream path */
197*b30d1939SAndy Fiddaman unsigned long line; /* stream line */
198*b30d1939SAndy Fiddaman int flags; /* stream flags */
199*b30d1939SAndy Fiddaman } Stream_t;
200*b30d1939SAndy Fiddaman
201*b30d1939SAndy Fiddaman typedef struct View_s /* viewpath level */
202*b30d1939SAndy Fiddaman {
203*b30d1939SAndy Fiddaman struct View_s* next; /* next level in viewpath */
204*b30d1939SAndy Fiddaman int node; /* viewpath node path length */
205*b30d1939SAndy Fiddaman char dir[1]; /* viewpath level dir prefix */
206*b30d1939SAndy Fiddaman } View_t;
207*b30d1939SAndy Fiddaman
208*b30d1939SAndy Fiddaman static struct /* program state */
209*b30d1939SAndy Fiddaman {
210*b30d1939SAndy Fiddaman Buf_t* buf; /* work buffer */
211*b30d1939SAndy Fiddaman Buf_t* old; /* dropped buffers */
212*b30d1939SAndy Fiddaman Buf_t* opt; /* option buffer */
213*b30d1939SAndy Fiddaman
214*b30d1939SAndy Fiddaman Dict_t* leaf; /* recursion leaf dictionary */
215*b30d1939SAndy Fiddaman Dict_t* libs; /* library dictionary */
216*b30d1939SAndy Fiddaman Dict_t* rules; /* rule dictionary */
217*b30d1939SAndy Fiddaman Dict_t* vars; /* variable dictionary */
218*b30d1939SAndy Fiddaman
219*b30d1939SAndy Fiddaman View_t* view; /* viewpath levels */
220*b30d1939SAndy Fiddaman
221*b30d1939SAndy Fiddaman char* directory; /* work in this directory */
222*b30d1939SAndy Fiddaman char* id; /* command name */
223*b30d1939SAndy Fiddaman char* file; /* first input file */
224*b30d1939SAndy Fiddaman char* pwd; /* current directory */
225*b30d1939SAndy Fiddaman char* recurse; /* recursion pattern */
226*b30d1939SAndy Fiddaman char* shell; /* ${SHELL} */
227*b30d1939SAndy Fiddaman
228*b30d1939SAndy Fiddaman int active; /* targets currently active */
229*b30d1939SAndy Fiddaman int debug; /* negative of debug level */
230*b30d1939SAndy Fiddaman int errors; /* some error(s) occurred */
231*b30d1939SAndy Fiddaman int exec; /* execute actions */
232*b30d1939SAndy Fiddaman int explain; /* explain actions */
233*b30d1939SAndy Fiddaman int force; /* all targets out of date */
234*b30d1939SAndy Fiddaman int ignore; /* ignore command errors */
235*b30d1939SAndy Fiddaman int indent; /* debug indent */
236*b30d1939SAndy Fiddaman int keepgoing; /* do siblings on error */
237*b30d1939SAndy Fiddaman int never; /* never execute */
238*b30d1939SAndy Fiddaman int peek; /* next line already in input */
239*b30d1939SAndy Fiddaman int probed; /* probe already done */
240*b30d1939SAndy Fiddaman int verified; /* don't bother with verify() */
241*b30d1939SAndy Fiddaman
242*b30d1939SAndy Fiddaman Stream_t streams[4]; /* input file stream stack */
243*b30d1939SAndy Fiddaman Stream_t* sp; /* input stream stack pointer */
244*b30d1939SAndy Fiddaman
245*b30d1939SAndy Fiddaman char input[8*CHUNK]; /* input buffer */
246*b30d1939SAndy Fiddaman } state;
247*b30d1939SAndy Fiddaman
248*b30d1939SAndy Fiddaman static unsigned long make(Rule_t*);
249*b30d1939SAndy Fiddaman
250*b30d1939SAndy Fiddaman static char mamfile[] = "Mamfile";
251*b30d1939SAndy Fiddaman static char sh[] = "/bin/sh";
252*b30d1939SAndy Fiddaman
253*b30d1939SAndy Fiddaman extern char** environ;
254*b30d1939SAndy Fiddaman
255*b30d1939SAndy Fiddaman #if !_PACKAGE_ast
256*b30d1939SAndy Fiddaman
257*b30d1939SAndy Fiddaman #if defined(NeXT) || defined(__NeXT)
258*b30d1939SAndy Fiddaman #define getcwd(a,b) getwd(a)
259*b30d1939SAndy Fiddaman #endif
260*b30d1939SAndy Fiddaman
261*b30d1939SAndy Fiddaman /*
262*b30d1939SAndy Fiddaman * emit usage message and exit
263*b30d1939SAndy Fiddaman */
264*b30d1939SAndy Fiddaman
265*b30d1939SAndy Fiddaman static void
usage()266*b30d1939SAndy Fiddaman usage()
267*b30d1939SAndy Fiddaman {
268*b30d1939SAndy Fiddaman fprintf(stderr, "Usage: %s [-iknFKNV] [-f mamfile] [-r pattern] [-C directory] [-D level] [target ...] [name=value ...]\n", state.id);
269*b30d1939SAndy Fiddaman exit(2);
270*b30d1939SAndy Fiddaman }
271*b30d1939SAndy Fiddaman
272*b30d1939SAndy Fiddaman #endif
273*b30d1939SAndy Fiddaman
274*b30d1939SAndy Fiddaman /*
275*b30d1939SAndy Fiddaman * output error message identification
276*b30d1939SAndy Fiddaman */
277*b30d1939SAndy Fiddaman
278*b30d1939SAndy Fiddaman static void
identify(Stdio_t * sp)279*b30d1939SAndy Fiddaman identify(Stdio_t* sp)
280*b30d1939SAndy Fiddaman {
281*b30d1939SAndy Fiddaman if (state.directory)
282*b30d1939SAndy Fiddaman fprintf(sp, "%s [%s]: ", state.id, state.directory);
283*b30d1939SAndy Fiddaman else
284*b30d1939SAndy Fiddaman fprintf(sp, "%s: ", state.id);
285*b30d1939SAndy Fiddaman }
286*b30d1939SAndy Fiddaman
287*b30d1939SAndy Fiddaman /*
288*b30d1939SAndy Fiddaman * emit error message
289*b30d1939SAndy Fiddaman * level:
290*b30d1939SAndy Fiddaman * <0 debug
291*b30d1939SAndy Fiddaman * 0 info
292*b30d1939SAndy Fiddaman * 1 warning
293*b30d1939SAndy Fiddaman * 2 error
294*b30d1939SAndy Fiddaman * >2 exit(level-2)
295*b30d1939SAndy Fiddaman */
296*b30d1939SAndy Fiddaman
297*b30d1939SAndy Fiddaman static void
report(int level,char * text,char * item,unsigned long stamp)298*b30d1939SAndy Fiddaman report(int level, char* text, char* item, unsigned long stamp)
299*b30d1939SAndy Fiddaman {
300*b30d1939SAndy Fiddaman int i;
301*b30d1939SAndy Fiddaman
302*b30d1939SAndy Fiddaman if (level >= state.debug)
303*b30d1939SAndy Fiddaman {
304*b30d1939SAndy Fiddaman if (level)
305*b30d1939SAndy Fiddaman identify(stderr);
306*b30d1939SAndy Fiddaman if (level < 0)
307*b30d1939SAndy Fiddaman {
308*b30d1939SAndy Fiddaman fprintf(stderr, "debug%d: ", level);
309*b30d1939SAndy Fiddaman for (i = 1; i < state.indent; i++)
310*b30d1939SAndy Fiddaman fprintf(stderr, " ");
311*b30d1939SAndy Fiddaman }
312*b30d1939SAndy Fiddaman else
313*b30d1939SAndy Fiddaman {
314*b30d1939SAndy Fiddaman if (state.sp && state.sp->line)
315*b30d1939SAndy Fiddaman {
316*b30d1939SAndy Fiddaman if (state.sp->file)
317*b30d1939SAndy Fiddaman fprintf(stderr, "%s: ", state.sp->file);
318*b30d1939SAndy Fiddaman fprintf(stderr, "%ld: ", state.sp->line);
319*b30d1939SAndy Fiddaman }
320*b30d1939SAndy Fiddaman if (level == 1)
321*b30d1939SAndy Fiddaman fprintf(stderr, "warning: ");
322*b30d1939SAndy Fiddaman else if (level > 1)
323*b30d1939SAndy Fiddaman state.errors = 1;
324*b30d1939SAndy Fiddaman }
325*b30d1939SAndy Fiddaman if (item)
326*b30d1939SAndy Fiddaman fprintf(stderr, "%s: ", item);
327*b30d1939SAndy Fiddaman fprintf(stderr, "%s", text);
328*b30d1939SAndy Fiddaman if (stamp && state.debug <= -2)
329*b30d1939SAndy Fiddaman fprintf(stderr, " %10lu", stamp);
330*b30d1939SAndy Fiddaman fprintf(stderr, "\n");
331*b30d1939SAndy Fiddaman if (level > 2)
332*b30d1939SAndy Fiddaman exit(level - 2);
333*b30d1939SAndy Fiddaman }
334*b30d1939SAndy Fiddaman }
335*b30d1939SAndy Fiddaman
336*b30d1939SAndy Fiddaman /*
337*b30d1939SAndy Fiddaman * don't know how to make or exit code making
338*b30d1939SAndy Fiddaman */
339*b30d1939SAndy Fiddaman
340*b30d1939SAndy Fiddaman static void
dont(Rule_t * r,int code,int keepgoing)341*b30d1939SAndy Fiddaman dont(Rule_t* r, int code, int keepgoing)
342*b30d1939SAndy Fiddaman {
343*b30d1939SAndy Fiddaman identify(stderr);
344*b30d1939SAndy Fiddaman if (!code)
345*b30d1939SAndy Fiddaman fprintf(stderr, "don't know how to make %s\n", r->name);
346*b30d1939SAndy Fiddaman else
347*b30d1939SAndy Fiddaman {
348*b30d1939SAndy Fiddaman fprintf(stderr, "*** exit code %d making %s%s\n", code, r->name, state.ignore ? " ignored" : "");
349*b30d1939SAndy Fiddaman unlink(r->name);
350*b30d1939SAndy Fiddaman if (state.ignore)
351*b30d1939SAndy Fiddaman return;
352*b30d1939SAndy Fiddaman }
353*b30d1939SAndy Fiddaman if (!keepgoing)
354*b30d1939SAndy Fiddaman exit(1);
355*b30d1939SAndy Fiddaman state.errors++;
356*b30d1939SAndy Fiddaman r->flags |= RULE_error;
357*b30d1939SAndy Fiddaman }
358*b30d1939SAndy Fiddaman
359*b30d1939SAndy Fiddaman /*
360*b30d1939SAndy Fiddaman * local strrchr()
361*b30d1939SAndy Fiddaman */
362*b30d1939SAndy Fiddaman
363*b30d1939SAndy Fiddaman static char*
last(register char * s,register int c)364*b30d1939SAndy Fiddaman last(register char* s, register int c)
365*b30d1939SAndy Fiddaman {
366*b30d1939SAndy Fiddaman register char* r = 0;
367*b30d1939SAndy Fiddaman
368*b30d1939SAndy Fiddaman for (r = 0; *s; s++)
369*b30d1939SAndy Fiddaman if (*s == c)
370*b30d1939SAndy Fiddaman r = s;
371*b30d1939SAndy Fiddaman return r;
372*b30d1939SAndy Fiddaman }
373*b30d1939SAndy Fiddaman
374*b30d1939SAndy Fiddaman /*
375*b30d1939SAndy Fiddaman * open a buffer stream
376*b30d1939SAndy Fiddaman */
377*b30d1939SAndy Fiddaman
378*b30d1939SAndy Fiddaman static Buf_t*
buffer(void)379*b30d1939SAndy Fiddaman buffer(void)
380*b30d1939SAndy Fiddaman {
381*b30d1939SAndy Fiddaman register Buf_t* buf;
382*b30d1939SAndy Fiddaman
383*b30d1939SAndy Fiddaman if (buf = state.old)
384*b30d1939SAndy Fiddaman state.old = state.old->old;
385*b30d1939SAndy Fiddaman else if (!(buf = newof(0, Buf_t, 1, 0)) || !(buf->buf = newof(0, char, CHUNK, 0)))
386*b30d1939SAndy Fiddaman report(3, "out of space [buffer]", NiL, (unsigned long)0);
387*b30d1939SAndy Fiddaman buf->end = buf->buf + CHUNK;
388*b30d1939SAndy Fiddaman buf->nxt = buf->buf;
389*b30d1939SAndy Fiddaman return buf;
390