version 1.32, 2008/11/29 17:50:11 |
version 1.33, 2008/11/30 22:37:55 |
Line 87 typedef struct _For { |
|
Line 87 typedef struct _For { |
|
Buffer buf; /* Body of loop */ |
Buffer buf; /* Body of loop */ |
char **vars; /* Iteration variables */ |
char **vars; /* Iteration variables */ |
int nvars; /* # of iteration vars */ |
int nvars; /* # of iteration vars */ |
|
int nitem; /* # of substitution items */ |
Lst lst; /* List of items */ |
Lst lst; /* List of items */ |
} For; |
} For; |
|
|
Line 97 static void ForAddVar(const char *, size |
|
Line 98 static void ForAddVar(const char *, size |
|
|
|
|
|
|
|
|
static char * |
|
make_str(const char *ptr, int len) |
|
{ |
|
char *new_ptr; |
|
|
|
new_ptr = bmake_malloc(len + 1); |
|
memcpy(new_ptr, ptr, len); |
|
new_ptr[len] = 0; |
|
return new_ptr; |
|
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* ForAddVar -- |
* ForAddVar -- |
Line 109 static void ForAddVar(const char *, size |
|
Line 121 static void ForAddVar(const char *, size |
|
static void |
static void |
ForAddVar(const char *data, size_t len) |
ForAddVar(const char *data, size_t len) |
{ |
{ |
Buffer buf; |
int nvars; |
int varlen; |
|
|
|
buf = Buf_Init(0); |
|
Buf_AddBytes(buf, len, (Byte *)UNCONST(data)); |
|
|
|
accumFor.nvars++; |
|
accumFor.vars = bmake_realloc(accumFor.vars, accumFor.nvars*sizeof(char *)); |
|
|
|
accumFor.vars[accumFor.nvars-1] = (char *)Buf_GetAll(buf, &varlen); |
nvars = accumFor.nvars; |
|
accumFor.nvars = nvars + 1; |
|
accumFor.vars = bmake_realloc(accumFor.vars, nvars * sizeof(char *)); |
|
|
Buf_Destroy(buf, FALSE); |
accumFor.vars[nvars] = make_str(data, len); |
} |
} |
|
|
/*- |
/*- |
Line 146 ForAddVar(const char *data, size_t len) |
|
Line 153 ForAddVar(const char *data, size_t len) |
|
int |
int |
For_Eval(char *line) |
For_Eval(char *line) |
{ |
{ |
char *ptr = line, *sub, *in, *wrd; |
char *ptr = line, *sub; |
Buffer buf; |
int len; |
int varlen; |
|
static const char instr[] = "in"; |
/* Forget anything we previously knew about - it cannot be useful */ |
|
memset(&accumFor, 0, sizeof accumFor); |
|
|
forLevel = 0; |
forLevel = 0; |
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++) |
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++) |
Line 171 For_Eval(char *line) |
|
Line 179 For_Eval(char *line) |
|
/* |
/* |
* we found a for loop, and now we are going to parse it. |
* we found a for loop, and now we are going to parse it. |
*/ |
*/ |
while (*ptr && isspace((unsigned char) *ptr)) |
|
ptr++; |
|
|
|
/* |
|
* Find the "in". |
|
*/ |
|
for (in = ptr; *in; in++) { |
|
if (isspace((unsigned char) in[0]) && in[1]== 'i' && |
|
in[2] == 'n' && |
|
(in[3] == '\0' || isspace((unsigned char) in[3]))) |
|
break; |
|
} |
|
if (*in == '\0') { |
|
Parse_Error(PARSE_FATAL, "missing `in' in for"); |
|
return -1; |
|
} |
|
|
|
/* |
/* Grab the variables. Terminate on "in". */ |
* Grab the variables. |
for (;; ptr += len) { |
*/ |
|
accumFor.vars = NULL; |
|
|
|
while (ptr < in) { |
|
wrd = ptr; |
|
while (*ptr && !isspace((unsigned char) *ptr)) |
|
ptr++; |
|
ForAddVar(wrd, ptr - wrd); |
|
while (*ptr && isspace((unsigned char) *ptr)) |
while (*ptr && isspace((unsigned char) *ptr)) |
ptr++; |
ptr++; |
|
if (*ptr == '\0') { |
|
Parse_Error(PARSE_FATAL, "missing `in' in for"); |
|
return -1; |
|
} |
|
for (len = 1; ptr[len] && !isspace((unsigned char)ptr[len]); len++) |
|
continue; |
|
if (len == 2 && ptr[0] == 'i' && ptr[1] == 'n') { |
|
ptr += 2; |
|
break; |
|
} |
|
ForAddVar(ptr, len); |
} |
} |
|
|
if (accumFor.nvars == 0) { |
if (accumFor.nvars == 0) { |
Line 207 For_Eval(char *line) |
|
Line 202 For_Eval(char *line) |
|
return -1; |
return -1; |
} |
} |
|
|
/* At this point we should be pointing right at the "in" */ |
|
/* |
|
* compensate for hp/ux's brain damaged assert macro that |
|
* does not handle double quotes nicely. |
|
*/ |
|
assert(!memcmp(ptr, instr, 2)); |
|
ptr += 2; |
|
|
|
while (*ptr && isspace((unsigned char) *ptr)) |
while (*ptr && isspace((unsigned char) *ptr)) |
ptr++; |
ptr++; |
|
|
Line 222 For_Eval(char *line) |
|
Line 209 For_Eval(char *line) |
|
* Make a list with the remaining words |
* Make a list with the remaining words |
*/ |
*/ |
accumFor.lst = Lst_Init(FALSE); |
accumFor.lst = Lst_Init(FALSE); |
buf = Buf_Init(0); |
|
sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE); |
sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE); |
|
|
#define ADDWORD() do { \ |
for (ptr = sub;; ptr += len, accumFor.nitem++) { |
Buf_AddBytes(buf, ptr - wrd, (Byte *)wrd); \ |
while (*ptr && isspace((unsigned char)*ptr)) |
Buf_AddByte(buf, (Byte)'\0'); \ |
ptr++; |
Lst_AtFront(accumFor.lst, Buf_GetAll(buf, &varlen)); \ |
if (*ptr == 0) |
Buf_Destroy(buf, FALSE); \ |
break; |
} while (0) |
for (len = 1; ptr[len] && !isspace((unsigned char)ptr[len]); len++) |
|
continue; |
|
Lst_AtFront(accumFor.lst, make_str(ptr, len)); |
|
} |
|
|
for (ptr = sub; *ptr && isspace((unsigned char) *ptr); ptr++) |
free(sub); |
continue; |
|
|
|
for (wrd = ptr; *ptr; ptr++) |
if (accumFor.nitem % accumFor.nvars) { |
if (isspace((unsigned char) *ptr)) { |
Parse_Error(PARSE_FATAL, |
ADDWORD(); |
"Wrong number of words in .for substitution list %d %d", |
buf = Buf_Init(0); |
accumFor.nitem, accumFor.nvars); |
while (*ptr && isspace((unsigned char) *ptr)) |
/* |
ptr++; |
* Return 'success' so that the body of the .for loop is accumulated. |
wrd = ptr--; |
* The loop will have zero iterations expanded due a later test. |
} |
*/ |
if (DEBUG(FOR)) { |
|
int i; |
|
for (i = 0; i < accumFor.nvars; i++) { |
|
(void)fprintf(debug_file, "For: variable %s\n", accumFor.vars[i]); |
|
} |
|
(void)fprintf(debug_file, "For: list %s\n", sub); |
|
} |
} |
if (ptr - wrd > 0) |
|
ADDWORD(); |
|
else |
|
Buf_Destroy(buf, TRUE); |
|
free(sub); |
|
|
|
accumFor.buf = Buf_Init(0); |
accumFor.buf = Buf_Init(0); |
forLevel = 1; |
forLevel = 1; |
Line 313 For_Run(int lineno) |
|
Line 290 For_Run(int lineno) |
|
int i, done = 0, len; |
int i, done = 0, len; |
char *guy, *orig_guy, *old_guy; |
char *guy, *orig_guy, *old_guy; |
|
|
if (accumFor.buf == NULL || accumFor.vars == NULL || accumFor.lst == NULL) |
|
return; |
|
arg = accumFor; |
arg = accumFor; |
accumFor.buf = NULL; |
accumFor.buf = NULL; |
accumFor.vars = NULL; |
accumFor.vars = NULL; |
accumFor.nvars = 0; |
accumFor.nvars = 0; |
accumFor.lst = NULL; |
accumFor.lst = NULL; |
|
|
|
if (arg.nitem % arg.nvars) |
|
/* Error message already printed */ |
|
return; |
|
|
if (Lst_Open(arg.lst) != SUCCESS) |
if (Lst_Open(arg.lst) != SUCCESS) |
return; |
return; |
|
|
Line 334 For_Run(int lineno) |
|
Line 313 For_Run(int lineno) |
|
for (i = arg.nvars - 1; i >= 0; i--) { |
for (i = arg.nvars - 1; i >= 0; i--) { |
ln = Lst_Next(arg.lst); |
ln = Lst_Next(arg.lst); |
if (ln == NILLNODE) { |
if (ln == NILLNODE) { |
if (i != arg.nvars-1) { |
|
Parse_Error(PARSE_FATAL, |
|
"Not enough words in for substitution list"); |
|
} |
|
done = 1; |
done = 1; |
break; |
break; |
} else { |
} else { |