Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/nmake/make.h
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1984-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Glenn Fowler
23
* AT&T Research
24
*
25
* make common definitions
26
*/
27
28
#include <ast.h>
29
#include <ls.h>
30
#include <ctype.h>
31
#include <dirent.h>
32
#include <fs3d.h>
33
#include <glob.h>
34
#include <hash.h>
35
#include <swap.h>
36
#include <namval.h>
37
#include <error.h>
38
#include <coshell.h>
39
#include <times.h>
40
#include <tok.h>
41
#include <setjmp.h>
42
#include <sfdisc.h>
43
#include <tmx.h>
44
45
#if DEBUG
46
#define debug(x) do if (error_info.trace < 0) { error x; } while (0)
47
#define PANIC (ERROR_PANIC|ERROR_SOURCE|ERROR_SYSTEM),__FILE__,__LINE__
48
#else
49
#define debug(x)
50
#define PANIC ERROR_PANIC
51
#endif
52
53
#define COMMENT '#' /* make comment char */
54
#define MARK_CONTEXT '\002' /* context mark -- not in input!*/
55
#define MARK_QUOTE '\003' /* quote mark -- not in input! */
56
#define SALT '#' /* preprocessor control char */
57
#define VIEWOFFSET '0' /* char offset for view==0 */
58
59
#if _WINIX
60
#define FILE_SPACE '\001' /* file name space */
61
#else
62
#define FILE_SPACE '?' /* file name space */
63
#endif
64
65
#define ATTRNAME '.' /* prefix to name an attribute */
66
#define ATTRSET '+' /* prefix to set an attribute */
67
#define ATTRCLEAR '-' /* prefix to clear an attribute */
68
69
#define CMDTRACE (-6) /* coshell trace debug level */
70
#define EXPTRACE (-5) /* explanation trace debug lev */
71
72
#define EXPLAIN (state.user&&(state.explain||error_info.trace<=EXPTRACE))
73
74
#undef atoi
75
#undef atol
76
#undef bind
77
#undef clrbit /* netbsd has one in <sys/param.h> */
78
#undef optinit
79
#undef setbit /* netbsd has one in <sys/param.h> */
80
81
#define bind bindrule /* avoids possible socket clash */
82
#define canon(x) ((state.context&&iscontextp(x,&state.tmppchar))?state.tmppchar:(state.mam.statix?mamcanon(x):pathcanon(x,0,0)))
83
#define clrbit(v,b) ((v)&=~(1L<<(b)))
84
#define getar(name) ((Dir_t*)hashget(table.ar,(name)))
85
#define getbound(name) ((char*)hashget(table.bound,(name)))
86
#define getdir(id) ((Dir_t*)hashget(table.dir,(char*)(id)))
87
#define getfile(name) ((File_t*)hashget(table.file,(name)))
88
#define getold(name) ((char*)hashget(table.oldvalue,(name)))
89
#define getreg(name) ((int*)hashget(table.regress,(name)))
90
#define getrule(name) ((Rule_t*)hashget(table.rule,(name)))
91
#define getvar(name) ((Var_t*)hashget(table.var,(name)))
92
#define message(x) do if (error_info.trace < 0) { error x; } while (0)
93
#define notfile(r) (((r)->property&(P_attribute|P_functional|P_make|P_operator|P_state|P_use|P_virtual))||((r)->dynamic&D_scope)||(r)->semaphore||((r)->property&P_dontcare)&&((r)->dynamic&D_bound)&&!(r)->time)
94
#define oldname(r) do{if(getbound(r->uname))putbound(0,0);if(r->dynamic&D_alias)r->dynamic&=~D_alias;else putrule(r->name,0);r->name=r->uname;r->uname=0;}while(0)
95
#define putbound(n,d) hashput(table.bound,(char*)(n),(char*)(d))
96
#define putar(name,d) hashput(table.ar,(name),(char*)(d))
97
#define putdir(id,d) hashput(table.dir,(char*)(id),(char*)(d))
98
#define putfile(name,f) hashput(table.file,(char*)(name),(char*)(f))
99
#define putold(name,v) hashput(table.oldvalue,(char*)(name),(char*)(v))
100
#define putptr(f,p) (internal.ptr=(char*)(p),sfwrite(f,&internal.ptr,sizeof(internal.ptr)))
101
#define putreg(name,r) hashput(table.regress,(char*)(name),(char*)(r))
102
#define putrule(name,r) hashput(table.rule,(char*)(name),(char*)(r))
103
#define putvar(name,v) hashput(table.var,(char*)(name),(char*)(v))
104
#define reason(x) do if(EXPLAIN)explain x;while(0)
105
#define ropen(f,m) ((f)==internal.openfile?(internal.openfile=0,internal.openfd):open(f,m))
106
#define rsfopen(f) ((f)==internal.openfile?(internal.openfile=0,sfnew(NiL,NiL,SF_UNBOUND,internal.openfd,SF_READ)):sfopen(NiL,f,"re"))
107
#define setbit(v,b) ((v)|=(1L<<(b)))
108
#define shquote shellquote /* netbsd has one in <stdlib.h>! */
109
#define statetimeq timestateq /* avoids statetime symbol truncation clash */
110
#define timefix(t) t-=(t<state.tolerance)?t:state.tolerance
111
#define trap() (state.caught?handle():0)
112
#define tstbit(v,b) ((v)&(1L<<(b)))
113
#define unviewname(s) (*(s)='(')
114
#define viewable(r) ((r->property&P_state)&&*r->name=='(')
115
#define viewname(s,v) (*(s)=VIEWOFFSET+(v))
116
#define zero(x) memzero(&(x),sizeof(x))
117
118
#define isaltstate(s) (nametype(s,NiL)&(NAME_altstate))
119
#define iscontext(s) (nametype(s,NiL)&(NAME_context))
120
#define iscontextp(s,p) (nametype(s,p)&(NAME_context))
121
#define isdynamic(s) (nametype(s,NiL)&(NAME_dynamic|NAME_glob))
122
#define isglob(s) (nametype(s,NiL)&(NAME_glob))
123
#define isintvar(s) (nametype(s,NiL)&(NAME_intvar))
124
#define isstate(s) (nametype(s,NiL)&(NAME_staterule|NAME_altstate|NAME_statevar))
125
#define isstatevar(s) (nametype(s,NiL)&(NAME_statevar))
126
127
#define freelist(x) do{if(x){(x)->rule=(Rule_t*)internal.freelists;internal.freelists=(char*)(x);}}while(0)
128
#define freerule(r) do{zero(*r);*((char**)r)=internal.freerules;internal.freerules=(char*)(r);}while(0)
129
#define freevar(v) do{(v)->property&=(V_free|V_import);*((char**)v)=internal.freevars;internal.freevars=(char*)(v);}while(0)
130
131
#define newlist(x) do{if(x=(List_t*)internal.freelists){if(x->next){x=x->next;*((char**)internal.freelists)=(char*)x->next;}else internal.freelists=(char*)x->rule;}else x=(List_t*)newchunk(&internal.freelists,sizeof(List_t));}while(0)
132
#define newrule(r) do{if(r=(Rule_t*)internal.freerules){internal.freerules=(*((char**)r));zero(*r);}else r=(Rule_t*)newchunk(&internal.freerules,sizeof(Rule_t));}while(0)
133
#define newvar(v) do{if(v=(Var_t*)internal.freevars){internal.freevars=(*((char**)v));}else v=(Var_t*)newchunk(&internal.freevars,sizeof(Var_t));}while(0)
134
135
#if CHAR_MIN < 0
136
#define ctable (ctypes-(CHAR_MIN)+1)
137
#else
138
#define ctable (ctypes)
139
#endif
140
141
#define istype(c,t) (ctable[c]&(t))
142
#define settype(c,t) (ctable[c]|=(t))
143
#define unsettype(c,t) (ctable[c]&=~(t))
144
145
#define NOTYET 0 /* don't know what to do yet */
146
#define UPDATE 1 /* rule in process of being updated */
147
#define MAKING 2 /* executing update action */
148
#define TOUCH 3 /* archive member to be touched */
149
#define EXISTS 4 /* rule already exists in desired state */
150
#define IGNORE 5 /* rule make failed but ignore errors */
151
#define FAILED 6 /* rule make failed */
152
#define OLDRULE 7 /* makefile compiler old rule mark */
153
154
#define RECOMPILE 1 /* recompile make object */
155
#define COMPILED 2 /* make object compiled (if necessary) */
156
#define SAVED 3 /* make state saved */
157
158
#define DELETE NiL /* delete path component in edit() */
159
#define KEEP ((char*)1) /* keep path component in edit() */
160
161
#define NOTIME TMX_NOTIME /* not checked time */
162
#define OLDTIME ((Time_t)(1)) /* oldest valid time */
163
#define CURTIME tmxgettime() /* high resolution current time */
164
#define CURSECS ((Seconds_t)time(NiL)) /* seconds resolution time */
165
166
/*
167
* VAR and RULE must not change -- the rest must be in sequence
168
*/
169
170
#define VAR 0 /* state var from var in staterule() */
171
#define CONSISTENT VAR /* consistency check bits */
172
#define RULE 1 /* state rule in staterule() */
173
#define PREREQS 2 /* alternate prereqs in staterule() */
174
#define STATERULES 2 /* last staterule() index */
175
176
#define MINVALUE 32 /* minimum variable value length */
177
#define MAXJOBS 128 /* maximum number concurrent jobs */
178
#define MAXNAME 1024 /* maximum file pathname length */
179
#define PCTGARBAGE 10 /* maximum state garbage percentage */
180
181
#define MAXVIEW (sizeof(Flags_t)*CHAR_BIT) /* max view index */
182
183
#if BINDINDEX
184
#define MAXBIND UCHAR_MAX/* maximum bind index */
185
#endif
186
187
#define A_clear (1<<0) /* assertion() .CLEAR */
188
#define A_copy (1<<1) /* assertion() .COPY */
189
#define A_delete (1<<2) /* assertion() .DELETE */
190
#define A_group (1<<3) /* assertion() metarule (...) grouping */
191
#define A_insert (1<<4) /* assertion() .INSERT */
192
#define A_metarule (1<<5) /* assertion() pattern metarule */
193
#define A_negate (1<<6) /* assertion() -attribute */
194
#define A_nooptions (1<<7) /* assertion() no more option prereqs */
195
#define A_norhs (1<<8) /* assertion() empty rhs */
196
#define A_null (1<<9) /* assertion() .NULL */
197
#define A_scan (1<<10) /* assertion() .SCAN */
198
#define A_scope (1<<11) /* assertion() metarule scope prereqs */
199
#define A_special (1<<12) /* assertion() .SPECIAL */
200
#define A_target (1<<13) /* assertion() set P_target */
201
202
#define C_ID1 (1<<0) /* istype() first identifier char */
203
#define C_ID2 (1<<1) /* istype() remaining id chars */
204
#define C_MATCH (1<<2) /* istype() shell pattern match chars */
205
#define C_OPTVAL (1<<3) /* istype() option value separator */
206
#define C_SEP (1<<4) /* istype() token separator */
207
#define C_TERMINAL (1<<5) /* istype() terminal chars */
208
#define C_VARIABLE1 (1<<6) /* istype() first variable name char */
209
#define C_VARIABLE2 (1<<7) /* istype() remaining variable chars */
210
211
#define C_VARPOS1 (1<<8) /* istype() var superimposed code 1 */
212
#define C_VARPOS2 (1<<9) /* istype() var superimposed code 2 */
213
#define C_VARPOS3 (1<<10) /* istype() var superimposed code 3 */
214
#define C_VARPOS4 (1<<11) /* istype() var superimposed code 4 */
215
#define C_VARPOS5 (1<<12) /* istype() var superimposed code 5 */
216
#define C_VARPOS6 (1<<13) /* istype() var superimposed code 6 */
217
#define C_VARPOS7 (1<<14) /* istype() var superimposed code 7 */
218
#define C_VARPOS8 (1L<<15)/* istype() var superimposed code 8 */
219
220
#define NAME_altstate 0x001 /* altername state rule name */
221
#define NAME_assignment 0x002 /* assignment */
222
#define NAME_context 0x004 /* context string */
223
#define NAME_dynamic 0x008 /* requires dynamic expand() */
224
#define NAME_glob 0x010 /* requires dynamic glob() */
225
#define NAME_identifier 0x020 /* identifier name */
226
#define NAME_intvar 0x040 /* internal variable name */
227
#define NAME_option 0x080 /* option */
228
#define NAME_path 0x100 /* path name */
229
#define NAME_staterule 0x200 /* state rule name */
230
#define NAME_statevar 0x400 /* state variable name */
231
#define NAME_variable 0x800 /* variable name */
232
233
#define ARG_ASSIGN (1<<0) /* command line assignment arg flag */
234
#define ARG_SCRIPT (1<<1) /* command line script arg flag */
235
#define ARG_TARGET (1<<2) /* command line target arg flag */
236
237
#define BIND_DOT (1<<0) /* bindfile in . */
238
#define BIND_FORCE (1<<1) /* force bindfile current time */
239
#define BIND_MAKEFILE (1<<2) /* bindfile using makefile dirs */
240
#define BIND_RULE (1<<3) /* force bindfile makerule */
241
242
#define MERGE_ALL (1<<0) /* merge everything */
243
#define MERGE_ASSOC (1<<1) /* pattern association merge */
244
#define MERGE_ATTR (1<<2) /* merge just attributes */
245
#define MERGE_BOUND (1<<3) /* MERGE_ALL but no bind */
246
#define MERGE_FORCE (1<<4) /* override attributes */
247
#define MERGE_SCANNED (1<<5) /* MERGE_ALL but no entries|scanned */
248
249
#define COMP_BASE (1<<0) /* base rules prereq */
250
#define COMP_DONTCARE (1<<1) /* optional include prereq */
251
#define COMP_FILE (1<<2) /* -f prereq */
252
#define COMP_GLOBAL (1<<3) /* -g prereq */
253
#define COMP_INCLUDE (1<<4) /* include prereq */
254
#define COMP_OPTIONS (1<<5) /* -[DIU]* prereq */
255
#define COMP_RULES (1<<6) /* from explicit rules statement */
256
#define COMP_NSEC (1<<7) /* next prereq nsec */
257
258
#define PREREQ_APPEND 1 /* addprereq append */
259
#define PREREQ_DELETE 2 /* addprereq delete */
260
#define PREREQ_INSERT 3 /* addprereq insert */
261
#define PREREQ_LENGTH 4 /* addprereq insert by length */
262
263
#define SCAN_IGNORE 1 /* .SCAN.IGNORE scan index */
264
#define SCAN_NULL 2 /* .SCAN.NULL scan index */
265
#define SCAN_STATE 3 /* .SCAN.STATE scan index */
266
#define SCAN_USER 8 /* first user defined scan index */
267
#define SCAN_MAX UCHAR_MAX/* max scan index */
268
269
#define CO_ALWAYS (CO_USER<<0) /* always exec */
270
#define CO_DATAFILE (CO_USER<<1) /* job output to state.tmpdata */
271
#define CO_ERRORS (CO_USER<<2) /* job had errors */
272
#define CO_FOREGROUND (CO_USER<<3) /* wait for completion */
273
#define CO_KEEPGOING (CO_USER<<4) /* keep going on job error */
274
#define CO_LOCALSTACK (CO_USER<<5) /* stack local vars for action */
275
#define CO_PRIMARY (CO_USER<<6) /* primary prereq added */
276
#define CO_SEMAPHORES (CO_USER<<7) /* release semaphores */
277
#define CO_URGENT (CO_USER<<8) /* enter job at top of queue */
278
279
/*
280
* rule.property flags
281
*/
282
283
#define P_accept (1<<0) /* ignore state conflicts */
284
#define P_after (1<<1) /* make after parent update */
285
#define P_always (1<<2) /* execute even if !state.exec */
286
#define P_archive (1<<3) /* rule bound to archive file */
287
#define P_attribute (1<<4) /* rule is an attribute */
288
#define P_before (1<<5) /* make before parent update */
289
#define P_command (1<<6) /* command target -- no pattern */
290
#define P_dontcare (1<<7) /* don't care if rule made */
291
#define P_force (1<<8) /* target is always out of date */
292
#define P_foreground (1<<9) /* run action in foreground */
293
#define P_functional (1<<10) /* associated w/functional var */
294
#define P_ignore (1<<11) /* parent to ignore this prereq */
295
#define P_immediate (1<<12) /* rule needs immediate action */
296
#define P_implicit (1<<13) /* force implicit prereq checks */
297
#define P_internal (1<<14) /* don't compile unless prereq */
298
#define P_joint (1L<<15) /* pseudo for joint targets */
299
#define P_make (1L<<16) /* make (not shell) action */
300
#define P_metarule (1L<<17) /* metarule */
301
#define P_multiple (1L<<18) /* multi prereq occurrences OK */
302
303
#define P_local (1L<<19) /* local affinity */
304
305
#define P_operator (1L<<20) /* rule is an operator */
306
#define P_parameter (1L<<21) /* rule bound to parameter file */
307
#define P_readonly (1L<<22) /* no user modifications */
308
#define P_repeat (1L<<23) /* make even if already made */
309
#define P_state (1L<<24) /* state atom */
310
#define P_staterule (1L<<25) /* staterule */
311
#define P_statevar (1L<<26) /* statevar */
312
#define P_target (1L<<27) /* rule is an explicit target */
313
#define P_terminal (1L<<28) /* terminal target or metarule */
314
#define P_use (1L<<29) /* rule is a .USE script */
315
#define P_virtual (1L<<30) /* target is not a file */
316
317
#define P_read (1L<<31) /* read action output */
318
319
#define P_failure (P_after|P_before) /* conjoined */
320
321
/*
322
* rule.dynamic flags
323
*/
324
325
#define D_alias (1<<0) /* more than one unbound name */
326
#define D_aliaschanged (1<<1) /* alias changed */
327
#define D_bound (1<<2) /* rule has been bound */
328
#define D_built (1<<3) /* triggered action built target*/
329
#define D_cached (1<<4) /* post assertion info cached */
330
#define D_compiled (1<<5) /* rule has been compiled */
331
#define D_dynamic (1<<6) /* must do dynamic expansion */
332
#define D_entries (1<<7) /* scanned rule has entries */
333
#define D_garbage (1<<8) /* state file GC mark */
334
#define D_hasafter (1<<9) /* rule has after prereqs */
335
#define D_hasbefore (1<<10) /* rule has before prereqs */
336
337
#define D_membertoo (1<<11) /* D_member was also set */
338
#define D_hassemaphore (1<<12) /* has rule.semaphore prereq */
339
#define D_same (1<<13) /* target unchanged by action */
340
341
#define D_lower (1<<14) /* state from lower view */
342
343
#define D_source (1L<<15) /* .SOURCE directory */
344
345
#define D_member (1L<<16) /* rule bound to archive member */
346
347
#define D_global (1L<<17) /* global view if view==0 */
348
349
#define D_regular (1L<<18) /* rule bound to regular file */
350
#define D_scanned (1L<<19) /* has been scanned */
351
#define D_select0 (1L<<20) /* $(...) select bit 0 */
352
#define D_select1 (1L<<21) /* $(...) select bit 1 */
353
#define D_triggered (1L<<22) /* rule action triggered */
354
355
#define D_index (1L<<23) /* load time index consistency */
356
357
#define D_bindindex (1L<<24) /* bind index table entry */
358
359
#define D_intermediate (1L<<25) /* intermediate pretend target */
360
361
#define D_hasscope (1L<<26) /* has D_scope prereqs */
362
#define D_scope (1L<<27) /* scoped var assignment */
363
364
#define D_hasmake (1L<<28) /* rule has .MAKE after prereqs */
365
366
#define D_context (1L<<29) /* ref may be diff dir context */
367
368
#define D_lowres (1L<<30) /* low resolution time */
369
370
#define D_CLEAROBJECT (~(D_bindindex|D_built|D_compiled|D_context|D_dynamic|D_index|D_lower|D_lowres|D_scope))
371
372
#define M_bind (1<<0) /* bind recursion mark */
373
#define M_compile (1<<1) /* compilation mark */
374
#define M_directory (1<<2) /* bind directory mark */
375
#define M_generate (1<<3) /* prereq generation mark */
376
#define M_mark (1<<4) /* temporary mark */
377
#define M_metarule (1<<5) /* metarule closure mark */
378
#define M_scan (1<<6) /* scan recursion mark */
379
#define M_waiting (1<<7) /* waiting to complete mark */
380
381
/*
382
* var.property flags
383
*/
384
385
#define V_compiled (1<<0) /* variable has been compiled */
386
#define V_frozen (1<<1) /* frozen in make object file */
387
#define V_functional (1<<2) /* make rule name before access */
388
#define V_import (1<<3) /* imported from environment */
389
#define V_local_D (1<<4) /* :T=D: localview reference */
390
#define V_oldvalue (1<<5) /* compile old value */
391
#define V_readonly (1<<6) /* only dynamic modifications */
392
#define V_retain (1<<7) /* retain value in state file */
393
#define V_scan (1<<8) /* scan for implicit state var */
394
395
#define V_local_E (1<<9) /* :T=E: localview reference */
396
397
#define V_auxiliary (1<<10) /* auxiliary &= assignment */
398
#define V_append (1<<11) /* cmd line += property or op */
399
#define V_free (1<<12) /* value may be freed */
400
#define V_builtin (1<<13) /* builtin V_functional */
401
#define V_scope (1<<14) /* scoped value */
402
403
#define V_restored (1L<<15) /* retained value stored */
404
405
#define V_CLEARSTATE (V_free|V_restored)
406
#define V_CLEAROBJECT (~(V_auxiliary|V_builtin|V_functional|V_import|V_retain|V_scan|V_scope))
407
408
/*
409
* getval() flags
410
*/
411
412
#define VAL_AUXILIARY (1<<0) /* auxilliary value */
413
#define VAL_BRACE (1<<1) /* { } */
414
#define VAL_FILE (1<<2) /* !notfile(r) */
415
#define VAL_PRIMARY (1<<3) /* primary value */
416
#define VAL_UNBOUND (1<<4) /* unbound name */
417
418
/*
419
* dumpjob() flags
420
*/
421
422
#define JOB_blocked 1 /* blocked jobs with prereqs */
423
#define JOB_status 2 /* job status list */
424
425
typedef struct dirent Dirent_t;
426
typedef struct stat Stat_t;
427
428
struct File_s; typedef struct File_s File_t;
429
struct Frame_s; typedef struct Frame_s Frame_t;
430
struct List_s; typedef struct List_s List_t;
431
struct Rule_s; typedef struct Rule_s Rule_t;
432
433
typedef uint32_t Flags_t; /* flag bit vector */
434
typedef uint32_t Seconds_t; /* seconds resolution time */
435
436
typedef struct Fileid_s /* unique file id */
437
{
438
long dev; /* device number */
439
long ino; /* inode number */
440
} Fileid_t;
441
442
typedef struct Dir_s /* scanned directory entry */
443
{
444
char* name; /* directory name */
445
Time_t time; /* modify time */
446
unsigned char archive; /* directory is an archive */
447
unsigned char directory; /* directory is a real directory*/
448
unsigned char ignorecase; /* pox on dirs that ignore case */
449
unsigned char truncate; /* names truncated to this */
450
} Dir_t;
451
452
struct File_s /* file table entry */
453
{
454
File_t* next; /* next in list */
455
Dir_t* dir; /* directory containing file */
456
Time_t time; /* modify time */
457
};
458
459
struct Frame_s /* active target frame */
460
{
461
Frame_t* parent; /* parent frame */
462
Frame_t* previous; /* previous active frame */
463
Rule_t* target; /* target in frame */
464
List_t* prereqs; /* original prereqs */
465
char* action; /* original action */
466
char* original; /* original bound name */
467
char* primary; /* metarule primary prereq name */
468
char* stem; /* metarule stem */
469
Flags_t flags; /* make() flags */
470
471
struct
472
{
473
char* name; /* original target name */
474
Frame_t* frame; /* original target frame */
475
Time_t time; /* original target time */
476
} context; /* context push/pop */
477
};
478
479
/*
480
* statevar data, staterule sync time and unbound rule name -- shared in rule.u1
481
*/
482
483
#define event u1.u_event
484
#define statedata u1.u_data
485
#define uname u1.u_uname
486
#define unbound(r) ((r)->uname?(r)->uname:(r)->name)
487
488
struct Rule_s /* rule */
489
{
490
char* name; /* rule name */
491
Frame_t* active; /* active target frame */
492
493
union
494
{
495
char* u_uname; /* unbound name */
496
char* u_data; /* state value */
497
Time_t u_event; /* state rule event time */
498
} u1;
499
500
List_t* prereqs; /* prerequisites */
501
char* action; /* update action */
502
Time_t time; /* modify time */
503
504
Flags_t attribute; /* external named attributes */
505
Flags_t dynamic; /* dynamic properties */
506
Flags_t property; /* stable properties */
507
508
unsigned char scan; /* file scan strategy index */
509
unsigned char semaphore; /* semaphore + count */
510
unsigned char status; /* disposition */
511
unsigned char view; /* view bind index */
512
513
unsigned char mark; /* M_* marks */
514
unsigned char preview; /* min prereq view */
515
unsigned short must; /* cancel if == 0 */
516
517
unsigned long complink; /* compilation link */
518
Flags_t checked[STATERULES+1]; /* view state check */
519
520
#if BINDINDEX
521
unsigned char source; /* source bind index */
522
#endif
523
};
524
525
typedef struct Internal_s /* internal rule and list info */
526
{
527
/*
528
* read/write rule attributes
529
*/
530
531
Rule_t* accept; /* .ACCEPT rule pointer */
532
Rule_t* after; /* .AFTER rule pointer */
533
Rule_t* alarm; /* .ALARM rule pointer */
534
Rule_t* always; /* .ALWAYS rule pointer */
535
Rule_t* archive; /* .ARCHIVE rule pointer */
536
Rule_t* attribute; /* .ATTRIBUTE rule pointer */
537
Rule_t* before; /* .BEFORE rule pointer */
538
Rule_t* command; /* .COMMAND rule pointer */
539
Rule_t* dontcare; /* .DONTCARE rule pointer */
540
Rule_t* force; /* .FORCE rule pointer */
541
Rule_t* foreground; /* .FOREGROUND rule pointer */
542
Rule_t* functional; /* .FUNCTIONAL rule pointer */
543
Rule_t* freeze; /* .FREEZE rule pointer */
544
Rule_t* ignore; /* .IGNORE rule pointer */
545
Rule_t* immediate; /* .IMMEDIATE rule pointer */
546
Rule_t* implicit; /* .IMPLICIT rule pointer */
547
Rule_t* insert; /* .INSERT rule pointer */
548
Rule_t* joint; /* .JOINT rule pointer */
549
Rule_t* local; /* .LOCAL rule pointer */
550
Rule_t* make; /* .MAKE rule pointer */
551
Rule_t* making; /* .MAKING rule pointer */
552
Rule_t* multiple; /* .MULTIPLE rule pointer */
553
Rule_t* op; /* .OPERATOR rule pointer */
554
Rule_t* parameter; /* .PARAMETER rule pointer */
555
Rule_t* read; /* .READ rule pointer */
556
Rule_t* readonly; /* .READONLY rule pointer */
557
Rule_t* regular; /* .REGULAR rule pointer */
558
Rule_t* repeat; /* .REPEAT rule pointer */
559
Rule_t* run; /* .RUN rule pointer */
560
Rule_t* semaphore; /* .SEMAPHORE rule pointer */
561
Rule_t* source; /* .SOURCE rule pointer */
562
Rule_t* state; /* .STATE rule pointer */
563
Rule_t* sync; /* .SYNC rule pointer */
564
Rule_t* terminal; /* .TERMINAL rule pointer */
565
Rule_t* use; /* .USE rule pointer */
566
Rule_t* virt; /* .VIRTUAL rule pointer */
567
Rule_t* wait; /* .WAIT rule pointer */
568
569
/*
570
* readonly rule attributes
571
*/
572
573
Rule_t* active; /* .ACTIVE rule pointer */
574
Rule_t* bound; /* .BOUND rule pointer */
575
Rule_t* built; /* .BUILT rule pointer */
576
Rule_t* entries; /* .ENTRIES rule pointer */
577
Rule_t* exists; /* .EXISTS rule pointer */
578
Rule_t* failed; /* .FAILED rule pointer */
579
Rule_t* file; /* .FILE rule pointer */
580
Rule_t* global; /* .GLOBAL rule pointer */
581
Rule_t* member; /* .MEMBER rule pointer */
582
Rule_t* notyet; /* .NOTYET rule pointer */
583
Rule_t* scanned; /* .SCANNED rule pointer */
584
Rule_t* staterule; /* .STATERULE rule pointer */
585
Rule_t* statevar; /* .STATEVAR rule pointer */
586
Rule_t* target; /* .TARGET rule pointer */
587
Rule_t* triggered; /* .TRIGGERED rule pointer */
588
589
/*
590
* special rules and names
591
*/
592
593
Rule_t* args; /* .ARGS rule pointer */
594
Rule_t* bind; /* .BIND rule pointer */
595
Rule_t* clear; /* .CLEAR rule pointer */
596
Rule_t* copy; /* .COPY rule pointer */
597
Rule_t* delete; /* .DELETE rule pointer */
598
Rule_t* dot; /* . rule pointer */
599
Rule_t* empty; /* "" rule pointer */
600
Rule_t* error; /* error intercept rule pointer */
601
Rule_t* exports; /* .EXPORT rule pointer */
602
Rule_t* globalfiles; /* .GLOBALFILES rule pointer */
603
Rule_t* include; /* .INCLUDE rule pointer */
604
Rule_t* internal; /* .INTERNAL rule pointer */
605
Rule_t* main; /* .MAIN rule pointer */
606
Rule_t* makefiles; /* .MAKEFILES rule pointer */
607
Rule_t* metarule; /* .METARULE rule pointer */
608
Rule_t* null; /* .NULL rule pointer */
609
Rule_t* preprocess; /* .PREPROCESS rule pointer */
610
Rule_t* query; /* .QUERY rule pointer */
611
Rule_t* rebind; /* .REBIND rule pointer */
612
Rule_t* reset; /* .RESET rule pointer */
613
Rule_t* retain; /* .RETAIN rule pointer */
614
Rule_t* scan; /* .SCAN rule pointer */
615
Rule_t* script; /* .SCRIPT rule pointer */
616
Rule_t* special; /* .SPECIAL rule pointer */
617
Rule_t* tmplist; /* .TMPLIST rule pointer */
618
Rule_t* unbind; /* .UNBIND rule pointer */
619
Rule_t* view; /* .VIEW rule pointer */
620
621
/*
622
* pattern association rules
623
*/
624
625
Rule_t* append_p; /* .APPEND. rule pointer */
626
Rule_t* assert_p; /* .ASSERT. rule pointer */
627
Rule_t* assign_p; /* .ASSIGN. rule pointer */
628
Rule_t* attribute_p; /* .ATTRIBUTE. rule pointer */
629
Rule_t* bind_p; /* .BIND. rule pointer */
630
Rule_t* dontcare_p; /* .DONTCARE. rule pointer */
631
Rule_t* insert_p; /* .INSERT. rule pointer */
632
Rule_t* require_p; /* .REQUIRE. rule pointer */
633
Rule_t* source_p; /* .SOURCE. rule pointer */
634
635
/*
636
* miscellaneous internal info
637
*/
638
639
Sfio_t* met; /* metarule expansion buffer */
640
Sfio_t* nam; /* name generation buffer */
641
Sfio_t* tmp; /* very temporary work buffer */
642
Sfio_t* val; /* initial getval return buffer */
643
Sfio_t* wrk; /* very temporary work buffer */
644
645
char* freelists; /* free lists list */
646
char* freerules; /* free rules list */
647
char* freevars; /* free variables list */
648
649
char* issource; /* internal.source* match pat */
650
char* openfile; /* bind()-scan() optimization */
651
char* pwd; /* PWD value */
652
char* ptr; /* temporary for sfstrptr() */
653
654
int openfd; /* bind()-scan() optimization */
655
int pwdlen; /* strlen(internal.pwd) */
656
} Internal_t;
657
658
typedef struct External_s /* external engine name info */
659
{
660
/*
661
* names of variables defined by engine, init, or environment
662
*/
663
664
char* args; /* candidate args file name(s) */
665
char* convert; /* makefile converter patterns */
666
char* file; /* main input makefile name */
667
char* files; /* candidate makefile name(s) */
668
char* import; /* explicit env override vars */
669
char* lib; /* related file lib directory */
670
char* make; /* program path name */
671
char* nproc; /* # jobs for compatibility */
672
char* old; /* old program path name */
673
char* pwd; /* pwd name */
674
char* rules; /* candidate rules file name(s) */
675
char* skip; /* order directory skip pattern */
676
char* version; /* engine version stamp */
677
char* viewdot; /* . view dir list */
678
char* viewnode; /* view node dir list */
679
680
/*
681
* infrequently used engine interface names
682
*/
683
684
char* compdone; /* made after makefile compiled */
685
char* compinit; /* made before makefile compiled*/
686
char* done; /* made just before exit */
687
char* init; /* made before first user target*/
688
char* interrupt; /* made on first interrupt */
689
char* jobdone; /* made when each job done */
690
char* makedone; /* made after done */
691
char* makeinit; /* made after before init */
692
char* makeprompt; /* made just before each prompt */
693
char* makerun; /* made just before each job */
694
char* mamname; /* external mam atom name */
695
char* mamaction; /* external mam action */
696
char* order; /* :W=[OPR]: favorites */
697
698
/*
699
* related file suffixes
700
*/
701
702
char* lock; /* make lock file suffix */
703
char* object; /* make object file suffix */
704
char* source; /* make source file suffix */
705
char* state; /* make state file suffix */
706
char* tmp; /* make temporary file suffix */
707
} External_t;
708
709
typedef struct Tables_s /* hash table pointers */
710
{
711
Hash_table_t* ar; /* archives dir info by name */
712
Hash_table_t* bound; /* directory of bound file */
713
Hash_table_t* dir; /* directories and archives */
714
Hash_table_t* file; /* files from scanned dirs */
715
Hash_table_t* oldvalue; /* old variable values */
716
Hash_table_t* regress; /* regression path maps */
717
Hash_table_t* rule; /* rule names */
718
Hash_table_t* var; /* variable names */
719
} Tables_t;
720
721
#define BIND_EXISTS (1<<0) /* statefile loaded */
722
#define BIND_LOADED (1<<1) /* statefile loaded */
723
724
typedef struct Binding_s /* binding info */
725
{
726
#if BINDINDEX
727
Rule_t* path; /* path name component */
728
#else
729
char* path; /* path name component */
730
#endif
731
char* root; /* path root */
732
short pathlen; /* path length */
733
short rootlen; /* root length */
734
unsigned char flags; /* BIND_* flags */
735
unsigned char map; /* external index map */
736
} Binding_t;
737
738
typedef struct Label_s /* resume label */
739
{
740
jmp_buf label;
741
} Label_t;
742
743
typedef struct Mam_s /* mam state */
744
{
745
Sfdisc_t disc; /* output discipline -- first! */
746
747
int hold; /* output hold nest level */
748
int level; /* next error() message level */
749
int parent; /* mam parent label */
750
int rootlen; /* strlen(state.mam.root) */
751
752
char* label; /* instruction label */
753
char* options; /* option string */
754
char* root; /* names relative to this root */
755
char* type; /* mam type name */
756
757
Sfio_t* out; /* output stream pointer */
758
759
unsigned char dynamic; /* dynamic mam */
760
unsigned char regress; /* regression mam */
761
unsigned char statix; /* static mam */
762
763
unsigned char dontcare; /* emit dontcare rules too */
764
unsigned char port; /* emit porting hints */
765
} Mam_t;
766
767
typedef struct State_s /* program state */
768
{
769
unsigned char accept; /* accept all existing targets */
770
unsigned char alias; /* enable directory aliasing */
771
unsigned char base; /* compile base|global rules */
772
unsigned char caught; /* a signal was caught */
773
unsigned char compile; /* make object compile state */
774
unsigned char compileonly; /* only compile (force) */
775
unsigned char compatibility; /* disable compatibility msgs */
776
unsigned char cross; /* don't run gen'd executables */
777
unsigned char exec; /* execute shell actions */
778
unsigned char expandall; /* expanding $(...) */
779
unsigned char expandview; /* expand paths if fsview!=0 */
780
unsigned char explain; /* explain reason for actions */
781
unsigned char explicitrules; /* explicit rules statement */
782
unsigned char finish; /* in finish() */
783
unsigned char force; /* force target updates */
784
unsigned char forceread; /* force makefiles to be read */
785
unsigned char forcescan; /* force implicit prereq scan */
786
unsigned char fsview; /* file system handles views */
787
unsigned char fullscan; /* scan for impl state prereqs */
788
unsigned char global; /* reading global rules */
789
unsigned char ignore; /* ignore sh action errors */
790
unsigned char ignorelock; /* ignore state lock */
791
unsigned char import; /* import var def precedence */
792
unsigned char init; /* engine initialization */
793
unsigned char intermediate; /* force intermediate targets */
794
unsigned char interpreter; /* in interpreter main loop */
795
unsigned char keepgoing; /* continue w/ sibling prereqs */
796
unsigned char list; /* list readable definitions */
797
unsigned char localview; /* automatics to local view */
798
#if BINDINDEX
799
unsigned char logical; /* emit logical pathnames */
800
#endif
801
unsigned char never; /* really - don't exec anything */
802
unsigned char op; /* currently parsing operator */
803
unsigned char override; /* override explicit rules */
804
unsigned char pushed; /* --global state */
805
unsigned char push_global; /* --global state */
806
unsigned char push_user; /* --global state */
807
unsigned char preprocess; /* preprocess all makefiles */
808
unsigned char reading; /* currently reading makefile */
809
unsigned char readonly; /* current vars|opts readonly */
810
unsigned char ruledump; /* dump rule information */
811
unsigned char savestate; /* must save state variables */
812
unsigned char scan; /* scan|check implicit prereqs */
813
unsigned char serialize; /* serialize concurrent output */
814
unsigned char silent; /* run silently */
815
unsigned char strictview; /* strict views */
816
unsigned char targetcontext; /* expand in target dir context */
817
unsigned char touch; /* touch out of date targets */
818
unsigned char user; /* user activities started */
819
unsigned char val; /* internal.val in use */
820
unsigned char vardump; /* dump variable information */
821
unsigned char virtualdot; /* fsview . is virtual */
822
unsigned char waiting; /* waiting for job completion */
823
unsigned char warn; /* enable source file warnings */
824
825
int argc; /* global argc */
826
int believe; /* believe state from this level*/
827
int errors; /* keepgoing error count */
828
int interrupt; /* interrupt causing exit */
829
int jobs; /* sh action concurrency level */
830
int pid; /* make pid */
831
int readstate; /* state files to this view ok */
832
int reread; /* input makefile reread count */
833
int stateview; /* state file view index */
834
int tabstops; /* tab stops for makefile parse */
835
int targetview; /* most recent active targ view */
836
int tolerance; /* time comparison tolerance */
837
int unwind; /* make() dontcare unwind level */
838
839
Flags_t questionable; /* questionable code enable bits*/
840
Flags_t test; /* test code enable bits */
841
842
Time_t start; /* start time of this make */
843
844
char* corrupt; /* corrupt state file action */
845
char* errorid; /* error message id */
846
char* hold; /* hold error trap */
847
char* loading; /* loading this object file */
848
char* makefile; /* first makefile name */
849
char* objectfile; /* make object file name */
850
char* regress; /* output for regression test */
851
char* rules; /* base rules base name */
852
char* statefile; /* state variable file name */
853
char* targetprefix; /* target prefix dir separator */
854
char* tmppchar; /* macro char* temporary */
855
char* tmpfile; /* temporary file name */
856
char* writeobject; /* 0:nowrite or object file def */
857
char* writestate; /* 0:nowrite or state file def */
858
859
int* argf; /* global argv ARG_* flags */
860
861
char** argv; /* global argv */
862
863
Dir_t* archive; /* .SCAN archive */
864
865
Sfio_t* context; /* localview() target context */
866
867
Frame_t* frame; /* current target frame */
868
869
#if BINDINDEX
870
Binding_t source[MAXBIND+1];/* source bind table */
871
int maxsource; /* max source bind index */
872
#endif
873
Binding_t view[MAXVIEW+1];/* view bind table */
874
unsigned int maxview; /* max view bind index */
875
876
int (*compnew)(const char*, char*, void*); /* new compile rule */
877
void* comparg; /* compnew handle */
878
879
Label_t resume; /* if interpreter!=0 */
880
881
Mam_t mam; /* mam state */
882
883
Coshell_t* coshell; /* coshell handle */
884
885
Sfio_t* io[11]; /* print/read streams */
886
} State_t;
887
888
typedef struct Var_s /* variable */
889
{
890
char* name; /* name */
891
char* value; /* value */
892
Flags_t property; /* static and dynamic */
893
size_t length; /* maximum length of value */
894
char* (*builtin)(char**); /* builtin function */
895
} Var_t;
896
897
struct List_s /* rule cons cell */
898
{
899
List_t* next; /* next in list */
900
Rule_t* rule; /* list item */
901
};
902
903
/*
904
* make globals
905
*/
906
907
extern External_t external; /* external engine names */
908
extern Internal_t internal; /* internal rule and list info */
909
extern State_t state; /* engine state */
910
extern Tables_t table; /* hash table pointers */
911
912
extern char null[]; /* null string */
913
extern char tmpname[]; /* temporary name buffer */
914
915
extern short ctypes[]; /* internal character types */
916
917
extern char* idname; /* interface id name */
918
extern char* initdynamic; /* dynamic initialization */
919
extern char* initstatic; /* static initialization */
920
extern char* version; /* program version stamp */
921
922
/*
923
* make routines
924
*/
925
926
extern File_t* addfile(Dir_t*, char*, Time_t);
927
extern void addprereq(Rule_t*, Rule_t*, int);
928
extern List_t* append(List_t*, List_t*);
929
extern int apply(Rule_t*, char*, char*, char*, Flags_t);
930
extern void argcount(void);
931
extern void arscan(Rule_t*);
932
extern void artouch(char*, char*);
933
extern char* arupdate(char*);
934
extern Rule_t* associate(Rule_t*, Rule_t*, char*, List_t**);
935
extern Var_t* auxiliary(char*, int);
936
extern Rule_t* bind(Rule_t*);
937
extern void bindattribute(Rule_t*);
938
extern Rule_t* bindfile(Rule_t*, char*, int);
939
extern Rule_t* bindstate(Rule_t*, char*);
940
extern int block(int);
941
extern void candidates(void);
942
extern char* call(Rule_t*, char*);
943
extern Rule_t* catrule(char*, char*, char*, int);
944
extern char* colonlist(Sfio_t*, char*, int, int);
945
extern void compile(char*, char*);
946
extern int complete(Rule_t*, List_t*, Time_t*, Flags_t);
947
extern void compref(Rule_t*, int);
948
extern List_t* cons(Rule_t*, List_t*);
949
extern void dirscan(Rule_t*);
950
extern void drop(void);
951
extern void dump(Sfio_t*, int);
952
extern void dumpaction(Sfio_t*, const char*, char*, const char*);
953
extern void dumpjobs(int, int);
954
extern void dumpregress(Sfio_t*, const char*, const char*, char*);
955
extern void dumprule(Sfio_t*, Rule_t*);
956
extern void dumpvar(Sfio_t*, Var_t*);
957
extern void dynamic(Rule_t*);
958
extern void edit(Sfio_t*, char*, char*, char*, char*);
959
extern void expand(Sfio_t*, char*);
960
extern void explain(int, ...);
961
extern long expr(Sfio_t*, char*);
962
extern Sfio_t* fapply(Rule_t*, char*, char*, char*, Flags_t);
963
extern void finish(int);
964
extern int forcescan(const char*, char* v, void*);
965
extern char* getarg(char**, int*);
966
extern void getop(Sfio_t*, char*, int);
967
extern char* getval(char*, int);
968
extern char** globv(glob_t*, char*);
969
extern int handle(void);
970
extern int hasattribute(Rule_t*, Rule_t*, Rule_t*);
971
extern int hasafter(Rule_t*, Flags_t);
972
extern void immediate(Rule_t*);
973
extern void initcode(void);
974
extern void inithash(void);
975
extern void initrule(void);
976
extern void initscan(int);
977
extern void inittrap(void);
978
extern void initview(void);
979
extern void initwakeup(int);
980
extern void interpreter(char*);
981
extern int isoption(const char*);
982
extern int nametype(const char*, char**);
983
extern List_t* joint(Rule_t*);
984
extern List_t* listcopy(List_t*);
985
extern void listops(Sfio_t*, int);
986
extern int load(Sfio_t*, const char*, int, int);
987
extern int loadable(Sfio_t*, Rule_t*, int);
988
extern void localvar(Sfio_t*, Var_t*, char*, int);
989
extern char* localview(Rule_t*);
990
extern void lockstate(int);
991
extern int make(Rule_t*, Time_t*, char*, Flags_t);
992
extern int makeafter(Rule_t*, Flags_t);
993
extern int makebefore(Rule_t*);
994
extern Rule_t* makerule(char*);
995
extern void maketop(Rule_t*, int, char*);
996
extern char* mamcanon(char*);
997
extern ssize_t mamerror(int, const void*, size_t);
998
extern char* mamname(Rule_t*);
999
extern void mampop(Sfio_t*, Rule_t*, Flags_t);
1000
extern int mampush(Sfio_t*, Rule_t*, Flags_t);
1001
extern Sfio_t* mamout(Rule_t*);
1002
extern char* maprule(char*, Rule_t*);
1003
extern void merge(Rule_t*, Rule_t*, int);
1004
extern void mergestate(Rule_t*, Rule_t*);
1005
extern void metaclose(Rule_t*, Rule_t*, int);
1006
extern void metaexpand(Sfio_t*, char*, char*);
1007
extern Rule_t* metaget(Rule_t*, Frame_t*, char*, Rule_t**);
1008
extern Rule_t* metainfo(int, char*, char*, int);
1009
extern int metamatch(char*, char*, char*);
1010
extern Rule_t* metarule(char*, char*, int);
1011
extern void negate(Rule_t*, Rule_t*);
1012
extern void* newchunk(char**, size_t);
1013
extern void newfile(Rule_t*, char*, Time_t);
1014
extern char* objectfile(void);
1015
extern void parentage(Sfio_t*, Rule_t*, char*);
1016
extern int parse(Sfio_t*, char*, char*, Sfio_t*);
1017
extern char* parsefile(void);
1018
extern char* pathname(char*, Rule_t*);
1019
extern void poplocal(void*);
1020
extern int prereqchange(Rule_t*, List_t*, Rule_t*, List_t*);
1021
extern void punt(int);
1022
extern void* pushlocal(void);
1023
extern void readcheck(void);
1024
extern void readclear(void);
1025
extern void readenv(void);
1026
extern int readfile(char*, int, char*);
1027
extern void readstate(void);
1028
extern void rebind(Rule_t*, int);
1029
extern void remdup(List_t*);
1030
extern void remtmp(int);
1031
extern int resolve(char*, int, int);
1032
extern int rstat(char*, Stat_t*, int);
1033
extern void rules(char*);
1034
extern Rule_t* rulestate(Rule_t*, int);
1035
extern void savestate(void);
1036
extern List_t* scan(Rule_t*, Time_t*);
1037
extern int scanargs(int, char**, int*);
1038
extern int set(char*, int, Sfio_t*);
1039
extern Var_t* setvar(char*, char*, int);
1040
extern void shquote(Sfio_t*, char*);
1041
extern Rule_t* source(Rule_t*);
1042
extern int special(Rule_t*);
1043
extern char* statefile(void);
1044
extern Rule_t* staterule(int, Rule_t*, char*, int);
1045
extern Time_t statetime(Rule_t*, int);
1046
extern int statetimeq(Rule_t*, Rule_t*);
1047
extern int strprintf(Sfio_t*, const char*, char*, int, int);
1048
extern void terminate(void);
1049
extern char* timefmt(const char*, Time_t);
1050
extern Time_t timenum(const char*, char**);
1051
extern char* timestr(Time_t);
1052
extern void trigger(Rule_t*, Rule_t*, char*, Flags_t);
1053
extern int unbind(const char*, char*, void*);
1054
extern Dir_t* unique(Rule_t*);
1055
extern void unparse(int);
1056
extern Var_t* varstate(Rule_t*, int);
1057
extern void wakeup(Seconds_t, List_t*);
1058
1059