int main(int argc, char **argv) { if (argc == 5 && !strcmp(argv[1], "split")) { struct string_list list = STRING_LIST_INIT_DUP; int i; const char *s = argv[2]; int delim = *argv[3]; int maxsplit = atoi(argv[4]); i = string_list_split(&list, s, delim, maxsplit); printf("%d\n", i); write_list(&list); string_list_clear(&list, 0); return 0; } if (argc == 5 && !strcmp(argv[1], "split_in_place")) { struct string_list list = STRING_LIST_INIT_NODUP; int i; char *s = xstrdup(argv[2]); int delim = *argv[3]; int maxsplit = atoi(argv[4]); i = string_list_split_in_place(&list, s, delim, maxsplit); printf("%d\n", i); write_list(&list); string_list_clear(&list, 0); free(s); return 0; } if (argc == 4 && !strcmp(argv[1], "filter")) { /* * Retain only the items that have the specified prefix. * Arguments: list|- prefix */ struct string_list list = STRING_LIST_INIT_DUP; const char *prefix = argv[3]; parse_string_list(&list, argv[2]); filter_string_list(&list, 0, prefix_cb, (void *)prefix); write_list_compact(&list); string_list_clear(&list, 0); return 0; } if (argc == 3 && !strcmp(argv[1], "remove_duplicates")) { struct string_list list = STRING_LIST_INIT_DUP; parse_string_list(&list, argv[2]); string_list_remove_duplicates(&list, 0); write_list_compact(&list); string_list_clear(&list, 0); return 0; } fprintf(stderr, "%s: unknown function name: %s\n", argv[0], argv[1] ? argv[1] : "(there was none)"); return 1; }
void string_list_add_refs_from_colon_sep(struct string_list *list, const char *globs) { struct string_list split = STRING_LIST_INIT_NODUP; char *globs_copy = xstrdup(globs); int i; string_list_split_in_place(&split, globs_copy, ':', -1); string_list_remove_empty_items(&split, 0); for (i = 0; i < split.nr; i++) string_list_add_refs_by_glob(list, split.items[i].string); string_list_clear(&split, 0); free(globs_copy); }
/* * Create a newly-allocated `snapshot` of the `packed-refs` file in * its current state and return it. The return value will already have * its reference count incremented. * * A comment line of the form "# pack-refs with: " may contain zero or * more traits. We interpret the traits as follows: * * Neither `peeled` nor `fully-peeled`: * * Probably no references are peeled. But if the file contains a * peeled value for a reference, we will use it. * * `peeled`: * * References under "refs/tags/", if they *can* be peeled, *are* * peeled in this file. References outside of "refs/tags/" are * probably not peeled even if they could have been, but if we find * a peeled value for such a reference we will use it. * * `fully-peeled`: * * All references in the file that can be peeled are peeled. * Inversely (and this is more important), any references in the * file for which no peeled value is recorded is not peelable. This * trait should typically be written alongside "peeled" for * compatibility with older clients, but we do not require it * (i.e., "peeled" is a no-op if "fully-peeled" is set). * * `sorted`: * * The references in this file are known to be sorted by refname. */ static struct snapshot *create_snapshot(struct packed_ref_store *refs) { struct snapshot *snapshot = xcalloc(1, sizeof(*snapshot)); int sorted = 0; snapshot->refs = refs; acquire_snapshot(snapshot); snapshot->peeled = PEELED_NONE; if (!load_contents(snapshot)) return snapshot; /* If the file has a header line, process it: */ if (snapshot->buf < snapshot->eof && *snapshot->buf == '#') { struct strbuf tmp = STRBUF_INIT; char *p; const char *eol; struct string_list traits = STRING_LIST_INIT_NODUP; eol = memchr(snapshot->buf, '\n', snapshot->eof - snapshot->buf); if (!eol) die_unterminated_line(refs->path, snapshot->buf, snapshot->eof - snapshot->buf); strbuf_add(&tmp, snapshot->buf, eol - snapshot->buf); if (!skip_prefix(tmp.buf, "# pack-refs with:", (const char **)&p)) die_invalid_line(refs->path, snapshot->buf, snapshot->eof - snapshot->buf); string_list_split_in_place(&traits, p, ' ', -1); if (unsorted_string_list_has_string(&traits, "fully-peeled")) snapshot->peeled = PEELED_FULLY; else if (unsorted_string_list_has_string(&traits, "peeled")) snapshot->peeled = PEELED_TAGS; sorted = unsorted_string_list_has_string(&traits, "sorted"); /* perhaps other traits later as well */ /* The "+ 1" is for the LF character. */ snapshot->header_len = eol + 1 - snapshot->buf; string_list_clear(&traits, 0); strbuf_release(&tmp); } verify_buffer_safe(snapshot); if (!sorted) { sort_snapshot(snapshot); /* * Reordering the records might have moved a short one * to the end of the buffer, so verify the buffer's * safety again: */ verify_buffer_safe(snapshot); } if (mmap_strategy != MMAP_OK && snapshot->mmapped) { /* * We don't want to leave the file mmapped, so we are * forced to make a copy now: */ size_t size = snapshot->eof - (snapshot->buf + snapshot->header_len); char *buf_copy = xmalloc(size); memcpy(buf_copy, snapshot->buf + snapshot->header_len, size); clear_snapshot_buffer(snapshot); snapshot->buf = buf_copy; snapshot->eof = buf_copy + size; } return snapshot; }