/*Helper function to add new node to the hashtable struct.*/ hash_node *add_node(char *s, int defn, int num, hash_node *hash_table[]) { hash_node *new_node; /*hashp pnew_node;*/ unsigned int hashval; if ((new_node = search_node(s, hash_table)) == NULL) { new_node = (hash_node *)malloc(sizeof(* new_node)); if (new_node == NULL || (new_node->name = duplicate_str(s)) == NULL) return NULL; else { hashval = hash_code_gen(s); new_node->next = hash_table[hashval]; hash_table[hashval] = new_node; } } new_node->num = defn; new_node->mem_words = num; /*Returns pointer to a new created node.*/ return new_node; }
/* Sets current line in @st to @s and increases the line number. * * Returns 0 on success; a negative enum errcode otherwise. */ static int st_update(struct state *st, const char *s) { free(st->line); st->line = duplicate_str(s); if (!st->line) return -err_no_mem; st->n += st->inc; return 0; }
/* Sets current @filename, increment (@inc) and line number (@n) in @st. * * Note that @filename, @inc and @n correspond to the yasm .lst file * source file information. * * Returns 0 on success; a negative enum errcode otherwise. */ static int st_set_file(struct state *st, const char *filename, int inc, int n) { if (bug_on(!st)) return -err_internal; if (bug_on(!filename)) return -err_internal; free(st->filename); st->filename = duplicate_str(filename); if (!st->filename) return -err_no_mem; st->inc = inc; st->n = n; return 0; }
/*Treatment for an Entry*/ void entry_treat(input_line * input) { skip_spaces(&(input->line_str)); input->line_str = strtok(input->line_str, " ,.-!?()\t\n\'0'");/*because we need only one word*/ if (!(input->line_str)) { ERROR("Must be symbol after \".entry\".", input->line_number); error_flag = TRUE; return; } if (!isalpha(input->line_str[0])) { ERROR("The symbol after \".entry\" must start by char!", input->line_number) error_flag = TRUE; return; } if (!((tmp_node = search_node(input->line_str, opNode)) == NULL)) { ERROR("The symbol after \".entry\" can't be like assembly command.", input->line_number) error_flag = TRUE; return; } else /*add_node(input->line_str, IC, 0, extern_table);*/ array_entry[entryCount++] = duplicate_str(input->line_str); skip_spaces(&(input->line_str)); input->line_str = strtok(NULL, " ,.-!?()\t\n\'0'"); if (input->line_str) { ERROR("The \".entry\" must have only ONE symbol!", input->line_number); return; } }
int l_append(struct label *l, const char *name, uint64_t addr) { int errcode; if (bug_on(!l)) return -err_internal; if (bug_on(!name)) return -err_internal; /* skip to the last label. */ while (l->next) l = l->next; /* append a new label. */ l->next = l_alloc(); if (!l->next) return -err_no_mem; /* save the name. */ l->next->name = duplicate_str(name); if (!l->next->name) { errcode = -err_no_mem; goto error; } /* save the address. */ l->next->addr = addr; return 0; error: free(l->next->name); free(l->next); l->next = NULL; return errcode; }
struct yasm *yasm_alloc(const char *pttfile) { char *tmp; size_t n; struct yasm *y; if (bug_on(!pttfile)) return NULL; y = calloc(1, sizeof(*y)); if (!y) return NULL; y->fl = fl_alloc(); if (!y->fl) goto error; y->st_asm = st_alloc(); if (!y->st_asm) goto error; y->fileroot = duplicate_str(pttfile); if (!y->fileroot) goto error; y->pttfile = duplicate_str(pttfile); if (!y->pttfile) goto error; tmp = strrchr(y->fileroot, '.'); if (tmp) *tmp = '\0'; tmp = strrchr(y->fileroot, path_separator); if (tmp) { tmp += 1; memmove(y->fileroot, tmp, strlen(tmp)+1); } y->binfile = malloc(strlen(y->fileroot)+strlen(bin_suffix)+1); if (!y->binfile) goto error; y->lstfile = malloc(strlen(y->fileroot)+strlen(lst_suffix)+1); if (!y->lstfile) goto error; n = strlen(y->fileroot); strcpy(y->binfile, y->fileroot); strcpy(y->binfile+n, bin_suffix); strcpy(y->lstfile, y->fileroot); strcpy(y->lstfile+n, lst_suffix); y->l = l_alloc(); if (!y->l) goto error; return y; error: yasm_free(y); return 0; }
int parse_yasm_labels(struct label *l, const struct text *t) { int errcode, no_org_directive; size_t i; uint64_t base_addr; enum { linelen = 1024 }; char line[linelen]; if (bug_on(!t)) return -err_internal; base_addr = 0; no_org_directive = 1; /* determine base address from org directive, error out on * sections. */ for (i = 0; i < t->n; i++) { char *tmp; errcode = text_line(t, line, linelen, i); if (errcode < 0) return errcode; tmp = strstr(line, "[section"); if (tmp) return -err_section; tmp = strstr(line, "[org"); if (!tmp) continue; base_addr = strtol(tmp+strlen("[org"), NULL, 0); no_org_directive = 0; break; } if (no_org_directive) return -err_no_org_directive; for (i = 0; i < t->n; i++) { char *tmp, *name; uint64_t addr; errcode = text_line(t, line, linelen, i); if (errcode < 0) goto error; /* skip line number count. */ tmp = strtok(line, " "); if (!tmp) continue; /* the label can now be on the same line as the memory * address or on a line by its own. * we look at the next token and (1) if it looks like a * label, we search in the following lines for the * corresponding address; or (2) if it looks like an * address, we store it and see if the token after the * opcode looks like a token; or (3) none of the above, * we continue with the next line. */ /* second token after the line number count. it's * either an address; or a label. */ tmp = strtok(NULL, " "); if (!tmp) continue; if (!make_label(tmp)) { /* get address in case we find a label later. */ if (sscanf(tmp, "%" PRIx64, &addr) != 1) continue; /* skip the opcode token. */ tmp = strtok(NULL, " "); if (!tmp) continue; /* this might be a label now. */ tmp = strtok(NULL, " "); if (!make_label(tmp)) continue; errcode = l_append(l, tmp, addr + base_addr); if (errcode < 0) goto error; continue; } name = duplicate_str(tmp); if (!name) { errcode = -err_no_mem; goto error; } /* there was a label so now an address needs to * be found. */ errcode = -err_label_addr; for (i += 1; i < t->n; i++) { int errcode_text; errcode_text = text_line(t, line, linelen, i); if (errcode_text < 0) { errcode = errcode_text; break; } if (sscanf(line, "%*d %" PRIx64 " %*x %*s", &addr) == 1) { errcode = l_append(l, name, addr + base_addr); break; } } if (errcode == -err_label_addr) fprintf(stderr, "label '%s' has no address\n", name); free(name); if (errcode < 0) goto error; } return 0; error: l_free(l->next); free(l->name); l->next = NULL; l->name = NULL; return errcode; }
int pd_parse(struct pt_directive *pd, struct state *st) { char *line, *comment, *ptdirective, *openpar, *closepar; char *directive, *payload; int errcode; char *c; if (bug_on(!pd)) return -err_internal; if (bug_on(!st)) return -err_internal; line = duplicate_str(st->line); if (!line) return -err_no_mem; /* make line lower case. */ for (c = line; *c; ++c) *c = (char) tolower(*c); /* if the current line is not a comment or contains no magic marker * -err_no_directive is returned. */ errcode = -err_no_directive; /* search where the comment begins. */ comment = strchr(line, ';'); /* if there is no comment in the line, we don't have anything to * do. */ if (!comment) goto cleanup; /* search for @pt marker. */ ptdirective = strstr(comment+1, marker); /* if there is no such marker in the comment, we don't have * anything to do. */ if (!ptdirective) goto cleanup; /* directive found, now parse the payload. */ errcode = 0; /* find position of next '(', separating the directive and the * payload. */ openpar = strchr(ptdirective, '('); if (!openpar) { errcode = -err_missing_openpar; st_print_err(st, "invalid syntax", errcode); goto cleanup; } /* find position of next ')', marking the end of the payload */ closepar = strchr(openpar, ')'); if (!closepar) { errcode = -err_missing_closepar; st_print_err(st, "invalid syntax", errcode); goto cleanup; } /* make "multiple" strings by artifically terminating them with * '\0' then get directive and payload substrings, which will * have leading and trailing whitespace "removed". */ *openpar = '\0'; *closepar = '\0'; /* skip leading whitespace. */ directive = ptdirective + strlen(marker); while (isspace(*directive)) directive += 1; payload = openpar+1; errcode = pd_set(pd, directive, payload); cleanup: free(line); return errcode; }
int parse_avp_db_scheme( char *s, struct db_scheme *scheme) { str foo; str bar; char *p; if (s==0 || *s==0) goto error; p = s; /*parse the name */ while (*p && isspace((int)*p)) p++; foo.s = p; while (*p && *p!=':' && !isspace((int)*p)) p++; if (foo.s==p || *p==0) /* missing name or empty scheme */ goto parse_error; foo.len = p - foo.s; /* dulicate it */ duplicate_str( scheme->name, foo, error); /* parse the ':' separator */ while (*p && isspace((int)*p)) p++; if (*p!=':') goto parse_error; p++; while (*p && isspace((int)*p)) p++; if (*p==0) goto parse_error; /* set as default value type string */ scheme->db_flags = AVP_VAL_STR; /* parse the attributes */ while (*p) { /* get the attribute name */ foo.s = p; while (*p && *p!='=' && !isspace((int)*p)) p++; if (p==foo.s || *p==0) /* missing attribute name */ goto parse_error; foo.len = p - foo.s; /* parse the '=' separator */ while (*p && isspace((int)*p)) p++; if (*p!='=') goto parse_error; p++; while (*p && isspace((int)*p)) p++; if (*p==0) goto parse_error; /* parse the attribute value */ bar.s = p; while (*p && *p!=';' && !isspace((int)*p)) p++; if (p==bar.s) /* missing attribute value */ goto parse_error; bar.len = p - bar.s; /* parse the ';' separator, if any */ while (*p && isspace((int)*p)) p++; if (*p!=0 && *p!=';') goto parse_error; if (*p==';') p++; while (*p && isspace((int)*p)) p++; /* identify the attribute */ if ( foo.len==SCHEME_UUID_COL_LEN && !strncasecmp( foo.s, SCHEME_UUID_COL, foo.len) ) { duplicate_str( scheme->uuid_col, bar, error); } else if ( foo.len==SCHEME_USERNAME_COL_LEN && !strncasecmp( foo.s, SCHEME_USERNAME_COL, foo.len) ) { duplicate_str( scheme->username_col, bar, error); } else if ( foo.len==SCHEME_DOMAIN_COL_LEN && !strncasecmp( foo.s, SCHEME_DOMAIN_COL, foo.len) ) { duplicate_str( scheme->domain_col, bar, error); } else if ( foo.len==SCHEME_VALUE_COL_LEN && !strncasecmp( foo.s, SCHEME_VALUE_COL, foo.len) ) { duplicate_str( scheme->value_col, bar, error); } else if ( foo.len==SCHEME_TABLE_LEN && !strncasecmp( foo.s, SCHEME_TABLE, foo.len) ) { duplicate_str( scheme->table, bar, error); } else if ( foo.len==SCHEME_VAL_TYPE_LEN && !strncasecmp( foo.s, SCHEME_VAL_TYPE, foo.len) ) { if ( bar.len==SCHEME_INT_TYPE_LEN && !strncasecmp( bar.s, SCHEME_INT_TYPE, bar.len) ) scheme->db_flags &= (~AVP_VAL_STR); else if ( bar.len==SCHEME_STR_TYPE_LEN && !strncasecmp( bar.s, SCHEME_STR_TYPE, bar.len) ) scheme->db_flags = AVP_VAL_STR; else { LM_ERR("unknown value type <%.*s>\n",bar.len,bar.s); goto error; } } else { LM_ERR("unknown attribute <%.*s>\n",foo.len,foo.s); goto error; } } /* end while */ return 0; parse_error: LM_ERR("parse error in <%s> around %ld\n", s, (long)(p-s)); error: return -1; }
int add_credential( unsigned int type, void *val) { struct uac_credential *crd; char *p; str foo; p = (char*)val; crd = 0; if (p==0 || *p==0) goto error; crd = (struct uac_credential*)pkg_malloc(sizeof(struct uac_credential)); if (crd==0) { LOG(L_ERR,"ERROR:uac:add_credential: no more pkg mem\n"); goto error; } memset( crd, 0, sizeof(struct uac_credential)); /*parse the user */ while (*p && isspace((int)*p)) p++; foo.s = p; while (*p && *p!=':' && !isspace((int)*p)) p++; if (foo.s==p || *p==0) /* missing or empty user */ goto parse_error; foo.len = p - foo.s; /* dulicate it */ duplicate_str( crd->user, foo, error); /* parse the ':' separator */ while (*p && isspace((int)*p)) p++; if (*p!=':') goto parse_error; p++; while (*p && isspace((int)*p)) p++; if (*p==0) goto parse_error; /*parse the realm */ while (*p && isspace((int)*p)) p++; foo.s = p; while (*p && *p!=':' && !isspace((int)*p)) p++; if (foo.s==p || *p==0) /* missing or empty realm */ goto parse_error; foo.len = p - foo.s; /* dulicate it */ duplicate_str( crd->realm, foo, error); /* parse the ':' separator */ while (*p && isspace((int)*p)) p++; if (*p!=':') goto parse_error; p++; while (*p && isspace((int)*p)) p++; if (*p==0) goto parse_error; /*parse the passwd */ while (*p && isspace((int)*p)) p++; foo.s = p; while (*p && !isspace((int)*p)) p++; if (foo.s==p) /* missing or empty passwd */ goto parse_error; foo.len = p - foo.s; /* dulicate it */ duplicate_str( crd->passwd, foo, error); /* end of string */ while (*p && isspace((int)*p)) p++; if (*p!=0) goto parse_error; /* link the new cred struct */ crd->next = crd_list; crd_list = crd; pkg_free(val); return 0; parse_error: LOG(L_ERR,"ERROR:uac:add_credential: parse error in <%s> " "around %ld\n", (char*)val, (long)(p-(char*)val)); error: if (crd) free_credential(crd); return -1; }
int parse_yasm_labels(struct label *l, const struct text *t) { int errcode, no_org_directive; size_t i; uint64_t base_addr; enum { linelen = 1024 }; char line[linelen]; struct label *length; if (bug_on(!t)) return -err_internal; base_addr = 0; no_org_directive = 1; length = NULL; /* determine base address from org directive and insert special * section labels. */ for (i = 0; i < t->n; i++) { char *tmp; errcode = text_line(t, line, linelen, i); if (errcode < 0) return errcode; tmp = strstr(line, "[section"); if (tmp) { tmp += strlen("[section"); errcode = parse_section(tmp, l, &length); if (errcode < 0) return errcode; continue; } tmp = strstr(line, "[org"); if (tmp) { base_addr = strtol(tmp+strlen("[org"), NULL, 0); errcode = l_append(l, "org", base_addr); if (errcode < 0) return errcode; no_org_directive = 0; continue; } /* update the section_<name>_length label, if we have one. * * this must be last; it destroys @line. */ if (length) { uint64_t value, size; tmp = strtok(line, " "); if (!tmp) continue; /* we expect a line number. */ errcode = str_to_uint64(tmp, &value, 10); if (errcode < 0) continue; tmp = strtok(NULL, " "); if (!tmp) continue; /* we expect an address. */ errcode = str_to_uint64(tmp, &value, 16); if (errcode < 0) continue; tmp = strtok(NULL, " "); if (!tmp) continue; /* we expect an opcode. */ errcode = str_to_uint64(tmp, &value, 16); if (errcode < 0) continue; /* we got an opcode - let's compute it's size. */ for (size = 0; value != 0; value >>= 8) size += 1; /* update the section_<name>_length label. */ length->addr += size; } } if (no_org_directive) return -err_no_org_directive; for (i = 0; i < t->n; i++) { char *tmp, *name; uint64_t addr; errcode = text_line(t, line, linelen, i); if (errcode < 0) goto error; /* Change the base on section switches. */ tmp = strstr(line, "[section"); if (tmp) { tmp += strlen("[section"); errcode = lookup_section_vstart(l, tmp, &base_addr); if (errcode < 0) return errcode; continue; } /* skip line number count. */ tmp = strtok(line, " "); if (!tmp) continue; /* the label can now be on the same line as the memory * address or on a line by its own. * we look at the next token and (1) if it looks like a * label, we search in the following lines for the * corresponding address; or (2) if it looks like an * address, we store it and see if the token after the * opcode looks like a token; or (3) none of the above, * we continue with the next line. */ /* second token after the line number count. it's * either an address; or a label. */ tmp = strtok(NULL, " "); if (!tmp) continue; if (!make_label(tmp)) { /* get address in case we find a label later. */ if (sscanf(tmp, "%" PRIx64, &addr) != 1) continue; /* skip the opcode token. */ tmp = strtok(NULL, " "); if (!tmp) continue; /* this might be a label now. */ tmp = strtok(NULL, " "); if (!make_label(tmp)) continue; errcode = l_append(l, tmp, addr + base_addr); if (errcode < 0) goto error; continue; } name = duplicate_str(tmp); if (!name) { errcode = -err_no_mem; goto error; } /* there was a label so now an address needs to * be found. */ errcode = -err_label_addr; for (i += 1; i < t->n; i++) { int errcode_text; errcode_text = text_line(t, line, linelen, i); if (errcode_text < 0) { errcode = errcode_text; break; } if (sscanf(line, "%*d %" PRIx64 " %*x %*s", &addr) == 1) { errcode = l_append(l, name, addr + base_addr); break; } } if (errcode == -err_label_addr) fprintf(stderr, "label '%s' has no address\n", name); free(name); if (errcode < 0) goto error; } return 0; error: l_free(l->next); free(l->name); l->next = NULL; l->name = NULL; return errcode; }