int GetExceptionIndex( int exception_no ) { int n; n = lindex(exception_nos, MAXEXCEPTIONS, exception_no); if( n == MAXEXCEPTIONS ) n = lindex(exception_nos, MAXEXCEPTIONS, XCPT_PROGRAM); return( n ); }
int insert_wordlist(const list *word_list, tree **t) { if (!word_list || !t) return -1; list *all_but_last = upto_last(word_list); if (!all_but_last) return 0; HASH h = key_from_wordlist((list *)all_but_last); if (!h) return -1; const DATA v = lindex((list *)word_list, -1); if (!v) error(ELIST); if (!*t) { *t = init_tree(h, v); } else { if (ins_tree(*t, h, v) < 0) error(ETREE); } return 0; }
uint StackFrameIndex(SCOPE scope) { uint n; /* was register. 112*/ if( scope == ExecScope ) return(1); if( NActFrames && ((n = lindex(ActScopes, NActFrames, (ulong)scope)) < NActFrames) ) return( n+2 ); return(0); }
static char * strrev(const char *s, char *r) { int j = 0; int i = lindex(s); for(char ch = 0; i > j; ) { r[j] = s[i]; r[i] = s[j]; i--; j++; } return r; }
/* Scan STRING for variable references and expansion-function calls. Only LENGTH bytes of STRING are actually scanned. If LENGTH is -1, scan until a null byte is found. Write the results to LINE, which must point into `variable_buffer'. If LINE is NULL, start at the beginning of the buffer. Return a pointer to LINE, or to the beginning of the buffer if LINE is NULL. */ char * variable_expand_string (char *line, const char *string, long length) { struct variable *v; const char *p, *p1; char *abuf = NULL; char *o; unsigned int line_offset; if (!line) line = initialize_variable_output(); o = line; line_offset = line - variable_buffer; if (length == 0) { variable_buffer_output (o, "", 1); return (variable_buffer); } /* If we want a subset of the string, allocate a temporary buffer for it. Most of the functions we use here don't work with length limits. */ if (length > 0 && string[length] != '\0') { abuf = xmalloc(length+1); memcpy(abuf, string, length); abuf[length] = '\0'; string = abuf; } p = string; while (1) { /* Copy all following uninteresting chars all at once to the variable output buffer, and skip them. Uninteresting chars end at the next $ or the end of the input. */ p1 = strchr (p, '$'); o = variable_buffer_output (o, p, p1 != 0 ? (unsigned int)(p1 - p) : strlen (p) + 1); if (p1 == 0) break; p = p1 + 1; /* Dispatch on the char that follows the $. */ switch (*p) { case '$': /* $$ seen means output one $ to the variable output buffer. */ o = variable_buffer_output (o, p, 1); break; case '(': case '{': /* $(...) or ${...} is the general case of substitution. */ { char openparen = *p; char closeparen = (openparen == '(') ? ')' : '}'; const char *begp; const char *beg = p + 1; char *op; char *abeg = NULL; const char *end, *colon; op = o; begp = p; if (handle_function (&op, &begp)) { o = op; p = begp; break; } /* Is there a variable reference inside the parens or braces? If so, expand it before expanding the entire reference. */ end = strchr (beg, closeparen); if (end == 0) /* Unterminated variable reference. */ fatal (*expanding_var, _("unterminated variable reference")); p1 = lindex (beg, end, '$'); if (p1 != 0) { /* BEG now points past the opening paren or brace. Count parens or braces until it is matched. */ int count = 0; for (p = beg; *p != '\0'; ++p) { if (*p == openparen) ++count; else if (*p == closeparen && --count < 0) break; } /* If COUNT is >= 0, there were unmatched opening parens or braces, so we go to the simple case of a variable name such as `$($(a)'. */ if (count < 0) { abeg = expand_argument (beg, p); /* Expand the name. */ beg = abeg; end = strchr (beg, '\0'); } } else /* Advance P to the end of this reference. After we are finished expanding this one, P will be incremented to continue the scan. */ p = end; /* This is not a reference to a built-in function and any variable references inside are now expanded. Is the resultant text a substitution reference? */ colon = lindex (beg, end, ':'); if (colon) { /* This looks like a substitution reference: $(FOO:A=B). */ const char *subst_beg, *subst_end, *replace_beg, *replace_end; subst_beg = colon + 1; subst_end = lindex (subst_beg, end, '='); if (subst_end == 0) /* There is no = in sight. Punt on the substitution reference and treat this as a variable name containing a colon, in the code below. */ colon = 0; else { replace_beg = subst_end + 1; replace_end = end; /* Extract the variable name before the colon and look up that variable. */ v = lookup_variable (beg, colon - beg); if (v == 0) warn_undefined (beg, colon - beg); /* If the variable is not empty, perform the substitution. */ if (v != 0 && *v->value != '\0') { char *pattern, *replace, *ppercent, *rpercent; char *value = (v->recursive ? recursively_expand (v) : v->value); /* Copy the pattern and the replacement. Add in an extra % at the beginning to use in case there isn't one in the pattern. */ pattern = alloca (subst_end - subst_beg + 2); *(pattern++) = '%'; memcpy (pattern, subst_beg, subst_end - subst_beg); pattern[subst_end - subst_beg] = '\0'; replace = alloca (replace_end - replace_beg + 2); *(replace++) = '%'; memcpy (replace, replace_beg, replace_end - replace_beg); replace[replace_end - replace_beg] = '\0'; /* Look for %. Set the percent pointers properly based on whether we find one or not. */ ppercent = find_percent (pattern); if (ppercent) { ++ppercent; rpercent = find_percent (replace); if (rpercent) ++rpercent; } else { ppercent = pattern; rpercent = replace; --pattern; --replace; } o = patsubst_expand_pat (o, value, pattern, replace, ppercent, rpercent); if (v->recursive) free (value); } } } if (colon == 0) /* This is an ordinary variable reference. Look up the value of the variable. */ o = reference_variable (o, beg, end - beg); if (abeg) free (abeg); } break; case '\0': break; default: if (isblank ((unsigned char)p[-1])) break; /* A $ followed by a random char is a variable reference: $a is equivalent to $(a). */ o = reference_variable (o, p, 1); break; } if (*p == '\0') break; ++p; } if (abuf) free (abuf); variable_buffer_output (o, "", 1); return (variable_buffer + line_offset); }
/* Scan STRING for variable references and expansion-function calls. Only LENGTH bytes of STRING are actually scanned. If LENGTH is -1, scan until a null byte is found. Write the results to LINE, which must point into `variable_buffer'. If LINE is NULL, start at the beginning of the buffer. Return a pointer to LINE, or to the beginning of the buffer if LINE is NULL. Set EOLP to point to the string terminator. */ char * variable_expand_string_2 (char *line, const char *string, long length, char **eolp) { struct variable *v; const char *p, *p1, *eos; char *o; unsigned int line_offset; if (!line) line = initialize_variable_output(); o = line; line_offset = line - variable_buffer; if (length < 0) length = strlen (string); else MY_ASSERT_MSG (string + length == (p1 = memchr (string, '\0', length)) || !p1, ("len=%ld p1=%p %s\n", length, p1, line)); /* Simple 1: Emptry string. */ if (length == 0) { o = variable_buffer_output (o, "\0", 2); *eolp = o - 2; return (variable_buffer + line_offset); } /* Simple 2: Nothing to expand. ~50% if the kBuild calls. */ p1 = (const char *)memchr (string, '$', length); if (p1 == 0) { o = variable_buffer_output (o, string, length); o = variable_buffer_output (o, "\0", 2); *eolp = o - 2; assert (strchr (variable_buffer + line_offset, '\0') == *eolp); return (variable_buffer + line_offset); } p = string; eos = p + length; while (1) { /* Copy all following uninteresting chars all at once to the variable output buffer, and skip them. Uninteresting chars end at the next $ or the end of the input. */ o = variable_buffer_output (o, p, p1 != 0 ? (p1 - p) : (eos - p)); if (p1 == 0) break; p = p1 + 1; /* Dispatch on the char that follows the $. */ switch (*p) { case '$': /* $$ seen means output one $ to the variable output buffer. */ o = variable_buffer_output (o, p, 1); break; case '(': case '{': /* $(...) or ${...} is the general case of substitution. */ { char openparen = *p; char closeparen = (openparen == '(') ? ')' : '}'; const char *begp; const char *beg = p + 1; char *op; char *abeg = NULL; unsigned int alen = 0; const char *end, *colon; op = o; begp = p; end = may_be_function_name (p + 1, eos); if ( end && handle_function (&op, &begp, end, eos)) { o = op; p = begp; MY_ASSERT_MSG (!(p1 = memchr (variable_buffer + line_offset, '\0', o - (variable_buffer + line_offset))), ("line=%p o/exp_end=%p act_end=%p\n", variable_buffer + line_offset, o, p1)); break; } /* Is there a variable reference inside the parens or braces? If so, expand it before expanding the entire reference. */ end = memchr (beg, closeparen, eos - beg); if (end == 0) /* Unterminated variable reference. */ fatal (*expanding_var, _("unterminated variable reference")); p1 = lindex (beg, end, '$'); if (p1 != 0) { /* BEG now points past the opening paren or brace. Count parens or braces until it is matched. */ int count = 0; for (p = beg; p < eos; ++p) { if (*p == openparen) ++count; else if (*p == closeparen && --count < 0) break; } /* If COUNT is >= 0, there were unmatched opening parens or braces, so we go to the simple case of a variable name such as `$($(a)'. */ if (count < 0) { unsigned int len; char saved; /* Expand the name. */ saved = *p; *(char *)p = '\0'; /* XXX: proove that this is safe! XXX2: shouldn't be necessary any longer! */ abeg = allocated_variable_expand_3 (beg, p - beg, &len, &alen); beg = abeg; end = beg + len; *(char *)p = saved; } } else /* Advance P to the end of this reference. After we are finished expanding this one, P will be incremented to continue the scan. */ p = end; /* This is not a reference to a built-in function and any variable references inside are now expanded. Is the resultant text a substitution reference? */ colon = lindex (beg, end, ':'); if (colon) { /* This looks like a substitution reference: $(FOO:A=B). */ const char *subst_beg, *subst_end, *replace_beg, *replace_end; subst_beg = colon + 1; subst_end = lindex (subst_beg, end, '='); if (subst_end == 0) /* There is no = in sight. Punt on the substitution reference and treat this as a variable name containing a colon, in the code below. */ colon = 0; else { replace_beg = subst_end + 1; replace_end = end; /* Extract the variable name before the colon and look up that variable. */ v = lookup_variable (beg, colon - beg); if (v == 0) warn_undefined (beg, colon - beg); /* If the variable is not empty, perform the substitution. */ if (v != 0 && *v->value != '\0') { char *pattern, *replace, *ppercent, *rpercent; char *value = (v->recursive ? recursively_expand (v) : v->value); /* Copy the pattern and the replacement. Add in an extra % at the beginning to use in case there isn't one in the pattern. */ pattern = alloca (subst_end - subst_beg + 2); *(pattern++) = '%'; memcpy (pattern, subst_beg, subst_end - subst_beg); pattern[subst_end - subst_beg] = '\0'; replace = alloca (replace_end - replace_beg + 2); *(replace++) = '%'; memcpy (replace, replace_beg, replace_end - replace_beg); replace[replace_end - replace_beg] = '\0'; /* Look for %. Set the percent pointers properly based on whether we find one or not. */ ppercent = find_percent (pattern); if (ppercent) { ++ppercent; rpercent = find_percent (replace); if (rpercent) ++rpercent; } else { ppercent = pattern; rpercent = replace; --pattern; --replace; } o = patsubst_expand_pat (o, value, pattern, replace, ppercent, rpercent); if (v->recursive) free (value); } } } if (colon == 0) /* This is an ordinary variable reference. Look up the value of the variable. */ o = reference_variable (o, beg, end - beg); if (abeg) recycle_variable_buffer (abeg, alen); } break; case '\0': assert (p == eos); break; default: if (isblank ((unsigned char)p[-1])) /* XXX: This looks incorrect, previous is '$' */ break; /* A $ followed by a random char is a variable reference: $a is equivalent to $(a). */ o = reference_variable (o, p, 1); break; } if (++p >= eos) break; p1 = memchr (p, '$', eos - p); } o = variable_buffer_output (o, "\0", 2); /* KMK: compensate for the strlen + 1 that was removed above. */ *eolp = o - 2; MY_ASSERT_MSG (strchr (variable_buffer + line_offset, '\0') == *eolp, ("expected=%d actual=%d\nlength=%ld string=%.*s\n", (int)(*eolp - variable_buffer + line_offset), (int)strlen(variable_buffer + line_offset), length, (int)length, string)); return (variable_buffer + line_offset); }