static void copy_templates(const char *template_dir) { struct strbuf path = STRBUF_INIT; struct strbuf template_path = STRBUF_INIT; size_t template_len; struct repository_format template_format = REPOSITORY_FORMAT_INIT; struct strbuf err = STRBUF_INIT; DIR *dir; char *to_free = NULL; if (!template_dir) template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT); if (!template_dir) template_dir = init_db_template_dir; if (!template_dir) template_dir = to_free = system_path(DEFAULT_GIT_TEMPLATE_DIR); if (!template_dir[0]) { free(to_free); return; } strbuf_addstr(&template_path, template_dir); strbuf_complete(&template_path, '/'); template_len = template_path.len; dir = opendir(template_path.buf); if (!dir) { warning(_("templates not found in %s"), template_dir); goto free_return; } /* Make sure that template is from the correct vintage */ strbuf_addstr(&template_path, "config"); read_repository_format(&template_format, template_path.buf); strbuf_setlen(&template_path, template_len); /* * No mention of version at all is OK, but anything else should be * verified. */ if (template_format.version >= 0 && verify_repository_format(&template_format, &err) < 0) { warning(_("not copying templates from '%s': %s"), template_dir, err.buf); strbuf_release(&err); goto close_free_return; } strbuf_addstr(&path, get_git_common_dir()); strbuf_complete(&path, '/'); copy_templates_1(&path, &template_path, dir); close_free_return: closedir(dir); free_return: free(to_free); strbuf_release(&path); strbuf_release(&template_path); clear_repository_format(&template_format); }
/* Returns 0 on success, negative on failure. */ static int do_submodule_path(struct strbuf *buf, const char *path, const char *fmt, va_list args) { struct strbuf git_submodule_common_dir = STRBUF_INIT; struct strbuf git_submodule_dir = STRBUF_INIT; int ret; ret = submodule_to_gitdir(&git_submodule_dir, path); if (ret) goto cleanup; strbuf_complete(&git_submodule_dir, '/'); strbuf_addbuf(buf, &git_submodule_dir); strbuf_vaddf(buf, fmt, args); if (get_common_dir_noenv(&git_submodule_common_dir, git_submodule_dir.buf)) update_common_dir(buf, git_submodule_dir.len, git_submodule_common_dir.buf); strbuf_cleanup_path(buf); cleanup: strbuf_release(&git_submodule_dir); strbuf_release(&git_submodule_common_dir); return ret; }
int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, const char *prefix, void *cb_data) { struct strbuf real_pattern = STRBUF_INIT; struct ref_filter filter; int ret; if (!prefix && !starts_with(pattern, "refs/")) strbuf_addstr(&real_pattern, "refs/"); else if (prefix) strbuf_addstr(&real_pattern, prefix); strbuf_addstr(&real_pattern, pattern); if (!has_glob_specials(pattern)) { /* Append implied '/' '*' if not present. */ strbuf_complete(&real_pattern, '/'); /* No need to check for '*', there is none. */ strbuf_addch(&real_pattern, '*'); } filter.pattern = real_pattern.buf; filter.fn = fn; filter.cb_data = cb_data; ret = for_each_ref(filter_refs, &filter); strbuf_release(&real_pattern); return ret; }
static int reopen_stdout(struct commit *commit, const char *subject, struct rev_info *rev, int quiet) { struct strbuf filename = STRBUF_INIT; int suffix_len = strlen(rev->patch_suffix) + 1; if (output_directory) { strbuf_addstr(&filename, output_directory); if (filename.len >= PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len) return error(_("name of output directory is too long")); strbuf_complete(&filename, '/'); } if (rev->numbered_files) strbuf_addf(&filename, "%d", rev->nr); else if (commit) fmt_output_commit(&filename, commit, rev); else fmt_output_subject(&filename, subject, rev); if (!quiet) fprintf(realstdout, "%s\n", filename.buf + outdir_offset); if (freopen(filename.buf, "w", stdout) == NULL) return error(_("Cannot open patch file %s"), filename.buf); strbuf_release(&filename); return 0; }
static void do_submodule_path(struct strbuf *buf, const char *path, const char *fmt, va_list args) { const char *git_dir; struct strbuf git_submodule_common_dir = STRBUF_INIT; struct strbuf git_submodule_dir = STRBUF_INIT; strbuf_addstr(buf, path); strbuf_complete(buf, '/'); strbuf_addstr(buf, ".git"); git_dir = read_gitfile(buf->buf); if (git_dir) { strbuf_reset(buf); strbuf_addstr(buf, git_dir); } strbuf_addch(buf, '/'); strbuf_addstr(&git_submodule_dir, buf->buf); strbuf_vaddf(buf, fmt, args); if (get_common_dir_noenv(&git_submodule_common_dir, git_submodule_dir.buf)) update_common_dir(buf, git_submodule_dir.len, git_submodule_common_dir.buf); strbuf_cleanup_path(buf); strbuf_release(&git_submodule_dir); strbuf_release(&git_submodule_common_dir); }
static void test_strbuf(void) { struct strbuf *sb; _cleanup_strv_free_ char **l; ssize_t a, b, c, d, e, f, g; sb = strbuf_new(); a = add_string(sb, "waldo"); b = add_string(sb, "foo"); c = add_string(sb, "bar"); d = add_string(sb, "waldo"); /* duplicate */ e = add_string(sb, "aldo"); /* duplicate */ f = add_string(sb, "do"); /* duplicate */ g = add_string(sb, "waldorf"); /* not a duplicate: matches from tail */ /* check the content of the buffer directly */ l = strv_parse_nulstr(sb->buf, sb->len); assert(streq(l[0], "")); /* root*/ assert(streq(l[1], "waldo")); assert(streq(l[2], "foo")); assert(streq(l[3], "bar")); assert(streq(l[4], "waldorf")); assert(sb->nodes_count == 5); /* root + 4 non-duplicates */ assert(sb->dedup_count == 3); assert(sb->in_count == 7); assert(sb->in_len == 29); /* length of all strings added */ assert(sb->dedup_len == 11); /* length of all strings duplicated */ assert(sb->len == 23); /* buffer length: in - dedup + \0 for each node */ /* check the returned offsets and the respective content in the buffer */ assert(a == 1); assert(b == 7); assert(c == 11); assert(d == 1); assert(e == 2); assert(f == 4); assert(g == 15); assert(streq(sb->buf + a, "waldo")); assert(streq(sb->buf + b, "foo")); assert(streq(sb->buf + c, "bar")); assert(streq(sb->buf + d, "waldo")); assert(streq(sb->buf + e, "aldo")); assert(streq(sb->buf + f, "do")); assert(streq(sb->buf + g, "waldorf")); strbuf_complete(sb); assert(sb->root == NULL); strbuf_cleanup(sb); }
int is_nonbare_repository_dir(struct strbuf *path) { int ret = 0; int gitfile_error; size_t orig_path_len = path->len; assert(orig_path_len != 0); strbuf_complete(path, '/'); strbuf_addstr(path, ".git"); if (read_gitfile_gently(path->buf, &gitfile_error) || is_git_directory(path->buf)) ret = 1; if (gitfile_error == READ_GITFILE_ERR_OPEN_FAILED || gitfile_error == READ_GITFILE_ERR_READ_FAILED) ret = 1; strbuf_setlen(path, orig_path_len); return ret; }
static int do_submodule_path(struct strbuf *buf, const char *path, const char *fmt, va_list args) { const char *git_dir; struct strbuf git_submodule_common_dir = STRBUF_INIT; struct strbuf git_submodule_dir = STRBUF_INIT; const struct submodule *sub; int err = 0; strbuf_addstr(buf, path); strbuf_complete(buf, '/'); strbuf_addstr(buf, ".git"); git_dir = read_gitfile(buf->buf); if (git_dir) { strbuf_reset(buf); strbuf_addstr(buf, git_dir); } if (!is_git_directory(buf->buf)) { gitmodules_config(); sub = submodule_from_path(null_sha1, path); if (!sub) { err = SUBMODULE_PATH_ERR_NOT_CONFIGURED; goto cleanup; } strbuf_reset(buf); strbuf_git_path(buf, "%s/%s", "modules", sub->name); } strbuf_addch(buf, '/'); strbuf_addbuf(&git_submodule_dir, buf); strbuf_vaddf(buf, fmt, args); if (get_common_dir_noenv(&git_submodule_common_dir, git_submodule_dir.buf)) update_common_dir(buf, git_submodule_dir.len, git_submodule_common_dir.buf); strbuf_cleanup_path(buf); cleanup: strbuf_release(&git_submodule_dir); strbuf_release(&git_submodule_common_dir); return err; }
static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { static const struct option options[] = { { "update", no_argument, NULL, 'u' }, { "root", required_argument, NULL, 'r' }, { "test", required_argument, NULL, 't' }, { "help", no_argument, NULL, 'h' }, {} }; const char *test = NULL; const char *root = ""; char *udev_hwdb_path = UDEV_HWDB_BIN; bool update = false; struct trie *trie = NULL; int err; int rc = EXIT_SUCCESS; for (;;) { int option; option = getopt_long(argc, argv, "ut:r:h", options, NULL); if (option == -1) break; switch (option) { case 'u': update = true; break; case 't': test = optarg; break; case 'r': root = optarg; break; case 'h': help(); return EXIT_SUCCESS; } } if (!update && !test) { help(); return EXIT_SUCCESS; } if (update) { char **files, **f; trie = calloc(sizeof(struct trie), 1); if (!trie) { rc = EXIT_FAILURE; goto out; } /* string store */ trie->strings = strbuf_new(); if (!trie->strings) { rc = EXIT_FAILURE; goto out; } /* index */ trie->root = calloc(sizeof(struct trie_node), 1); if (!trie->root) { rc = EXIT_FAILURE; goto out; } trie->nodes_count++; err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs); if (err < 0) { log_error("failed to enumerate hwdb files: %s\n", strerror(-err)); rc = EXIT_FAILURE; goto out; } STRV_FOREACH(f, files) { log_debug("reading file '%s'", *f); import_file(udev, trie, *f); } strv_free(files); strbuf_complete(trie->strings); log_debug("=== trie in-memory ===\n"); log_debug("nodes: %8zu bytes (%8zu)\n", trie->nodes_count * sizeof(struct trie_node), trie->nodes_count); log_debug("children arrays: %8zu bytes (%8zu)\n", trie->children_count * sizeof(struct trie_child_entry), trie->children_count); log_debug("values arrays: %8zu bytes (%8zu)\n", trie->values_count * sizeof(struct trie_value_entry), trie->values_count); log_debug("strings: %8zu bytes\n", trie->strings->len); log_debug("strings incoming: %8zu bytes (%8zu)\n", trie->strings->in_len, trie->strings->in_count); log_debug("strings dedup'ed: %8zu bytes (%8zu)\n", trie->strings->dedup_len, trie->strings->dedup_count); if (root) { if (asprintf(&udev_hwdb_path, "%s/%s", root, udev_hwdb_path) < 0) { rc = EXIT_FAILURE; goto out; } } mkdir_parents(udev_hwdb_path, 0755); err = trie_store(trie, udev_hwdb_path); if (root) { free(udev_hwdb_path); } if (err < 0) { log_error("Failure writing database %s: %s", udev_hwdb_path, strerror(-err)); rc = EXIT_FAILURE; } }
static int queue_diff(struct diff_options *o, const char *name1, const char *name2) { int mode1 = 0, mode2 = 0; if (get_mode(name1, &mode1) || get_mode(name2, &mode2)) return -1; if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) { struct diff_filespec *d1, *d2; if (S_ISDIR(mode1)) { /* 2 is file that is created */ d1 = noindex_filespec(NULL, 0); d2 = noindex_filespec(name2, mode2); name2 = NULL; mode2 = 0; } else { /* 1 is file that is deleted */ d1 = noindex_filespec(name1, mode1); d2 = noindex_filespec(NULL, 0); name1 = NULL; mode1 = 0; } /* emit that file */ diff_queue(&diff_queued_diff, d1, d2); /* and then let the entire directory be created or deleted */ } if (S_ISDIR(mode1) || S_ISDIR(mode2)) { struct strbuf buffer1 = STRBUF_INIT; struct strbuf buffer2 = STRBUF_INIT; struct string_list p1 = STRING_LIST_INIT_DUP; struct string_list p2 = STRING_LIST_INIT_DUP; int i1, i2, ret = 0; size_t len1 = 0, len2 = 0; if (name1 && read_directory_contents(name1, &p1)) return -1; if (name2 && read_directory_contents(name2, &p2)) { string_list_clear(&p1, 0); return -1; } if (name1) { strbuf_addstr(&buffer1, name1); strbuf_complete(&buffer1, '/'); len1 = buffer1.len; } if (name2) { strbuf_addstr(&buffer2, name2); strbuf_complete(&buffer2, '/'); len2 = buffer2.len; } for (i1 = i2 = 0; !ret && (i1 < p1.nr || i2 < p2.nr); ) { const char *n1, *n2; int comp; strbuf_setlen(&buffer1, len1); strbuf_setlen(&buffer2, len2); if (i1 == p1.nr) comp = 1; else if (i2 == p2.nr) comp = -1; else comp = strcmp(p1.items[i1].string, p2.items[i2].string); if (comp > 0) n1 = NULL; else { strbuf_addstr(&buffer1, p1.items[i1++].string); n1 = buffer1.buf; } if (comp < 0) n2 = NULL; else { strbuf_addstr(&buffer2, p2.items[i2++].string); n2 = buffer2.buf; } ret = queue_diff(o, n1, n2); } string_list_clear(&p1, 0); string_list_clear(&p2, 0); strbuf_release(&buffer1); strbuf_release(&buffer2); return ret; } else { struct diff_filespec *d1, *d2; if (o->flags.reverse_diff) { SWAP(mode1, mode2); SWAP(name1, name2); } d1 = noindex_filespec(name1, mode1); d2 = noindex_filespec(name2, mode2); diff_queue(&diff_queued_diff, d1, d2); return 0; } }
static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { static const struct option options[] = { { "update", no_argument, NULL, 'u' }, { "test", required_argument, NULL, 't' }, { "root", required_argument, NULL, 'r' }, { "help", no_argument, NULL, 'h' }, {} }; const char *test = NULL; const char *root = ""; bool update = false; struct trie *trie = NULL; int err, c; int rc = EXIT_SUCCESS; while ((c = getopt_long(argc, argv, "ut:r:h", options, NULL)) >= 0) switch(c) { case 'u': update = true; break; case 't': test = optarg; break; case 'r': root = optarg; break; case 'h': help(); return EXIT_SUCCESS; case '?': return EXIT_FAILURE; default: assert_not_reached("Unknown option"); } if (!update && !test) { log_error("Either --update or --test must be used"); return EXIT_FAILURE; } if (update) { char **files, **f; _cleanup_free_ char *hwdb_bin = UDEV_HWDB_BIN; trie = calloc(sizeof(struct trie), 1); if (!trie) { rc = EXIT_FAILURE; goto out; } /* string store */ trie->strings = strbuf_new(); if (!trie->strings) { rc = EXIT_FAILURE; goto out; } /* index */ trie->root = calloc(sizeof(struct trie_node), 1); if (!trie->root) { rc = EXIT_FAILURE; goto out; } trie->nodes_count++; err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs); if (err < 0) { log_error("failed to enumerate hwdb files: %s", strerror(-err)); rc = EXIT_FAILURE; goto out; } STRV_FOREACH(f, files) { log_debug("reading file '%s'", *f); import_file(udev, trie, *f); } strv_free(files); strbuf_complete(trie->strings); log_debug("=== trie in-memory ==="); log_debug("nodes: %8zu bytes (%8zu)", trie->nodes_count * sizeof(struct trie_node), trie->nodes_count); log_debug("children arrays: %8zu bytes (%8zu)", trie->children_count * sizeof(struct trie_child_entry), trie->children_count); log_debug("values arrays: %8zu bytes (%8zu)", trie->values_count * sizeof(struct trie_value_entry), trie->values_count); log_debug("strings: %8zu bytes", trie->strings->len); log_debug("strings incoming: %8zu bytes (%8zu)", trie->strings->in_len, trie->strings->in_count); log_debug("strings dedup'ed: %8zu bytes (%8zu)", trie->strings->dedup_len, trie->strings->dedup_count); if (asprintf(&hwdb_bin, "%s/%s", root, hwdb_bin) < 0) { rc = EXIT_FAILURE; goto out; } mkdir_parents(hwdb_bin, 0755); err = trie_store(trie, hwdb_bin); if (err < 0) { log_error("Failure writing database %s: %s", hwdb_bin, strerror(-err)); rc = EXIT_FAILURE; } }
void end_url_with_slash(struct strbuf *buf, const char *url) { strbuf_addstr(buf, url); strbuf_complete(buf, '/'); }