Reformat before editing.

This commit is contained in:
David Given 2019-02-15 23:24:10 +01:00
parent 4474d6433a
commit e976e10708

View file

@ -36,17 +36,20 @@ static void getcallargs(trf *);
static growstring without_bslash(const char*); static growstring without_bslash(const char*);
static void getprogram(trf*); static void getprogram(trf*);
int transform(trf *phase) { int transform(trf* phase)
{
int ok; int ok;
if ( !setfiles(phase) ) { if (!setfiles(phase))
{
disc_files(phase); disc_files(phase);
return 0; return 0;
} }
getcallargs(phase); getcallargs(phase);
getprogram(phase); getprogram(phase);
ok = runphase(phase); ok = runphase(phase);
if ( !ok ) rmfile(&out) ; if (!ok)
rmfile(&out);
/* Free the space occupied by the arguments, /* Free the space occupied by the arguments,
except for the linker, since we are bound to exit soon except for the linker, since we are bound to exit soon
and do not foresee further need of memory space */ and do not foresee further need of memory space */
@ -56,59 +59,66 @@ int transform(trf *phase) {
return ok; return ok;
} }
void getmapflags(trf *phase) { void getmapflags(trf* phase)
{
register path* l_in; register path* l_in;
register list_elem* elem; register list_elem* elem;
int scanned; int scanned;
register char* ptr; register char* ptr;
scanlist(l_first(flags),elem) { scanlist(l_first(flags), elem)
{
scanned = *(l_content(*elem)) & NO_SCAN; scanned = *(l_content(*elem)) & NO_SCAN;
*(l_content(*elem)) &= ~NO_SCAN; *(l_content(*elem)) &= ~NO_SCAN;
if ( mapflag(&(phase->t_mapf),l_content(*elem)) ) { if (mapflag(&(phase->t_mapf), l_content(*elem)))
{
scanned = NO_SCAN; scanned = NO_SCAN;
#ifdef DEBUG #ifdef DEBUG
if ( debug >=4 ) { if (debug >= 4)
vprint("phase %s, added mapflag for %s\n", {
phase->t_name, vprint("phase %s, added mapflag for %s\n", phase->t_name, l_content(*elem));
l_content(*elem) ) ;
} }
#endif #endif
} }
*(l_content(*elem)) |= scanned; *(l_content(*elem)) |= scanned;
} }
if ( phase->t_linker ) { if (phase->t_linker)
scanlist(l_first(phase->t_inputs),elem) { {
scanlist(l_first(phase->t_inputs), elem)
{
l_in = p_cont(*elem); l_in = p_cont(*elem);
if ( mapflag(&(phase->t_mapf),l_in->p_path) ) { if (mapflag(&(phase->t_mapf), l_in->p_path))
{
growstring temp; growstring temp;
temp = without_bslash(getvar(LIBVAR)); temp = without_bslash(getvar(LIBVAR));
ptr = gr_final(&temp); ptr = gr_final(&temp);
#ifdef DEBUG #ifdef DEBUG
if ( debug >=4 ) { if (debug >= 4)
vprint("phase %s, library %s(%s)\n", {
phase->t_name,l_in->p_path,ptr) ; vprint("phase %s, library %s(%s)\n", phase->t_name, l_in->p_path, ptr);
} }
#endif #endif
if ( l_in->p_keeps) throws(l_in->p_path) ; if (l_in->p_keeps)
throws(l_in->p_path);
l_in->p_path = ptr; l_in->p_path = ptr;
l_in->p_keeps = YES; l_in->p_keeps = YES;
} }
} }
scanlist(l_first(flags),elem) { scanlist(l_first(flags), elem)
{
/* Get the flags remaining for the loader, /* Get the flags remaining for the loader,
That is: all the flags neither eaten by ack nor That is: all the flags neither eaten by ack nor
one of the subprograms called so-far. one of the subprograms called so-far.
The last fact is indicated by the NO_SCAN bit The last fact is indicated by the NO_SCAN bit
in the first character of the flag. in the first character of the flag.
*/ */
if ( !( *(l_content(*elem))&NO_SCAN ) ) { if (!(*(l_content(*elem)) & NO_SCAN))
{
l_add(&(phase->t_flags), l_content(*elem)); l_add(&(phase->t_flags), l_content(*elem));
#ifdef DEBUG #ifdef DEBUG
if ( debug >=4 ) { if (debug >= 4)
vprint("phase %s, added flag %s\n", {
phase->t_name, vprint("phase %s, added flag %s\n", phase->t_name, l_content(*elem));
l_content(*elem) ) ;
} }
#endif #endif
} }
@ -116,43 +126,53 @@ void getmapflags(trf *phase) {
} }
} }
static char* headvar(void)
static char *headvar(void) { {
if ( !touch_head) return "" ; if (!touch_head)
return "";
return gr_start(head); return gr_start(head);
} }
void add_head(const char *str) { void add_head(const char* str)
if ( !touch_head) { {
if (!touch_head)
{
gr_init(&head); gr_init(&head);
touch_head = YES; touch_head = YES;
} }
gr_cat(&head, str); gr_cat(&head, str);
} }
static char *tailvar(void) { static char* tailvar(void)
if ( !touch_tail ) return "" ; {
if (!touch_tail)
return "";
return gr_start(tail); return gr_start(tail);
} }
void add_tail(const char *str) { void add_tail(const char* str)
if ( !touch_tail ) { {
if (!touch_tail)
{
gr_init(&tail); gr_init(&tail);
touch_tail = YES; touch_tail = YES;
} }
gr_cat(&tail, str); gr_cat(&tail, str);
} }
void transini(void)
void transini(void) { {
register list_elem* elem; register list_elem* elem;
register trf* phase; register trf* phase;
scanlist(l_first(tr_list), elem) { scanlist(l_first(tr_list), elem)
{
phase = t_cont(*elem); phase = t_cont(*elem);
if ( !phase->t_linker ) getmapflags(phase); if (!phase->t_linker)
getmapflags(phase);
} }
scanlist(l_first(R_list), elem) { scanlist(l_first(R_list), elem)
{
set_Rflag(l_content(*elem)); set_Rflag(l_content(*elem));
} }
l_clear(&R_list); l_clear(&R_list);
@ -160,7 +180,8 @@ void transini(void) {
setpvar(keeps(TAIL), tailvar); setpvar(keeps(TAIL), tailvar);
} }
static void set_Rflag(char *argp) { static void set_Rflag(char* argp)
{
register char* eos; register char* eos;
register list_elem* prog; register list_elem* prog;
register int length; register int length;
@ -169,36 +190,51 @@ static void set_Rflag(char *argp) {
eos = strchr(&argp[2], '-'); eos = strchr(&argp[2], '-');
eq = strchr(&argp[2], EQUAL); eq = strchr(&argp[2], EQUAL);
colon = strchr(&argp[2], ':'); colon = strchr(&argp[2], ':');
if ( !eos ) { if (!eos)
{
eos = eq; eos = eq;
} else {
if ( eq && eq<eos ) eos= eq ;
} }
if ( colon && ( !eos || eos>colon ) ) eos= colon ; else
if ( !eos ) { {
if ( !(argp[0]&NO_SCAN) ) werror("Incorrect use of -R flag") ; if (eq && eq < eos)
eos = eq;
}
if (colon && (!eos || eos > colon))
eos = colon;
if (!eos)
{
if (!(argp[0] & NO_SCAN))
werror("Incorrect use of -R flag");
return; return;
} }
length = eos - &argp[2]; length = eos - &argp[2];
scanlist(l_first(tr_list), prog) { scanlist(l_first(tr_list), prog)
if ( strncmp(t_cont(*prog)->t_name, &argp[2], length )==0 && {
t_cont(*prog)->t_name[length]==0 /* Same name length */) { if (strncmp(t_cont(*prog)->t_name, &argp[2], length) == 0
if ( *eos=='-' ) { && t_cont(*prog)->t_name[length] == 0 /* Same name length */)
if ( !(argp[0]&NO_SCAN) ) { {
if (*eos == '-')
{
if (!(argp[0] & NO_SCAN))
{
/* If not already taken by a mapflag */ /* If not already taken by a mapflag */
l_add(&(t_cont(*prog)->t_flags), eos); l_add(&(t_cont(*prog)->t_flags), eos);
} }
} else }
if ( *eos=='=' ) { else if (*eos == '=')
{
t_cont(*prog)->t_prog = eos + 1; t_cont(*prog)->t_prog = eos + 1;
} else { }
else
{
t_cont(*prog)->t_priority = atoi(eos + 1); t_cont(*prog)->t_priority = atoi(eos + 1);
} }
argp[0] |= NO_SCAN; argp[0] |= NO_SCAN;
return; return;
} }
} }
if ( !(argp[0]&NO_SCAN) ) werror("Cannot find program for %s",argp) ; if (!(argp[0] & NO_SCAN))
werror("Cannot find program for %s", argp);
return; return;
} }
@ -208,7 +244,8 @@ static void set_Rflag(char *argp) {
/* */ /* */
/**************************************************************************/ /**************************************************************************/
static growstring scanvars(const char *line) { static growstring scanvars(const char* line)
{
/* Scan a line variable replacements started by S_VAR. /* Scan a line variable replacements started by S_VAR.
Two sequences exist: S_VAR name C_VAR, S_VAR name A_VAR text C_VAR. Two sequences exist: S_VAR name C_VAR, S_VAR name A_VAR text C_VAR.
neither name nor text may contain further replacements. neither name nor text may contain further replacements.
@ -220,17 +257,29 @@ static growstring scanvars(const char *line) {
int token, token_r; int token, token_r;
growstring result, name; growstring result, name;
char* tr; char* tr;
enum { TEXT, FIRST, NAME, SKIP, COPY } state = TEXT ; enum
{
TEXT,
FIRST,
NAME,
SKIP,
COPY
} state
= TEXT;
int escaped = NO; int escaped = NO;
gr_init(&result) ; gr_init(&name) ; gr_init(&result);
for ( in_c= line ; *in_c ; in_c++ ) { gr_init(&name);
for (in_c = line; *in_c; in_c++)
{
token = *in_c & 0377; token = *in_c & 0377;
token_r = (escaped ? 0 : token); token_r = (escaped ? 0 : token);
/* A backslash escapes the next character. */ /* A backslash escapes the next character. */
if ( token_r==BSLASH ) { if (token_r == BSLASH)
if ( state==TEXT || state==COPY ) { {
if (state == TEXT || state == COPY)
{
/* Keep BSLASH for later scans. */ /* Keep BSLASH for later scans. */
gr_add(&result, token); gr_add(&result, token);
} }
@ -239,16 +288,21 @@ static growstring scanvars(const char *line) {
} }
escaped = NO; escaped = NO;
switch( state ) { switch (state)
{
case TEXT: case TEXT:
if ( token_r==S_VAR ) { if (token_r == S_VAR)
{
state = FIRST; state = FIRST;
} else { }
else
{
gr_add(&result, token); gr_add(&result, token);
} }
break; break;
case FIRST: case FIRST:
switch ( token_r ) { switch (token_r)
{
case A_VAR: case A_VAR:
case C_VAR: case C_VAR:
fatal("empty string variable name"); fatal("empty string variable name");
@ -259,28 +313,36 @@ static growstring scanvars(const char *line) {
} }
break; break;
case NAME: case NAME:
switch ( token_r ) { switch (token_r)
{
case A_VAR: case A_VAR:
gr_add(&name, 0); gr_add(&name, 0);
if ( tr=getvar(gr_start(name)) ) { if (tr = getvar(gr_start(name)))
while ( *tr ) { {
while (*tr)
{
gr_add(&result, *tr++); gr_add(&result, *tr++);
} }
state = SKIP; state = SKIP;
} else { }
else
{
state = COPY; state = COPY;
} }
gr_throw(&name); gr_throw(&name);
break; break;
case C_VAR: case C_VAR:
gr_add(&name, 0); gr_add(&name, 0);
if ( tr=getvar(gr_start(name)) ) { if (tr = getvar(gr_start(name)))
while ( *tr ) { {
while (*tr)
{
gr_add(&result, *tr++); gr_add(&result, *tr++);
} }
} else { }
werror("No definition for %s", else
gr_start(name)) ; {
werror("No definition for %s", gr_start(name));
} }
state = TEXT; state = TEXT;
gr_throw(&name); gr_throw(&name);
@ -291,25 +353,32 @@ static growstring scanvars(const char *line) {
} }
break; break;
case SKIP: case SKIP:
if ( token_r==C_VAR ) state= TEXT ; if (token_r == C_VAR)
state = TEXT;
break; break;
case COPY: case COPY:
if ( token_r==C_VAR ) state= TEXT ; else { if (token_r == C_VAR)
state = TEXT;
else
{
gr_add(&result, token); gr_add(&result, token);
} }
break; break;
} }
} }
gr_add(&result, 0); gr_add(&result, 0);
if ( escaped ) werror("flag line ends with %c",BSLASH) ; if (escaped)
if ( state!=TEXT ) { werror("flag line ends with %c", BSLASH);
if (state != TEXT)
{
werror("flag line misses %c", C_VAR); werror("flag line misses %c", C_VAR);
gr_throw(&name); gr_throw(&name);
} }
return result; return result;
} }
static growstring scanexpr(const char *line) { static growstring scanexpr(const char* line)
{
/* Scan a line for conditional or flag expressions, /* Scan a line for conditional or flag expressions,
dependent on the type. The format is dependent on the type. The format is
S_EXPR suflist M_EXPR suflist T_EXPR tail C_EXPR S_EXPR suflist M_EXPR suflist T_EXPR tail C_EXPR
@ -321,17 +390,31 @@ static growstring scanexpr(const char *line) {
int token, token_r; int token, token_r;
growstring sufs, tailval, result; growstring sufs, tailval, result;
static list_head fsuff, lsuff; static list_head fsuff, lsuff;
enum { TEXT, FDOT, FSUF, LDOT, LSUF, FTAIL } state = TEXT ; enum
{
TEXT,
FDOT,
FSUF,
LDOT,
LSUF,
FTAIL
} state
= TEXT;
int escaped = NO; int escaped = NO;
gr_init(&result) ; gr_init(&sufs) ; gr_init(&tailval) ; gr_init(&result);
for ( in_c= line ; *in_c ; in_c++ ) { gr_init(&sufs);
gr_init(&tailval);
for (in_c = line; *in_c; in_c++)
{
token = *in_c & 0377; token = *in_c & 0377;
token_r = (escaped ? 0 : token); token_r = (escaped ? 0 : token);
/* A backslash escapes the next character. */ /* A backslash escapes the next character. */
if ( token_r==BSLASH ) { if (token_r == BSLASH)
if ( state==TEXT || state==FTAIL ) { {
if (state == TEXT || state == FTAIL)
{
/* Keep BSLASH for later scans. */ /* Keep BSLASH for later scans. */
gr_add(&result, token); gr_add(&result, token);
} }
@ -340,99 +423,130 @@ static growstring scanexpr(const char *line) {
} }
escaped = NO; escaped = NO;
switch( state ) { switch (state)
{
case TEXT: case TEXT:
if ( token_r==S_EXPR ) { if (token_r == S_EXPR)
{
state = FDOT; state = FDOT;
heads = in_c; heads = in_c;
} else gr_add(&result,token) ; }
else
gr_add(&result, token);
break; break;
case FDOT: case FDOT:
if ( token_r==M_EXPR ) { if (token_r == M_EXPR)
{
state = LDOT; state = LDOT;
break; break;
} }
if ( token!=SUFCHAR ) { if (token != SUFCHAR)
{
error("Missing %c in expression", SUFCHAR); error("Missing %c in expression", SUFCHAR);
} }
gr_add(&sufs,token) ; state=FSUF ; gr_add(&sufs, token);
state = FSUF;
break; break;
case FSUF: case FSUF:
if ( token_r==M_EXPR || token==SUFCHAR ) { if (token_r == M_EXPR || token == SUFCHAR)
{
gr_add(&sufs, 0); gr_add(&sufs, 0);
l_add(&fsuff, gr_final(&sufs)); l_add(&fsuff, gr_final(&sufs));
} }
if ( token_r==M_EXPR ) { if (token_r == M_EXPR)
{
state = LDOT; state = LDOT;
} else gr_add(&sufs,token) ; }
else
gr_add(&sufs, token);
break; break;
case LDOT: case LDOT:
if ( token_r==T_EXPR ) { if (token_r == T_EXPR)
{
state = FTAIL; state = FTAIL;
break; break;
} }
if ( token!=SUFCHAR ) { if (token != SUFCHAR)
{
error("Missing %c in expression", SUFCHAR); error("Missing %c in expression", SUFCHAR);
} }
gr_add(&sufs,token) ; state=LSUF ; gr_add(&sufs, token);
state = LSUF;
break; break;
case LSUF: case LSUF:
if ( token_r==T_EXPR || token==SUFCHAR) { if (token_r == T_EXPR || token == SUFCHAR)
{
gr_add(&sufs, 0); gr_add(&sufs, 0);
l_add(&lsuff, gr_final(&sufs)); l_add(&lsuff, gr_final(&sufs));
} }
if ( token_r==T_EXPR ) { if (token_r == T_EXPR)
{
state = FTAIL; state = FTAIL;
} else gr_add(&sufs,token) ; }
else
gr_add(&sufs, token);
break; break;
case FTAIL: case FTAIL:
if ( token_r==C_EXPR ) { if (token_r == C_EXPR)
{
/* Found one !! */ /* Found one !! */
gr_add(&tailval, 0); gr_add(&tailval, 0);
condit(&result, &fsuff, &lsuff, gr_start(tailval)); condit(&result, &fsuff, &lsuff, gr_start(tailval));
l_throw(&fsuff) ; l_throw(&lsuff) ; l_throw(&fsuff);
l_throw(&lsuff);
gr_throw(&tailval); gr_throw(&tailval);
state = TEXT; state = TEXT;
} else gr_add(&tailval,token) ; }
else
gr_add(&tailval, token);
break; break;
} }
} }
gr_add(&result, 0); gr_add(&result, 0);
if ( state!=TEXT ) { if (state != TEXT)
l_throw(&fsuff) ; l_throw(&lsuff) ; gr_throw(&tailval) ; {
werror("flag line has unclosed expression starting with %6s", l_throw(&fsuff);
heads) ; l_throw(&lsuff);
gr_throw(&tailval);
werror("flag line has unclosed expression starting with %6s", heads);
} }
return result; return result;
} }
static void condit(growstring *line, list_head *fsuff, list_head *lsuff, static void condit(growstring* line, list_head* fsuff, list_head* lsuff, char* tailval)
char *tailval)
{ {
register list_elem* first; register list_elem* first;
register list_elem* last; register list_elem* last;
#ifdef DEBUG #ifdef DEBUG
if ( debug>=4 ) vprint("Conditional for %s, ",tailval) ; if (debug >= 4)
vprint("Conditional for %s, ", tailval);
#endif #endif
scanlist( l_first(*fsuff), first ) { scanlist(l_first(*fsuff), first)
scanlist( l_first(*lsuff), last ) { {
if ( strcmp(l_content(*first),l_content(*last))==0 ) { scanlist(l_first(*lsuff), last)
{
if (strcmp(l_content(*first), l_content(*last)) == 0)
{
/* Found */ /* Found */
#ifdef DEBUG #ifdef DEBUG
if ( debug>=4 ) vprint(" matched\n") ; if (debug >= 4)
vprint(" matched\n");
#endif #endif
while ( *tailval) gr_add(line,*tailval++ ) ; while (*tailval)
gr_add(line, *tailval++);
return; return;
} }
} }
} }
#ifdef DEBUG #ifdef DEBUG
if ( debug>=4) vprint(" non-matched\n") ; if (debug >= 4)
vprint(" non-matched\n");
#endif #endif
} }
static int mapflag(list_head *maplist, const char *cflag) { static int mapflag(list_head* maplist, const char* cflag)
{
/* Expand a flag expression */ /* Expand a flag expression */
/* The flag "cflag" is checked for each of the mapflags. /* The flag "cflag" is checked for each of the mapflags.
A mapflag entry has the form A mapflag entry has the form
@ -446,26 +560,32 @@ static int mapflag(list_head *maplist, const char *cflag) {
*/ */
register list_elem* elem; register list_elem* elem;
scanlist(l_first(*maplist),elem) { scanlist(l_first(*maplist), elem)
if ( mapexpand(l_content(*elem),cflag) ) { {
if (mapexpand(l_content(*elem), cflag))
{
return 1; return 1;
} }
} }
return 0; return 0;
} }
static int mapexpand(char *mapentry, const char *cflag) { static int mapexpand(char* mapentry, const char* cflag)
{
const char* star; const char* star;
char *ptr, *space; char *ptr, *space;
int length; int length;
star = strchr(mapentry, STAR); star = strchr(mapentry, STAR);
space = firstblank(mapentry); space = firstblank(mapentry);
if ( star >space ) star= (char *)0 ; if (star > space)
if ( star ) { star = (char*)0;
if (star)
{
length = space - star - 1; length = space - star - 1;
if ( strncmp(mapentry,cflag,star-mapentry) || if (strncmp(mapentry, cflag, star - mapentry)
strncmp(star+1,cflag+strlen(cflag)-length,length) ) { || strncmp(star + 1, cflag + strlen(cflag) - length, length))
{
return 0; return 0;
} }
/* Match */ /* Match */
@ -473,27 +593,32 @@ static int mapexpand(char *mapentry, const char *cflag) {
replacement and length to its length replacement and length to its length
*/ */
length = strlen(cflag) - (star - mapentry) - length; length = strlen(cflag) - (star - mapentry) - length;
if ( length<0 ) return 0 ; if (length < 0)
return 0;
star = cflag + (star - mapentry); star = cflag + (star - mapentry);
#ifdef DEBUG #ifdef DEBUG
if ( debug>=6 ) { if (debug >= 6)
vprint("Starmatch (%s,%s) %.*s\n", {
mapentry,cflag,length,star) ; vprint("Starmatch (%s,%s) %.*s\n", mapentry, cflag, length, star);
} }
#endif #endif
} else { }
if ( strncmp(mapentry,cflag,space-mapentry)!=0 || else
cflag[space-mapentry] ) { {
if (strncmp(mapentry, cflag, space - mapentry) != 0 || cflag[space - mapentry])
{
return 0; return 0;
} }
} }
ptr = skipblank(space); ptr = skipblank(space);
if ( *ptr==0 ) return 1 ; if (*ptr == 0)
return 1;
doassign(ptr, star, length); doassign(ptr, star, length);
return 1; return 1;
} }
void doassign(const char *line, const char *star, int length) { void doassign(const char* line, const char* star, int length)
{
growstring varval, name, temp; growstring varval, name, temp;
const char* ptr; const char* ptr;
int escaped = NO; int escaped = NO;
@ -501,23 +626,29 @@ void doassign(const char *line, const char *star, int length) {
gr_init(&varval); gr_init(&varval);
gr_init(&name); gr_init(&name);
ptr = line; ptr = line;
for ( ; *ptr && *ptr!=SPACE && *ptr!=TAB && *ptr!=EQUAL ; ptr++ ) { for (; *ptr && *ptr != SPACE && *ptr != TAB && *ptr != EQUAL; ptr++)
{
gr_add(&name, *ptr); gr_add(&name, *ptr);
} }
ptr = strchr(ptr, EQUAL); ptr = strchr(ptr, EQUAL);
if ( !ptr ) { if (!ptr)
{
error("Missing %c in assignment %s", EQUAL, line); error("Missing %c in assignment %s", EQUAL, line);
return; return;
} }
temp = scanvars(ptr + 1); temp = scanvars(ptr + 1);
for ( ptr=gr_start(temp); *ptr; ptr++ ) switch ( *ptr ) { for (ptr = gr_start(temp); *ptr; ptr++)
switch (*ptr)
{
case BSLASH: case BSLASH:
escaped = YES; escaped = YES;
gr_add(&varval, *ptr); gr_add(&varval, *ptr);
break; break;
case STAR: case STAR:
if ( star && !escaped ) { if (star && !escaped)
while ( length-- ) { {
while (length--)
{
gr_add(&varval, BSLASH); gr_add(&varval, BSLASH);
gr_add(&varval, *star++); gr_add(&varval, *star++);
} }
@ -530,47 +661,66 @@ void doassign(const char *line, const char *star, int length) {
break; break;
} }
gr_throw(&temp); gr_throw(&temp);
gr_add(&name,0) ; gr_add(&varval,0) ; gr_add(&name, 0);
gr_add(&varval, 0);
setsvar(gr_final(&name), gr_final(&varval)); setsvar(gr_final(&name), gr_final(&varval));
} }
#define ISBLANK(c) ((c) == SPACE || (c) == TAB) #define ISBLANK(c) ((c) == SPACE || (c) == TAB)
static void unravel(const char *line, void (*action)(char *)) { static void unravel(const char* line, void (*action)(char*))
{
/* Unravel the line, get arguments a la shell */ /* Unravel the line, get arguments a la shell */
/* each argument is handled to action */ /* each argument is handled to action */
/* The input string is left intact */ /* The input string is left intact */
const char* in_c; const char* in_c;
int token; int token;
enum { BLANK, ARG, ESCAPED } state = BLANK ; enum
{
BLANK,
ARG,
ESCAPED
} state
= BLANK;
growstring argum; growstring argum;
/* Loop for each character of line, including final '\0' */ /* Loop for each character of line, including final '\0' */
in_c = line; in_c = line;
for (;;) { for (;;)
{
token = *in_c & 0377; token = *in_c & 0377;
switch ( state ) { switch (state)
{
case BLANK: case BLANK:
if ( token==0 ) break ; if (token == 0)
if ( !ISBLANK(token) ) { break;
if (!ISBLANK(token))
{
gr_init(&argum); gr_init(&argum);
gr_add(&argum, token); gr_add(&argum, token);
if ( token == BSLASH ) { if (token == BSLASH)
{
state = ESCAPED; state = ESCAPED;
} else { }
else
{
state = ARG; state = ARG;
} }
} }
break; break;
case ARG: case ARG:
if ( ISBLANK(token) || token==0 ) { if (ISBLANK(token) || token == 0)
{
gr_add(&argum, 0); gr_add(&argum, 0);
(*action)(gr_start(argum)); (*action)(gr_start(argum));
gr_throw(&argum); gr_throw(&argum);
state = BLANK; state = BLANK;
} else { }
else
{
gr_add(&argum, token); gr_add(&argum, token);
if ( token == BSLASH ) state= ESCAPED ; if (token == BSLASH)
state = ESCAPED;
} }
break; break;
case ESCAPED: case ESCAPED:
@ -578,7 +728,8 @@ static void unravel(const char *line, void (*action)(char *)) {
state = ARG; state = ARG;
break; break;
} }
if ( token == 0 ) break ; if (token == 0)
break;
in_c++; in_c++;
} }
} }
@ -586,8 +737,7 @@ static void unravel(const char *line, void (*action)(char *)) {
static list_head* curargs; static list_head* curargs;
static list_head* comb_args; static list_head* comb_args;
static void addargs3(const char *prefix1, const char *prefix2, static void addargs3(const char* prefix1, const char* prefix2, const char* string)
const char *string)
{ {
/* Prepend prefix1 and prefix2 to string, then add it to /* Prepend prefix1 and prefix2 to string, then add it to
curargs. string is scanned to strip backslashes and curargs. string is scanned to strip backslashes and
@ -602,34 +752,44 @@ static void addargs3(const char *prefix1, const char *prefix2,
int escaped = NO; int escaped = NO;
gr_init(&argum); gr_init(&argum);
for ( in_c= prefix1 ; *in_c ; in_c++ ) { for (in_c = prefix1; *in_c; in_c++)
{
gr_add(&argum, *in_c); gr_add(&argum, *in_c);
} }
for ( in_c= prefix2 ; *in_c ; in_c++ ) { for (in_c = prefix2; *in_c; in_c++)
{
gr_add(&argum, *in_c); gr_add(&argum, *in_c);
} }
for ( in_c= string ; *in_c ; in_c++ ) { for (in_c = string; *in_c; in_c++)
{
token = *in_c & 0377; token = *in_c & 0377;
if ( escaped ) { if (escaped)
{
/* Strip BSLASH, keep escaped character. */ /* Strip BSLASH, keep escaped character. */
gr_add(&argum, token); gr_add(&argum, token);
escaped = NO; escaped = NO;
continue; continue;
} }
switch ( token ) { switch (token)
{
case BSLASH: case BSLASH:
escaped = YES; escaped = YES;
break; break;
case C_IN: /* Input file */ case C_IN: /* Input file */
if ( in.p_path ) { /* Not for the combiners */ if (in.p_path)
for ( tr= in.p_path ; *tr; tr++ ) { { /* Not for the combiners */
for (tr = in.p_path; *tr; tr++)
{
gr_add(&argum, *tr); gr_add(&argum, *tr);
} }
} else { /* For the combiners */ }
else
{ /* For the combiners */
gr_add(&argum, 0); gr_add(&argum, 0);
tr = gr_final(&argum); tr = gr_final(&argum);
in_c++; in_c++;
scanlist( l_first(*comb_args), elem ) { scanlist(l_first(*comb_args), elem)
{
char* p = p_cont(*elem)->p_path; char* p = p_cont(*elem)->p_path;
addargs3(tr, p, in_c); addargs3(tr, p, in_c);
} }
@ -639,9 +799,11 @@ static void addargs3(const char *prefix1, const char *prefix2,
break; break;
case C_OUT: /* Output file */ case C_OUT: /* Output file */
#ifdef DEBUG #ifdef DEBUG
if ( !out.p_path ) fatal("missing output filename") ; if (!out.p_path)
fatal("missing output filename");
#endif #endif
for ( tr= out.p_path ; *tr ; tr++ ) { for (tr = out.p_path; *tr; tr++)
{
gr_add(&argum, *tr); gr_add(&argum, *tr);
} }
break; break;
@ -655,29 +817,35 @@ static void addargs3(const char *prefix1, const char *prefix2,
l_add(curargs, tr); l_add(curargs, tr);
} }
static void addargs(char *string) { static void addargs(char* string)
{
addargs3("", "", string); addargs3("", "", string);
} }
static void getcallargs(trf *phase) { static void getcallargs(trf* phase)
{
growstring arg1, arg2; growstring arg1, arg2;
arg1 = scanvars(phase->t_argd); arg1 = scanvars(phase->t_argd);
#ifdef DEBUG #ifdef DEBUG
if ( debug>=3 ) vprint("\tvars: %s", gr_start(arg1)) ; if (debug >= 3)
vprint("\tvars: %s", gr_start(arg1));
#endif #endif
arg2 = scanexpr(gr_start(arg1)); arg2 = scanexpr(gr_start(arg1));
#ifdef DEBUG #ifdef DEBUG
if ( debug>=3 ) vprint("\texpr: %s", gr_start(arg2)) ; if (debug >= 3)
vprint("\texpr: %s", gr_start(arg2));
#endif #endif
gr_throw(&arg1); gr_throw(&arg1);
curargs = &phase->t_args; curargs = &phase->t_args;
if (phase->t_combine) comb_args = &phase->t_inputs ; if (phase->t_combine)
comb_args = &phase->t_inputs;
unravel(gr_start(arg2), addargs); unravel(gr_start(arg2), addargs);
gr_throw(&arg2); gr_throw(&arg2);
} }
static growstring without_bslash(const char *string) { static growstring without_bslash(const char* string)
{
/* Strip backslashes from a copy of the string. */ /* Strip backslashes from a copy of the string. */
growstring result; growstring result;
const char* in_c; const char* in_c;
@ -685,11 +853,15 @@ static growstring without_bslash(const char *string) {
int escaped = NO; int escaped = NO;
gr_init(&result); gr_init(&result);
for ( in_c= string ; *in_c ; in_c++ ) { for (in_c = string; *in_c; in_c++)
{
token = *in_c & 0377; token = *in_c & 0377;
if ( token==BSLASH && !escaped ) { if (token == BSLASH && !escaped)
{
escaped = YES; escaped = YES;
} else { }
else
{
gr_add(&result, token); gr_add(&result, token);
escaped = NO; escaped = NO;
} }
@ -698,7 +870,8 @@ static growstring without_bslash(const char *string) {
return result; return result;
} }
static void getprogram(trf *phase) { static void getprogram(trf* phase)
{
growstring prog1, prog2; growstring prog1, prog2;
const char* in_c; const char* in_c;
int token; int token;