static int parse_patch_binary( git_patch_parsed *patch, git_patch_parse_ctx *ctx) { int error; if (parse_advance_expected_s(ctx, "GIT binary patch") < 0 || parse_advance_nl(ctx) < 0) return parse_err("corrupt git binary header at line %d", ctx->line_num); /* parse old->new binary diff */ if ((error = parse_patch_binary_side( &patch->base.binary.new_file, ctx)) < 0) return error; if (parse_advance_nl(ctx) < 0) return parse_err("corrupt git binary separator at line %d", ctx->line_num); /* parse new->old binary diff */ if ((error = parse_patch_binary_side( &patch->base.binary.old_file, ctx)) < 0) return error; if (parse_advance_nl(ctx) < 0) return parse_err("corrupt git binary patch separator at line %d", ctx->line_num); patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY; return 0; }
static void parse_ops(int argc, char **argv, int i) { enum { STATE_INIT, STATE_GOT_FILTER, STATE_GOT_OP } state = STATE_INIT; struct pci_filter filter; struct pci_dev **selected_devices = NULL; while (i < argc) { char *c = argv[i++]; if (*c == '-') { if (state != STATE_GOT_FILTER) pci_filter_init(pacc, &filter); i = parse_filter(argc, argv, i-1, &filter); state = STATE_GOT_FILTER; } else { if (state == STATE_INIT) parse_err("Filter specification expected"); if (state == STATE_GOT_FILTER) selected_devices = select_devices(&filter); if (!selected_devices[0] && !force) fprintf(stderr, "setpci: Warning: No devices selected for \"%s\".\n", c); parse_op(c, selected_devices); state = STATE_GOT_OP; } } if (state == STATE_INIT) parse_err("No operation specified"); }
static int parse_filter(int argc, char **argv, int i, struct pci_filter *filter) { char *c = argv[i++]; char *d; if (!c[1] || !strchr("sd", c[1])) parse_err("Invalid option -%c", c[1]); if (c[2]) d = (c[2] == '=') ? c+3 : c+2; else if (i < argc) d = argv[i++]; else parse_err("Option -%c requires an argument", c[1]); switch (c[1]) { case 's': if (d = pci_filter_parse_slot(filter, d)) parse_err("Unable to parse filter -s %s", d); break; case 'd': if (d = pci_filter_parse_id(filter, d)) parse_err("Unable to parse filter -d %s", d); break; default: parse_err("Unknown filter option -%c", c[1]); } return i; }
get_outputs() { int i; int j; struct nf *n; char buf[80]; get_str(cfp,buf," "); /* next line must specify outputs */ if (strcmp(buf, "output") != 0) parse_err(); get_str(cfp,buf," "); if (strcmp(buf, "node") != 0){ if (strcmp(buf, "nodes") != 0) parse_err(); } get_str(cfp,buf," "); if (strcmp(buf, "are") != 0){ if (strcmp(buf, "is") != 0) parse_err(); } get_str(cfp,buf,"\n"); get_nums(buf,nn+ni,ni,selects); if (selects[0] == 1){ fprintf(stderr,"Node 0 cannot be an output\n"); exit(1); } for (i = 1; i <= ni; i++){ if (selects[i] == 1){ fprintf(stderr,"An input cannot be an output\n"); exit(1); } } n = ninfo; for (i = ni+1, j = -1; i <= nn+ni; i++, n++){ if (selects[i] > 0){ if (++j < no){ outputs[j] = i-ni; n->targ = 1; } } } if (++j != no){ fprintf(stderr,"Expecting %d outputs, found %d\n",no,j); exit(1); } }
static int check_filenames(git_patch_parsed *patch) { const char *prefixed_new, *prefixed_old; size_t old_prefixlen = 0, new_prefixlen = 0; bool added = (patch->base.delta->status == GIT_DELTA_ADDED); bool deleted = (patch->base.delta->status == GIT_DELTA_DELETED); if (patch->old_path && !patch->new_path) return parse_err("missing new path"); if (!patch->old_path && patch->new_path) return parse_err("missing old path"); /* Ensure (non-renamed) paths match */ if (check_header_names( patch->header_old_path, patch->old_path, "old", added) < 0 || check_header_names( patch->header_new_path, patch->new_path, "new", deleted) < 0) return -1; prefixed_old = (!added && patch->old_path) ? patch->old_path : patch->header_old_path; prefixed_new = (!deleted && patch->new_path) ? patch->new_path : patch->header_new_path; if (check_prefix( &patch->old_prefix, &old_prefixlen, patch, prefixed_old) < 0 || check_prefix( &patch->new_prefix, &new_prefixlen, patch, prefixed_new) < 0) return -1; /* Prefer the rename filenames as they are unambiguous and unprefixed */ if (patch->rename_old_path) patch->base.delta->old_file.path = patch->rename_old_path; else patch->base.delta->old_file.path = prefixed_old + old_prefixlen; if (patch->rename_new_path) patch->base.delta->new_file.path = patch->rename_new_path; else patch->base.delta->new_file.path = prefixed_new + new_prefixlen; if (!patch->base.delta->old_file.path && !patch->base.delta->new_file.path) return parse_err("git diff header lacks old / new paths"); return 0; }
/* * parse_line - Parse the current line and process the found token. */ static int parse_line(const char *line, int nl, parser_ctx_t *ctx, gamelist_t *list) { int tok = get_token(line, ctx->top); D_PRINTF("%4i %i %s\n", nl, tok, line); /* * Check if current token is expected - makes sure that the list * operations succeed. */ if (!(ctx->next & tok)) { parse_err(nl, "parse error: %s invalid here", tok2str(tok)); return -1; } /* Process actual token and add it to the list it belongs to. */ switch (tok) { case TOK_GAME_TITLE: ctx->game = __make_game(line); if (ctx->game == NULL) { parse_err(nl, "make_game() failed"); return -1; } GAMES_INSERT_TAIL(list, ctx->game); break; case TOK_CHEAT_DESC: ctx->cheat = __make_cheat(line); if (ctx->cheat == NULL) { parse_err(nl, "make_cheat() failed"); return -1; } CHEATS_INSERT_TAIL(&ctx->game->cheats, ctx->cheat); break; case TOK_CHEAT_CODE: ctx->code = __make_code(line); if (ctx->code == NULL) { parse_err(nl, "make_code() failed"); return -1; } CODES_INSERT_TAIL(&ctx->cheat->codes, ctx->code); break; } ctx->next = next_token(tok); return 0; }
static int check_patch(git_patch_parsed *patch) { git_diff_delta *delta = patch->base.delta; if (check_filenames(patch) < 0) return -1; if (delta->old_file.path && delta->status != GIT_DELTA_DELETED && !delta->new_file.mode) delta->new_file.mode = delta->old_file.mode; if (delta->status == GIT_DELTA_MODIFIED && !(delta->flags & GIT_DIFF_FLAG_BINARY) && delta->new_file.mode == delta->old_file.mode && git_array_size(patch->base.hunks) == 0) return parse_err("patch with no hunks"); if (delta->status == GIT_DELTA_ADDED) { memset(&delta->old_file.id, 0x0, sizeof(git_oid)); delta->old_file.id_abbrev = 0; } if (delta->status == GIT_DELTA_DELETED) { memset(&delta->new_file.id, 0x0, sizeof(git_oid)); delta->new_file.id_abbrev = 0; } return 0; }
int set_iof_rule(const char* path, const char* prob, const char* fake_err, const char* extra_arg) { int err = 0; iof_t* iof = NULL; iof_t val; memset(&val, 0, sizeof(val)); if (NULL == path || NULL == prob || NULL == fake_err || NULL == extra_arg) { err = -EINVAL; error("set_iof_rule():EINVAL\n"); } else if (NULL == (iof = get_iof_ctrl())) { err = errno; } else if (0 == strncmp(TCP_PREFIX, path, strlen(TCP_PREFIX))) { val.type = SOCK_TYPE; val.port = atoi(path + strlen(TCP_PREFIX)); } else { val.type = REG_TYPE; val.dev_no = get_dev_no_by_path(path); } if (0 == err) { val.prob = atof(prob); val.err = parse_err(fake_err); val.arg = atoi(extra_arg); while(!set_iof(iof, &val)) ; } return err; }
int check_header_names( const char *one, const char *two, const char *old_or_new, bool two_null) { if (!one || !two) return 0; if (two_null && strcmp(two, "/dev/null") != 0) return parse_err("expected %s path of '/dev/null'", old_or_new); else if (!two_null && strcmp(one, two) != 0) return parse_err("mismatched %s path names", old_or_new); return 0; }
static int parse_header_similarity( git_patch_parsed *patch, git_patch_parse_ctx *ctx) { if (parse_header_percent(&patch->base.delta->similarity, ctx) < 0) return parse_err("invalid similarity percentage at line %d", ctx->line_num); return 0; }
static int parse_patch_header( git_patch_parsed *patch, git_patch_parse_ctx *ctx) { int error = 0; for (ctx->line = ctx->remain; ctx->remain_len > 0; parse_advance_line(ctx)) { /* This line is too short to be a patch header. */ if (ctx->line_len < 6) continue; /* This might be a hunk header without a patch header, provide a * sensible error message. */ if (parse_ctx_contains_s(ctx, "@@ -")) { size_t line_num = ctx->line_num; git_patch_hunk hunk; /* If this cannot be parsed as a hunk header, it's just leading * noise, continue. */ if (parse_hunk_header(&hunk, ctx) < 0) { giterr_clear(); continue; } error = parse_err("invalid hunk header outside patch at line %d", line_num); goto done; } /* This buffer is too short to contain a patch. */ if (ctx->remain_len < ctx->line_len + 6) break; /* A proper git patch */ if (parse_ctx_contains_s(ctx, "diff --git ")) { error = parse_header_git(patch, ctx); goto done; } error = 0; continue; } giterr_set(GITERR_PATCH, "no patch found"); error = GIT_ENOTFOUND; done: return error; }
static int parse_hunk_header( git_patch_hunk *hunk, git_patch_parse_ctx *ctx) { const char *header_start = ctx->line; hunk->hunk.old_lines = 1; hunk->hunk.new_lines = 1; if (parse_advance_expected_s(ctx, "@@ -") < 0 || parse_int(&hunk->hunk.old_start, ctx) < 0) goto fail; if (ctx->line_len > 0 && ctx->line[0] == ',') { if (parse_advance_expected_s(ctx, ",") < 0 || parse_int(&hunk->hunk.old_lines, ctx) < 0) goto fail; } if (parse_advance_expected_s(ctx, " +") < 0 || parse_int(&hunk->hunk.new_start, ctx) < 0) goto fail; if (ctx->line_len > 0 && ctx->line[0] == ',') { if (parse_advance_expected_s(ctx, ",") < 0 || parse_int(&hunk->hunk.new_lines, ctx) < 0) goto fail; } if (parse_advance_expected_s(ctx, " @@") < 0) goto fail; parse_advance_line(ctx); if (!hunk->hunk.old_lines && !hunk->hunk.new_lines) goto fail; hunk->hunk.header_len = ctx->line - header_start; if (hunk->hunk.header_len > (GIT_DIFF_HUNK_HEADER_SIZE - 1)) return parse_err("oversized patch hunk header at line %d", ctx->line_num); memcpy(hunk->hunk.header, header_start, hunk->hunk.header_len); hunk->hunk.header[hunk->hunk.header_len] = '\0'; return 0; fail: giterr_set(GITERR_PATCH, "invalid patch hunk header at line %d", ctx->line_num); return -1; }
static int parse_header_dissimilarity( git_patch_parsed *patch, git_patch_parse_ctx *ctx) { uint16_t dissimilarity; if (parse_header_percent(&dissimilarity, ctx) < 0) return parse_err("invalid similarity percentage at line %d", ctx->line_num); patch->base.delta->similarity = 100 - dissimilarity; return 0; }
int main(int argc, char *argv[]) { #if defined(_WIN32) || defined(__CYGWIN__) const char * port = "COM1"; #else const char * port = "/dev/ttyS11"; #endif int fcnt; char * fnam[64]; extern char *optarg; /* getopt */ extern int optind; /* getopt */ int c; /* the program name start just after the last slash */ if ((progname = (char *)strrchr(argv[0], '/')) == NULL) progname = argv[0]; else progname++; /* parse the command line options */ while ((c = getopt(argc, argv, "dvhp:")) > 0) { switch (c) { case 'v': show_version(); return 0; case 'h': show_usage(); return 1; case 'p': port = optarg; break; default: parse_err(optarg); return 2; } } if (optind < argc) { fcnt = 0; do { fnam[fcnt++] = argv[optind]; optind++; } while (optind < argc); return ymodem_send(port, fcnt, fnam); } return ymodem_recv(port); }
get_nodes() { int i; char buf[80]; char tmp[80]; /* read nn, ni, no */ nn = ni = no = -1; get_str(cfp,buf,"\n"); /* first line must be "NODES:" */ if (strcmp(buf, "NODES:") != 0){ fprintf(stderr,".cf file must begin with NODES:\n"); exit(1); } /* next three lines must specify nn, ni, and no in any order */ for (i = 0; i < 3; i++){ get_str(cfp,buf," "); get_str(cfp,tmp," "); if (tmp[0] != '=') parse_err(); get_str(cfp,tmp,"\n"); if (strcmp(buf, "nodes") == 0) nn = atoi(tmp); if (strcmp(buf, "inputs") == 0) ni = atoi(tmp); if (strcmp(buf, "outputs") == 0) no = atoi(tmp); } if ((nn < 1) || (ni < 0) || (no < 0) || (nn < no)){ fprintf(stderr,"ERROR: Invalid specification\n\n"); parse_err(); } nt = 1 + ni + nn; np = 1 + ni; }
static int parse_patch_binary_nodata( git_patch_parsed *patch, git_patch_parse_ctx *ctx) { if (parse_advance_expected_str(ctx, "Binary files ") < 0 || parse_advance_expected_str(ctx, patch->header_old_path) < 0 || parse_advance_expected_str(ctx, " and ") < 0 || parse_advance_expected_str(ctx, patch->header_new_path) < 0 || parse_advance_expected_str(ctx, " differ") < 0 || parse_advance_nl(ctx) < 0) return parse_err("corrupt git binary header at line %"PRIuZ, ctx->line_num); patch->base.binary.contains_data = 0; patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY; return 0; }
static void parse_register(struct op *op, char *base) { const struct reg_name *r; unsigned int cap; op->cap_type = op->cap_id = 0; if (parse_x32(base, NULL, &op->addr) > 0) return; else if (r = parse_reg_name(base)) { switch (r->cap & 0xff0000) { case 0x10000: op->cap_type = PCI_CAP_NORMAL; break; case 0x20000: op->cap_type = PCI_CAP_EXTENDED; break; } op->cap_id = r->cap & 0xffff; op->addr = r->offset; if (r->width && !op->width) op->width = r->width; return; } else if (!strncasecmp(base, "CAP", 3)) { if (parse_x32(base+3, NULL, &cap) > 0 && cap < 0x100) { op->cap_type = PCI_CAP_NORMAL; op->cap_id = cap; op->addr = 0; return; } } else if (!strncasecmp(base, "ECAP", 4)) { if (parse_x32(base+4, NULL, &cap) > 0 && cap < 0x1000) { op->cap_type = PCI_CAP_EXTENDED; op->cap_id = cap; op->addr = 0; return; } } parse_err("Unknown register \"%s\"", base); }
static int parse_header_mode(uint16_t *mode, git_patch_parse_ctx *ctx) { const char *end; int32_t m; int ret; if (ctx->line_len < 1 || !git__isdigit(ctx->line[0])) return parse_err("invalid file mode at line %d", ctx->line_num); if ((ret = git__strntol32(&m, ctx->line, ctx->line_len, &end, 8)) < 0) return ret; if (m > UINT16_MAX) return -1; *mode = (uint16_t)m; parse_advance_chars(ctx, (end - ctx->line)); return ret; }
static int check_prefix( char **out, size_t *out_len, git_patch_parsed *patch, const char *path_start) { const char *path = path_start; size_t prefix_len = patch->ctx->opts.prefix_len; size_t remain_len = prefix_len; *out = NULL; *out_len = 0; if (prefix_len == 0) goto done; /* leading slashes do not count as part of the prefix in git apply */ while (*path == '/') path++; while (*path && remain_len) { if (*path == '/') remain_len--; path++; } if (remain_len || !*path) return parse_err( "header filename does not contain %d path components", prefix_len); done: *out_len = (path - path_start); *out = git__strndup(path_start, *out_len); return (out == NULL) ? -1 : 0; }
static int parse_header_oid( git_oid *oid, int *oid_len, git_patch_parse_ctx *ctx) { size_t len; for (len = 0; len < ctx->line_len && len < GIT_OID_HEXSZ; len++) { if (!git__isxdigit(ctx->line[len])) break; } if (len < GIT_OID_MINPREFIXLEN || git_oid_fromstrn(oid, ctx->line, len) < 0) return parse_err("invalid hex formatted object id at line %d", ctx->line_num); parse_advance_chars(ctx, len); *oid_len = (int)len; return 0; }
/* Returns 1 if argument consumed, 0 if all done, -1 on error. */ int parse_one(int *argc, char *argv[], unsigned *offset, void (*errlog)(const char *fmt, ...)) { unsigned i, arg, len; const char *o, *optarg = NULL; char *problem; if (getenv("POSIXLY_CORRECT")) { /* Don't find options after non-options. */ arg = 1; } else { for (arg = 1; argv[arg]; arg++) { if (argv[arg][0] == '-') break; } } if (!argv[arg] || argv[arg][0] != '-') return 0; /* Special arg terminator option. */ if (strcmp(argv[arg], "--") == 0) { consume_option(argc, argv, arg); return 0; } /* Long options start with -- */ if (argv[arg][1] == '-') { assert(*offset == 0); for (o = first_lopt(&i, &len); o; o = next_lopt(o, &i, &len)) { if (strncmp(argv[arg] + 2, o, len) != 0) continue; if (argv[arg][2 + len] == '=') optarg = argv[arg] + 2 + len + 1; else if (argv[arg][2 + len] != '\0') continue; break; } if (!o) return parse_err(errlog, argv[0], argv[arg], strlen(argv[arg]), "unrecognized option"); /* For error messages, we include the leading '--' */ o -= 2; len += 2; } else { /* offset allows us to handle -abc */ for (o = first_sopt(&i); o; o = next_sopt(o, &i)) { if (argv[arg][*offset + 1] != *o) continue; (*offset)++; break; } if (!o) return parse_err(errlog, argv[0], argv[arg], strlen(argv[arg]), "unrecognized option"); /* For error messages, we include the leading '-' */ o--; len = 2; } if (opt_table[i].type == OPT_NOARG) { if (optarg) return parse_err(errlog, argv[0], o, len, "doesn't allow an argument"); problem = opt_table[i].cb(opt_table[i].u.arg); } else { if (!optarg) { /* Swallow any short options as optarg, eg -afile */ if (*offset && argv[arg][*offset + 1]) { optarg = argv[arg] + *offset + 1; *offset = 0; } else optarg = argv[arg+1]; } if (!optarg) return parse_err(errlog, argv[0], o, len, "requires an argument"); problem = opt_table[i].cb_arg(optarg, opt_table[i].u.arg); } if (problem) { parse_err(errlog, argv[0], o, len, problem); free(problem); return -1; } /* If no more letters in that short opt, reset offset. */ if (*offset && !argv[arg][*offset + 1]) *offset = 0; /* All finished with that option? */ if (*offset == 0) { consume_option(argc, argv, arg); if (optarg && optarg == argv[arg]) consume_option(argc, argv, arg); } return 1; }
get_connections() { int i; int j; int k; struct cf *ci; int gn; float min; float max; char buf[80]; int *tmp; int *iselects; /* malloc space for iselects */ iselects = (int *) malloc(nt * sizeof(int)); if (iselects == NULL){ perror("iselects malloc failed"); exit(1); } get_str(cfp,buf,"\n"); /* next line must be "CONNECTIONS:" */ if (strcmp(buf, "CONNECTIONS:") != 0) parse_err(); get_str(cfp,buf," "); /* next line must be "groups = #" */ if (strcmp(buf, "groups") != 0) parse_err(); get_str(cfp,buf," "); if (buf[0] != '=') parse_err(); get_str(cfp,buf,"\n"); ngroups = atoi(buf); /* malloc space for tmp */ tmp = (int *) malloc((ngroups+1) * sizeof(int)); if (tmp == NULL){ perror("tmp malloc failed"); exit(1); } get_str(cfp,buf," "); while (strcmp(buf, "SPECIAL:") != 0){ /* a group is identified */ if (strcmp(buf,"group") == 0){ get_str(cfp,buf," "); get_nums(buf,ngroups,0,tmp); get_str(cfp,buf," "); if (buf[0] != '=') parse_err(); get_str(cfp,buf," "); /* group * = fixed */ if (strcmp(buf,"fixed") == 0){ for (i = 0; i < nn; i++){ ci = *(cinfo + i); for (j = 0; j < nt; j++, ci++){ if (tmp[ci->num]) ci->fix = 1; } } } /* group * = wmin & wmax */ else { min = (float) atof(buf); get_str(cfp,buf," "); if (buf[0] != '&') parse_err(); get_str(cfp,buf," "); max = (float) atof(buf); if (max < min){ fprintf(stderr,"ERROR: %g < %g\n\n",max,min); parse_err(); } for (i = 0; i < nn; i++){ ci = *(cinfo + i); for (j = 0; j < nt; j++, ci++){ if (tmp[ci->num]){ limits = 1; ci->lim = 1; ci->min = min; ci->max = max; } } } } strcat(pbuf,"\n"); get_str(cfp,buf," "); } /* a connection is specified */ else { get_nums(buf,nn+ni,ni,selects); if (selects[0]){ fprintf(stderr,"Connecting TO a bias\n\n"); parse_err(); } for (i = 1; i <= ni; i++){ if (selects[i]){ fprintf(stderr,"Connecting TO an input\n\n"); parse_err(); } } get_str(cfp,buf," "); if (strcmp(buf,"from") != 0) parse_err(); get_str(cfp,buf," "); get_nums(buf,nn+ni,ni,iselects); for (i = 0; i < nn; i++){ ci = *(cinfo + i); for (j = 0; j < nt; j++, ci++){ if ((selects[i+ni+1]) && (iselects[j])) ci->con += 1; } } strcat(pbuf,"\t"); get_str(cfp,buf," "); if (buf[0] == '='){ get_str(cfp,buf," "); /* connection = fixed */ if (strcmp(buf,"fixed") == 0){ for (i = 0; i < nn; i++){ ci = *(cinfo + i); for (j = 0; j < nt; j++, ci++){ if ((selects[i+ni+1]) && (iselects[j])) ci->fix = 1; } } } else { /* connection = group # */ if (strcmp(buf,"group") == 0){ get_str(cfp,buf," "); gn = atoi(buf); for (i = 0; i < nn; i++){ ci = *(cinfo + i); for (j = 0; j < nt; j++, ci++){ if ((selects[i+ni+1]) && (iselects[j])) ci->num = gn; } } } /* connection = min & max */ else { min = (float) atof(buf); get_str(cfp,buf," "); if (buf[0] != '&') parse_err(); get_str(cfp,buf," "); max = (float) atof(buf); if (max < min){ fprintf(stderr,"ERROR: %g < %g\n\n",max,min); parse_err(); } for (i = 0; i < nn; i++){ ci = *(cinfo + i); for (j = 0; j < nt; j++, ci++){ if ((selects[i+ni+1]) && (iselects[j])){ limits = 1; ci->lim = 1; ci->min = min; ci->max = max; } } } } } get_str(cfp,buf,"\t"); if (strcmp(buf,"fixed") == 0){ for (i = 0; i < nn; i++){ ci = *(cinfo + i); for (j = 0; j < nt; j++, ci++){ if ((selects[i+ni+1]) && (iselects[j])) ci->fix = 1; } } get_str(cfp,buf,"\t"); } if (strcmp(buf,"one-to-one") == 0){ for (k = 0; k < nt; k++){ if (iselects[k]) break; } for (i = 0; i < nn; i++){ ci = *(cinfo + i); for (j = 0; j < nt; j++, ci++){ if ((selects[i+ni+1]) && (iselects[j])){ if (ci->con == 1){ ci->con = 0; ci->fix = 0; ci->lim = 0; } else ci->con -= 1; } } if (selects[i+np]){ ci = *(cinfo + i) + k++; ci->con = 1; ci->fix = 1; ci->lim = 1; } } get_str(cfp,buf,"\n"); } } } } /* for (i = 0; i < nn; i++){ ci = *(cinfo + i); for (j = 0; j < nt; j++, ci++){ fprintf(stderr,"i: %d j: %d c: %d f: %d g: %d\n", i,j,ci->con,ci->fix,ci->num); } } */ }
get_special() { char buf[80]; char tmp[80]; int i; int *iselects; struct nf *n; /* malloc space for iselects */ iselects = (int *) malloc(nt * sizeof(int)); if (iselects == NULL){ perror("iselects malloc failed"); exit(1); } while (fscanf(cfp,"%s",buf) != EOF){ if (strlen(pbuf) > MAX_PARSE_BUF -512) strcpy(pbuf, pbuf +512); strcat(pbuf,buf); strcat(pbuf," "); get_str(cfp,tmp," "); if (tmp[0] != '=') parse_err(); get_str(cfp,tmp,"\n"); if (strcmp(buf,"weight_limit") == 0) weight_limit = (float) atof(tmp); if (strcmp(buf,"selected") == 0){ get_nums(tmp,nn,0,selects); } if (strcmp(buf,"linear") == 0){ get_nums(tmp,nn,0,iselects); n = ninfo; for (i = 1; i <= nn; i++, n++){ if (iselects[i]) n->func = 2; } } if (strcmp(buf,"bipolar") == 0){ get_nums(tmp,nn,0,iselects); n = ninfo; for (i = 1; i <= nn; i++, n++){ if (iselects[i]) n->func = 1; } } if (strcmp(buf,"binary") == 0){ get_nums(tmp,nn,0,iselects); n = ninfo; for (i = 1; i <= nn; i++, n++){ if (iselects[i]) n->func = 3; } } if (strcmp(buf,"delayed") == 0){ get_nums(tmp,nn,0,iselects); n = ninfo; for (i = 1; i <= nn; i++, n++){ if (iselects[i]) n->dela = 1; } } } }
asm86_t *ack_get_instruction(void) { asm86_t *a= nil; expression_t *e; token_t *t; while ((t= get_token(0))->symbol == ';') skip_token(1); if (t->type == T_EOF) return nil; if (t->symbol == '#') { /* Preprocessor line and file change. */ if ((t= get_token(1))->type != T_WORD || !isanumber(t->name) || get_token(2)->type != T_STRING ) { parse_err(1, t, "file not preprocessed?\n"); zap(); } else { set_file(get_token(2)->name, strtol(get_token(1)->name, nil, 0) - 1); /* GNU CPP adds extra cruft, simply zap the line. */ zap(); } a= ack_get_instruction(); } else if (t->type == T_WORD && get_token(1)->symbol == ':') { /* A label definition. */ a= new_asm86(); a->line= t->line; a->opcode= DOT_LABEL; a->optype= PSEUDO; a->args= e= new_expr(); e->operator= ':'; e->name= copystr(t->name); skip_token(2); } else if (t->type == T_WORD && get_token(1)->symbol == '=') { int n= 2; if ((e= ack_get_C_expression(&n)) == nil) { zap(); a= ack_get_instruction(); } else if (get_token(n)->symbol != ';') { parse_err(1, t, "garbage after assignment\n"); zap(); a= ack_get_instruction(); } else { a= new_asm86(); a->line= t->line; a->opcode= DOT_EQU; a->optype= PSEUDO; a->args= new_expr(); a->args->operator= '='; a->args->name= copystr(t->name); a->args->middle= e; skip_token(n+1); } } else if (t->type == T_WORD) { if ((a= ack_get_statement()) == nil) { zap(); a= ack_get_instruction(); } } else { parse_err(1, t, "syntax error\n"); zap(); a= ack_get_instruction(); } return a; }
static int parse_header_git( git_patch_parsed *patch, git_patch_parse_ctx *ctx) { size_t i; int error = 0; /* Parse the diff --git line */ if (parse_advance_expected_s(ctx, "diff --git ") < 0) return parse_err("corrupt git diff header at line %d", ctx->line_num); if (parse_header_path(&patch->header_old_path, ctx) < 0) return parse_err("corrupt old path in git diff header at line %d", ctx->line_num); if (parse_advance_ws(ctx) < 0 || parse_header_path(&patch->header_new_path, ctx) < 0) return parse_err("corrupt new path in git diff header at line %d", ctx->line_num); /* Parse remaining header lines */ for (parse_advance_line(ctx); ctx->remain_len > 0; parse_advance_line(ctx)) { bool found = false; if (ctx->line_len == 0 || ctx->line[ctx->line_len - 1] != '\n') break; for (i = 0; i < ARRAY_SIZE(header_git_ops); i++) { const header_git_op *op = &header_git_ops[i]; size_t op_len = strlen(op->str); if (memcmp(ctx->line, op->str, min(op_len, ctx->line_len)) != 0) continue; /* Do not advance if this is the patch separator */ if (op->fn == NULL) goto done; parse_advance_chars(ctx, op_len); if ((error = op->fn(patch, ctx)) < 0) goto done; parse_advance_ws(ctx); parse_advance_expected_s(ctx, "\n"); if (ctx->line_len > 0) { error = parse_err("trailing data at line %d", ctx->line_num); goto done; } found = true; break; } if (!found) { error = parse_err("invalid patch header at line %d", ctx->line_num); goto done; } } done: return error; }
static asm86_t *ack_get_statement(void) /* Get a pseudo op or machine instruction with arguments. */ { token_t *t= get_token(0); asm86_t *a; mnemonic_t *m; int n; int prefix_seen; int oaz_prefix; int deref; assert(t->type == T_WORD); if (strcmp(t->name, ".sect") == 0) { /* .sect .text etc. Accept only four segment names. */ skip_token(1); t= get_token(0); if (t->type != T_WORD || ( strcmp(t->name, ".text") != 0 && strcmp(t->name, ".rom") != 0 && strcmp(t->name, ".data") != 0 && strcmp(t->name, ".bss") != 0 && strcmp(t->name, ".end") != 0 )) { parse_err(1, t, "weird section name to .sect\n"); return nil; } } a= new_asm86(); /* Process instruction prefixes. */ oaz_prefix= 0; for (prefix_seen= 0;; prefix_seen= 1) { if (strcmp(t->name, "o16") == 0) { if (use16()) { parse_err(1, t, "o16 in an 8086 section\n"); } oaz_prefix|= OPZ; } else if (strcmp(t->name, "o32") == 0) { if (use32()) { parse_err(1, t, "o32 in an 80386 section\n"); } oaz_prefix|= OPZ; } else if (strcmp(t->name, "a16") == 0) { if (use16()) { parse_err(1, t, "a16 in an 8086 section\n"); } oaz_prefix|= ADZ; } else if (strcmp(t->name, "a32") == 0) { if (use32()) { parse_err(1, t, "a32 in an 80386 section\n"); } oaz_prefix|= ADZ; } else if (strcmp(t->name, "rep") == 0 || strcmp(t->name, "repe") == 0 || strcmp(t->name, "repne") == 0 || strcmp(t->name, "repz") == 0 || strcmp(t->name, "repnz") == 0 ) { if (a->rep != ONCE) { parse_err(1, t, "can't have more than one rep\n"); } switch (t->name[3]) { case 0: a->rep= REP; break; case 'e': case 'z': a->rep= REPE; break; case 'n': a->rep= REPNE; break; } } else if (strchr("cdefgs", t->name[0]) != nil && strcmp(t->name+1, "seg") == 0) { if (a->seg != DEFSEG) { parse_err(1, t, "can't have more than one segment prefix\n"); } switch (t->name[0]) { case 'c': a->seg= CSEG; break; case 'd': a->seg= DSEG; break; case 'e': a->seg= ESEG; break; case 'f': a->seg= FSEG; break; case 'g': a->seg= GSEG; break; case 's': a->seg= SSEG; break; } } else if (!prefix_seen) { /* No prefix here, get out! */ break; } else { /* No more prefixes, next must be an instruction. */ if (t->type != T_WORD || (m= search_mnem(t->name)) == nil || m->optype == PSEUDO ) { parse_err(1, t, "machine instruction expected after instruction prefix\n"); del_asm86(a); return nil; } if (oaz_prefix != 0 && m->optype != JUMP && m->optype != WORD) { parse_err(1, t, "'%s' can't have an operand size prefix\n", m->name); } break; } /* Skip the prefix and extra newlines. */ do { skip_token(1); } while ((t= get_token(0))->symbol == ';'); } /* All the readahead being done upsets the line counter. */ a->line= t->line; /* Read a machine instruction or pseudo op. */ if ((m= search_mnem(t->name)) == nil) { parse_err(1, t, "unknown instruction '%s'\n", t->name); del_asm86(a); return nil; } a->opcode= m->opcode; a->optype= m->optype; a->oaz= oaz_prefix; switch (a->opcode) { case IN: case OUT: case INT: deref= 0; break; default: deref= (a->optype >= BYTE); } n= 1; if (get_token(1)->symbol != ';' && (a->args= ack_get_oplist(&n, deref)) == nil) { del_asm86(a); return nil; } if (get_token(n)->symbol != ';') { parse_err(1, t, "garbage at end of instruction\n"); del_asm86(a); return nil; } switch (a->opcode) { case DOT_ALIGN: /* Restrict .align to have a single numeric argument, some * assemblers think of the argument as a power of two, so * we need to be able to change the value. */ if (a->args == nil || a->args->operator != 'W' || !isanumber(a->args->name)) { parse_err(1, t, ".align is restricted to one numeric argument\n"); del_asm86(a); return nil; } break; case JMPF: case CALLF: /* NCC jmpf off,seg -> ACK jmpf seg:off */ if (dialect == NCC && a->args != nil && a->args->operator == ',') { expression_t *t; t= a->args->left; a->args->left= a->args->right; a->args->right= t; break; } /*FALL THROUGH*/ case JMP: case CALL: /* NCC jmp @(reg) -> ACK jmp (reg) */ if (dialect == NCC && a->args != nil && ( (a->args->operator == '(' && a->args->middle != nil && a->args->middle->operator == 'O') || (a->args->operator == 'O' && a->args->left == nil && a->args->middle != nil && a->args->right == nil) )) { expression_t *t; t= a->args; a->args= a->args->middle; t->middle= nil; del_expr(t); if (a->args->operator == 'B') a->args->operator= 'W'; } break; default:; } skip_token(n+1); return a; }
static expression_t *ack_get_operand(int *pn, int deref) /* Get something like: (memory), offset(base)(index*scale), or simpler. */ { expression_t *e, *offset, *base, *index; token_t *t; int c; /* Is it (memory)? */ if (get_token(*pn)->symbol == '(' && ((t= get_token(*pn + 1))->type != T_WORD || !isregister(t->name)) ) { /* A memory dereference. */ (*pn)++; if ((offset= ack_get_C_expression(pn)) == nil) return nil; if (get_token(*pn)->symbol != ')') { parse_err(1, t, "operand syntax error\n"); del_expr(offset); return nil; } (*pn)++; e= new_expr(); e->operator= '('; e->middle= offset; return e; } /* #constant? */ if (dialect == NCC && deref && ((c= get_token(*pn)->symbol) == '#' || c == '*')) { /* NCC: mov ax,#constant -> ACK: mov ax,constant */ (*pn)++; return ack_get_C_expression(pn); } /* @address? */ if (dialect == NCC && get_token(*pn)->symbol == '@') { /* NCC: jmp @address -> ACK: jmp (address) */ (*pn)++; if ((offset= ack_get_operand(pn, deref)) == nil) return nil; e= new_expr(); e->operator= '('; e->middle= offset; return e; } /* Offset? */ if (get_token(*pn)->symbol != '(') { /* There is an offset. */ if ((offset= ack_get_C_expression(pn)) == nil) return nil; } else { /* No offset. */ offset= nil; } /* (base)? */ if (get_token(*pn)->symbol == '(' && (t= get_token(*pn + 1))->type == T_WORD && isregister(t->name) && get_token(*pn + 2)->symbol == ')' ) { /* A base register expression. */ base= new_expr(); base->operator= 'B'; base->name= copystr(t->name); (*pn)+= 3; } else { /* No base register expression. */ base= nil; } /* (index*scale)? */ if (get_token(*pn)->symbol == '(') { /* An index most likely. */ token_t *m= nil; if (!( /* This must be true: */ (t= get_token(*pn + 1))->type == T_WORD && isregister(t->name) && (get_token(*pn + 2)->symbol == ')' || ( get_token(*pn + 2)->symbol == '*' && (m= get_token(*pn + 3))->type == T_WORD && strchr("1248", m->name[0]) != nil && m->name[1] == 0 && get_token(*pn + 4)->symbol == ')' )) )) { /* Alas it isn't */ parse_err(1, t, "operand syntax error\n"); del_expr(offset); del_expr(base); return nil; } /* Found an index. */ index= new_expr(); index->operator= m == nil ? '1' : m->name[0]; index->name= copystr(t->name); (*pn)+= (m == nil ? 3 : 5); } else { /* No index. */ index= nil; } if (dialect == NCC && deref && base == nil && index == nil && !(offset != nil && offset->operator == 'W' && isregister(offset->name)) ) { /* NCC: mov ax,thing -> ACK mov ax,(thing) */ e= new_expr(); e->operator= '('; e->middle= offset; return e; } if (base == nil && index == nil) { /* Return a lone offset as is. */ e= offset; } else { e= new_expr(); e->operator= 'O'; e->left= offset; e->middle= base; e->right= index; } return e; }
static expression_t *ack_get_C_expression(int *pn) /* Read a "C-like" expression. Note that we don't worry about precedence, * the expression is printed later like it is read. If the target language * does not have all the operators (like ~) then this has to be repaired by * changing the source file. (No problem, you still have one source file * to maintain, not two.) */ { expression_t *e, *a1, *a2; token_t *t; if ((t= get_token(*pn))->symbol == '[') { /* [ expr ]: grouping. */ (*pn)++; if ((a1= ack_get_C_expression(pn)) == nil) return nil; if (get_token(*pn)->symbol != ']') { parse_err(1, t, "missing ]\n"); del_expr(a1); return nil; } (*pn)++; e= new_expr(); e->operator= '['; e->middle= a1; } else if (t->type == T_WORD || t->type == T_STRING) { /* Label, number, or string. */ e= new_expr(); e->operator= t->type == T_WORD ? 'W' : 'S'; e->name= allocate(nil, (t->len+1) * sizeof(e->name[0])); memcpy(e->name, t->name, t->len+1); e->len= t->len; (*pn)++; } else if (t->symbol == '+' || t->symbol == '-' || t->symbol == '~') { /* Unary operator. */ (*pn)++; if ((a1= ack_get_C_expression(pn)) == nil) return nil; e= new_expr(); e->operator= t->symbol; e->middle= a1; } else { parse_err(1, t, "expression syntax error\n"); return nil; } switch ((t= get_token(*pn))->symbol) { case '+': case '-': case '*': case '/': case '%': case '&': case '|': case '^': case S_LEFTSHIFT: case S_RIGHTSHIFT: (*pn)++; a1= e; if ((a2= ack_get_C_expression(pn)) == nil) { del_expr(a1); return nil; } e= new_expr(); e->operator= t->symbol; e->left= a1; e->right= a2; } return e; }
static int parse_hunk_body( git_patch_parsed *patch, git_patch_hunk *hunk, git_patch_parse_ctx *ctx) { git_diff_line *line; int error = 0; int oldlines = hunk->hunk.old_lines; int newlines = hunk->hunk.new_lines; for (; ctx->remain_len > 4 && (oldlines || newlines) && memcmp(ctx->line, "@@ -", 4) != 0; parse_advance_line(ctx)) { int origin; int prefix = 1; if (ctx->line_len == 0 || ctx->line[ctx->line_len - 1] != '\n') { error = parse_err("invalid patch instruction at line %d", ctx->line_num); goto done; } switch (ctx->line[0]) { case '\n': prefix = 0; case ' ': origin = GIT_DIFF_LINE_CONTEXT; oldlines--; newlines--; break; case '-': origin = GIT_DIFF_LINE_DELETION; oldlines--; break; case '+': origin = GIT_DIFF_LINE_ADDITION; newlines--; break; default: error = parse_err("invalid patch hunk at line %d", ctx->line_num); goto done; } line = git_array_alloc(patch->base.lines); GITERR_CHECK_ALLOC(line); memset(line, 0x0, sizeof(git_diff_line)); line->content = ctx->line + prefix; line->content_len = ctx->line_len - prefix; line->content_offset = ctx->content_len - ctx->remain_len; line->origin = origin; hunk->line_count++; } if (oldlines || newlines) { error = parse_err( "invalid patch hunk, expected %d old lines and %d new lines", hunk->hunk.old_lines, hunk->hunk.new_lines); goto done; } /* Handle "\ No newline at end of file". Only expect the leading * backslash, though, because the rest of the string could be * localized. Because `diff` optimizes for the case where you * want to apply the patch by hand. */ if (parse_ctx_contains_s(ctx, "\\ ") && git_array_size(patch->base.lines) > 0) { line = git_array_get(patch->base.lines, git_array_size(patch->base.lines) - 1); if (line->content_len < 1) { error = parse_err("cannot trim trailing newline of empty line"); goto done; } line->content_len--; parse_advance_line(ctx); } done: return error; }
static int parse_patch_binary_side( git_diff_binary_file *binary, git_patch_parse_ctx *ctx) { git_diff_binary_t type = GIT_DIFF_BINARY_NONE; git_buf base85 = GIT_BUF_INIT, decoded = GIT_BUF_INIT; git_off_t len; int error = 0; if (parse_ctx_contains_s(ctx, "literal ")) { type = GIT_DIFF_BINARY_LITERAL; parse_advance_chars(ctx, 8); } else if (parse_ctx_contains_s(ctx, "delta ")) { type = GIT_DIFF_BINARY_DELTA; parse_advance_chars(ctx, 6); } else { error = parse_err( "unknown binary delta type at line %d", ctx->line_num); goto done; } if (parse_number(&len, ctx) < 0 || parse_advance_nl(ctx) < 0 || len < 0) { error = parse_err("invalid binary size at line %d", ctx->line_num); goto done; } while (ctx->line_len) { char c = ctx->line[0]; size_t encoded_len, decoded_len = 0, decoded_orig = decoded.size; if (c == '\n') break; else if (c >= 'A' && c <= 'Z') decoded_len = c - 'A' + 1; else if (c >= 'a' && c <= 'z') decoded_len = c - 'a' + (('z' - 'a') + 1) + 1; if (!decoded_len) { error = parse_err("invalid binary length at line %d", ctx->line_num); goto done; } parse_advance_chars(ctx, 1); encoded_len = ((decoded_len / 4) + !!(decoded_len % 4)) * 5; if (encoded_len > ctx->line_len - 1) { error = parse_err("truncated binary data at line %d", ctx->line_num); goto done; } if ((error = git_buf_decode_base85( &decoded, ctx->line, encoded_len, decoded_len)) < 0) goto done; if (decoded.size - decoded_orig != decoded_len) { error = parse_err("truncated binary data at line %d", ctx->line_num); goto done; } parse_advance_chars(ctx, encoded_len); if (parse_advance_nl(ctx) < 0) { error = parse_err("trailing data at line %d", ctx->line_num); goto done; } } binary->type = type; binary->inflatedlen = (size_t)len; binary->datalen = decoded.size; binary->data = git_buf_detach(&decoded); done: git_buf_free(&base85); git_buf_free(&decoded); return error; }