static void buf_add_node_attr(char **b, tgt_node_t *x) { char *buf; tgt_node_t *n; int len; /* ---- null byte and starting '<' character ---- */ len = strlen(x->x_name) + 2; if ((buf = malloc(len)) == NULL) return; (void) snprintf(buf, len, "<%s", x->x_name); buf_add_str(b, buf); free(buf); for (n = x->x_attr; n; n = n->x_sibling) { len = strlen(n->x_name) + strlen(n->x_value) + 5; if ((buf = malloc(len)) == NULL) return; (void) snprintf(buf, len, " %s='%s'", n->x_name, n->x_value); buf_add_str(b, buf); free(buf); } buf_add_str(b, ">"); }
inline void crypt(ErlNifEnv* env, struct buf *rbuf, unsigned char *data, int len) { int i; for (i = 0; i < len; i++) { switch (data[i]) { case '&': buf_add_str(env, rbuf, "&", 5); break; case '<': buf_add_str(env, rbuf, "<", 4); break; case '>': buf_add_str(env, rbuf, ">", 4); break; case '"': buf_add_str(env, rbuf, """, 6); break; case '\'': buf_add_str(env, rbuf, "'", 6); break; default: buf_add_char(env, rbuf, data[i]); break; }; }; }
static int make_attrs(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM attrs) { ErlNifBinary name, data; ERL_NIF_TERM head, tail; const ERL_NIF_TERM *tuple; int arity, ret = 1; while (enif_get_list_cell(env, attrs, &head, &tail)) { if (enif_get_tuple(env, head, &arity, &tuple)) { if (arity == 2) { if (enif_inspect_iolist_as_binary(env, tuple[0], &name) && enif_inspect_iolist_as_binary(env, tuple[1], &data)) { buf_add_char(env, rbuf, ' '); buf_add_str(env, rbuf, (char *)name.data, name.size); buf_add_str(env, rbuf, "='", 2); crypt(env, rbuf, data.data, data.size); buf_add_char(env, rbuf, '\''); attrs = tail; } else { ret = 0; break; }; } else { ret = 0; break; }; } else { ret = 0; break; }; }; return ret; }
static void print_horizontal_tab_title(struct view *v, int idx) { int skip = v->tt_width - v->tt_truncated_width; const char *filename = buffer_filename(v->buffer); char buf[16]; if (skip > 0) { filename += u_skip_chars(filename, &skip); } snprintf(buf, sizeof(buf), "%c%d%s", obuf.x == 0 && idx > 0 ? '<' : ' ', idx + 1, buffer_modified(v->buffer) ? "+" : ":"); if (v == v->window->view) set_builtin_color(BC_ACTIVETAB); else set_builtin_color(BC_INACTIVETAB); buf_add_str(buf); buf_add_str(filename); if (obuf.x == obuf.width - 1 && idx < v->window->views.count - 1) buf_put_char('>'); else buf_put_char(' '); }
static void print_vertical_tab_title(struct view *v, int idx, int width) { const char *orig_filename = buffer_filename(v->buffer); const char *filename = orig_filename; int max = options.tab_bar_max_components; char buf[16]; int skip; snprintf(buf, sizeof(buf), "%2d%s", idx + 1, buffer_modified(v->buffer) ? "+" : " "); if (max) { int i, count = 1; for (i = 0; filename[i]; i++) { if (filename[i] == '/') count++; } // ignore first slash because it does not separate components if (filename[0] == '/') count--; if (count > max) { // skip possible first slash for (i = 1; ; i++) { if (filename[i] == '/' && --count == max) { i++; break; } } filename += i; } } else { skip = strlen(buf) + u_str_width(filename) - width + 1; if (skip > 0) filename += u_skip_chars(filename, &skip); } if (filename != orig_filename) { // filename was shortened. add "<<" symbol long i = strlen(buf); u_set_char(buf, &i, 0xab); buf[i] = 0; } if (v == v->window->view) set_builtin_color(BC_ACTIVETAB); else set_builtin_color(BC_INACTIVETAB); buf_add_str(buf); buf_add_str(filename); buf_clear_eol(); }
void buf_add_xml (struct buf *buf, char c) { if (c == '<') { buf_add_str(buf, "<"); } else if (c == '>') { buf_add_str(buf, ">"); } else if (c == '\"') { buf_add_str(buf, """); } else if (c == '\'') { buf_add_str(buf, "'"); } else if (c == '&') { buf_add_str(buf, "&"); } else { buf_add(buf, c); } }
static ERL_NIF_TERM escape_cdata(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary input; ERL_NIF_TERM output; struct buf *rbuf; int i; if (argc != 1) { return enif_make_badarg(env); } // CData should be iolist() or binary() if (enif_is_binary(env, argv[0])) { if (!enif_inspect_binary(env, argv[0], &input)) { return enif_make_badarg(env); } } else { if (!enif_inspect_iolist_as_binary(env, argv[0], &input)) { return enif_make_badarg(env); } } rbuf = init_buf(env, EXML_CDATA_BUF_SIZE); for (i = 0; i < input.size; i++) { switch (input.data[i]) { case '&': buf_add_str(env, EXML_CDATA_BUF_SIZE, rbuf, "&", 5); break; case '<': buf_add_str(env, EXML_CDATA_BUF_SIZE, rbuf, "<", 4); break; case '>': buf_add_str(env, EXML_CDATA_BUF_SIZE, rbuf, ">", 4); break; default: buf_add_char(env, EXML_CDATA_BUF_SIZE, rbuf, input.data[i]); break; }; }; unsigned char* data = enif_make_new_binary(env, rbuf->len, &output); memcpy(data, rbuf->b, rbuf->len); destroy_buf(env, rbuf); return output; }
static ERL_NIF_TERM escape_attr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary input; ERL_NIF_TERM output; struct buf *rbuf; int i; if (argc != 1) { return enif_make_badarg(env); } if (!enif_inspect_binary(env, argv[0], &input)) { return enif_make_badarg(env); } rbuf = init_buf(env, EXML_ATTR_BUF_SIZE); for (i = 0; i < input.size; i++) { switch (input.data[i]) { case '&': buf_add_str(env, EXML_ATTR_BUF_SIZE, rbuf, "&", 5); break; case '<': buf_add_str(env, EXML_ATTR_BUF_SIZE, rbuf, "<", 4); break; case '>': buf_add_str(env, EXML_ATTR_BUF_SIZE, rbuf, ">", 4); break; case '"': buf_add_str(env, EXML_ATTR_BUF_SIZE, rbuf, """, 6); break; case '\'': buf_add_str(env, EXML_ATTR_BUF_SIZE, rbuf, "'", 6); break; case '\t': buf_add_str(env, EXML_ATTR_BUF_SIZE, rbuf, "	", 5); break; case '\n': buf_add_str(env, EXML_ATTR_BUF_SIZE, rbuf, "
", 5); break; case '\r': buf_add_str(env, EXML_ATTR_BUF_SIZE, rbuf, "
", 5); break; default: buf_add_char(env, EXML_ATTR_BUF_SIZE, rbuf, input.data[i]); break; }; }; unsigned char *data = enif_make_new_binary(env, rbuf->len, &output); memcpy(data, rbuf->b, rbuf->len); destroy_buf(env, rbuf); return output; }
static int make_element(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM el) { ErlNifBinary cdata, name; const ERL_NIF_TERM *tuple; int arity, ret = 0; if (enif_get_tuple(env, el, &arity, &tuple)) { if (arity == 2) { if (!ENIF_COMPARE(tuple[0], atom_xmlcdata)) { if (enif_inspect_iolist_as_binary(env, tuple[1], &cdata)) { crypt(env, rbuf, cdata.data, cdata.size); ret = 1; }; }; }; if (arity == 4) { if (!ENIF_COMPARE(tuple[0], atom_xmlelement)) { if (enif_inspect_iolist_as_binary(env, tuple[1], &name)) { buf_add_char(env, rbuf, '<'); buf_add_str(env, rbuf, (char *)name.data, name.size); ret = make_attrs(env, rbuf, tuple[2]); if (ret) { if (enif_is_empty_list(env, tuple[3])) { buf_add_str(env, rbuf, "/>", 2); } else { buf_add_char(env, rbuf, '>'); ret = make_elements(env, rbuf, tuple[3]); if (ret) { buf_add_str(env, rbuf, "</", 2); buf_add_str(env, rbuf, (char*)name.data, name.size); buf_add_char(env, rbuf, '>'); }; }; }; }; }; }; }; return ret; }
void update_git_open(void) { int x = 0; int y = 0; int w = screen_w; int h = screen_h - 1; int max_y = git_open.scroll + h - 1; int i; if (h >= git_open.files.count) git_open.scroll = 0; if (git_open.scroll > git_open.selected) git_open.scroll = git_open.selected; if (git_open.selected > max_y) git_open.scroll += git_open.selected - max_y; buf_reset(x, w, 0); buf_move_cursor(0, 0); cmdline_x = print_command('/'); buf_clear_eol(); y++; for (i = 0; i < h; i++) { int file_idx = git_open.scroll + i; char *file; struct term_color color; if (file_idx >= git_open.files.count) break; file = git_open.files.ptrs[file_idx]; obuf.x = 0; buf_move_cursor(x, y + i); color = *builtin_colors[BC_DEFAULT]; if (file_idx == git_open.selected) mask_color(&color, builtin_colors[BC_SELECTION]); buf_set_color(&color); buf_add_str(file); buf_clear_eol(); } set_builtin_color(BC_DEFAULT); for (; i < h; i++) { obuf.x = 0; buf_move_cursor(x, y + i); buf_clear_eol(); } }
/* * []---- * | tgt_buf_add_tag_and_attr -- variant on tgt_buf_add_tag which also gives * | attr * []---- */ void tgt_buf_add_tag_and_attr(char **b, char *str, char *attr) { char *buf; int len; /* * In addition to the 'str' and 'attr' strings the code will add * three characters plus a null byte. */ len = strlen(str) + strlen(attr) + 4; if ((buf = malloc(len)) == NULL) return; (void) snprintf(buf, len, "<%s %s>", str, attr); buf_add_str(b, buf); free(buf); }
/* * []---- * | tgt_buf_add_tag -- adds string to buffer allocating space, sets up tags too * | * | Helper function to build a string by allocating memory as we go. * | If the string argument 'str' is defined to be a start or end tag * | as declared by 'type' argument add the appropriate characters. * []---- */ void tgt_buf_add_tag(char **b, const char *str, val_type_t type) { char *buf; int len; /* * We will add potentially up to 3 extra characters plus the NULL byte */ len = strlen(str) + 4; if ((buf = malloc(len)) == NULL) return; (void) snprintf(buf, len, "%s%s%s%s", type == Tag_String ? "" : "<", type == Tag_End ? "/" : "", str, type == Tag_String ? "" : ">"); buf_add_str(b, buf); free(buf); }
void update_status_line(struct window *win) { struct formatter f; char lbuf[256]; char rbuf[256]; int lw, rw; sf_init(&f, win); f.misc_status = format_misc_status(win); sf_format(&f, lbuf, sizeof(lbuf), options.statusline_left); sf_format(&f, rbuf, sizeof(rbuf), options.statusline_right); buf_reset(win->x, win->w, 0); buf_move_cursor(win->x, win->y + win->h - 1); set_builtin_color(BC_STATUSLINE); lw = u_str_width(lbuf); rw = u_str_width(rbuf); if (lw + rw <= win->w) { // both fit buf_add_str(lbuf); buf_set_bytes(' ', win->w - lw - rw); buf_add_str(rbuf); } else if (lw <= win->w && rw <= win->w) { // both would fit separately, draw overlapping buf_add_str(lbuf); obuf.x = win->w - rw; buf_move_cursor(win->x + win->w - rw, win->y + win->h - 1); buf_add_str(rbuf); } else if (lw <= win->w) { // left fits buf_add_str(lbuf); buf_clear_eol(); } else if (rw <= win->w) { // right fits buf_set_bytes(' ', win->w - rw); buf_add_str(rbuf); } else { buf_clear_eol(); } }
int main (int argc, char *argv[]) { FILE *fpi = stdin, *fpo = stdout, *fpmap; struct mapper mapper; struct record record; struct map *map; struct field *field; struct buf *val_buf = buf_new(1024), *xml_buf = NULL; char *xml_key, *key_buf, prev_seq[9], seq[9], tag[4], ind1, ind2; int file_args = 0, array = 1, xml = 0, mapfile = 0, count = 0, first = 0, first_sub = 0, first_char, skip_sub = 0, c, i, j; tag[3] = '\0'; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "--usage") || !strcmp(argv[i], "--help") || !strcmp(argv[i], "-?")) { usage(argv[0], 0); } else if (!strcmp(argv[i], "--newline")) { array = 0; } else if (!strcmp(argv[i], "--xml")) { xml = 1; } else if (!strcmp(argv[i], "--json")) { xml = 0; } else if (!strcmp(argv[i], "--xmlkey")) { if (++i == argc) usage(argv[0], 1); xml_key = argv[i]; xml_buf = buf_new(2048); } else if (!strcmp(argv[i], "--mapfile")) { if (++i == argc) usage(argv[0], 1); key_buf = malloc(256); if ((fpmap = fopen(argv[i], "r")) == NULL) { fprintf(stderr, "Can't open %s for reading\n", argv[i]); return 1; } if (!mapfile) { mapfile = 1; mapper.size = mapper.grow = 100; mapper.used = 0; mapper.maps = malloc(sizeof(struct map) * mapper.size); record.size = record.grow = 100; record.used = 0; record.fields = malloc(sizeof(struct field) * record.size); for (j = 0; j < record.size; j++) { record.fields[j].val = buf_new(1024); } } while ((c = getc(fpmap)) != EOF) { if (isspace(c)) continue; if (c == '#') { while (more(c = getc(fpmap))); continue; } map = mapper.maps + mapper.used; map->key = NULL; map->tag[0] = c; map->tag[1] = getc(fpmap); map->tag[2] = getc(fpmap); if (isspace(c = getc(fpmap))) { map->op = '\0'; } else { map->op = c; fscanf(fpmap, "%s", map->subfields); } fscanf(fpmap, "%s", key_buf); for (j = 0; j < mapper.used; j++) { if (!strcmp(mapper.maps[j].key, key_buf)) { map->key = mapper.maps[j].key; break; } } if (!map->key) { map->key = malloc(strlen(key_buf) + 1); strcpy(map->key, key_buf); } mapper.used++; if (mapper.used == mapper.size) { mapper.size += mapper.grow; mapper.maps = realloc(mapper.maps, sizeof(struct map) * mapper.size); } } free(key_buf); fclose(fpmap); } else { switch (++file_args) { case 1: if ((fpi = fopen(argv[i], "r")) == NULL) { fprintf(stderr, "Can't open %s for reading\n", argv[i]); return 1; } break; case 2: if ((fpo = fopen(argv[i], "w")) == NULL) { fprintf(stderr, "Can't open %s for writing\n", argv[i]); return 1; } break; } } } if (xml) { fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?><collection xmlns=\"http://www.loc.gov/MARC21/slim\">", fpo); } else if (array) { fputs("[", fpo); } while ((c = getc(fpi)) != EOF) { if (isspace(c)) continue; seq[0] = c; for (i = 1; i < 9; ++i) seq[i] = getc(fpi); getc(fpi); for (i = 0; i < 3; ++i) tag[i] = getc(fpi); ind1 = getc(fpi); ind2 = getc(fpi); for (i = 0; i < 3; ++i) getc(fpi); val_buf->used = 0; while (more(c = getc(fpi))) buf_add(val_buf, c); buf_add(val_buf, '\0'); if (!count || strncmp(seq, prev_seq, 9)) { if (count++) { if (xml_buf) { buf_add_str(xml_buf, "</record>"); buf_add(xml_buf, '\0'); } if (mapfile) { fputs("{", fpo); for (i = 0; i < record.used; i++) { field = record.fields + i; if (i) putc(',', fpo); buf_add(field->val, '\0'); fprintf(fpo, "\"%s\":[%s]", field->key, field->val->str); } if (xml_buf) { if (i) putc(',', fpo); fprintf(fpo, "\"%s\":\"", xml_key); put_json_str(xml_buf->str, fpo); putc('\"', fpo); } fputs(array ? "},\n" : "}\n", fpo); record.used = 0; } else if (xml) { fputs("</record>\n", fpo); } else { fputs(array ? "]},\n" : "]}\n", fpo); } if (xml_buf) { xml_buf->used = 0; } } } for (i = 0; i < 9; ++i) prev_seq[i] = seq[i]; if (mapfile) { for (i = 0; i < mapper.used; i++) { map = mapper.maps + i; if ((map->tag[0] == '*' || map->tag[0] == tag[0]) && (map->tag[1] == '*' || map->tag[1] == tag[1]) && (map->tag[2] == '*' || map->tag[2] == tag[2])) { field = NULL; for (j = 0; j < record.used; j++) { field = record.fields + j; if (field->key == map->key) { break; } field = NULL; } if (!field) { field = record.fields + record.used; field->key = map->key; field->val->used = 0; record.used++; } skip_sub = 0; first_char = 1; for (j = 0; j < val_buf->used-1; j++) { if (val_buf->str[j] == '$' && val_buf->str[j+1] == '$') { j+= 2; if ( (map->op == '+' && strchr(map->subfields, val_buf->str[j]) == NULL) || (map->op == '-' && strchr(map->subfields, val_buf->str[j]) != NULL) ) { skip_sub = 1; continue; } skip_sub = 0; j++; if (j == val_buf->used-1) break; } if (!skip_sub) { if (first_char) { if (field->val->used) buf_add(field->val, ','); buf_add(field->val, '"'); first_char = 0; } if (val_buf->str[j] == '"') buf_add(field->val, '\\'); if (val_buf->str[j] == '\\') buf_add(field->val, '\\'); buf_add(field->val, val_buf->str[j]); } } if (!first_char) buf_add(field->val, '"'); } } } if (!strncmp(tag, "FMT", 3)) continue; if (!strncmp(tag, "LDR", 3)) { if (xml_buf) { buf_add_str(xml_buf, "<record><leader>"); buf_add_str(xml_buf, val_buf->str); buf_add_str(xml_buf, "</leader>"); } else if (xml) { fprintf(fpo, "<record><leader>%s</leader>", val_buf->str); } else if (!mapfile) { fprintf(fpo, "{\"leader\":\"%s\",\"fields\":[", val_buf->str); } first = 1; continue; } if (first) { first = 0; } else if (!xml_buf && !xml && !mapfile) { putc(',', fpo); } if (tag[0] == '0' && tag[1] == '0') { if (xml_buf) { buf_add_str(xml_buf, "<controlfield tag=\""); for (i = 0; i < 3; i++) buf_add(xml_buf, tag[i]); buf_add_str(xml_buf, "\">"); buf_add_xml_str(xml_buf, val_buf->str); buf_add_str(xml_buf, "</controlfield>"); } else if (xml) { fprintf(fpo, "<controlfield tag=\"%3s\">", tag); for (i = 0; i < val_buf->used-1; i++) put_xml(val_buf->str[i], fpo); fputs("</controlfield>", fpo); } else if (!mapfile) { fprintf(fpo, "{\"%3s\":\"", tag); for (i = 0; i < val_buf->used-1; i++) put_json(val_buf->str[i], fpo); fputs("\"}", fpo); } } else { if (xml_buf) { buf_add_str(xml_buf, "<datafield tag=\""); for (i = 0; i < 3; i++) buf_add(xml_buf, tag[i]); buf_add_str(xml_buf, "\" ind1=\""); buf_add(xml_buf, ind1); buf_add_str(xml_buf, "\" ind2=\""); buf_add(xml_buf, ind2); buf_add_str(xml_buf, "\">"); } else if (xml) { fprintf(fpo, "<datafield tag=\"%3s\" ind1=\"%c\" ind2=\"%c\">", tag, ind1, ind2); } else if (!mapfile) { fprintf(fpo, "{\"%3s\":{\"ind1\":\"%c\",\"ind2\":\"%c\",\"subfields\":[", tag, ind1, ind2); } first_sub = 1; for (i = 0; i < val_buf->used-1; i++) { if (val_buf->str[i] == '$' && val_buf->str[i+1] == '$') { i+= 2; if (first_sub) { first_sub = 0; } else { if (xml_buf) { buf_add_str(xml_buf, "</subfield>"); } else if (xml) { fputs("</subfield>", fpo); } else if (!mapfile) { fputs("\"},", fpo); } } if (xml_buf) { buf_add_str(xml_buf, "<subfield code=\""); buf_add(xml_buf, val_buf->str[i]); buf_add_str(xml_buf, "\">"); } else if (xml) { fprintf(fpo, "<subfield code=\"%c\">", val_buf->str[i]); } else if (!mapfile) { fprintf(fpo, "{\"%c\":\"", val_buf->str[i]); } continue; } if (xml_buf) { buf_add_xml(xml_buf, val_buf->str[i]); } else if (xml) { put_xml(val_buf->str[i], fpo); } else if (!mapfile) { put_json(val_buf->str[i], fpo); } } if (!first_sub) { if (xml_buf) { buf_add_str(xml_buf, "</subfield>"); } else if (xml) { fputs("</subfield>", fpo); } else if (!mapfile) { fputs("\"}", fpo); } } if (xml_buf) { buf_add_str(xml_buf, "</datafield>"); } else if (xml) { fputs("</datafield>", fpo); } else if (!mapfile) { fputs("]", fpo); } } } if (count && mapfile) { fputs("{", fpo); for (i = 0; i < record.used; i++) { field = record.fields + i; if (i) putc(',', fpo); buf_add(field->val, '\0'); fprintf(fpo, "\"%s\":[%s]", field->key, field->val->str); } if (xml_buf) { if (i) putc(',', fpo); fprintf(fpo, "\"%s\":\"", xml_key); put_json_str(xml_buf->str, fpo); putc('\"', fpo); } } if (xml) { if (count) fputs("</record>", fpo); fputs("</collection>", fpo); } else { if (count) fputs("}", fpo); if (array) fputs("]", fpo); } fclose(fpi); fclose(fpo); return 0; }