1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1984-2013 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 <glenn.s.fowler@gmail.com> * 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 TMX_NOW /* 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* serialize; /* - rule pointer */ 617 Rule_t* special; /* .SPECIAL rule pointer */ 618 Rule_t* tmplist; /* .TMPLIST rule pointer */ 619 Rule_t* unbind; /* .UNBIND rule pointer */ 620 Rule_t* view; /* .VIEW rule pointer */ 621 622 /* 623 * pattern association rules 624 */ 625 626 Rule_t* append_p; /* .APPEND. rule pointer */ 627 Rule_t* assert_p; /* .ASSERT. rule pointer */ 628 Rule_t* assign_p; /* .ASSIGN. rule pointer */ 629 Rule_t* attribute_p; /* .ATTRIBUTE. rule pointer */ 630 Rule_t* bind_p; /* .BIND. rule pointer */ 631 Rule_t* dontcare_p; /* .DONTCARE. rule pointer */ 632 Rule_t* insert_p; /* .INSERT. rule pointer */ 633 Rule_t* require_p; /* .REQUIRE. rule pointer */ 634 Rule_t* source_p; /* .SOURCE. rule pointer */ 635 636 /* 637 * miscellaneous internal info 638 */ 639 640 Sfio_t* met; /* metarule expansion buffer */ 641 Sfio_t* nam; /* name generation buffer */ 642 Sfio_t* tmp; /* very temporary work buffer */ 643 Sfio_t* val; /* initial getval return buffer */ 644 Sfio_t* wrk; /* very temporary work buffer */ 645 646 char* freelists; /* free lists list */ 647 char* freerules; /* free rules list */ 648 char* freevars; /* free variables list */ 649 650 char* issource; /* internal.source* match pat */ 651 char* openfile; /* bind()-scan() optimization */ 652 char* pwd; /* PWD value */ 653 char* ptr; /* temporary for sfstrptr() */ 654 655 int openfd; /* bind()-scan() optimization */ 656 int pwdlen; /* strlen(internal.pwd) */ 657 } Internal_t; 658 659 typedef struct External_s /* external engine name info */ 660 { 661 /* 662 * names of variables defined by engine, init, or environment 663 */ 664 665 char* args; /* candidate args file name(s) */ 666 char* convert; /* makefile converter patterns */ 667 char* file; /* main input makefile name */ 668 char* files; /* candidate makefile name(s) */ 669 char* import; /* explicit env override vars */ 670 char* lib; /* related file lib directory */ 671 char* make; /* program path name */ 672 char* nproc; /* # jobs for compatibility */ 673 char* old; /* old program path name */ 674 char* pwd; /* pwd name */ 675 char* rules; /* candidate rules file name(s) */ 676 char* skip; /* order directory skip pattern */ 677 char* version; /* engine version stamp */ 678 char* viewdot; /* . view dir list */ 679 char* viewnode; /* view node dir list */ 680 681 /* 682 * infrequently used engine interface names 683 */ 684 685 char* compdone; /* made after makefile compiled */ 686 char* compinit; /* made before makefile compiled*/ 687 char* done; /* made just before exit */ 688 char* init; /* made before first user target*/ 689 char* interrupt; /* made on first interrupt */ 690 char* jobdone; /* made when each job done */ 691 char* makedone; /* made after done */ 692 char* makeinit; /* made after before init */ 693 char* makeprompt; /* made just before each prompt */ 694 char* makerun; /* made just before each job */ 695 char* mamname; /* external mam atom name */ 696 char* mamaction; /* external mam action */ 697 char* order; /* :W=[OPR]: favorites */ 698 699 /* 700 * related file suffixes 701 */ 702 703 char* lock; /* make lock file suffix */ 704 char* object; /* make object file suffix */ 705 char* source; /* make source file suffix */ 706 char* state; /* make state file suffix */ 707 char* tmp; /* make temporary file suffix */ 708 } External_t; 709 710 typedef struct Tables_s /* hash table pointers */ 711 { 712 Hash_table_t* ar; /* archives dir info by name */ 713 Hash_table_t* bound; /* directory of bound file */ 714 Hash_table_t* dir; /* directories and archives */ 715 Hash_table_t* file; /* files from scanned dirs */ 716 Hash_table_t* oldvalue; /* old variable values */ 717 Hash_table_t* regress; /* regression path maps */ 718 Hash_table_t* rule; /* rule names */ 719 Hash_table_t* var; /* variable names */ 720 } Tables_t; 721 722 #define BIND_EXISTS (1<<0) /* statefile loaded */ 723 #define BIND_LOADED (1<<1) /* statefile loaded */ 724 725 typedef struct Binding_s /* binding info */ 726 { 727 #if BINDINDEX 728 Rule_t* path; /* path name component */ 729 #else 730 char* path; /* path name component */ 731 #endif 732 char* root; /* path root */ 733 short pathlen; /* path length */ 734 short rootlen; /* root length */ 735 unsigned char flags; /* BIND_* flags */ 736 unsigned char map; /* external index map */ 737 } Binding_t; 738 739 typedef struct Label_s /* resume label */ 740 { 741 jmp_buf label; 742 } Label_t; 743 744 typedef struct Mam_s /* mam state */ 745 { 746 Sfdisc_t disc; /* output discipline -- first! */ 747 748 int hold; /* output hold nest level */ 749 int level; /* next error() message level */ 750 int parent; /* mam parent label */ 751 int rootlen; /* strlen(state.mam.root) */ 752 753 char* label; /* instruction label */ 754 char* options; /* option string */ 755 char* root; /* names relative to this root */ 756 char* type; /* mam type name */ 757 758 Sfio_t* out; /* output stream pointer */ 759 760 unsigned char dynamic; /* dynamic mam */ 761 unsigned char regress; /* regression mam */ 762 unsigned char statix; /* static mam */ 763 764 unsigned char dontcare; /* emit dontcare rules too */ 765 unsigned char port; /* emit porting hints */ 766 } Mam_t; 767 768 typedef struct State_s /* program state */ 769 { 770 unsigned char accept; /* accept all existing targets */ 771 unsigned char alias; /* enable directory aliasing */ 772 unsigned char base; /* compile base|global rules */ 773 unsigned char caught; /* a signal was caught */ 774 unsigned char compile; /* make object compile state */ 775 unsigned char compileonly; /* only compile (force) */ 776 unsigned char compatibility; /* disable compatibility msgs */ 777 unsigned char cross; /* don't run gen'd executables */ 778 unsigned char exec; /* execute shell actions */ 779 unsigned char expandall; /* expanding $(...) */ 780 unsigned char expandview; /* expand paths if fsview!=0 */ 781 unsigned char explain; /* explain reason for actions */ 782 unsigned char explicitrules; /* explicit rules statement */ 783 unsigned char finish; /* in finish() */ 784 unsigned char force; /* force target updates */ 785 unsigned char forceread; /* force makefiles to be read */ 786 unsigned char forcescan; /* force implicit prereq scan */ 787 unsigned char fsview; /* file system handles views */ 788 unsigned char fullscan; /* scan for impl state prereqs */ 789 unsigned char global; /* reading global rules */ 790 unsigned char ignore; /* ignore sh action errors */ 791 unsigned char ignorelock; /* ignore state lock */ 792 unsigned char import; /* import var def precedence */ 793 unsigned char init; /* engine initialization */ 794 unsigned char intermediate; /* force intermediate targets */ 795 unsigned char interpreter; /* in interpreter main loop */ 796 unsigned char keepgoing; /* continue w/ sibling prereqs */ 797 unsigned char list; /* list readable definitions */ 798 unsigned char localview; /* automatics to local view */ 799 #if BINDINDEX 800 unsigned char logical; /* emit logical pathnames */ 801 #endif 802 unsigned char never; /* really - don't exec anything */ 803 unsigned char op; /* currently parsing operator */ 804 unsigned char override; /* override explicit rules */ 805 unsigned char pushed; /* --global state */ 806 unsigned char push_global; /* --global state */ 807 unsigned char push_user; /* --global state */ 808 unsigned char preprocess; /* preprocess all makefiles */ 809 unsigned char reading; /* currently reading makefile */ 810 unsigned char readonly; /* current vars|opts readonly */ 811 unsigned char ruledump; /* dump rule information */ 812 unsigned char savestate; /* must save state variables */ 813 unsigned char scan; /* scan|check implicit prereqs */ 814 unsigned char serialize; /* serialize concurrent output */ 815 unsigned char silent; /* run silently */ 816 unsigned char strictview; /* strict views */ 817 unsigned char targetcontext; /* expand in target dir context */ 818 unsigned char touch; /* touch out of date targets */ 819 unsigned char user; /* user activities started */ 820 unsigned char val; /* internal.val in use */ 821 unsigned char vardump; /* dump variable information */ 822 unsigned char virtualdot; /* fsview . is virtual */ 823 unsigned char waiting; /* waiting for job completion */ 824 unsigned char warn; /* enable source file warnings */ 825 826 int argc; /* global argc */ 827 int believe; /* believe state from this level*/ 828 int errors; /* keepgoing error count */ 829 int interrupt; /* interrupt causing exit */ 830 int jobs; /* sh action concurrency level */ 831 int pid; /* make pid */ 832 int readstate; /* state files to this view ok */ 833 int reread; /* input makefile reread count */ 834 int stateview; /* state file view index */ 835 int tabstops; /* tab stops for makefile parse */ 836 int targetview; /* most recent active targ view */ 837 int tolerance; /* time comparison tolerance */ 838 int unwind; /* make() dontcare unwind level */ 839 840 Flags_t questionable; /* questionable code enable bits*/ 841 Flags_t test; /* test code enable bits */ 842 843 Time_t start; /* start time of this make */ 844 845 char* corrupt; /* corrupt state file action */ 846 char* errorid; /* error message id */ 847 char* hold; /* hold error trap */ 848 char* loading; /* loading this object file */ 849 char* makefile; /* first makefile name */ 850 char* objectfile; /* make object file name */ 851 char* regress; /* output for regression test */ 852 char* rules; /* base rules base name */ 853 char* statefile; /* state variable file name */ 854 char* targetprefix; /* target prefix dir separator */ 855 char* tmppchar; /* macro char* temporary */ 856 char* tmpfile; /* temporary file name */ 857 char* writeobject; /* 0:nowrite or object file def */ 858 char* writestate; /* 0:nowrite or state file def */ 859 860 int* argf; /* global argv ARG_* flags */ 861 862 char** argv; /* global argv */ 863 864 Dir_t* archive; /* .SCAN archive */ 865 866 Sfio_t* context; /* localview() target context */ 867 868 Frame_t* frame; /* current target frame */ 869 870 #if BINDINDEX 871 Binding_t source[MAXBIND+1];/* source bind table */ 872 int maxsource; /* max source bind index */ 873 #endif 874 Binding_t view[MAXVIEW+1];/* view bind table */ 875 unsigned int maxview; /* max view bind index */ 876 877 int (*compnew)(const char*, char*, void*); /* new compile rule */ 878 void* comparg; /* compnew handle */ 879 880 Label_t resume; /* if interpreter!=0 */ 881 882 Mam_t mam; /* mam state */ 883 884 Coshell_t* coshell; /* coshell handle */ 885 886 Sfio_t* io[11]; /* print/read streams */ 887 } State_t; 888 889 typedef struct Var_s /* variable */ 890 { 891 char* name; /* name */ 892 char* value; /* value */ 893 Flags_t property; /* static and dynamic */ 894 size_t length; /* maximum length of value */ 895 char* (*builtin)(char**); /* builtin function */ 896 } Var_t; 897 898 struct List_s /* rule cons cell */ 899 { 900 List_t* next; /* next in list */ 901 Rule_t* rule; /* list item */ 902 }; 903 904 /* 905 * make globals 906 */ 907 908 extern External_t external; /* external engine names */ 909 extern Internal_t internal; /* internal rule and list info */ 910 extern State_t state; /* engine state */ 911 extern Tables_t table; /* hash table pointers */ 912 913 extern char null[]; /* null string */ 914 extern char tmpname[]; /* temporary name buffer */ 915 916 extern short ctypes[]; /* internal character types */ 917 918 extern char* idname; /* interface id name */ 919 extern char* initdynamic; /* dynamic initialization */ 920 extern char* initstatic; /* static initialization */ 921 extern char* version; /* program version stamp */ 922 923 /* 924 * make routines 925 */ 926 927 extern File_t* addfile(Dir_t*, char*, Time_t); 928 extern void addprereq(Rule_t*, Rule_t*, int); 929 extern List_t* append(List_t*, List_t*); 930 extern int apply(Rule_t*, char*, char*, char*, Flags_t); 931 extern void argcount(void); 932 extern void arscan(Rule_t*); 933 extern void artouch(char*, char*); 934 extern char* arupdate(char*); 935 extern Rule_t* associate(Rule_t*, Rule_t*, char*, List_t**); 936 extern Var_t* auxiliary(char*, int); 937 extern Rule_t* bind(Rule_t*); 938 extern void bindattribute(Rule_t*); 939 extern Rule_t* bindfile(Rule_t*, char*, int); 940 extern Rule_t* bindstate(Rule_t*, char*); 941 extern int block(int); 942 extern void candidates(void); 943 extern char* call(Rule_t*, char*); 944 extern Rule_t* catrule(char*, char*, char*, int); 945 extern char* colonlist(Sfio_t*, char*, int, int); 946 extern void compile(char*, char*); 947 extern int complete(Rule_t*, List_t*, Time_t*, Flags_t); 948 extern void compref(Rule_t*, int); 949 extern List_t* cons(Rule_t*, List_t*); 950 extern void dirscan(Rule_t*); 951 extern void drop(void); 952 extern void dump(Sfio_t*, int); 953 extern void dumpaction(Sfio_t*, const char*, char*, const char*); 954 extern void dumpjobs(int, int); 955 extern void dumpregress(Sfio_t*, const char*, const char*, char*); 956 extern void dumprule(Sfio_t*, Rule_t*); 957 extern void dumpvar(Sfio_t*, Var_t*); 958 extern void dynamic(Rule_t*); 959 extern void edit(Sfio_t*, char*, char*, char*, char*); 960 extern void expand(Sfio_t*, char*); 961 extern void explain(int, ...); 962 extern long expr(Sfio_t*, char*); 963 extern Sfio_t* fapply(Rule_t*, char*, char*, char*, Flags_t); 964 extern void finish(int); 965 extern int forcescan(const char*, char* v, void*); 966 extern char* getarg(char**, int*); 967 extern void getop(Sfio_t*, char*, int); 968 extern char* getval(char*, int); 969 extern char** globv(glob_t*, char*); 970 extern int handle(void); 971 extern int hasattribute(Rule_t*, Rule_t*, Rule_t*); 972 extern int hasafter(Rule_t*, Flags_t); 973 extern void immediate(Rule_t*); 974 extern void initcode(void); 975 extern void inithash(void); 976 extern void initrule(void); 977 extern void initscan(int); 978 extern void inittrap(void); 979 extern void initview(void); 980 extern void initwakeup(int); 981 extern void interpreter(char*); 982 extern int isoption(const char*); 983 extern int nametype(const char*, char**); 984 extern List_t* joint(Rule_t*); 985 extern List_t* listcopy(List_t*); 986 extern void listops(Sfio_t*, int); 987 extern int load(Sfio_t*, const char*, int, int); 988 extern int loadable(Sfio_t*, Rule_t*, int); 989 extern void localvar(Sfio_t*, Var_t*, char*, int); 990 extern char* localview(Rule_t*); 991 extern void lockstate(int); 992 extern int make(Rule_t*, Time_t*, char*, Flags_t); 993 extern int makeafter(Rule_t*, Flags_t); 994 extern int makebefore(Rule_t*); 995 extern Rule_t* makerule(char*); 996 extern void maketop(Rule_t*, int, char*); 997 extern char* mamcanon(char*); 998 extern ssize_t mamerror(int, const void*, size_t); 999 extern char* mamname(Rule_t*); 1000 extern void mampop(Sfio_t*, Rule_t*, Flags_t); 1001 extern int mampush(Sfio_t*, Rule_t*, Flags_t); 1002 extern Sfio_t* mamout(Rule_t*); 1003 extern char* maprule(char*, Rule_t*); 1004 extern void merge(Rule_t*, Rule_t*, int); 1005 extern void mergestate(Rule_t*, Rule_t*); 1006 extern void metaclose(Rule_t*, Rule_t*, int); 1007 extern void metaexpand(Sfio_t*, char*, char*); 1008 extern Rule_t* metaget(Rule_t*, Frame_t*, char*, Rule_t**); 1009 extern Rule_t* metainfo(int, char*, char*, int); 1010 extern int metamatch(char*, char*, char*); 1011 extern Rule_t* metarule(char*, char*, int); 1012 extern void negate(Rule_t*, Rule_t*); 1013 extern void* newchunk(char**, size_t); 1014 extern void newfile(Rule_t*, char*, Time_t); 1015 extern char* objectfile(void); 1016 extern void parentage(Sfio_t*, Rule_t*, char*); 1017 extern int parse(Sfio_t*, char*, char*, Sfio_t*); 1018 extern char* parsefile(void); 1019 extern char* pathname(char*, Rule_t*); 1020 extern void poplocal(void*); 1021 extern int prereqchange(Rule_t*, List_t*, Rule_t*, List_t*); 1022 extern void punt(int); 1023 extern void* pushlocal(void); 1024 extern void readcheck(void); 1025 extern void readclear(void); 1026 extern void readenv(void); 1027 extern int readfile(char*, int, char*); 1028 extern void readstate(void); 1029 extern void rebind(Rule_t*, int); 1030 extern void remdup(List_t*); 1031 extern void remtmp(int); 1032 extern int resolve(char*, int, int); 1033 extern int rstat(char*, Stat_t*, int); 1034 extern void rules(char*); 1035 extern Rule_t* rulestate(Rule_t*, int); 1036 extern void savestate(void); 1037 extern List_t* scan(Rule_t*, Time_t*); 1038 extern int scanargs(int, char**, int*); 1039 extern int set(char*, int, Sfio_t*); 1040 extern Var_t* setvar(char*, char*, int); 1041 extern void shquote(Sfio_t*, char*); 1042 extern Rule_t* source(Rule_t*); 1043 extern int special(Rule_t*); 1044 extern char* statefile(void); 1045 extern Rule_t* staterule(int, Rule_t*, char*, int); 1046 extern Time_t statetime(Rule_t*, int); 1047 extern int statetimeq(Rule_t*, Rule_t*); 1048 extern int strprintf(Sfio_t*, const char*, char*, int, int); 1049 extern void terminate(void); 1050 extern char* timefmt(const char*, Time_t); 1051 extern Time_t timenum(const char*, char**); 1052 extern char* timestr(Time_t); 1053 extern void trigger(Rule_t*, Rule_t*, char*, Flags_t); 1054 extern int unbind(const char*, char*, void*); 1055 extern Dir_t* unique(Rule_t*); 1056 extern void unparse(int); 1057 extern Var_t* varstate(Rule_t*, int); 1058 extern void wakeup(Seconds_t, List_t*); 1059