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