static char * variable_append (const char *name, unsigned int length, const struct variable_set_list *set) { const struct variable *v; char *buf = 0; /* If there's nothing left to check, return the empty buffer. */ if (!set) return initialize_variable_output (); /* Try to find the variable in this variable set. */ v = lookup_variable_in_set (name, length, set->set); /* If there isn't one, look to see if there's one in a set above us. */ if (!v) return variable_append (name, length, set->next); /* If this variable type is append, first get any upper values. If not, initialize the buffer. */ if (v->append) buf = variable_append (name, length, set->next); else buf = initialize_variable_output (); /* Append this value to the buffer, and return it. If we already have a value, first add a space. */ if (buf > variable_buffer) buf = variable_buffer_output (buf, " ", 1); #ifdef CONFIG_WITH_VALUE_LENGTH assert (v->value_length == strlen (v->value)); #endif /* Either expand it or copy it, depending. */ if (! v->recursive) #ifdef CONFIG_WITH_VALUE_LENGTH return variable_buffer_output (buf, v->value, v->value_length); #else return variable_buffer_output (buf, v->value, strlen (v->value)); #endif #ifdef CONFIG_WITH_VALUE_LENGTH variable_expand_string_2 (buf, v->value, v->value_length, &buf); return buf; #else buf = variable_expand_string (buf, v->value, strlen (v->value)); return (buf + strlen (buf)); #endif }
VarList *setup_variables(InstructionList *list) { if (!list) kasm_exit("Passed null list to variable pass.", 0); if (list->size == 0) return NULL; VarList *v = varlist_create(); int local_addr = 0; Instruction *current = list->start; while(current) { int index = current->index; StrNode *n = current->list->head; if (n->str[0] == '.') { local_addr = variable_append(v, current, local_addr); current = current->next; instruction_list_remove(list, index); } else { current = current->next; } } return v; }
static char * variable_append (const char *name, unsigned int length, const struct variable_set_list *set, int local) { const struct variable *v; char *buf = 0; /* If this set is local and the next is not a parent, then next is local. */ int nextlocal = local && set->next_is_parent == 0; /* If there's nothing left to check, return the empty buffer. */ if (!set) return initialize_variable_output (); /* Try to find the variable in this variable set. */ v = lookup_variable_in_set (name, length, set->set); /* If there isn't one, or this one is private, try the set above us. */ if (!v || (!local && v->private_var)) return variable_append (name, length, set->next, nextlocal); /* If this variable type is append, first get any upper values. If not, initialize the buffer. */ if (v->append) buf = variable_append (name, length, set->next, nextlocal); else buf = initialize_variable_output (); /* Append this value to the buffer, and return it. If we already have a value, first add a space. */ if (buf > variable_buffer) buf = variable_buffer_output (buf, " ", 1); /* Either expand it or copy it, depending. */ if (! v->recursive) return variable_buffer_output (buf, v->value, strlen (v->value)); buf = variable_expand_string (buf, v->value, strlen (v->value)); return (buf + strlen (buf)); }
static char * allocated_variable_append (const struct variable *v) { char *val; /* Construct the appended variable value. */ char *obuf = variable_buffer; unsigned int olen = variable_buffer_length; variable_buffer = 0; val = variable_append (v->name, strlen (v->name), current_variable_set_list); variable_buffer_output (val, "", 1); val = variable_buffer; variable_buffer = obuf; variable_buffer_length = olen; return val; }
static int process_text_line(char *buf, struct category **cat, struct config *cfg, int lineno, const char *configfile) { char *curr = buf, *c; /* a category header */ if (curr[0] == '[') { if ((c = strchr(curr, ']')) == NULL) { xcb_log(XCB_LOG_WARNING, "no closing ']', line %d of '%s'", lineno, configfile); return -1; } *c = '\0'; ++curr; /* FIXME */ if ((*cat = category_new(curr, cfg->include_level == 1 ? "" : configfile, lineno)) == NULL) return -1; category_append(cfg, *cat); /* directive #include */ } else if (curr[0] == '#') { ++curr; c = curr; while (*c && *c > 32) ++c; if (*c) { *c = '\0'; c = strip(c + 1); if (*c == '\0') c = NULL; } else c = NULL; if (strcasecmp(curr, "include")) { xcb_log(XCB_LOG_WARNING, "Unknown directive '#%s' at line %d of %s", curr, lineno, configfile); return 0; } if (c == NULL) { xcb_log(XCB_LOG_WARNING, "Directive '#include' needs an argument (filename)" "at line %d of %s", lineno, configfile); return 0; } curr = c; if (*c == '"' || *c == '<') { char quote_char = *c; if (quote_char == '<') quote_char = '>'; if (*(c + strlen(c) - 1) == quote_char) { ++curr; *(c + strlen(c) - 1) = '\0'; } } /* FIXME */ config_include_new(cfg, curr); if (config_internal_load(curr, cfg) == NULL) return -1; /* just a line (variable = value) */ } else { struct variable *var; if (*cat == NULL) { xcb_log(XCB_LOG_WARNING, "no category context for line %d of '%s'", lineno, configfile); return -1; } if ((c = strchr(curr, '=')) == NULL) { xcb_log(XCB_LOG_WARNING, "no '=' (equal sign) in line %d of '%s'", lineno, configfile); return -1; } *c++ = '\0'; /* FIXME */ if ((var = variable_new(strip(curr), strip(c), cfg->include_level == 1 ? "" : configfile, lineno)) == NULL) return -1; variable_append(*cat, var); } return 0; }