diff -r 3831dbdd6ae8 src/Makefile.am --- a/src/Makefile.am Thu Jun 12 16:05:12 2008 -0700 +++ b/src/Makefile.am Fri Jun 13 12:35:50 2008 -0400 @@ -21,7 +21,7 @@ syntax.c syntax.h parser.y builtin.c lens.c lens.h regexp.c \ transform.c get.c put.c list.h libaugeas_la_LDFLAGS = -Wl,--version-script=$(srcdir)/augeas_sym.version -libaugeas_la_LIBADD = liblexer.la libfa.la $(GNULIB) +libaugeas_la_LIBADD = liblexer.la libfa.la $(GNULIB) -lustr augtool_SOURCES = augtool.c augtool_LDADD = libaugeas.la $(READLINE_LIBS) $(GNULIB) diff -r 3831dbdd6ae8 src/builtin.c --- a/src/builtin.c Thu Jun 12 16:05:12 2008 -0700 +++ b/src/builtin.c Fri Jun 13 12:35:50 2008 -0400 @@ -43,7 +43,7 @@ assert(rxp->tag == V_REGEXP); assert(dflt->tag == V_STRING); return lns_make_prim(L_DEL, ref(info), - ref(rxp->regexp), ref(dflt->string)); + ref(rxp->regexp), ustr_dup(dflt->string)); } /* V_REGEXP -> V_LENS */ @@ -61,19 +61,19 @@ /* V_STRING -> V_LENS */ static struct value *lns_label(struct info *info, struct value *str) { assert(str->tag == V_STRING); - return lns_make_prim(L_LABEL, ref(info), NULL, ref(str->string)); + return lns_make_prim(L_LABEL, ref(info), NULL, ustr_dup(str->string)); } /* V_STRING -> V_LENS */ static struct value *lns_seq(struct info *info, struct value *str) { assert(str->tag == V_STRING); - return lns_make_prim(L_SEQ, ref(info), NULL, ref(str->string)); + return lns_make_prim(L_SEQ, ref(info), NULL, ustr_dup(str->string)); } /* V_STRING -> V_LENS */ static struct value *lns_counter(struct info *info, struct value *str) { assert(str->tag == V_STRING); - return lns_make_prim(L_COUNTER, ref(info), NULL, ref(str->string)); + return lns_make_prim(L_COUNTER, ref(info), NULL, ustr_dup(str->string)); } static struct value *make_exn_lns_error(struct info *info, @@ -114,7 +114,7 @@ assert(str->tag == V_STRING); struct lns_error *err; struct value *v; - const char *text = str->string->str; + const char *text = ustr_cstr(str->string); struct tree *tree = lns_get(info, l->lens, text, &err); if (err == NULL) { @@ -145,14 +145,14 @@ struct lns_error *err; init_memstream(&ms); - lns_put(ms.stream, l->lens, tree->tree, str->string->str, &err); + lns_put(ms.stream, l->lens, tree->tree, ustr_cstr(str->string), &err); close_memstream(&ms); if (err == NULL) { v = make_value(V_STRING, ref(info)); v->string = make_string(ms.buf); } else { - v = make_exn_lns_error(info, err, str->string->str); + v = make_exn_lns_error(info, err, ustr_cstr(str->string)); free_lns_error(err); FREE(ms.buf); } @@ -168,10 +168,11 @@ assert(path->tag == V_STRING); assert(val->tag == V_STRING); assert(tree->tag == V_TREE); - if (tree_set(tree->tree, path->string->str, val->string->str) == NULL) { + const char *s_path = ustr_cstr(path->string); + const char *s_val = ustr_cstr(val->string); + if (tree_set(tree->tree, s_path, s_val) == NULL) { return make_exn_value(ref(info), - "Tree set of %s to '%s' failed", - path->string->str, val->string->str); + "Tree set of %s to '%s' failed", s_path, s_val); } return ref(tree); } @@ -185,9 +186,9 @@ // need to copy TREE first assert(path->tag == V_STRING); assert(tree->tag == V_TREE); - if (tree_rm(&tree->tree, path->string->str) == -1) { + if (tree_rm(&tree->tree, ustr_cstr(path->string)) == -1) { return make_exn_value(ref(info), "Tree rm of %s failed", - path->string->str); + ustr_cstr(path->string)); } return ref(tree); } @@ -197,14 +198,12 @@ assert(prefix->tag == V_STRING); static unsigned int count = 0; struct value *v; - char *s; - int r; + Ustr *s1 = USTR_NULL; - r = asprintf(&s, "%s%u", prefix->string->str, count); - if (r == -1) + if (!(s1 = ustr_dup_fmt("%s%u", ustr_cstr(prefix->string), count))) return NULL; v = make_value(V_STRING, ref(info)); - v->string = make_string(s); + v->string = s1; return v; } @@ -212,7 +211,7 @@ static struct value *xform_incl(struct info *info, struct value *s) { assert(s->tag == V_STRING); struct value *v = make_value(V_FILTER, ref(info)); - v->filter = make_filter(ref(s->string), 1); + v->filter = make_filter(ustr_dup(s->string), 1); return v; } @@ -220,7 +219,7 @@ static struct value *xform_excl(struct info *info, struct value *s) { assert(s->tag == V_STRING); struct value *v = make_value(V_FILTER, ref(info)); - v->filter = make_filter(ref(s->string), 0); + v->filter = make_filter(ustr_dup(s->string), 0); return v; } diff -r 3831dbdd6ae8 src/fa.c --- a/src/fa.c Thu Jun 12 16:05:12 2008 -0700 +++ b/src/fa.c Fri Jun 13 12:35:50 2008 -0400 @@ -2991,7 +2991,7 @@ return (r < 0) ? NULL : result; } -static char *re_as_string(const struct re *re) { +static char *re_as_string(const struct re *re) { /* FIXME: return Ustr */ char *result = NULL; switch(re->type) { case UNION: @@ -3174,12 +3174,12 @@ * the transition INI -> FIN * (5) Convert that STRUCT RE to a string with RE_AS_STRING */ -int fa_as_regexp(struct fa *fa, char **regexp) { +int fa_as_regexp(struct fa *fa, Ustr **regexp) { int r; struct state *fin = NULL, *ini = NULL; struct re *eps = make_re(EPSILON); - *regexp = NULL; + *regexp = USTR_NULL; fa = fa_clone(fa); fin = add_state(fa,1); @@ -3233,7 +3233,9 @@ for_each_trans(t, fa->initial) { if (t->to == fin) { - *regexp = re_as_string(t->re); + char *tmp = re_as_string(t->re); + *regexp = ustr_dup_cstr(tmp); + free(tmp); } } diff -r 3831dbdd6ae8 src/fa.h --- a/src/fa.h Thu Jun 12 16:05:12 2008 -0700 +++ b/src/fa.h Fri Jun 13 12:35:50 2008 -0400 @@ -25,6 +25,7 @@ #include #include +#include /* The type for a finite automaton. */ typedef struct fa *fa_t; @@ -181,7 +182,7 @@ * Return 0 on success, and a negative number on failure. The only reason * to fail for FA_AS_REGEXP is running out of memory. */ -int fa_as_regexp(fa_t fa, char **regexp); +int fa_as_regexp(fa_t fa, Ustr **regexp); #endif diff -r 3831dbdd6ae8 src/get.c --- a/src/get.c Thu Jun 12 16:05:12 2008 -0700 +++ b/src/get.c Fri Jun 13 12:35:50 2008 -0400 @@ -253,7 +253,7 @@ for (p = word; *p != '\0' && *p != '\n'; p++); *p = '\0'; - pat = escape(l->ctype->pattern->str, -1); + pat = escape(ustr_cstr(l->ctype->pattern), -1); get_error(state, l, "expected %s at '%s'", pat, word); free(pat); } @@ -294,8 +294,8 @@ abort(); } else if (count == -1) { char *text = strndup(outer->start, outer->size); - get_error(state, lens, - "Failed to match /%s/ with %s", ctype->pattern->str, text); + get_error(state, lens, "Failed to match /%s/ with %s", + ustr_cstr(ctype->pattern), text); free(text); return NULL; } @@ -388,7 +388,7 @@ static struct tree *get_seq(struct lens *lens, struct state *state) { assert(lens->tag == L_SEQ); - struct seq *seq = find_seq(lens->string->str, state); + struct seq *seq = find_seq(ustr_cstr(lens->string), state); if (asprintf((char **) &(state->key), "%d", seq->value) == -1) { // FIXME: We are out of memory .. find a way to report that @@ -405,7 +405,7 @@ static struct tree *get_counter(struct lens *lens, struct state *state) { assert(lens->tag == L_COUNTER); - struct seq *seq = find_seq(lens->string->str, state); + struct seq *seq = find_seq(ustr_cstr(lens->string), state); seq->value = 1; return NULL; } @@ -463,7 +463,7 @@ static struct tree *get_label(struct lens *lens, struct state *state) { assert(lens->tag == L_LABEL); - state->key = strdup(lens->string->str); + state->key = ustr_sc_export(lens->string, malloc); return NULL; } diff -r 3831dbdd6ae8 src/lens.c --- a/src/lens.c Thu Jun 12 16:05:12 2008 -0700 +++ b/src/lens.c Fri Jun 13 12:35:50 2008 -0400 @@ -196,7 +196,7 @@ * Lens primitives */ struct value *lns_make_prim(enum lens_tag tag, struct info *info, - struct regexp *regexp, struct string *string) { + struct regexp *regexp, Ustr *string) { struct lens *lens = NULL; struct value *exn = NULL; fa_t fa_slash = NULL; @@ -220,7 +220,7 @@ if (! fa_is_basic(fa_isect, FA_EMPTY)) { exn = make_exn_value(info, "The key regexp /%s/ matches a '/'", - regexp->pattern->str); + ustr_cstr(regexp->pattern)); goto error; } fa_free(fa_isect); @@ -228,10 +228,10 @@ fa_free(fa_slash); fa_isect = fa_key = fa_slash = NULL; } else if (tag == L_LABEL) { - if (strchr(string->str, SEP) != NULL) { + if (ustr_srch_chr_fwd(string, 0, SEP)) { exn = make_exn_value(info, "The label string \"%s\" contains a '/'", - string->str); + ustr_cstr(string)); goto error; } } @@ -421,7 +421,7 @@ if (fa_contains(eps, fa)) { exn = make_exn_value(ref(info), "illegal optional expression: /%s/ matches the empty word", - l->ctype->pattern->str); + ustr_cstr(l->ctype->pattern)); } fa_free(eps); fa_free(fa); @@ -430,23 +430,20 @@ static struct regexp *make_key_regexp(struct info *info, const char *pat) { struct regexp *regexp; - size_t len = strlen(pat) + 4; make_ref(regexp); - make_ref(regexp->pattern); regexp->info = ref(info); - CALLOC(regexp->pattern->str, len); - snprintf(regexp->pattern->str, len, "(%s)/", pat); + regexp->pattern = ustr_dup_fmt("(%s)/", pat); return regexp; } static struct regexp *make_regexp_from_string(struct info *info, - struct string *string) { + Ustr *string) { struct regexp *r; make_ref(r); if (r != NULL) { r->info = ref(info); - r->pattern = ref(string); + r->pattern = ustr_dup(string); } return r; } @@ -460,37 +457,29 @@ label of the tree that STORE created. */ static struct regexp *lns_key_regexp(struct lens *l, struct value **exn) { - static const struct string leaf_key_string = { - .ref = REF_MAX, .str = (char *) "/" - }; - static const struct string *const leaf_key_pat = &leaf_key_string; - - static const struct string digits_string = { - .ref = REF_MAX, .str = (char *) "[0-9]+/" - }; - static const struct string *const digits_pat = &digits_string; + static Ustr *const leaf_key_pat = USTR1(\1, "/"); + static Ustr *const digits_pat = USTR1(\7, "[0-9]+/"); *exn = NULL; switch(l->tag) { case L_STORE: - return make_regexp_from_string(l->info, (struct string *) leaf_key_pat); + return make_regexp_from_string(l->info, leaf_key_pat); case L_DEL: case L_COUNTER: return NULL; case L_SEQ: - return make_regexp_from_string(l->info, (struct string *) digits_pat); + return make_regexp_from_string(l->info, digits_pat); case L_KEY: - return make_key_regexp(l->info, l->regexp->pattern->str); + return make_key_regexp(l->info, ustr_cstr(l->regexp->pattern)); case L_LABEL: { - struct regexp *r = make_regexp_literal(l->info, l->string->str); + struct regexp *r = make_regexp_literal(l->info, ustr_cstr(l->string)); if (r == NULL) return NULL; - if (REALLOC_N(r->pattern->str, strlen(r->pattern->str) + 2) == -1) { + if (!ustr_add_cstr(&r->pattern, "/")) { unref(r, regexp); return NULL; } - strcat(r->pattern->str, "/"); return r; } case L_CONCAT: @@ -566,7 +555,7 @@ switch (lens->tag) { case L_DEL: unref(lens->regexp, regexp); - unref(lens->string, string); + ustr_free(lens->string); break; case L_STORE: case L_KEY: @@ -575,7 +564,7 @@ case L_LABEL: case L_SEQ: case L_COUNTER: - unref(lens->string, string); + ustr_free(lens->string); break; case L_SUBTREE: case L_STAR: diff -r 3831dbdd6ae8 src/lens.h --- a/src/lens.h Thu Jun 12 16:05:12 2008 -0700 +++ b/src/lens.h Fri Jun 13 12:35:50 2008 -0400 @@ -52,7 +52,7 @@ /* Primitive lenses */ struct { /* L_DEL uses both */ struct regexp *regexp; /* L_STORE, L_KEY */ - struct string *string; /* L_LABEL, L_SEQ, L_COUNTER */ + struct Ustr *string; /* L_LABEL, L_SEQ, L_COUNTER */ }; /* Combinators */ struct lens *child; /* L_SUBTREE, L_STAR, L_MAYBE */ @@ -70,7 +70,7 @@ * exception iftypechecking fails. */ struct value *lns_make_prim(enum lens_tag tag, struct info *info, - struct regexp *regexp, struct string *string); + struct regexp *regexp, struct Ustr *string); struct value *lns_make_union(struct info *, struct lens *, struct lens *, int check); struct value *lns_make_concat(struct info *, struct lens *, struct lens *, diff -r 3831dbdd6ae8 src/lexer.l --- a/src/lexer.l Thu Jun 12 16:05:12 2008 -0700 +++ b/src/lexer.l Fri Jun 13 12:35:50 2008 -0400 @@ -35,11 +35,11 @@ #define YY_USER_INIT LOCATION_STEP(*yylloc) -#define YY_EXTRA_TYPE struct string * +#define YY_EXTRA_TYPE Ustr * int augl_get_column (yyscan_t yyscanner); static void augl_set_column (int column_no , yyscan_t yyscanner); -int augl_init_lexer(struct string *name, yyscan_t * scanner); +int augl_init_lexer(Ustr *name, yyscan_t * scanner); static int to_int(const char *str) { int v; @@ -128,7 +128,7 @@ BEGIN(COMMENT); } . { - fprintf(stderr, "%s:%d:%d: Unexpected character %c\n", augl_get_extra(yyscanner)->str, yylineno, yylloc->first_column, yytext[0]); + fprintf(stderr, "%s:%d:%d: Unexpected character %c\n", ustr_cstr(augl_get_extra(yyscanner)), yylineno, yylloc->first_column, yytext[0]); } <> { @@ -150,16 +150,16 @@ } . /* Skip */; <> { - fprintf(stderr, "%s:%d:%d: Missing *)\n", augl_get_extra(yyscanner)->str, yylineno, yylloc->first_column); + fprintf(stderr, "%s:%d:%d: Missing *)\n", ustr_cstr(augl_get_extra(yyscanner)), yylineno, yylloc->first_column); yyterminate(); } } %% -int augl_init_lexer(struct string *name, yyscan_t *scanner) { +int augl_init_lexer(Ustr *name, yyscan_t *scanner) { FILE *f; - f = fopen(name->str, "r"); + f = fopen(ustr_cstr(name), "r"); if (f == NULL) return -1; diff -r 3831dbdd6ae8 src/parser.y --- a/src/parser.y Thu Jun 12 16:05:12 2008 -0700 +++ b/src/parser.y Fri Jun 13 12:35:50 2008 -0400 @@ -92,11 +92,11 @@ %{ /* Lexer */ extern int augl_lex (YYSTYPE * yylval_param,struct info * yylloc_param ,yyscan_t yyscanner); - int augl_init_lexer(struct string *name, yyscan_t * scanner); + int augl_init_lexer(Ustr *name, yyscan_t * scanner); int augl_lex_destroy (yyscan_t yyscanner ); int augl_get_lineno (yyscan_t yyscanner ); int augl_get_column (yyscan_t yyscanner); -struct string *augl_get_extra (yyscan_t yyscanner ); +Ustr *augl_get_extra (yyscan_t yyscanner ); char *augl_get_text (yyscan_t yyscanner ); static void augl_error(struct info *locp, struct term **term, @@ -304,15 +304,14 @@ int augl_parse_file(const char *name, struct term **term) { yyscan_t scanner; - struct string *sname = NULL; + Ustr *sname = NULL; struct info info; int result = -1; int r; *term = NULL; - make_ref(sname); - sname->str = strdup(name); + sname = ustr_dup_cstr(name); memset(&info, '\0', sizeof(info)); info.ref = UINT_MAX; info.filename = sname; @@ -334,7 +333,7 @@ result = 0; done: - unref(sname, string); + ustr_free(sname); // free TERM return result; } @@ -343,7 +342,7 @@ static struct info *clone_info(struct info *locp) { struct info *info; make_ref(info); - info->filename = ref(locp->filename); + info->filename = ustr_dup(locp->filename); info->first_line = locp->first_line; info->first_column = locp->first_column; info->last_line = locp->last_line; @@ -432,7 +431,7 @@ term->type = make_base_type(T_STRING); } else { term->type = make_base_type(T_REGEXP); - term->value->regexp = make_regexp(term->info, value); + term->value->regexp = make_regexp(term->info, make_string(value)); } return term; } @@ -495,16 +494,16 @@ yyscan_t scanner, const char *s) { struct info info; - struct string string; - info.ref = string.ref = UINT_MAX; - info.filename = &string; + + info.ref = UINT_MAX; + info.filename = USTR(""); if (locp != NULL) { info.first_line = locp->first_line; info.first_column = locp->first_column; info.last_line = locp->last_line; info.last_column = locp->last_column; - info.filename->str = locp->filename->str; + info.filename = locp->filename; /* borrowed reference ? */ } else if (scanner != NULL) { info.first_line = augl_get_lineno(scanner); info.first_column = augl_get_column(scanner); diff -r 3831dbdd6ae8 src/put.c --- a/src/put.c Thu Jun 12 16:05:12 2008 -0700 +++ b/src/put.c Fri Jun 13 12:35:50 2008 -0400 @@ -167,7 +167,7 @@ outer->end - outer->start); put_error(state, lens, "Failed to match /%s/ with %s", - atype->pattern->str, labels); + ustr_cstr(atype->pattern), labels); free(labels); return NULL; } @@ -509,7 +509,7 @@ 0, NULL) != strlen(state->value)) { put_error(state, lens, "Value '%s' does not match regexp /%s/ in store lens", - state->value, lens->regexp->pattern->str); + state->value, ustr_cstr(lens->regexp->pattern)); } else { fprintf(state->out, "%s", state->value); } @@ -568,7 +568,7 @@ static void create_del(struct lens *lens, struct state *state) { assert(lens->tag == L_DEL); - print_escaped_chars(state->out, lens->string->str); + print_escaped_chars(state->out, ustr_cstr(lens->string)); } static void create_union(struct lens *lens, struct state *state) { diff -r 3831dbdd6ae8 src/regexp.c --- a/src/regexp.c Thu Jun 12 16:05:12 2008 -0700 +++ b/src/regexp.c Fri Jun 13 12:35:50 2008 -0400 @@ -25,11 +25,8 @@ #include "syntax.h" #include "memory.h" -static const struct string empty_pattern_string = { - .ref = REF_MAX, .str = (char *) "()" -}; -static const struct string *const empty_pattern = &empty_pattern_string; +static const Ustr *const empty_pattern = USTR1(\2, "()"); void print_regexp(FILE *out, struct regexp *r) { if (r == NULL) { @@ -41,18 +38,17 @@ if (r->pattern == NULL) fprintf(out, "%p", r); else - print_chars(out, r->pattern->str, -1); + print_chars(out, ustr_cstr(r->pattern), -1); fputc('/', out); } -struct regexp *make_regexp(struct info *info, char *pat) { +struct regexp *make_regexp(struct info *info, Ustr *pat) { struct regexp *regexp; make_ref(regexp); regexp->info = ref(info); - make_ref(regexp->pattern); - regexp->pattern->str = pat; + regexp->pattern = pat; return regexp; } @@ -61,7 +57,7 @@ return; assert(regexp->ref == 0); unref(regexp->info, info); - unref(regexp->pattern, string); + ustr_free(regexp->pattern); if (regexp->re != NULL) { regfree(regexp->re); free(regexp->re); @@ -70,56 +66,57 @@ } struct regexp *make_regexp_literal(struct info *info, const char *text) { - char *pattern, *p; + Ustr *pattern = ustr_dup_empty(); /* Escape special characters in text since it should be taken literally */ - CALLOC(pattern, 2*strlen(text)+1); - p = pattern; for (const char *t = text; *t != '\0'; t++) { if ((*t == '\\') && t[1]) { - *p++ = *t++; - *p++ = *t; + ustr_add_rep_chr(&pattern, *t++, 1); + ustr_add_rep_chr(&pattern, *t, 1); } else if (strchr(".|{}[]()+*?", *t) != NULL) { - *p++ = '\\'; - *p++ = *t; + ustr_add_rep_chr(&pattern, '\\', 1); + ustr_add_rep_chr(&pattern, *t, 1); } else { - *p++ = *t; + ustr_add_rep_chr(&pattern, *t, 1); } } + + if (ustr_enomem(pattern)) { /* FIXME */ } + return make_regexp(info, pattern); } struct regexp * regexp_union(struct info *info, struct regexp *r1, struct regexp *r2) { - const char *p1 = r1->pattern->str; - const char *p2 = r2->pattern->str; - char *s; + const char *p1 = ustr_cstr(r1->pattern); + const char *p2 = ustr_cstr(r2->pattern); + Ustr *s = ustr_dup_fmt("(%s)|(%s)", p1, p2); - if (asprintf(&s, "(%s)|(%s)", p1, p2) == -1) + if (!s) return NULL; return make_regexp(info, s); } struct regexp * regexp_concat(struct info *info, struct regexp *r1, struct regexp *r2) { - const char *p1 = r1->pattern->str; - const char *p2 = r2->pattern->str; - char *s; + const char *p1 = ustr_cstr(r1->pattern); + const char *p2 = ustr_cstr(r2->pattern); + Ustr *s = ustr_dup_fmt("(%s)(%s)", p1, p2); - if (asprintf(&s, "(%s)(%s)", p1, p2) == -1) + if (!s) return NULL; return make_regexp(info, s); } struct regexp * regexp_minus(struct info *info, struct regexp *r1, struct regexp *r2) { - const char *p1 = r1->pattern->str; - const char *p2 = r2->pattern->str; + const char *p1 = ustr_cstr(r1->pattern); + const char *p2 = ustr_cstr(r2->pattern); struct regexp *result = NULL; fa_t fa = NULL, fa1 = NULL, fa2 = NULL; int r; - char *s = NULL; + Ustr *s = NULL; r = fa_compile(p1, &fa1); if (r != REG_NOERROR) @@ -143,13 +140,13 @@ } result = make_regexp(info, s); - s = NULL; + s = USTR_NULL; done: fa_free(fa); fa_free(fa1); fa_free(fa2); - free(s); + ustr_free(s); return result; error: unref(result, regexp); @@ -159,29 +156,27 @@ struct regexp * regexp_iter(struct info *info, struct regexp *r, int min, int max) { - const char *p = r->pattern->str; - char *s; - int ret = 0; + const char *p = ustr_cstr(r->pattern); + Ustr *s; if ((min == 0 || min == 1) && max == -1) { char q = (min == 0) ? '*' : '+'; - ret = asprintf(&s, "(%s)%c", p, q); + s = ustr_dup_fmt("(%s)%c", p, q); } else if (min == max) { - ret = asprintf(&s, "(%s){%d}", p, min); + s = ustr_dup_fmt("(%s){%d}", p, min); } else { - ret = asprintf(&s, "(%s){%d,%d}", p, min, max); + s = ustr_dup_fmt("(%s){%d,%d}", p, min, max); } - return (ret == -1) ? NULL : make_regexp(info, s); + return s ? make_regexp(info, s) : NULL; } struct regexp * regexp_maybe(struct info *info, struct regexp *r) { - const char *p = r->pattern->str; - char *s; - int ret; + const char *p = ustr_cstr(r->pattern); + Ustr *s; - ret = asprintf(&s, "(%s)?", p); - return (ret == -1) ? NULL : make_regexp(info, s); + s = ustr_dup_fmt("(%s)?", p); + return s ? make_regexp(info, s) : NULL; } struct regexp *regexp_make_empty(struct info *info) { @@ -192,7 +187,7 @@ regexp->info = ref(info); /* Casting away the CONST for EMPTY_PATTERN is ok since it is protected against changes because REF == REF_MAX */ - regexp->pattern = (struct string *) empty_pattern; + regexp->pattern = ustr_dup(empty_pattern); } return regexp; } @@ -203,10 +198,10 @@ re_syntax_options = RE_SYNTAX_POSIX_MINIMAL_EXTENDED & ~(RE_DOT_NEWLINE); const char *c = - re_compile_pattern(r->pattern->str, strlen(r->pattern->str), r->re); + re_compile_pattern(ustr_cstr(r->pattern), ustr_len(r->pattern), r->re); if (c != NULL) { - char *p = escape(r->pattern->str, -1); + char *p = escape(ustr_cstr(r->pattern), -1); syntax_error(r->info, "invalid regexp /%s/: %s", p, c); free(p); return -1; @@ -233,11 +228,11 @@ fa_t regexp_to_fa(struct regexp *regexp) { fa_t fa; - int error = fa_compile(regexp->pattern->str, &fa); + int error = fa_compile(ustr_cstr(regexp->pattern), &fa); if (error != REG_NOERROR) { syntax_error(regexp->info, "unexpected error from fa_compile %d compiling %s", - error, regexp->pattern->str); + error, ustr_cstr(regexp->pattern)); return NULL; } return fa; diff -r 3831dbdd6ae8 src/syntax.c --- a/src/syntax.c Thu Jun 12 16:05:12 2008 -0700 +++ b/src/syntax.c Fri Jun 13 12:35:50 2008 -0400 @@ -80,7 +80,7 @@ int r = 0; int fl = info->first_line, ll = info->last_line; int fc = info->first_column, lc = info->last_column; - fname = (info->filename != NULL) ? info->filename->str : "(unknown file)"; + fname = info->filename ? ustr_cstr(info->filename) : "(unknown file)"; if (fl > 0) { if (fl == ll) { @@ -98,7 +98,7 @@ void print_info(FILE *out, struct info *info) { fprintf(out, "%s:", - info->filename != NULL ? info->filename->str : "(unknown file)"); + info->filename ? ustr_cstr(info->filename) : "(unknown file)"); if (info->first_line > 0) { if (info->first_line == info->last_line) { if (info->first_column == info->last_column) { @@ -150,19 +150,11 @@ fprintf(stderr, "\n"); } -void free_string(struct string *string) { - if (string == NULL) - return; - assert(string->ref == 0); - free(string->str); - free(string); -} - void free_info(struct info *info) { if (info == NULL) return; assert(info->ref == 0); - unref(info->filename, string); + ustr_free(info->filename); free(info); } @@ -171,7 +163,7 @@ return; assert(param->ref == 0); unref(param->info, info); - unref(param->name, string); + ustr_free(param->name); unref(param->type, type); free(param); } @@ -203,7 +195,7 @@ unref(term->value, value); break; case A_IDENT: - unref(term->ident, string); + ustr_free(term->ident); break; case A_BRACKET: unref(term->brexp, term); @@ -234,7 +226,7 @@ return; assert(binding->ref == 0); unref(binding->next, binding); - unref(binding->ident, string); + ustr_free(binding->ident); unref(binding->type, type); unref(binding->value, value); free(binding); @@ -283,7 +275,7 @@ switch(v->tag) { case V_STRING: - unref(v->string, string); + ustr_free(v->string); break; case V_REGEXP: unref(v->regexp, regexp); @@ -337,8 +329,7 @@ struct term *term = make_term(A_FUNC, info); make_ref(term->param); term->param->info = ref(term->info); - make_ref(term->param->name); - term->param->name->str = name; + term->param->name = ustr_dup_cstr(name); term->param->type = type; return term; } @@ -351,11 +342,8 @@ return value; } -struct string *make_string(char *str) { - struct string *string; - make_ref(string); - string->str = str; - return string; +Ustr *make_string(char *str) { + return ustr_dup_cstr(str); } struct term *make_app_term(struct term *lambda, struct term *arg, @@ -464,7 +452,7 @@ static struct binding *bnd_lookup(struct binding *bindings, const char *name) { list_for_each(b, bindings) { - if (STREQ(b->ident->str, name)) + if (ustr_cmp_cstr_eq(b->ident, name)) return b; } return NULL; @@ -517,14 +505,14 @@ } static struct value *ctx_lookup(struct info *info, - struct ctx *ctx, struct string *ident) { - struct binding *b = ctx_lookup_bnd(info, ctx, ident->str); + struct ctx *ctx, Ustr *ident) { + struct binding *b = ctx_lookup_bnd(info, ctx, ustr_cstr(ident)); return b == NULL ? NULL : b->value; } static struct type *ctx_lookup_type(struct info *info, - struct ctx *ctx, struct string *ident) { - struct binding *b = ctx_lookup_bnd(info, ctx, ident->str); + struct ctx *ctx, Ustr *ident) { + struct binding *b = ctx_lookup_bnd(info, ctx, ustr_cstr(ident)); return b == NULL ? NULL : b->type; } @@ -533,8 +521,7 @@ const char *name, struct type *type) { struct binding *binding; make_ref(binding); - make_ref(binding->ident); - binding->ident->str = strdup(name); + binding->ident = ustr_dup_cstr(name); binding->type = ref(type); list_cons(*bnds, binding); @@ -546,7 +533,7 @@ struct value *v) { struct binding *b; make_ref(b); - b->ident = ref(param->name); + b->ident = ustr_dup(param->name); b->type = ref(param->type); b->value = ref(v); ref(*bnds); @@ -577,7 +564,7 @@ static void dump_bindings(struct binding *bnds) { list_for_each(b, bnds) { char *st = type_string(b->type); - fprintf(stderr, " %s: %s", b->ident->str, st); + fprintf(stderr, " %s: %s", ustr_cstr(b->ident), st); fprintf(stderr, " = "); print_value(stderr, b->value); fputc('\n', stderr); @@ -614,10 +601,10 @@ switch(v->tag) { case V_STRING: - fprintf(out, "\"%s\"", v->string->str); + fprintf(out, "\"%s\"", ustr_cstr(v->string)); break; case V_REGEXP: - fprintf(out, "/%s/", v->regexp->pattern->str); + fprintf(out, "/%s/", ustr_cstr(v->regexp->pattern)); break; case V_LENS: fprintf(out, "filter) { - fprintf(out, "%c%s%c", f->include ? '+' : '-', f->glob->str, - (f->next != NULL) ? ':' : '>'); + fprintf(out, "%c%s%c", f->include ? '+' : '-', ustr_cstr(f->glob), + (f->next != NULL) ? ':' : '>'); } break; case V_TRANSFORM: @@ -671,11 +658,11 @@ return 0; switch (v1->tag) { case V_STRING: - return STREQ(v1->string->str, v2->string->str); + return ustr_cmp_eq(v1->string, v2->string); break; case V_REGEXP: // FIXME: Should probably build FA's and compare them - return STREQ(v1->regexp->pattern->str, v2->regexp->pattern->str); + return ustr_cmp_eq(v1->regexp->pattern, v2->regexp->pattern); break; case V_LENS: return v1->lens == v2->lens; @@ -877,7 +864,7 @@ } if (vt->tag == T_STRING && t->tag == T_REGEXP) { struct value *rxp = make_value(V_REGEXP, ref(v->info)); - rxp->regexp = make_regexp_literal(v->info, v->string->str); + rxp->regexp = make_regexp_literal(v->info, ustr_cstr(v->string)); unref(v, value); unref(vt, type); return rxp; @@ -1161,7 +1148,7 @@ struct type *t = ctx_lookup_type(term->info, ctx, term->ident); if (t == NULL) { syntax_error(term->info, "Undefined variable %s", - term->ident->str); + ustr_cstr(term->ident)); result = 0; } else { term->type = ref(t); @@ -1263,9 +1250,9 @@ /* Check that the module name is consistent with the filename */ fname = module_basename(term->mname); - basenam = strrchr(term->info->filename->str, SEP); + basenam = strrchr(ustr_cstr(term->info->filename), SEP); if (basenam == NULL) - basenam = term->info->filename->str; + basenam = ustr_cstr(term->info->filename); else basenam += 1; if (STRNEQ(fname, basenam)) { @@ -1345,8 +1332,8 @@ if (re == NULL) { v = make_exn_value(ref(info), "Regular expression subtraction 'r1 - r2' failed"); - exn_printf_line(v, "r1: /%s/", re1->pattern->str); - exn_printf_line(v, "r2: /%s/", re2->pattern->str); + exn_printf_line(v, "r1: /%s/", ustr_cstr(re1->pattern)); + exn_printf_line(v, "r2: /%s/", ustr_cstr(re2->pattern)); } else { v = make_value(V_REGEXP, ref(info)); v->regexp = re; @@ -1378,7 +1365,7 @@ ref(info)); param->type = ref(exp->left->type); struct term *ident = make_term(A_IDENT, ref(info)); - ident->ident = ref(param->param->name); + ident->ident = ustr_dup(param->param->name); ident->type = ref(param->type); struct term *app = make_app_term(ref(exp->left), ident, ref(info)); app->type = ref(app->left->type->img); @@ -1415,14 +1402,8 @@ v1 = coerce(v1, t); v2 = coerce(v2, t); if (t->tag == T_STRING) { - const char *s1 = v1->string->str; - const char *s2 = v2->string->str; v = make_value(V_STRING, ref(info)); - make_ref(v->string); - CALLOC(v->string->str, strlen(s1) + strlen(s2) + 1); - char *s = v->string->str; - strcpy(s, s1); - strcat(s, s2); + v->string = ustr_sc_concat(v1->string, v2->string, USTR_NULL); } else if (t->tag == T_REGEXP) { v = make_value(V_REGEXP, ref(info)); v->regexp = regexp_concat(info, v1->regexp, v2->regexp); @@ -1438,8 +1419,8 @@ v->filter = ref(f1); } else { struct filter *cf1, *cf2; - cf1 = make_filter(ref(f1->glob), f1->include); - cf2 = make_filter(ref(f2->glob), f2->include); + cf1 = make_filter(ustr_dup(f1->glob), f1->include); + cf2 = make_filter(ustr_dup(f2->glob), f2->include); cf1->next = ref(f1->next); cf2->next = ref(f2->next); list_append(cf1, cf2); @@ -1711,8 +1692,7 @@ make_ref(info); info->first_line = info->last_line = line; info->first_column = info->last_column = 0; - make_ref(info->filename); - info->filename->str = strdup(fname); + info->filename = ustr_dup_cstr(fname); return info; } diff -r 3831dbdd6ae8 src/syntax.h --- a/src/syntax.h Thu Jun 12 16:05:12 2008 -0700 +++ b/src/syntax.h Fri Jun 13 12:35:50 2008 -0400 @@ -30,9 +30,19 @@ #include "ref.h" #include "fa.h" +#if 0 +struct string { + unsigned int ref; + char *str; +}; +#define Ustr struct string +#else +# include +#endif + struct info { unsigned int ref; - struct string *filename; + Ustr *filename; unsigned int first_line; unsigned int first_column; unsigned int last_line; @@ -104,7 +114,7 @@ }; struct value *value; /* A_VALUE */ struct term *brexp; /* A_BRACKET */ - struct string *ident; /* A_IDENT */ + Ustr *ident; /* A_IDENT */ struct { /* A_REP */ enum quant_tag quant; struct term *rexp; @@ -124,19 +134,14 @@ struct param { struct info *info; unsigned int ref; - struct string *name; + Ustr *name; struct type *type; -}; - -struct string { - unsigned int ref; - char *str; }; struct regexp { unsigned int ref; struct info *info; - struct string *pattern; + Ustr *pattern; struct re_pattern_buffer *re; }; @@ -147,7 +152,7 @@ /* Make a regexp with pattern PAT, which is not copied. Ownership * of INFO is taken. */ -struct regexp *make_regexp(struct info *info, char *pat); +struct regexp *make_regexp(struct info *info, Ustr *pat); /* Make a regexp that matches TEXT literally; the string TEXT * is not used by the returned rgexp and must be freed by the caller @@ -219,11 +224,11 @@ struct filter { unsigned int ref; struct filter *next; - struct string *glob; + Ustr *glob; unsigned int include : 1; }; -struct filter *make_filter(struct string *glb, unsigned int include); +struct filter *make_filter(Ustr *glb, unsigned int include); void free_filter(struct filter *filter); /* Transformers that actually run lenses on contents of files */ @@ -286,7 +291,7 @@ struct info *info; enum value_tag tag; union { - struct string *string; /* V_STRING */ + Ustr *string; /* V_STRING */ struct regexp *regexp; /* V_REGEXP */ struct lens *lens; /* V_LENS */ struct native *native; /* V_NATIVE */ @@ -326,7 +331,7 @@ struct binding { unsigned int ref; struct binding *next; - struct string *ident; + Ustr *ident; struct type *type; struct value *value; }; @@ -351,7 +356,7 @@ struct term *make_term(enum term_tag tag, struct info *info); struct term *make_param(char *name, struct type *type, struct info *info); struct value *make_value(enum value_tag tag, struct info *info); -struct string *make_string(char *str); +Ustr *make_string(char *str); struct term *make_app_term(struct term *func, struct term *arg, struct info *info); struct term *make_app_ident(char *id, struct term *func, struct info *info); @@ -377,7 +382,6 @@ /* Do not call these directly, use UNREF instead */ void free_info(struct info *info); -void free_string(struct string *string); void free_value(struct value *v); void free_module(struct module *module); diff -r 3831dbdd6ae8 src/transform.c --- a/src/transform.c Thu Jun 12 16:05:12 2008 -0700 +++ b/src/transform.c Fri Jun 13 12:35:50 2008 -0400 @@ -62,7 +62,7 @@ /* * Filters */ -struct filter *make_filter(struct string *glb, unsigned int include) { +struct filter *make_filter(Ustr *glb, unsigned int include) { struct filter *f; make_ref(f); f->glob = glb; @@ -75,7 +75,7 @@ return; assert(f->ref == 0); unref(f->next, filter); - unref(f->glob, string); + ustr_free(f->glob); free(f); } @@ -98,7 +98,7 @@ char *globpat = NULL; if (! f->include) continue; - pathjoin(&globpat, 2, root, f->glob->str); + pathjoin(&globpat, 2, root, ustr_cstr(f->glob)); r = glob(globpat, gl_flags, NULL, &globbuf); free(globpat); @@ -119,9 +119,9 @@ continue; for (int i=0; i < pathc;) { const char *path = pathv[i]; - if (strchr(e->glob->str, SEP) == NULL) + if (!ustr_srch_chr_fwd(e->glob, 0, SEP)) path = pathbase(path); - if (fnmatch(e->glob->str, path, fnm_flags) == 0) { + if (fnmatch(ustr_cstr(e->glob), path, fnm_flags) == 0) { free(pathv[i]); pathc -= 1; if (i < pathc) { @@ -148,12 +148,12 @@ int found = 0; list_for_each(f, filter) { if (f->include) - found |= (fnmatch(f->glob->str, path, fnm_flags) == 0); + found |= (fnmatch(ustr_cstr(f->glob), path, fnm_flags) == 0); } if (! found) return 0; list_for_each(f, filter) { - if (!f->include && (fnmatch(f->glob->str, path, fnm_flags) == 0)) + if (!f->include && (fnmatch(ustr_cstr(f->glob), path, fnm_flags) == 0)) return 0; } return 1; @@ -328,13 +328,12 @@ struct info *info; make_ref(info); - make_ref(info->filename); - info->filename->str = filename; + info->filename = ustr_dup_cstr(filename); info->first_line = 1; tree = lns_get(info, lens, text, &err); - info->filename->str = NULL; + ustr_sc_free(&info->filename); unref(info, info); if (err != NULL) { diff -r 3831dbdd6ae8 tests/fatest.c --- a/tests/fatest.c Thu Jun 12 16:05:12 2008 -0700 +++ b/tests/fatest.c Fri Jun 13 12:35:50 2008 -0400 @@ -70,7 +70,7 @@ } static void assertAsRegexp(CuTest *tc, fa_t fa) { - char *re; + Ustr *re; fa_t fa1, fa2; fa_t empty = mark(fa_make_basic(FA_EPSILON)); int r; @@ -84,13 +84,13 @@ r = fa_as_regexp(fa1, &re); CuAssertIntEquals(tc, 0, r); - r = fa_compile(re, &fa2); + r = fa_compile(ustr_cstr(re), &fa2); CuAssertIntEquals(tc, REG_NOERROR, r); CuAssertTrue(tc, fa_equals(fa, fa2)); fa_free(fa2); - free(re); + ustr_free(re); } static fa_t make_fa(CuTest *tc, const char *regexp, int exp_err) { @@ -374,7 +374,7 @@ } static void assertFaAsRegexp(CuTest *tc, const char *regexp) { - char *re; + Ustr *re; fa_t fa1 = make_good_fa(tc, regexp); fa_t fa2; int r; @@ -382,13 +382,13 @@ r = fa_as_regexp(fa1, &re); CuAssertIntEquals(tc, 0, r); - r = fa_compile(re, &fa2); + r = fa_compile(ustr_cstr(re), &fa2); CuAssertIntEquals(tc, REG_NOERROR, r); CuAssert(tc, regexp, fa_equals(fa1, fa2)); fa_free(fa2); - free(re); + ustr_free(re); } static void testAsRegexp(CuTest *tc) { @@ -404,16 +404,16 @@ fa_t fa1 = make_good_fa(tc, "[A-Za-z]+"); fa_t fa2 = make_good_fa(tc, "Deny(Users|Groups|Other)"); fa_t fa = mark(fa_minus(fa1, fa2)); - char *re; + Ustr *re; int r; r = fa_as_regexp(fa, &re); CuAssertIntEquals(tc, 0, r); - fa_t far = make_good_fa(tc, re); + fa_t far = make_good_fa(tc, ustr_cstr(re)); CuAssertTrue(tc, fa_equals(fa, far)); - free(re); + ustr_free(re); } int main(int argc, char **argv) { @@ -453,11 +453,11 @@ char *s = fa_example(fa); printf("Example for %s: %s\n", argv[i], s); free(s); - char *re; + Ustr *re; r = fa_as_regexp(fa, &re); if (r == 0) { - printf("/%s/ = /%s/\n", argv[i], re); - free(re); + printf("/%s/ = /%s/\n", argv[i], ustr_cstr(re)); + ustr_free(re); } else { printf("/%s/ = ***\n", argv[i]); }