/* * get command line flags, initialize keywords & traps. * get values from environment. * set $pid, $cflag, $* * fabricate bootstrap code and start it (*=(argv);. /usr/lib/rcmain $*) * start interpreting code */ int main(int argc, char *argv[]) { code bootstrap[32]; char num[12], *rcmain; int i; /* needed for rcmain later */ putenv("PLAN9", unsharp("#9")); argc = getflags(argc, argv, "ftjSsrdiIlxepvVc:1m:1[command]", 1); if(argc==-1) usage("[file [arg ...]]"); if(argv[0][0]=='-') flag['l'] = flagset; if(flag['I']) flag['i'] = 0; else if(flag['i']==0 && argc==1 && Isatty(0)) flag['i'] = flagset; rcmain = flag['m'] ? flag['m'][0] : Rcmain(); err = openfd(2); kinit(); Trapinit(); Vinit(); inttoascii(num, mypid = getpid()); pathinit(); setvar("pid", newword(num, (word *)0)); setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0) :(word *)0); setvar("rcname", newword(argv[0], (word *)0)); i = 0; bootstrap[i++].i = 1; bootstrap[i++].f = Xmark; bootstrap[i++].f = Xword; bootstrap[i++].s="*"; bootstrap[i++].f = Xassign; bootstrap[i++].f = Xmark; bootstrap[i++].f = Xmark; bootstrap[i++].f = Xword; bootstrap[i++].s="*"; bootstrap[i++].f = Xdol; bootstrap[i++].f = Xword; bootstrap[i++].s = rcmain; bootstrap[i++].f = Xword; bootstrap[i++].s="."; bootstrap[i++].f = Xsimple; bootstrap[i++].f = Xexit; bootstrap[i].i = 0; start(bootstrap, 1, (var *)0); /* prime bootstrap argv */ pushlist(); argv0 = strdup(argv[0]); for(i = argc-1;i!=0;--i) pushword(argv[i]); for(;;){ if(flag['r']) pfnc(err, runq); runq->pc++; (*runq->code[runq->pc-1].f)(); if(ntrap) dotrap(); } }
void readenv(void) { char **p, *s; Word *w; for(p = environ; *p; p++){ /* rsc 5/5/2004 -- This misparses fn#cd={whatever} s = shname(*p); if(*s == '=') { *s = 0; w = newword(s+1); } else w = newword(""); */ s = strchr(*p, '='); if(s){ *s = 0; w = newword(s+1); } else w = newword(""); if (symlook(*p, S_INTERNAL, 0)) continue; s = strdup(*p); setvar(s, (void *)w); symlook(s, S_EXPORTED, (void*)"")->u.ptr = ""; } }
void bigpath(var *v) { /* convert $PATH to $path */ char *p, *q; word **l, *w; if(v->val == nil){ _setvar("path", nil, 0); return; } p = v->val->word; w = nil; l = &w; /* * Doesn't handle escaped colon nonsense. */ if(p[0] == 0) p = nil; while(p){ q = strchr(p, ':'); if(q) *q = 0; *l = newword(p[0] ? p : ".", nil); l = &(*l)->next; if(q){ *q = ':'; p = q+1; }else p = nil; } _setvar("path", w, 0); }
struct e *add(int x, int y, char *s, void *f, int len, enum tagtype tt, enum wordtype wt) { struct word *w=newword(); struct tag1 *t=tags.end++; t->x=x; t->y=y; t->open=0; t->e=&w->def; t->e->t=tt; t->e->nospace=nospace; t->e->w=w; w->gen=gen; w->data=f; w->len=len; w->t=wt; strncpy(w->s,s,7); resize(w); if(wt==compiled) { struct e *e=editcode_e++; *e=final; w->def.n=e; } else {
void pushword(char *wd) { if(runq->argv==0) panic("pushword but no argv!", 0); runq->argv->words = newword(wd, runq->argv->words); }
void Xdol(void) { word *a, *star; char *s, *t; int n; if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } s = runq->argv->words->word; deglob(s); n = 0; for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; a = runq->argv->next->words; if(n==0 || *t) a = copywords(vlook(s)->val, a); else{ star = vlook("*")->val; if(star && 1<=n && n<=count(star)){ while(--n) star = star->next; a = newword(star->word, a); } } poplist(); runq->argv->words = a; }
void vinit(void) { char **env, *name, *val, *p; int i; Word *w; Io *f; int n; Var *v; env = _environ; for(i=0; env[i]; free(name), i++) { name = strdup(env[i]); p = strchr(name, '='); if(p == 0 || p == name) continue; *p = 0; val = p+1; n = strlen(val); if(n == 0) continue; if(strncmp(name, "fn#", 3)!=0) { /* variable */ w = 0; p = val+n-1; while(*p) { if(*p == IWS) *p-- = 0; for(; *p && *p != IWS; p--) ; w=newword(p+1, w); } setvar(name, w); vlook(name)->changed=0; } else { /* function */ f = opencore(val, n); execcmds(f); } } v = vlook("path"); p = getenv("path"); if(v->val == 0 && p) v->val = newword(p, 0); }
word* copywords(word *a, word *tail) { word *v = 0, **end; for(end=&v;a;a = a->next,end=&(*end)->next) *end = newword(a->word, 0); *end = tail; return v; }
void readenv(void) { char **p, *s; Word *w; for(p = environ; *p; p++) { s = shname(*p); if(*s == '=') { *s = 0; w = newword(s+1); } else w = newword(""); if (symlook(*p, S_INTERNAL, 0)) continue; s = strdup9(*p); setvar(s, (void *)w); symlook(s, S_EXPORTED, (void *)"")->value = ""; } }
void addw(Word *w, char *s) { Word *lw; for(lw = w; w = w->next; lw = w){ if(strcmp(s, w->s) == 0) return; } lw->next = newword(s); }
void Vinit(void) { int dir, f, len, i, n, nent; char *buf, *s; char envname[Maxenvname]; word *val; Dir *ent; dir = open("/env", OREAD); if(dir<0){ pfmt(err, "rc: can't open /env: %r\n"); return; } ent = nil; for(;;){ nent = dirread(dir, &ent); if(nent <= 0) break; for(i = 0; i<nent; i++){ len = ent[i].length; if(len && strncmp(ent[i].name, "fn#", 3)!=0){ snprint(envname, sizeof envname, "/env/%s", ent[i].name); if((f = open(envname, 0))>=0){ buf = emalloc(len+1); n = readn(f, buf, len); if (n <= 0) buf[0] = '\0'; else buf[n] = '\0'; val = 0; /* Charitably add a 0 at the end if need be */ if(buf[len-1]) buf[len++]='\0'; s = buf+len-1; for(;;){ while(s!=buf && s[-1]!='\0') --s; val = newword(s, val); if(s==buf) break; --s; } setvar(ent[i].name, val); vlook(ent[i].name)->changed = 0; close(f); efree(buf); } } } free(ent); } close(dir); }
void globdir(uint8_t *p, uint8_t *namep) { uint8_t *t, *newp; int f; /* scan the pattern looking for a component with a metacharacter in it */ if(*p=='\0'){ globv = newword(globname, globv); return; } t = namep; newp = p; while(*newp){ if(*newp==GLOB) break; *t=*newp++; if(*t++=='/'){ namep = t; p = newp; } } /* If we ran out of pattern, append the name if accessible */ if(*newp=='\0'){ *t='\0'; if(access(globname, 0)==0) globv = newword(globname, globv); return; } /* read the directory and recur for any entry that matches */ *namep='\0'; if((f = Opendir(globname[0]?globname:"."))<0) return; while(*newp!='/' && *newp!='\0') newp++; while(Readdir(f, namep, *newp=='/')){ if(matchfn(namep, p)){ for(t = namep;*t;t++); globdir(newp, t); } } Closedir(f); }
/* break string of values into words at 01's or nulls*/ static Word * encodenulls(char *s, int n) { Word *w, *head; char *cp; head = w = 0; while (n-- > 0) { for (cp = s; *cp && *cp != '\0'; cp++) n--; *cp = 0; if (w) { w->next = newword(s); w = w->next; } else head = w = newword(s); s = cp+1; } if (!head) head = newword(""); return head; }
void glob(void *ap) { uint8_t *p = ap; word *svglobv = globv; int globlen = Globsize(ap); if(!globlen){ deglob(p); globv = newword((char *)p, globv); return; } globname = emalloc(globlen); globname[0]='\0'; globdir(p, (uint8_t *)globname); efree(globname); if(svglobv==globv){ deglob(p); globv = newword((char *)p, globv); } else globsort(globv, svglobv); }
word* copynwords(word *a, word *tail, int n) { word *v, **end; v = 0; end = &v; while(n-- > 0){ *end = newword(a->word, 0); end = &(*end)->next; a = a->next; } *end = tail; return v; }
word* conclist(word *lp, word *rp, word *tail) { char *buf; word *v; if(lp->next || rp->next) tail = conclist(lp->next==0?lp:lp->next, rp->next==0?rp:rp->next, tail); buf = emalloc(strlen(lp->word)+strlen(rp->word)+1); strcpy(buf, lp->word); strcat(buf, rp->word); v = newword(buf, tail); efree(buf); return v; }
TWERD *make_tess_word( //convert word WERD *word, //word to do TEXTROW *row //fake row ) { TWERD *tessword; //tess format tessword = newword (); //use old allocator tessword->row = row; //give them something //copy string tessword->correct = strsave (word->text ()); tessword->guess = NULL; tessword->blobs = make_tess_blobs (word->blob_list ()); tessword->blanks = 1; tessword->blobcount = word->blob_list ()->length (); tessword->next = NULL; return tessword; }
/******************************************************************** * NAME * newbound * DESCR * Make a new sentence boundary word structure. This is * a "word" with a morpheme of #. * RETRN * New word structure. */ static Word *newbound( void ) { Word *t; Ambig *amb; Morph *mp; t = newword(); t->numamb = 1; amb = t->ambigs = newambig(); amb->cat = ""; mp = amb->morphs = newmorph(); mp->type = RT; /* Type is root */ mp->name = (unsigned char *)"#"; mp->cat = ""; return( t ); }
Envy* buildenv(Job *j, int slot) { char **p, *cp, *qp; Word *w, *v, **l; int i; char buf[256]; envupd("target", wdup(j->t)); if(j->r->attr®EXP) envupd("stem",newword("")); else envupd("stem", newword(j->stem)); envupd("prereq", wdup(j->p)); sprint(buf, "%d", getpid()); envupd("pid", newword(buf)); sprint(buf, "%d", slot); envupd("nproc", newword(buf)); envupd("newprereq", wdup(j->np)); envupd("alltarget", wdup(j->at)); l = &v; v = w = wdup(j->np); while(w){ cp = strchr(w->s, '('); if(cp){ qp = strchr(cp+1, ')'); if(qp){ *qp = 0; strcpy(w->s, cp+1); l = &w->next; w = w->next; continue; } } *l = w->next; free(w->s); free(w); w = *l; } envupd("newmember", v); /* update stem0 -> stem9 */ for(p = myenv; *p; p++) if(strcmp(*p, "stem0") == 0) break; for(i = 0; *p; i++, p++){ if((j->r->attr®EXP) && j->match[i]) envupd(*p, newword(j->match[i])); else envupd(*p, newword("")); } return envy; }
static Word* expandvar(char **s) { Word *w; Bufblock *buf; Symtab *sym; char *cp, *begin, *end; begin = *s; (*s)++; /* skip the '{' */ buf = varname(s); if (buf == 0) return 0; cp = *s; if (*cp == '}') { /* ${name} variant*/ (*s)++; /* skip the '}' */ w = varmatch(buf->start, s); freebuf(buf); return w; } if (*cp != ':') { SYNERR(-1); fprint(2, "bad variable name <%s>\n", buf->start); freebuf(buf); return 0; } cp++; end = charin(cp , "}"); if(end == 0){ SYNERR(-1); fprint(2, "missing '}': %s\n", begin); Exit(); } *end = 0; *s = end+1; sym = symlook(buf->start, S_VAR, 0); if(sym == 0 || sym->value == 0) w = newword(buf->start); else w = subsub((Word*) sym->value, cp, end); freebuf(buf); return w; }
void yyerror(char *m) { pfmt(err, "rc: "); if(runq->cmdfile && !runq->iflag) pfmt(err, "%s:%d: ", runq->cmdfile, runq->lineno); else if(runq->cmdfile) pfmt(err, "%s: ", runq->cmdfile); else if(!runq->iflag) pfmt(err, "line %d: ", runq->lineno); if(tok[0] && tok[0]!='\n') pfmt(err, "token %q: ", tok); pfmt(err, "%s\n", m); flush(err); lastword = 0; lastdol = 0; while(lastc!='\n' && lastc!=EOF) advance(); nerror++; setvar("status", newword(m, (word *)0)); }
static struct psfontmap *SearchPSFontMap(char* fontname, struct filemmap* search_mmap) { static char *pos=NULL,*end=NULL; static struct filemmap* searching_mmap=NULL; struct psfontmap *entry=NULL; if (pos==end && search_mmap!=searching_mmap) { searching_mmap=search_mmap; pos=searching_mmap->data; end=searching_mmap->data+searching_mmap->size; } while(pos<end && (entry==NULL || strcmp(entry->tfmname,fontname)!=0)) { while(pos < end && (*pos=='\r' || *pos=='\n' || *pos==' ' || *pos=='\t' || *pos=='%' || *pos=='*' || *pos==';' || *pos=='#')) { while(pos < end && *pos!='\r' && *pos!='\n') pos++; /* skip comments/empty rows */ pos++; } if (pos < end) { entry=NewPSFont(NULL); entry->line = pos; /* skip <something and quoted entries */ while(pos < end && (*pos=='<' || *pos=='"')) { if (*pos=='<') while(pos < end && *pos!=' ' && *pos!='\t') pos++; else while(pos < end && *pos!='"') pos++; while(pos < end && (*pos==' ' || *pos=='\t')) pos++; } /* first word is font name */ entry->tfmname = newword(&pos,end); while(pos < end && *pos!='\r' && *pos!='\n') pos++; entry->end = pos; } pos++; } if (entry!=NULL && strcmp(entry->tfmname,fontname)!=0) entry=NULL; return(entry); }
void setstatus(char *s) { setvar("status", newword(s, (word *)0)); }
static void ReadPSFontMap(struct psfontmap *entry) { char *pos,*end,*psname; int nameno = 0; DEBUG_PRINT(DEBUG_FT,("\n PSFONTMAP: %s ",entry->tfmname)); pos=entry->line; end=entry->end; while(pos < end) { if (*pos=='<') { /* filename follows */ pos++; if (pos<end && *pos=='<') { /* <<download.font */ pos++; entry->psfile = newword((char**)&pos,end); DEBUG_PRINT(DEBUG_FT,("<%s ",entry->psfile)); } else if (pos<end && *pos=='[') { /* <[encoding.file */ pos++; entry->encname = newword((char**)&pos,end); DEBUG_PRINT(DEBUG_FT,("<[%s ",entry->encname)); } else { /* <some.file */ char* word =newword((char**)&pos,end); if (strncmp(word+strlen(word)-4,".enc",4)==0) {/* <some.enc */ entry->encname=word; DEBUG_PRINT(DEBUG_FT,("<[%s ",entry->encname)); } else { /* <font */ entry->psfile=word; DEBUG_PRINT(DEBUG_FT,("<%s ",entry->psfile)); } } } else if (*pos=='"') { /* PS code: reencoding/tranformation exists */ char *word; double cxx=1.0,cxy=0.0; pos++; DEBUG_PRINT(DEBUG_FT,("\"")); while(pos < end && *pos!='"') { word=newword((char**)&pos,end); while(pos < end && (*pos==' ' || *pos=='\t')) pos++; if (pos+10<end && strncmp(pos,"ExtendFont",10)==0) { cxx=strtod(word,NULL); pos+=10; DEBUG_PRINT(DEBUG_FT,("%f ExtendFont ",cxx)); } else if (pos+9<end && strncmp(pos,"SlantFont",9)==0) { pos+=9; cxy=strtod(word,NULL); DEBUG_PRINT(DEBUG_FT,("%f SlantFont ",cxy)); } else if (pos+12<end && strncmp(pos,"ReEncodeFont",12)==0) { pos+=12; DEBUG_PRINT(DEBUG_FT,("%s ReEncodeFont ",word)); } else { DEBUG_PRINT(DEBUG_FT,("(?:%s) ",word)); } free(word); } #ifdef HAVE_FT2 entry->ft_transformp=&(entry->ft_transform); entry->ft_transform.xx=(FT_Fixed)(cxx*0x10000); entry->ft_transform.xy=(FT_Fixed)(cxy*0x10000); entry->ft_transform.yx=0; entry->ft_transform.yy=0x10000; #endif DEBUG_PRINT(DEBUG_FT,("\" ")); pos++; } else { /* bare word */ switch (++nameno) { case 1: /* first word is tfmname and perhaps psname, NOT psfile */ while(pos<end && *pos!=' ' && *pos!='\t') pos++; psname=entry->tfmname; break; case 2: /* second word is psname, NOT psfile */ psname = newword((char**)&pos,end); DEBUG_PRINT(DEBUG_FT,("(%s) ",psname)); free(psname); break; case 3: /* third word is encoding */ entry->encname = newword((char**)&pos,end); DEBUG_PRINT(DEBUG_FT,("<[%s ",entry->encname)); break; default: while(pos<end && *pos!=' ' && *pos!='\t') pos++; Warning("more than three bare words in font map entry"); } } while(pos < end && (*pos==' ' || *pos=='\t')) pos++; } if (entry->psfile==NULL) { /* No psfile-name given, use tfmname */ entry->psfile=copyword(entry->tfmname); DEBUG_PRINT(DEBUG_FT,(" <%s ",entry->psfile)); } if (entry->encname!=NULL && (entry->encoding=FindEncoding(entry->encname))==NULL) Warning("unable to load font encoding '%s' for %s", entry->encname,entry->tfmname); }
static Word* subsub(Word *v, char *s, char *end) { int nmid; Word *head, *tail, *w, *h; Word *a, *b, *c, *d; Bufblock *buf; char *cp, *enda; a = extractpat(s, &cp, "=%&", end); b = c = d = 0; if(PERCENT(*cp)) b = extractpat(cp+1, &cp, "=", end); if(*cp == '=') c = extractpat(cp+1, &cp, "&%", end); if(PERCENT(*cp)) d = stow(cp+1); else if(*cp) d = stow(cp); head = tail = 0; buf = newbuf(); for(; v; v = v->next){ h = w = 0; if(submatch(v->s, a, b, &nmid, &enda)){ /* enda points to end of A match in source; * nmid = number of chars between end of A and start of B */ if(c){ h = w = wdup(c); while(w->next) w = w->next; } if(PERCENT(*cp) && nmid > 0){ if(w){ bufcpy(buf, w->s, strlen(w->s)); bufcpy(buf, enda, nmid); insert(buf, 0); free(w->s); w->s = strdup(buf->start); } else { bufcpy(buf, enda, nmid); insert(buf, 0); h = w = newword(buf->start); } buf->current = buf->start; } if(d && *d->s){ if(w){ bufcpy(buf, w->s, strlen(w->s)); bufcpy(buf, d->s, strlen(d->s)); insert(buf, 0); free(w->s); w->s = strdup(buf->start); w->next = wdup(d->next); while(w->next) w = w->next; buf->current = buf->start; } else h = w = wdup(d); } } if(w == 0) h = w = newword(v->s); if(head == 0) head = h; else tail->next = h; tail = w; } freebuf(buf); delword(a); delword(b); delword(c); delword(d); return head; }
void main(int argc, char **argv) { Word *w; char *s, *temp; char *files[256], **f = files, **ff; int sflag = 0; int i; int tfd = -1; Biobuf tb; Bufblock *buf; Bufblock *whatif; /* * start with a copy of the current environment variables * instead of sharing them */ Binit(&bout, 1, OWRITE); buf = newbuf(); whatif = 0; USED(argc); for(argv++; *argv && (**argv == '-'); argv++) { bufcpy(buf, argv[0], strlen(argv[0])); insert(buf, ' '); switch(argv[0][1]) { case 'a': aflag = 1; break; case 'd': if(*(s = &argv[0][2])) while(*s) switch(*s++) { case 'p': debug |= D_PARSE; break; case 'g': debug |= D_GRAPH; break; case 'e': debug |= D_EXEC; break; } else debug = 0xFFFF; break; case 'e': explain = &argv[0][2]; break; case 'f': if(*++argv == 0) badusage(); *f++ = *argv; bufcpy(buf, argv[0], strlen(argv[0])); insert(buf, ' '); break; case 'i': iflag = 1; break; case 'k': kflag = 1; break; case 'n': nflag = 1; break; case 's': sflag = 1; break; case 't': tflag = 1; break; case 'u': uflag = 1; break; case 'w': if(whatif == 0) whatif = newbuf(); else insert(whatif, ' '); if(argv[0][2]) bufcpy(whatif, &argv[0][2], strlen(&argv[0][2])); else { if(*++argv == 0) badusage(); bufcpy(whatif, &argv[0][0], strlen(&argv[0][0])); } break; default: badusage(); } } #ifdef PROF { extern etext(); monitor(main, etext, buf, sizeof buf, 300); } #endif if(aflag) iflag = 1; usage(); syminit(); initenv(); usage(); /* assignment args become null strings */ temp = 0; for(i = 0; argv[i]; i++) if(utfrune(argv[i], '=')){ bufcpy(buf, argv[i], strlen(argv[i])); insert(buf, ' '); if(tfd < 0){ temp = maketmp(); if(temp == 0) { perror("temp file"); Exit(); } close(create(temp, OWRITE, 0600)); if((tfd = open(temp, 2)) < 0){ perror(temp); Exit(); } Binit(&tb, tfd, OWRITE); } Bprint(&tb, "%s\n", argv[i]); *argv[i] = 0; } if(tfd >= 0){ Bflush(&tb); LSEEK(tfd, 0L, 0); parse("command line args", tfd, 1); remove(temp); } if (buf->current != buf->start) { buf->current--; insert(buf, 0); } symlook("MKFLAGS", S_VAR, (void *) stow(buf->start)); buf->current = buf->start; for(i = 0; argv[i]; i++){ if(*argv[i] == 0) continue; if(i) insert(buf, ' '); bufcpy(buf, argv[i], strlen(argv[i])); } insert(buf, 0); symlook("MKARGS", S_VAR, (void *) stow(buf->start)); freebuf(buf); if(f == files){ if(access(MKFILE, 4) == 0) parse(MKFILE, open(MKFILE, 0), 0); } else for(ff = files; ff < f; ff++) parse(*ff, open(*ff, 0), 0); if(DEBUG(D_PARSE)){ dumpw("default targets", target1); dumpr("rules", rules); dumpr("metarules", metarules); dumpv("variables"); } if(whatif){ insert(whatif, 0); timeinit(whatif->start); freebuf(whatif); } execinit(); /* skip assignment args */ while(*argv && (**argv == 0)) argv++; catchnotes(); if(*argv == 0){ if(target1) for(w = target1; w; w = w->next) mk(w->s); else { fprint(2, "mk: nothing to mk\n"); Exit(); } } else { if(sflag){ for(; *argv; argv++) if(**argv) mk(*argv); } else { Word *head, *tail, *t; /* fake a new rule with all the args as prereqs */ tail = 0; t = 0; for(; *argv; argv++) if(**argv){ if(tail == 0) tail = t = newword(*argv); else { t->next = newword(*argv); t = t->next; } } if(tail->next == 0) mk(tail->s); else { head = newword("command line arguments"); addrules(head, tail, strdup(""), VIR, mkinline, 0); mk(head->s); } } } if(uflag) prusage(); exits(0); }
int dorecipe(Node *node) { int did = 0; char buf[BIGBLOCK], cwd[256]; Arc *a, *aa; Node *n; Rule *r = 0; Symtab *s; Word head, ahead, lp, ln, *w, *ww, *aw; aa = 0; /* pick up the rule */ for(a = node->prereqs; a; a = a->next) if(*a->r->recipe) r = (aa = a)->r; /* no recipe? go to buggery! */ if(r == 0){ if(!(node->flags&VIRTUAL) && !(node->flags&NORECIPE)){ if(getwd(cwd, sizeof cwd)) fprint(2, "mk: no recipe to make '%s' in directory %s\n", node->name, cwd); else fprint(2, "mk: no recipe to make '%s'\n", node->name); Exit(); } if(strchr(node->name, '(') && node->time == 0) MADESET(node, MADE); else update(0, node); if(tflag){ if(!(node->flags&VIRTUAL)) touch(node->name); else if(explain) Bprint(&bout, "no touch of virtual '%s'\n", node->name); } return(did); } /* build the node list */ node->next = 0; head.next = 0; ww = &head; ahead.next = 0; aw = &ahead; if(r->attr®EXP){ ww->next = newword(node->name); aw->next = newword(node->name); } else { for(w = r->alltargets; w; w = w->next){ if(r->attr&META) subst(aa->stem, w->s, buf, sizeof(buf)); else strecpy(buf, buf + sizeof buf - 1, w->s); aw->next = newword(buf); aw = aw->next; if((s = symlook(buf, S_NODE, 0)) == 0) continue; /* not a node we are interested in */ n = s->u.ptr; if(aflag == 0 && n->time) { for(a = n->prereqs; a; a = a->next) if(a->n && outofdate(n, a, 0)) break; if(a == 0) continue; } ww->next = newword(buf); ww = ww->next; if(n == node) continue; n->next = node->next; node->next = n; } } for(n = node; n; n = n->next) if((n->flags&READY) == 0) return(did); /* gather the params for the job */ lp.next = ln.next = 0; for(n = node; n; n = n->next){ for(a = n->prereqs; a; a = a->next){ if(a->n){ addw(&lp, a->n->name); if(outofdate(n, a, 0)){ addw(&ln, a->n->name); if(explain) fprint(1, "%s(%ld) < %s(%ld)\n", n->name, n->time, a->n->name, a->n->time); } } else { if(explain) fprint(1, "%s has no prerequisites\n", n->name); } } MADESET(n, BEINGMADE); } /* print("lt=%s ln=%s lp=%s\n",wtos(head.next, ' '),wtos(ln.next, ' '),wtos(lp.next, ' '));/**/ run(newjob(r, node, aa->stem, aa->match, lp.next, ln.next, head.next, ahead.next)); return(1); }
/************************************************************** * NAME * loadword * ARGS * infile - file to load from * DESCR * Load a word into the structures. * RETRN * Pointer to first word structure, NULL at eof or error. */ static Word *loadword( FILE *infile ) { Word *wd; /* Temp word struct to load */ int first_aline; /* Flag for first \a line in loop */ int n; /* Temp counter */ Ambig *amb; /* Temp ambig */ char *s; char* pszTmp; if ( first_call ) /* If first call */ { if ( !fgets ( line, MAXLINE, infile ) ) /* Get first line */ return( NULL ); /* If none, return eof */ first_call = FALSE; /* No longer first */ } if ( eofseen ) /* If eof seen last time */ return( NULL ); /* Return eof */ wd = newword(); /* Allocate a word struct */ /* * Handling of end of file: * The loop below expects to be entered with a line already * in place in "line". It is handled this way because it * stops when it sees the \a line of the next record. But * the \a line has already been read, so it is left to be * processed as the first line of the next record. * The code above assures that at the first call a line is * read in, so that the loop below will see it. * When the code below sees eof, it has to return the last * record as good. So, it sets eofseen, which triggers * the next call to return eof. */ first_aline = TRUE; /* Set first line */ while ( TRUE ) /* Terminates on next \a or eof */ { /* Process a line */ if ( !strncmp( "\\a ", line, 3 ) ) /* If line is \a line */ { if ( first_aline ) /* If first one */ { /* Load the ambigs */ loadambigs( wd, line ); first_aline = FALSE; /* No longer first */ } else /* Else (not first) */ { addcats( wd ); /* Add any missing cats */ return( wd ); /* Return finished word */ } } else if ( !strncmp( "\\d ", line, 3 ) ) /* If line is \d line */ { n = numambigs( line + 3 ); /* Set up ambigs */ n = wd->numamb; /* More trustable number */ n = n ? n : 1; /* At least 1 */ for ( amb = wd->ambigs; n--; amb = amb->next ) /* For each ambig */ amb->decomp = nextambig(); /* Load decomp */ } else if ( !strncmp( "\\cat ", line, 5 ) ) /* If line is \cat line */ { n = numambigs( line + 5 ); /* Set up ambigs */ n = wd->numamb; /* More trustable number */ n = n ? n : 1; /* At least 1 */ for ( amb = wd->ambigs; n--; amb = amb->next ) /* For each ambig */ { amb->cat = nextambig(); /* Load cat */ /* Cut off any morph category pairs */ if ( ( s = strchr( amb->cat, ' ' ) ) ) /* If space in cat */ *s = '\0'; /* Cut off */ } } #if 1 else if ( !strncmp( "\\p ", line, 3 ) ) /* If line is \p property line */ { n = numambigs( line + 3 ); /* Set up ambigs */ n = wd->numamb; /* More trustable number */ wd->bHasProps = TRUE; n = n ? n : 1; /* At least 1 */ for ( amb = wd->ambigs; n--; amb = amb->next ) /* For each ambig */ { pszTmp = nextambig(); /* Load morpheme */ /* Parse the morpheme properties. */ GetMorphProperties(pszTmp, amb->morphs); } } #endif else if ( !strncmp( "\\fd ", line, 4 ) ) /* If line is \fd line */ { n = numambigs( line + 4 ); /* Set up ambigs */ n = wd->numamb; /* More trustable number */ n = n ? n : 1; /* At least 1 */ for ( amb = wd->ambigs; n--; amb = amb->next ) /* For each ambig */ amb->feat = nextambig(); /* Load feat */ } else if ( !strncmp( "\\w ", line, 3 ) ) /* If line is \w line */ { wd->name = (unsigned char *)mystrdup( line + 3 ); *( wd->name + strlen( (char *)wd->name ) - 1 ) = '\0'; /* Cut off nl */ } else if ( !strncmp( "\\f ", line, 3 ) ) /* If line is \f line */ { wd->format = mystrdup( line ); while ( TRUE ) { if ( !fgets( line, MAXLINE, infile ) ) /* If no next line */ { eofseen = TRUE; /* Remember eof seen */ addcats( wd ); /* Add any missing cats */ return( wd ); /* Return last word */ } else if ( *line == '\n' ) /* Else if blank line */ ; /* Don't load it */ else if ( *line != '\\' ) /* Else if continued format */ wd->format = mystrappend( wd->format, line ); /* append */ else /* Else (backslash mark) */ break; /* Let other code see line */ } continue; /* Go to top of loop */ } else if ( !strncmp( "\\c ", line, 3 ) ) /* If line is \c line */ { wd->cap = mystrdup( line ); } else if ( !strncmp( "\\n ", line, 3 ) ) /* If line is \n line */ { wd->punc = mystrdup( line ); } #ifndef hab02t else if ( !strncmp( "\\u ", line, 3 ) ) /* If line is \u line */ { wd->underForm = mystrdup( line ); } #endif /* hab02t */ else /* Else (blank lines) ignore */ { /* Everything except blank */ } /* lines should be loaded */ if ( !fgets( line, MAXLINE, infile ) ) /* Get another line */ { /* If here, eof but a good word */ eofseen = TRUE; /* Remember eof seen */ addcats( wd ); /* Add any missing cats */ return( wd ); /* Return last word */ } } }