/* We might need more ../ for nested modules. */ static const char *link_prefix(struct manifest *m) { char *prefix = tal_strdup(m, "../../"); unsigned int i; for (i = 0; i < strcount(m->modname, "/"); i++) prefix = tal_strcat(m, take(prefix), "../"); return tal_strcat(m, take(prefix), "licenses/"); }
static const char *concat(struct score *score, char *bits[]) { unsigned int i; char *ret = tal_strdup(score, ""); for (i = 0; bits[i]; i++) { if (i) ret = tal_strcat(score, take(ret), " "); ret = tal_strcat(score, take(ret), bits[i]); } return ret; }
/* Returns leaks, and sets errs[] */ static char *analyze_output(const char *output, char **errs) { char *leaks = tal_strdup(output, ""); unsigned int i; char **lines = tal_strsplit(output, output, "\n", STR_EMPTY_OK); *errs = tal_strdup(output, ""); for (i = 0; i < tal_count(lines) - 1; i++) { unsigned int preflen = strspn(lines[i], "=0123456789"); char *prefix, **sublines; /* Ignore erased lines, or weird stuff. */ if (preflen == 0) continue; prefix = tal_strndup(output, lines[i], preflen); sublines = extract_matching(prefix, lines); leaks = tal_strcat(output, take(leaks), take(get_leaks(sublines, errs))); } if (!leaks[0]) { tal_free(leaks); leaks = NULL; } if (!(*errs)[0]) { tal_free(*errs); *errs = NULL; } return leaks; }
static const char *expected_link(const tal_t *ctx, const char *prefix, enum license license) { const char *shortname; switch (license) { case LICENSE_LGPLv2_PLUS: case LICENSE_LGPLv2: shortname = "LGPL-2.1"; break; case LICENSE_LGPLv3: case LICENSE_LGPL: shortname = "LGPL-3"; break; case LICENSE_GPLv2_PLUS: case LICENSE_GPLv2: shortname = "GPL-2"; break; case LICENSE_GPLv3: case LICENSE_GPL: shortname = "GPL-3"; break; case LICENSE_BSD: shortname = "BSD-3CLAUSE"; break; case LICENSE_MIT: shortname = "BSD-MIT"; break; case LICENSE_CC0: shortname = "CC0"; break; default: return NULL; } return tal_strcat(ctx, prefix, shortname); }
/* We only handle simple function definitions here. */ static char *add_func(const tal_t *ctx, char *others, const char *line) { const char *p, *end = strchr(line, '(') - 1; char *use; while (cisspace(*end)) { end--; if (end == line) return others; } for (p = end; cisalnum(*p) || *p == '_'; p--) { if (p == line) return others; } use = tal_fmt(ctx, "printf(\"%%p\", %.*s);\n", (unsigned)(end - p), p+1); if (others) use = tal_strcat(ctx, take(others), take(use)); return use; }
static int lazytrie_edge_info(const struct aga_graph *g, const struct aga_node *n, ptrint_t *e, struct aga_edge_info *ei) { struct trie_node *tn = container_of(n, struct trie_node, agan); struct trie_node *next; int index = ptr2int(e); assert((index >= 1) && (index <= NLETTERS)); next = tn->next[index - 1]; if (!next) { int depth = strlen(tn->prefix); int start, end; start = tn->start; while (start < tn->end) { if (wordarray[start][depth] >= LETTERS[index - 1]) break; start++; } end = start; while (end < tn->end) { if (wordarray[end][depth] > LETTERS[index - 1]) break; end++; } if (end > start) { char plus[2] = { LETTERS[index - 1], '\0' }; next = tal(tn, struct trie_node); init_trie_node(next, start, end, tal_strcat(next, tn->prefix, plus)); }
static void add_files(struct manifest *m, const char *base, const char *subdir) { DIR *d; struct dirent *ent; char **subs = tal_arr(m, char *, 0); const char *thisdir; if (!subdir) thisdir = base; else thisdir = path_join(subs, base, subdir); d = opendir(thisdir); if (!d) err(1, "Opening directory %s", thisdir); while ((ent = readdir(d)) != NULL) { struct stat st; struct ccan_file *f; struct list_head *dest; bool is_c_src; if (ent->d_name[0] == '.') continue; f = new_ccan_file(m, m->dir, subdir ? path_join(m, subdir, ent->d_name) : ent->d_name); if (lstat(f->fullname, &st) != 0) err(1, "lstat %s", f->fullname); if (S_ISDIR(st.st_mode)) { size_t len = tal_count(subs); tal_resize(&subs, len+1); subs[len] = tal_strcat(subs, f->name, "/"); continue; } if (!S_ISREG(st.st_mode)) { tal_free(f); continue; } if (streq(f->name, "_info")) { m->info_file = f; continue; } is_c_src = strends(f->name, ".c"); if (!is_c_src && !strends(f->name, ".h")) { dest = &m->other_files; } else if (!strchr(f->name, '/')) { if (is_c_src) dest = &m->c_files; else dest = &m->h_files; } else if (strstarts(f->name, "test/")) { if (is_c_src) { if (strstarts(f->name, "test/api")) dest = &m->api_tests; else if (strstarts(f->name, "test/run")) dest = &m->run_tests; else if (strstarts(f->name, "test/compile_ok")) dest = &m->compile_ok_tests; else if (strstarts(f->name, "test/compile_fail")) dest = &m->compile_fail_tests; else dest = &m->other_test_c_files; } else dest = &m->other_test_files; } else dest = &m->other_files; list_add(dest, &f->list); } closedir(d); /* Before we recurse, sanity check this is a ccan module. */ if (!subdir) { size_t i; if (!m->info_file && list_empty(&m->c_files) && list_empty(&m->h_files)) errx(1, "No _info, C or H files found here!"); for (i = 0; i < tal_count(subs); i++) add_files(m, base, subs[i]); } tal_free(subs); }
int main(void) { char *parent, *c; plan_tests(43); parent = tal(NULL, char); ok1(parent); c = tal_strdup(parent, "hello"); ok1(strcmp(c, "hello") == 0); ok1(tal_parent(c) == parent); ok1(tal_count(c) == strlen(c) + 1); tal_free(c); c = tal_strndup(parent, "hello", 3); ok1(strcmp(c, "hel") == 0); ok1(tal_parent(c) == parent); ok1(tal_count(c) == strlen(c) + 1); tal_free(c); #ifdef TAL_USE_TALLOC c = tal_talloc_typechk_(parent, char *); #else c = tal_typechk_(parent, char *); #endif c = tal_dup_arr(parent, char, "hello", 6, 0); ok1(strcmp(c, "hello") == 0); ok1(strcmp(tal_name(c), "char[]") == 0); ok1(tal_count(c) == 6); ok1(tal_parent(c) == parent); tal_free(c); /* Now with an extra byte. */ c = tal_dup_arr(parent, char, "hello", 6, 1); ok1(strcmp(c, "hello") == 0); ok1(strcmp(tal_name(c), "char[]") == 0); ok1(tal_count(c) == 7); ok1(tal_parent(c) == parent); strcat(c, "x"); tal_free(c); c = tal_fmt(parent, "hello %s", "there"); ok1(strcmp(c, "hello there") == 0); ok1(tal_count(c) == strlen(c) + 1); ok1(tal_parent(c) == parent); tal_free(c); c = tal_strcat(parent, "hello ", "there"); ok1(strcmp(c, "hello there") == 0); ok1(tal_count(c) == strlen(c) + 1); ok1(tal_parent(c) == parent); /* Make sure take works correctly. */ c = tal_strcat(parent, take(c), " again"); ok1(strcmp(c, "hello there again") == 0); ok1(tal_count(c) == strlen(c) + 1); ok1(tal_parent(c) == parent); ok1(single_child(parent, c)); c = tal_strcat(parent, "And ", take(c)); ok1(tal_count(c) == strlen(c) + 1); ok1(strcmp(c, "And hello there again") == 0); ok1(tal_parent(c) == parent); ok1(single_child(parent, c)); /* NULL pass through works... */ c = tal_strcat(parent, take(NULL), take(c)); ok1(!c); ok1(no_children(parent)); c = tal_strcat(parent, take(tal_strdup(parent, "hi")), take(NULL)); ok1(!c); ok1(no_children(parent)); c = tal_strcat(parent, take(NULL), take(NULL)); ok1(!c); ok1(no_children(parent)); /* Appending formatted strings. */ c = tal_strdup(parent, "hi"); ok1(tal_count(c) == strlen(c) + 1); ok1(tal_append_fmt(&c, "%s %s", "there", "world")); ok1(strcmp(c, "hithere world") == 0); ok1(tal_count(c) == strlen(c) + 1); ok1(tal_parent(c) == parent); ok1(!tal_append_fmt(&c, take(NULL), "there", "world")); ok1(strcmp(c, "hithere world") == 0); ok1(tal_count(c) == strlen(c) + 1); tal_free(parent); return exit_status(); }