R_API void r_cons_less_str(const char *str) { int lines_count; int w, h, ch, to, ui = 1, from = 0; char *p = strdup (str); int *lines = splitlines (p, &lines_count); r_cons_set_raw (R_TRUE); r_cons_show_cursor (R_FALSE); r_cons_reset (); h = 0; while (ui) { w = r_cons_get_size (&h); to = R_MIN (lines_count, from+h); if (from+3>lines_count) from = lines_count-3; printpage (p, lines, from, to); ch = r_cons_readchar (); ch = r_cons_arrow_to_hjkl (ch); switch (ch) { case ' ': from += h; break; case 'g': from = 0; break; case 'G': from = lines_count-1-h; break; case 'q': ui = 0; break; case '\r': case '\n': case 'j': from++; break; case 'J': from+=h; break; case 'k': if (from>0) from--; break; case 'K': from = (from>=h)? from-h: 0; break; } } free (lines); r_cons_set_raw (R_FALSE); r_cons_show_cursor (R_TRUE); }
// gcopnames creates opnames.h from go.h. // It finds the OXXX enum, pulls out all the constants // from OXXX to OEND, and writes a table mapping // op to string. void gcopnames(char *dir, char *file) { char *p, *q; int i, j, end; Buf in, b, out; Vec lines, fields; binit(&in); binit(&b); binit(&out); vinit(&lines); vinit(&fields); bwritestr(&out, bprintf(&b, "// auto generated by go tool dist\n")); bwritestr(&out, bprintf(&b, "static char *opnames[] = {\n")); readfile(&in, bprintf(&b, "%s/go.h", dir)); splitlines(&lines, bstr(&in)); i = 0; while(i<lines.len && !contains(lines.p[i], "OXXX")) i++; end = 0; for(; i<lines.len && !end; i++) { p = xstrstr(lines.p[i], "//"); if(p != nil) *p = '\0'; end = contains(lines.p[i], "OEND"); splitfields(&fields, lines.p[i]); for(j=0; j<fields.len; j++) { q = fields.p[j]; if(*q == 'O') q++; p = q+xstrlen(q)-1; if(*p == ',') *p = '\0'; bwritestr(&out, bprintf(&b, " [O%s] = \"%s\",\n", q, q)); } } bwritestr(&out, bprintf(&b, "};\n")); writefile(&out, file, 0); bfree(&in); bfree(&b); bfree(&out); vfree(&lines); vfree(&fields); }
static PyObject *blocks(PyObject *self, PyObject *args) { PyObject *sa, *sb, *rl = NULL, *m; struct line *a, *b; struct hunk l, *h; int an, bn, count, pos = 0; if (!PyArg_ParseTuple(args, "SS:bdiff", &sa, &sb)) return NULL; an = splitlines(PyBytes_AsString(sa), PyBytes_Size(sa), &a); bn = splitlines(PyBytes_AsString(sb), PyBytes_Size(sb), &b); if (!a || !b) goto nomem; l.next = NULL; count = diff(a, an, b, bn, &l); if (count < 0) goto nomem; rl = PyList_New(count); if (!rl) goto nomem; for (h = l.next; h; h = h->next) { m = Py_BuildValue("iiii", h->a1, h->a2, h->b1, h->b2); PyList_SetItem(rl, pos, m); pos++; } nomem: free(a); free(b); freehunks(l.next); return rl ? rl : PyErr_NoMemory(); }
/* * Reminder: SonyEricsson doesn't return <used> and <total> values of memory usage: * > AT+CPBS? * +CPBS: "ME" */ static gn_error ReplyMemoryStatus(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state) { at_line_buffer buf; char *pos; buf.line1 = buffer; buf.length = length; splitlines(&buf); if (buf.line1 == NULL) return GN_ERR_INVALIDMEMORYTYPE; if (data->memory_status) { if (strstr(buf.line2, "+CPBR")) { pos = strchr(buf.line2, '-'); if (pos) { data->memory_status->used = atoi(++pos); data->memory_status->free = 0; } else { return GN_ERR_NOTSUPPORTED; } } } return GN_ERR_NONE; }
static gn_error ReplyIdentify(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state) { at_line_buffer buf; gn_error error; char *model; /* If we got incorrect answer, fallback to the default handler; * we got error handling in there. * strlen(buffer) < 2 is to avoid overflow with buffer + 1 */ if (strlen(buffer) < 2 || strncmp(buffer + 1, "AT+CGMM", 7) != 0) { return (*identify)(messagetype, buffer, length, data, state); } if ((error = at_error_get(buffer, state)) != GN_ERR_NONE) return error; buf.line1 = buffer + 1; buf.length = length; splitlines(&buf); /* The line usually looks like: * +CGMM: "GSM900","GSM1800","GSM1900","GSM850","MODEL=V547" */ model = strstr(buf.line2, "MODEL="); if (!model) { snprintf(data->model, GN_MODEL_MAX_LENGTH, "%s", strip_quotes(buf.line2 + 1 + strlen("+CGMM: "))); } else { snprintf(data->model, GN_MODEL_MAX_LENGTH, "%s", strip_quotes(model + strlen("MODEL="))); model = strchr(data->model, '"'); if (model) *model = '\0'; } return GN_ERR_NONE; }
//-- // TODO: implement the r_diff_lines // we need to implement r_file_line_at (file, off); R_API int r_diff_buffers_delta(RDiff *d, const ut8 *sa, int la, const ut8 *sb, int lb) { RDiffOp dop; struct line *al = NULL; struct line *bl = NULL; struct hunklist l = { NULL, NULL }; struct hunk *h; int an, bn, offa, rlen, offb, len = 0; int hits = -1; an = splitlines ((const char *)sa, la, &al); if (an<0) { free (al); return -1; } bn = splitlines ((const char *)sb, lb, &bl); if (bn<0) { free (al); free (bl); return -1; } if (!al || !bl) { eprintf ("bindiff_buffers: Out of memory.\n"); goto beach; } l = diff (al, an, bl, bn); if (!l.head) { eprintf ("bindiff_buffers: Out of memory.\n"); goto beach; } hits = la = lb = 0; for (h = l.base; h != l.head; h++) { if (h->a1 != la || h->b1 != lb) { len = bl[h->b1].l - bl[lb].l; offa = al[la].l - al->l; offb = al[h->a1].l - al->l; rlen = offb-offa; if (d->callback) { /* source file */ dop.a_off = offa; dop.a_buf = (ut8 *)al[la].l; dop.a_len = rlen; /* destination file */ dop.b_off = offa; // XXX offb not used?? dop.b_buf = (ut8 *)bl[lb].l; dop.b_len = len; if (!d->callback (d, d->user, &dop)) break; } #if 0 if (rlen > 0) { //printf ("Remove %d bytes at %d\n", rlen, offa); printf ("r-%d @ 0x%"PFMT64x"\n", rlen, (ut64)offa); } printf ("e file.write=true\n"); // XXX printf ("wx "); for(i=0; i<len; i++) printf ("%02x", bl[lb].l[i]); printf (" @ 0x%"PFMT64x"\n", (ut64)offa); rb += 12 + len; #endif } la = h->a2; lb = h->b2; } beach: free (al); free (bl); free (l.base); return hits; }
// shouldbuild reports whether we should build this file. // It applies the same rules that are used with context tags // in package go/build, except that the GOOS and GOARCH // can appear anywhere in the file name, not just after _. // In particular, they can be the entire file name (like windows.c). // We also allow the special tag cmd_go_bootstrap. // See ../go/bootstrap.go and package go/build. static bool shouldbuild(char *file, char *dir) { char *name, *p; int i, j, ret; Buf b; Vec lines, fields; // Check file name for GOOS or GOARCH. name = lastelem(file); for(i=0; i<nelem(okgoos); i++) if(contains(name, okgoos[i]) && !streq(okgoos[i], goos)) return 0; for(i=0; i<nelem(okgoarch); i++) if(contains(name, okgoarch[i]) && !streq(okgoarch[i], goarch)) return 0; // Omit test files. if(contains(name, "_test")) return 0; // cmd/go/doc.go has a giant /* */ comment before // it gets to the important detail that it is not part of // package main. We don't parse those comments, // so special case that file. if(hassuffix(file, "cmd/go/doc.go") || hassuffix(file, "cmd\\go\\doc.go")) return 0; if(hassuffix(file, "cmd/cgo/doc.go") || hassuffix(file, "cmd\\cgo\\doc.go")) return 0; // Check file contents for // +build lines. binit(&b); vinit(&lines); vinit(&fields); ret = 1; readfile(&b, file); splitlines(&lines, bstr(&b)); for(i=0; i<lines.len; i++) { p = lines.p[i]; while(*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') p++; if(*p == '\0') continue; if(contains(p, "package documentation")) { ret = 0; goto out; } if(contains(p, "package main") && !streq(dir, "cmd/go") && !streq(dir, "cmd/cgo")) { ret = 0; goto out; } if(!hasprefix(p, "//")) break; if(!contains(p, "+build")) continue; splitfields(&fields, lines.p[i]); if(fields.len < 2 || !streq(fields.p[1], "+build")) continue; for(j=2; j<fields.len; j++) { p = fields.p[j]; if((*p == '!' && !matchfield(p+1)) || matchfield(p)) goto fieldmatch; } ret = 0; goto out; fieldmatch:; } out: bfree(&b); vfree(&lines); vfree(&fields); return ret; }
int bdiff(const char *filea, const char *fileb) { char *sa, *sb; int i, an, bn, offa, rlen, offb, len = 0; int la, lb, hits = 0; struct line *al, *bl; struct hunklist l = { NULL, NULL }; struct hunk *h; if((sa = slurp(filea, &la)) == NULL) return fprintf(stderr, "Cannot open %s\n", filea), 0; if((sb = slurp(fileb, &lb)) == NULL) return fprintf(stderr, "Cannot open %s\n", fileb), 0; /* TODO: split to function here */ an = splitlines(sa, la, &al); bn = splitlines(sb, lb, &bl); if(!al || !bl) return -1; l = diff(al, an, bl, bn); if(!l.head) return -1; la = lb = 0; for(h = l.base; h != l.head; h++) { if(h->a1 != la || h->b1 != lb) { len = bl[h->b1].l - bl[lb].l; offa = al[la].l - al->l; offb = al[h->a1].l - al->l; rlen = offb-offa; //fprintf(stderr, "all: %d %d\n", ); //fprintf(stderr, "len: %d %d\n", len, rlen); //fprintf(stderr, "off: %d %d\n", offa, offb); if(rlen>len) printf("r-%d@%d\n", (rlen-len), offa); else printf("r+%d@%d\n", (len-rlen), offb); if(len == rlen) { for(i=0; i<len; i++) { if(bl[lb].l[i] != bl[la].l[i]) fprintf(stderr, "%02x %02x\n", (unsigned char) bl[lb].l[i], (unsigned char) bl[la].l[i]); } // XXX fprintf(stderr, "%02x @ 0x%x\n", bl[la].l[i], offa); fprintf(stderr, "WARNING: Binary patch failed\n"); } if(len > 0) { printf("w "); for(i=0;i<len;i++) printf("%02x", (unsigned char)bl[lb].l[i]); printf("@%d#len\n", offa); } else if(rlen > 0) { printf("w "); for(i=0; i<rlen; i++) printf("%02x", (unsigned char)bl[la].l[i]); printf("@%d#rlen\n", offa); } } la = h->a2; lb = h->b2; } free(al); free(bl); free(l.base); return hits; }
clidata_t *handle_cp( int clisock, char *hdrs, int proto ) { char *macaddr; iprange_t *ranges=NULL; iprange_t **rangep=&ranges; char *body; char **lines; clidata_t *client; char buf[CP2_OK_MAXBODY]; int i; int len; /* Get body of request. body gets malloc()d data */ if( (body=getbody(clisock, hdrs, &len)) == NULL ) { lprintf(log, WARN, "Client did not send expected amount"); goto cleanup1; } dprintf(log, DEBUG, "Got body: %s", body); /* Split lines of input. lines get malloc()d data */ if( (lines=splitlines(body)) == NULL ) { lprintf(log, ERROR, "Problem splittling lines with splitlines()"); fdprintf(clisock, RESPONSE_500_ERR); goto cleanup2; } dprintf(log, DEBUG, "split lines successfully."); /* Set macaddr based on the first line */ if( (macaddr=lines[0]) == NULL ) { lprintf(log, WARN, "Client did not send MAC address line!"); fdprintf(clisock, RESPONSE_400); goto cleanup3; } chomp(macaddr); dprintf(log, DEBUG, "Got macaddr %s.", macaddr); /* Interpret the ipranges. make_iprange() ranges gets malloc()d data */ for( i=1; lines[i]; i++ ) { dprintf(log, DEBUG, "About to convert %s", lines[i]); if( (*rangep=make_iprange(lines[i])) == NULL ) { if( *lines[i] ) { lprintf(log, WARN, "Client sent invalid ip range: %s", lines[i]); } continue; } rangep=&(*rangep)->next; } if( ranges == NULL ) { lprintf(log, WARN, "Client sent no ip ranges. Dropping."); fdprintf(clisock, RESPONSE_400); goto cleanup3; } dprintf(log, DEBUG, "About to get clidata for MAC addr %s.", macaddr); /* Get clidata for this client */ if( (client=get_clidata(clients, macaddr)) == NULL ) { dprintf(log, DEBUG, "Need to make new clidata for %s.", macaddr); if( (client=add_clidata(clients, macaddr)) == NULL ) { lprintf(log, WARN, "Could not create clidata! Dropping client."); fdprintf(clisock, RESPONSE_500_ERR); free_iprange_list(&ranges); goto cleanup3; } client->iprange = ranges; client->chan1 = clisock; dprintf(log, DEBUG, "About to call srv_tun_alloc()"); if( srv_tun_alloc(client, clients) == -1 ) { fdprintf(clisock, RESPONSE_503); goto cleanup4; } if( proto == 1 ) { if( srv_start_tunfile_reader(client) == -1 ) goto cleanup4; } if( srv_start_tunfile_writer(client) == -1 ) goto cleanup4; } else { char ip1[16], ip2[16]; strcpy(ip1, inet_ntoa(client->srvaddr)); strcpy(ip2, inet_ntoa(client->cliaddr)); lprintf(log, INFO, "Client %s found. localip=%s, peerip=%s.", macaddr, ip1, ip2); if( client->chan1 != -1 ) { lprintf(log, WARN, "Client chan1 appears to be connected already. Dropping old."); close(client->chan1); client->chan1 = -1; } if( client->chan2 != -1 ) { lprintf(log, WARN, "Client chan2 appears to be connected already. Dropping old."); close(client->chan2); client->chan2 = -1; } if( client->iprange ) free_iprange_list( &client->iprange ); client->iprange = ranges; client->chan1 = clisock; } dprintf(log, DEBUG, "About to respond to client"); { char ip1[16], ip2[16]; strcpy(ip1,inet_ntoa(client->cliaddr)); strcpy(ip2,inet_ntoa(client->srvaddr)); sprintf(buf, "%s\n%s\n", ip1, ip2); } fdprintf(clisock, RESPONSE_200, strlen(buf), buf); dprintf(log, DEBUG, "Returning"); return client; cleanup4: remove_clidata(clients, client->macaddr); cleanup3: free(lines); cleanup2: free(body); cleanup1: return NULL; }
clidata_t *handle_cr( int clisock, char *hdrs ) { char *macaddr; char *body; char **lines; clidata_t *client; int len; if( (body=getbody(clisock, hdrs, &len)) == NULL ) { lprintf(log, WARN, "Client did not send the expected amount"); goto cleanup1; } dprintf(log, DEBUG, "Got body: %s", body); if( (lines=splitlines(body)) == NULL ) { lprintf(log, ERROR, "Problem splittling lines with splitlines()"); fdprintf(clisock, RESPONSE_500_ERR); goto cleanup2; } dprintf(log, DEBUG, "split lines successfully."); if( (macaddr=lines[0]) == NULL ) { lprintf(log, WARN, "Client did not send MAC address line!"); fdprintf(clisock, RESPONSE_400); goto cleanup3; } chomp(macaddr); dprintf(log, DEBUG, "Got macaddr %s.", macaddr); dprintf(log, DEBUG, "About to get clidata for MAC addr %s.", macaddr); if( (client=get_clidata(clients, macaddr)) == NULL ) { lprintf(log, INFO, "Client tried to connect chan2 before chan1"); fdprintf(clisock, RESPONSE_412); goto cleanup3; } dprintf(log, DEBUG, "Clidata found for MAC addr %s.", macaddr); client->chan2 = clisock; dprintf(log, DEBUG, "Creating recvq for new send channel"); if( (client->sendq=q_init()) == NULL ) { lprintf(log, ERROR, "Unable to create recvq for new client!"); goto cleanup3; } if( srv_start_tunfile_reader(client) == -1 ) { dprintf(log, DEBUG, "About to start tunfile reader"); fdprintf(clisock, RESPONSE_500_BUSY); goto cleanup3; } dprintf(log, DEBUG, "About to respond to client"); fdprintf(clisock, RESPONSE_204); dprintf(log, DEBUG, "Returning"); return client; cleanup3: free(lines); cleanup2: free(body); cleanup1: return NULL; }
// mkzruntimedefs writes zruntime_defs_$GOOS_$GOARCH.h, // which contains Go struct definitions equivalent to the C ones. // Mostly we just write the output of 6c -q to the file. // However, we run it on multiple files, so we have to delete // the duplicated definitions, and we don't care about the funcs // and consts, so we delete those too. // void mkzruntimedefs(char *dir, char *file) { int i, skip; char *p; Buf in, b, out; Vec argv, lines, fields, seen; binit(&in); binit(&b); binit(&out); vinit(&argv); vinit(&lines); vinit(&fields); vinit(&seen); bwritestr(&out, "// auto generated by go tool dist\n" "\n" "package runtime\n" "import \"unsafe\"\n" "var _ unsafe.Pointer\n" "\n" ); // Run 6c -DGOOS_goos -DGOARCH_goarch -Iworkdir -q // on each of the runtimedefs C files. vadd(&argv, bpathf(&b, "%s/%sc", tooldir, gochar)); vadd(&argv, bprintf(&b, "-DGOOS_%s", goos)); vadd(&argv, bprintf(&b, "-DGOARCH_%s", goarch)); vadd(&argv, bprintf(&b, "-I%s", workdir)); vadd(&argv, "-q"); vadd(&argv, ""); p = argv.p[argv.len-1]; for(i=0; i<nelem(runtimedefs); i++) { argv.p[argv.len-1] = runtimedefs[i]; runv(&b, dir, CheckExit, &argv); bwriteb(&in, &b); } argv.p[argv.len-1] = p; // Process the aggregate output. skip = 0; splitlines(&lines, bstr(&in)); for(i=0; i<lines.len; i++) { p = lines.p[i]; // Drop comment, func, and const lines. if(hasprefix(p, "//") || hasprefix(p, "const") || hasprefix(p, "func")) continue; // Note beginning of type or var decl, which can be multiline. // Remove duplicates. The linear check of seen here makes the // whole processing quadratic in aggregate, but there are only // about 100 declarations, so this is okay (and simple). if(hasprefix(p, "type ") || hasprefix(p, "var ")) { splitfields(&fields, p); if(fields.len < 2) continue; if(find(fields.p[1], seen.p, seen.len) >= 0) { if(streq(fields.p[fields.len-1], "{")) skip = 1; // skip until } continue; } vadd(&seen, fields.p[1]); } if(skip) { if(hasprefix(p, "}")) skip = 0; continue; } bwritestr(&out, p); } writefile(&out, file, 0); bfree(&in); bfree(&b); bfree(&out); vfree(&argv); vfree(&lines); vfree(&fields); vfree(&seen); }
// mkzasm writes zasm_$GOOS_$GOARCH.h, // which contains struct offsets for use by // assembly files. It also writes a copy to the work space // under the name zasm_GOOS_GOARCH.h (no expansion). // void mkzasm(char *dir, char *file) { int i, n; char *aggr, *p; Buf in, b, out; Vec argv, lines, fields; binit(&in); binit(&b); binit(&out); vinit(&argv); vinit(&lines); vinit(&fields); bwritestr(&out, "// auto generated by go tool dist\n\n"); for(i=0; i<nelem(zasmhdr); i++) { if(hasprefix(goarch, zasmhdr[i].goarch) && hasprefix(goos, zasmhdr[i].goos)) { bwritestr(&out, zasmhdr[i].hdr); goto ok; } } fatal("unknown $GOOS/$GOARCH in mkzasm"); ok: // Run 6c -DGOOS_goos -DGOARCH_goarch -Iworkdir -a proc.c // to get acid [sic] output. vreset(&argv); vadd(&argv, bpathf(&b, "%s/%sc", tooldir, gochar)); vadd(&argv, bprintf(&b, "-DGOOS_%s", goos)); vadd(&argv, bprintf(&b, "-DGOARCH_%s", goarch)); vadd(&argv, bprintf(&b, "-I%s", workdir)); vadd(&argv, "-a"); vadd(&argv, "proc.c"); runv(&in, dir, CheckExit, &argv); // Convert input like // aggr G // { // Gobuf 24 sched; // 'Y' 48 stack0; // } // into output like // #define g_sched 24 // #define g_stack0 48 // aggr = nil; splitlines(&lines, bstr(&in)); for(i=0; i<lines.len; i++) { splitfields(&fields, lines.p[i]); if(fields.len == 2 && streq(fields.p[0], "aggr")) { if(streq(fields.p[1], "G")) aggr = "g"; else if(streq(fields.p[1], "M")) aggr = "m"; else if(streq(fields.p[1], "Gobuf")) aggr = "gobuf"; else if(streq(fields.p[1], "WinCall")) aggr = "wincall"; } if(hasprefix(lines.p[i], "}")) aggr = nil; if(aggr && hasprefix(lines.p[i], "\t") && fields.len >= 2) { n = fields.len; p = fields.p[n-1]; if(p[xstrlen(p)-1] == ';') p[xstrlen(p)-1] = '\0'; bwritestr(&out, bprintf(&b, "#define %s_%s %s\n", aggr, fields.p[n-1], fields.p[n-2])); } } // Write both to file and to workdir/zasm_GOOS_GOARCH.h. writefile(&out, file, 0); writefile(&out, bprintf(&b, "%s/zasm_GOOS_GOARCH.h", workdir), 0); bfree(&in); bfree(&b); bfree(&out); vfree(&argv); vfree(&lines); vfree(&fields); }
// mkzasm writes zasm_$GOOS_$GOARCH.h, // which contains struct offsets for use by // assembly files. It also writes a copy to the work space // under the name zasm_GOOS_GOARCH.h (no expansion). // void mkzasm(char *dir, char *file) { int i, n; char *aggr, *p; Buf in, b, out, exp; Vec argv, lines, fields; binit(&in); binit(&b); binit(&out); binit(&exp); vinit(&argv); vinit(&lines); vinit(&fields); bwritestr(&out, "// auto generated by go tool dist\n\n"); for(i=0; i<nelem(zasmhdr); i++) { if(hasprefix(goarch, zasmhdr[i].goarch) && hasprefix(goos, zasmhdr[i].goos)) { bwritestr(&out, zasmhdr[i].hdr); goto ok; } } fatal("unknown $GOOS/$GOARCH in mkzasm"); ok: // Run 6c -D GOOS_goos -D GOARCH_goarch -I workdir -a -n -o workdir/proc.acid proc.c // to get acid [sic] output. vreset(&argv); vadd(&argv, bpathf(&b, "%s/%sc", tooldir, gochar)); vadd(&argv, "-D"); vadd(&argv, bprintf(&b, "GOOS_%s", goos)); vadd(&argv, "-D"); vadd(&argv, bprintf(&b, "GOARCH_%s", goarch)); vadd(&argv, "-I"); vadd(&argv, bprintf(&b, "%s", workdir)); vadd(&argv, "-a"); vadd(&argv, "-n"); vadd(&argv, "-o"); vadd(&argv, bpathf(&b, "%s/proc.acid", workdir)); vadd(&argv, "proc.c"); runv(nil, dir, CheckExit, &argv); readfile(&in, bpathf(&b, "%s/proc.acid", workdir)); // Convert input like // aggr G // { // Gobuf 24 sched; // 'Y' 48 stack0; // } // StackMin = 128; // into output like // #define g_sched 24 // #define g_stack0 48 // #define const_StackMin 128 aggr = nil; splitlines(&lines, bstr(&in)); for(i=0; i<lines.len; i++) { splitfields(&fields, lines.p[i]); if(fields.len == 2 && streq(fields.p[0], "aggr")) { if(streq(fields.p[1], "G")) aggr = "g"; else if(streq(fields.p[1], "M")) aggr = "m"; else if(streq(fields.p[1], "P")) aggr = "p"; else if(streq(fields.p[1], "Gobuf")) aggr = "gobuf"; else if(streq(fields.p[1], "LibCall")) aggr = "libcall"; else if(streq(fields.p[1], "WinCallbackContext")) aggr = "cbctxt"; else if(streq(fields.p[1], "SEH")) aggr = "seh"; } if(hasprefix(lines.p[i], "}")) aggr = nil; if(aggr && hasprefix(lines.p[i], "\t") && fields.len >= 2) { n = fields.len; p = fields.p[n-1]; if(p[xstrlen(p)-1] == ';') p[xstrlen(p)-1] = '\0'; bwritestr(&out, bprintf(&b, "#define %s_%s %s\n", aggr, fields.p[n-1], fields.p[n-2])); } if(fields.len == 3 && streq(fields.p[1], "=")) { // generated from enumerated constants p = fields.p[2]; if(p[xstrlen(p)-1] == ';') p[xstrlen(p)-1] = '\0'; bwritestr(&out, bprintf(&b, "#define const_%s %s\n", fields.p[0], p)); } } // Some #defines that are used for .c files. if(streq(goos, "windows")) { bwritestr(&out, bprintf(&b, "#define cb_max %d\n", MAXWINCB)); } xgetenv(&exp, "GOEXPERIMENT"); bwritestr(&out, bprintf(&b, "#define GOEXPERIMENT \"%s\"\n", bstr(&exp))); // Write both to file and to workdir/zasm_GOOS_GOARCH.h. writefile(&out, file, 0); writefile(&out, bprintf(&b, "%s/zasm_GOOS_GOARCH.h", workdir), 0); bfree(&in); bfree(&b); bfree(&out); bfree(&exp); vfree(&argv); vfree(&lines); vfree(&fields); }
static PyObject *bdiff(PyObject *self, PyObject *args) { char *sa, *sb, *rb; PyObject *result = NULL; struct line *al, *bl; struct hunk l, *h; int an, bn, count; Py_ssize_t len = 0, la, lb; PyThreadState *_save; if (!PyArg_ParseTuple(args, "s#s#:bdiff", &sa, &la, &sb, &lb)) return NULL; if (la > UINT_MAX || lb > UINT_MAX) { PyErr_SetString(PyExc_ValueError, "bdiff inputs too large"); return NULL; } _save = PyEval_SaveThread(); an = splitlines(sa, la, &al); bn = splitlines(sb, lb, &bl); if (!al || !bl) goto nomem; l.next = NULL; count = diff(al, an, bl, bn, &l); if (count < 0) goto nomem; /* calculate length of output */ la = lb = 0; for (h = l.next; h; h = h->next) { if (h->a1 != la || h->b1 != lb) len += 12 + bl[h->b1].l - bl[lb].l; la = h->a2; lb = h->b2; } PyEval_RestoreThread(_save); _save = NULL; result = PyBytes_FromStringAndSize(NULL, len); if (!result) goto nomem; /* build binary patch */ rb = PyBytes_AsString(result); la = lb = 0; for (h = l.next; h; h = h->next) { if (h->a1 != la || h->b1 != lb) { len = bl[h->b1].l - bl[lb].l; putbe32((uint32_t)(al[la].l - al->l), rb); putbe32((uint32_t)(al[h->a1].l - al->l), rb + 4); putbe32((uint32_t)len, rb + 8); memcpy(rb + 12, bl[lb].l, len); rb += 12 + len; } la = h->a2; lb = h->b2; } nomem: if (_save) PyEval_RestoreThread(_save); free(al); free(bl); freehunks(l.next); return result ? result : PyErr_NoMemory(); }
R_API void r_cons_less_str(const char *str) { int lines_count; RRegex *rx = NULL; int w, h, ch, to, ui = 1, from = 0, i; const char *sreg; if(str == NULL || str[0] == '\0') return; char *p = strdup (str); int *lines = splitlines (p, &lines_count); RRegexMatch **ms = malloc(lines_count * sizeof(void *)); for(i = 0; i < lines_count; i++) ms[i] = calloc(NMATCHES, sizeof(RRegexMatch)); r_cons_set_raw (R_TRUE); r_cons_show_cursor (R_FALSE); r_cons_reset (); w = h = 0; while (ui) { w = r_cons_get_size (&h); to = R_MIN (lines_count, from+h); if (from+3>lines_count) from = lines_count-3; if (from<0) from = 0; printpage (p, lines, ms, from, to, w); ch = r_cons_readchar (); ch = r_cons_arrow_to_hjkl (ch); switch (ch) { case ' ': from += h; break; case 'g': from = 0; break; case 'G': from = lines_count-1-h; break; case -1: // EOF case 'q': ui = 0; break; case '\r': case '\n': case 'j': from++; break; case 'J': from+=h; break; case 'k': if (from>0) from--; break; case 'K': from = (from>=h)? from-h: 0; break; case '/': /* search */ r_cons_reset_colors(); r_line_set_prompt("/"); sreg = r_line_readline(); from = R_MIN(lines_count - 1, from); /* repeat last search if empty string is provided */ if(sreg[0]){ /* prepare for a new search */ if(rx) r_regex_free(rx); rx = r_regex_new(sreg, ""); } else { /* we got an empty string */ from = next_match(from, ms, lines_count); break; } if(!rx) break; /* find all occurences */ if(all_matches(p, rx, ms, lines, lines_count)) from = next_match(from, ms, lines_count); break; case 'n': /* next match */ /* search already performed */ if(rx) from = next_match(from, ms, lines_count); break; case 'p': /* previous match */ if(rx) from = prev_match(from, ms); break; } } for(i = 0; i < lines_count; i++) free(ms[i]); free(ms); if(rx) r_regex_free(rx); free (lines); free (p); r_cons_reset_colors(); r_cons_set_raw (R_FALSE); r_cons_show_cursor (R_TRUE); }
// mkanames reads [5689].out.h and writes anames[5689].c // The format is much the same as the Go opcodes above. // It also writes out cnames array for C_* constants and the dnames // array for D_* constants. void mkanames(char *dir, char *file) { int i, j, ch, n, unknown; Buf in, b, out, out2; Vec lines; char *p, *p2; Vec dnames[128]; binit(&b); binit(&in); binit(&out); binit(&out2); vinit(&lines); for(i=0; i<nelem(dnames); i++) vinit(&dnames[i]); ch = file[xstrlen(file)-3]; bprintf(&b, "%s/../cmd/%cl/%c.out.h", dir, ch, ch); readfile(&in, bstr(&b)); splitlines(&lines, bstr(&in)); // Include link.h so that the extern declaration there is // checked against the non-extern declaration we are generating. bwritestr(&out, bprintf(&b, "// auto generated by go tool dist\n")); bwritestr(&out, bprintf(&b, "#include <u.h>\n")); bwritestr(&out, bprintf(&b, "#include <libc.h>\n")); bwritestr(&out, bprintf(&b, "#include <bio.h>\n")); bwritestr(&out, bprintf(&b, "#include <link.h>\n")); bwritestr(&out, bprintf(&b, "#include \"../cmd/%cl/%c.out.h\"\n", ch, ch)); bwritestr(&out, bprintf(&b, "\n")); bwritestr(&out, bprintf(&b, "char* anames%c[] = {\n", ch)); for(i=0; i<lines.len; i++) { if(hasprefix(lines.p[i], "\tA")) { p = xstrstr(lines.p[i], ","); if(p) *p = '\0'; p = xstrstr(lines.p[i], "\n"); if(p) *p = '\0'; p = lines.p[i] + 2; bwritestr(&out, bprintf(&b, "\t\"%s\",\n", p)); } } bwritestr(&out, "};\n"); j=0; bprintf(&out2, "char* cnames%c[] = {\n", ch); for(i=0; i<lines.len; i++) { if(hasprefix(lines.p[i], "\tC_")) { p = xstrstr(lines.p[i], ","); if(p) *p = '\0'; p = xstrstr(lines.p[i], "\n"); if(p) *p = '\0'; p = lines.p[i] + 3; bwritestr(&out2, bprintf(&b, "\t\"%s\",\n", p)); j++; } } bwritestr(&out2, "};\n"); if(j>0) bwriteb(&out, &out2); j=unknown=0; n=-1; for(i=0; i<lines.len; i++) { if(hasprefix(lines.p[i], "\tD_")) { p = xstrstr(lines.p[i], ","); if(p) *p = '\0'; p = xstrstr(lines.p[i], "\n"); if(p) *p = '\0'; // Parse explicit value, if any p = xstrstr(lines.p[i], "="); if(p) { // Skip space after '=' p2 = p + 1; while(*p2 == ' ' || *p2 == '\t') p2++; n = xatoi(p2, &p2); // We can't do anything about // non-numeric values or anything that // follows while(*p2 == ' ' || *p2 == '\t') p2++; if(*p2 != 0) { unknown = 1; continue; } // Truncate space before '=' while(*(p-1) == ' ' || *(p-1) == '\t') p--; *p = '\0'; unknown = 0; } else { n++; } if(unknown || n >= nelem(dnames)) continue; p = lines.p[i] + 3; if(xstrcmp(p, "LAST") == 0) continue; vadd(&dnames[n], p); j++; } } if(j>0){ bwritestr(&out, bprintf(&b, "char* dnames%c[D_LAST] = {\n", ch)); for(i=0; i<nelem(dnames); i++) { if(dnames[i].len == 0) continue; bwritestr(&out, bprintf(&b, "\t[D_%s] = \"", dnames[i].p[0])); for(j=0; j<dnames[i].len; j++) { if(j != 0) bwritestr(&out, "/"); bwritestr(&out, dnames[i].p[j]); } bwritestr(&out, "\",\n"); } bwritestr(&out, "};\n"); } writefile(&out, file, 0); bfree(&b); bfree(&in); bfree(&out); bfree(&out2); vfree(&lines); for(i=0; i<nelem(dnames); i++) vfree(&dnames[i]); }