static clj_Result read_comment(clj_Reader *r, wint_t initch) { wint_t c; do { c = pop_char(r); } while (!ends_line(c) && c != WEOF); return ok_read(c); }
static void push_char(clj_Reader *r, wint_t c) { assert(r->_readback == 0); r->_readback = c; if (ends_line(c)) { r->line--; r->column = r->_readback_column; } else { r->column--; } }
static wint_t pop_char(clj_Reader *r) { wint_t c; if (r->_readback == 0) { c = r->getwchar(r); } else { c = r->_readback; r->_readback = 0; } if (ends_line(c)) { r->line++; r->_readback_column = r->column; r->column = 0; } else { r->column++; } return c; }
void DocumentView::trim_trailing_newlines() { //FIXME: Don't strip whitespace if the language doesn't like it (e.g. 'diff') auto buffer_end = buffer()->end(); if(buffer_end.starts_line()) { auto itr = buffer_end; while(itr.backward_line()) { if(!itr.ends_line()) { itr.forward_to_line_end(); break; } } buffer()->erase(itr, buffer_end); } auto current = buffer()->get_insert()->get_iter().get_offset(); buffer()->insert(buffer()->end(), "\n"); //Make sure we have a newline at the end buffer()->place_cursor(buffer()->get_iter_at_offset(current)); }
static int do_diff(int argc, char *argv[], int obj, int ispatch, int which, int reverse) { /* create a diff (line or char) of two streams */ struct stream f, flist[3]; int chunks1 = 0, chunks2 = 0, chunks3 = 0; int exit_status = 0; struct file fl[2]; struct csl *csl; switch (argc) { case 0: fprintf(stderr, "%s: no file given for --diff\n", Cmd); return 2; case 1: f = load_file(argv[0]); if (f.body == NULL) { fprintf(stderr, "%s: cannot load file '%s' - %s\n", Cmd, argv[0], strerror(errno)); return 2; } chunks1 = chunks2 = split_patch(f, &flist[0], &flist[1]); if (!flist[0].body || !flist[1].body) { fprintf(stderr, "%s: couldn't parse patch %s\n", Cmd, argv[0]); return 2; } break; case 2: flist[0] = load_file(argv[0]); if (flist[0].body == NULL) { fprintf(stderr, "%s: cannot load file '%s' - %s\n", Cmd, argv[0], strerror(errno)); return 2; } if (ispatch) { f = load_file(argv[1]); if (f.body == NULL) { fprintf(stderr, "%s: cannot load patch" " '%s' - %s\n", Cmd, argv[1], strerror(errno)); return 2; } if (which == '2') chunks2 = chunks3 = split_patch(f, &flist[2], &flist[1]); else chunks2 = chunks3 = split_patch(f, &flist[1], &flist[2]); } else flist[1] = load_file(argv[1]); if (flist[1].body == NULL) { fprintf(stderr, "%s: cannot load file" " '%s' - %s\n", Cmd, argv[1], strerror(errno)); return 2; } break; default: fprintf(stderr, "%s: too many files given for --diff\n", Cmd); return 2; } if (reverse) { f = flist[1]; flist[1] = flist[2]; flist[2] = f; } fl[0] = split_stream(flist[0], obj == 'l' ? ByLine : ByWord); fl[1] = split_stream(flist[1], obj == 'l' ? ByLine : ByWord); if (chunks2 && !chunks1) csl = pdiff(fl[0], fl[1], chunks2); else csl = diff_patch(fl[0], fl[1]); if (obj == 'l') { if (!chunks1) printf("@@ -1,%d +1,%d @@\n", fl[0].elcnt, fl[1].elcnt); exit_status = do_diff_lines(fl, csl); } else { if (!chunks1) { /* count lines in each file */ int l1, l2, i; l1 = l2 = 0; for (i = 0 ; i < fl[0].elcnt ; i++) if (ends_line(fl[0].list[i])) l1++; for (i = 0 ; i < fl[1].elcnt ; i++) if (ends_line(fl[1].list[i])) l2++; printf("@@ -1,%d +1,%d @@\n", l1, l2); } exit_status = do_diff_words(fl, csl); } return exit_status; }
static int do_diff_words(struct file fl[2], struct csl *csl) { int a, b; int exit_status = 0; int sol = 1; /* start of line */ a = b = 0; while (a < fl[0].elcnt || b < fl[1].elcnt) { if (a < csl->a) { exit_status++; if (sol) { int a1; /* If we remove a * whole line, output * +line else clear * sol and retry */ sol = 0; for (a1 = a; a1 < csl->a ; a1++) if (ends_line(fl[0].list[a1])) { sol = 1; break; } if (sol) { printf("-"); for (; a < csl->a ; a++) { printword(stdout, fl[0].list[a]); if (ends_line(fl[0].list[a])) { a++; break; } } } else printf("|"); } if (!sol) { printf("<<<--"); do { if (sol) printf("|"); printword(stdout, fl[0].list[a]); sol = ends_line(fl[0].list[a]); a++; } while (a < csl->a); printf("%s-->>>", sol ? "|" : ""); sol = 0; } } else if (b < csl->b) { exit_status++; if (sol) { int b1; sol = 0; for (b1 = b; b1 < csl->b; b1++) if (ends_line(fl[1].list[b1])) { sol = 1; break; } if (sol) { printf("+"); for (; b < csl->b ; b++) { printword(stdout, fl[1].list[b]); if (ends_line(fl[1].list[b])) { b++; break; } } } else printf("|"); } if (!sol) { printf("<<<++"); do { if (sol) printf("|"); printword(stdout, fl[1].list[b]); sol = ends_line(fl[1].list[b]); b++; } while (b < csl->b); printf("%s++>>>", sol ? "|" : ""); sol = 0; } } else { if (sol) { int a1; sol = 0; for (a1 = a; a1 < csl->a+csl->len; a1++) if (ends_line(fl[0].list[a1])) sol = 1; if (sol) { if (fl[0].list[a].start[0]) { printf(" "); for (; a < csl->a+csl->len; a++, b++) { printword(stdout, fl[0].list[a]); if (ends_line(fl[0].list[a])) { a++, b++; break; } } } else { printsep(fl[0].list[a], fl[1].list[b]); a++; b++; } } else printf("|"); } if (!sol) { printword(stdout, fl[0].list[a]); if (ends_line(fl[0].list[a])) sol = 1; a++; b++; } if (a >= csl->a+csl->len) csl++; } } return exit_status; }
struct csl *pdiff(struct file a, struct file b, int chunks) { struct csl *csl1, *csl2; struct best *best = xmalloc(sizeof(struct best)*(chunks+1)); int i; struct file asmall, bsmall; int xmin; asmall = reduce(a); bsmall = reduce(b); for (i = 0; i < chunks+1; i++) best[i].val = 0; find_best_inorder(&asmall, &bsmall, 0, asmall.elcnt, 0, bsmall.elcnt, best, 1, chunks+1); remap(best, chunks+1, asmall, bsmall, a, b); if (asmall.list != a.list) free(asmall.list); if (bsmall.list != b.list) free(bsmall.list); csl1 = NULL; xmin = 0; for (i = 1; i <= chunks; i++) if (best[i].val > 0) { /* If we there are any newlines in the hunk before * ylo, then extend xlo back that many newlines if * possible and diff_partial the extended regions. */ int lines = 0; int ylo = best[i].ylo; int yhi; while (ylo > 0 && b.list[ylo-1].start[0]) { ylo--; lines += !!ends_line(b.list[ylo]); } if (lines) { int xlo = best[i].xlo; while (lines && xlo > xmin) { xlo--; lines -= !!ends_line(a.list[xlo]); } while (xlo > xmin && !ends_line(a.list[xlo-1])) xlo--; csl2 = diff_partial(a, b, xlo, best[i].xlo, ylo, best[i].ylo); csl1 = csl_join(csl1, csl2); } /* Now diff_partial the good bit of the hunk with the * good match */ csl2 = diff_partial(a, b, best[i].xlo, best[i].xhi, best[i].ylo, best[i].yhi); csl1 = csl_join(csl1, csl2); /* Now if there are newlines at the end of the * hunk that weren't matched, find as many in * original and diff_partial those bits */ lines = 0; yhi = best[i].yhi; while (yhi < b.elcnt && b.list[yhi].start[0]) { lines += !!ends_line(b.list[yhi]); yhi++; } xmin = best[i].xhi; if (lines) { int xhi = best[i].xhi; int xmax = a.elcnt; if (i < chunks) xmax = best[i+1].xlo; while (lines && xhi < xmax) { lines -= !!ends_line(a.list[xhi]); xhi++; } csl2 = diff_partial(a, b, best[i].xhi, xhi, best[i].yhi, yhi); csl1 = csl_join(csl1, csl2); xmin = xhi; } } else { /* FIXME we just lost a hunk!! */; } if (csl1) { for (csl2 = csl1; csl2->len; csl2++) ; csl2->a = a.elcnt; csl2->b = b.elcnt; } else { csl1 = xmalloc(sizeof(*csl1)); csl1->len = 0; csl1->a = a.elcnt; csl1->b = b.elcnt; } free(best); return csl1; }
static inline int is_skipped(struct elmnt e) { return !(ends_line(e) || isalnum(e.start[0]) || e.start[0] == '_'); }