Mercurial > hg > index.cgi
changeset 308:670ea8f90212 ccdev
Converted preproc logic to library and moved some utility stuff to lwlib
The strbuf and strpool stuff is generally useful so move it to lwlib where
other such things live.
Also, package the preprocessor logic into a library for easy use in multiple
places.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sat, 21 Sep 2013 13:33:54 -0600 |
parents | 9e342c4e4b66 |
children | 65ed8dde5331 |
files | Makefile lwcc/cpp.c lwcc/cpp.h lwcc/lex.c lwcc/preproc.c lwcc/strbuf.c lwcc/strbuf.h lwcc/strpool.c lwcc/strpool.h lwlib/lw_strbuf.c lwlib/lw_strbuf.h lwlib/lw_strpool.c lwlib/lw_strpool.h |
diffstat | 13 files changed, 322 insertions(+), 279 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Sat Sep 21 12:27:48 2013 -0600 +++ b/Makefile Sat Sep 21 13:33:54 2013 -0600 @@ -69,7 +69,8 @@ lwar_srcs := $(addprefix lwar/,$(lwar_srcs)) lwlib_srcs := lw_alloc.c lw_realloc.c lw_free.c lw_error.c lw_expr.c \ - lw_stack.c lw_string.c lw_stringlist.c lw_cmdline.c + lw_stack.c lw_string.c lw_stringlist.c lw_cmdline.c lw_strbuf.c \ + lw_strpool.c lwlib_srcs := $(addprefix lwlib/,$(lwlib_srcs)) lwlink_srcs := main.c lwlink.c readfiles.c expr.c script.c link.c output.c map.c @@ -101,12 +102,17 @@ lwcc_driver_objs := $(lwcc_driver_srcs:.c=.o) lwcc_driver_deps := $(lwcc_driver_srcs:.c=.d) -lwcc_cpp_srcs := cpp-main.c cpp.c lex.c strbuf.c token.c preproc.c symbol.c strpool.c +lwcc_cpp_srcs := cpp-main.c lwcc_cpp_srcs := $(addprefix lwcc/,$(lwcc_cpp_srcs)) lwcc_cpp_objs := $(lwcc_cpp_srcs:.c=.o) lwcc_cpp_deps := $(lwcc_cpp_srcs:.c=.d) -lwcc_deps := $(lwcc_cpp_deps) $(lwcc_driver_deps) +lwcc_cpplib_srcs := cpp.c lex.c token.c preproc.c symbol.c +lwcc_cpplib_srcs := $(addprefix lwcc/,$(lwcc_cpplib_srcs)) +lwcc_cpplib_objs := $(lwcc_cpplib_srcs:.c=.o) +lwcc_cpplib_deps := $(lwcc_cpplib_srcs:.c=.d) + +lwcc_deps := $(lwcc_cpp_deps) $(lwcc_driver_deps) $(lwcc_cpplib_deps) .PHONY: lwlink lwasm lwar lwobjdump lwcc lwlink: lwlink/lwlink$(PROGSUFFIX) @@ -115,6 +121,7 @@ lwobjdump: lwlink/lwobjdump$(PROGSUFFIX) lwcc: lwcc/lwcc$(PROGSUFFIX) lwcc-cpp: lwcc/lwcc-cpp$(PROGSUFFIX) +lwcc-cpplib: lwcc/libcpp.a lwasm/lwasm$(PROGSUFFIX): $(lwasm_objs) lwlib @echo Linking $@ @@ -136,9 +143,16 @@ @echo Linking $@ @$(CC) -o $@ $(lwcc_driver_objs) $(LDFLAGS) -lwcc/lwcc-cpp$(PROGSUFFIX): $(lwcc_cpp_objs) lwlib +lwcc/lwcc-cpp$(PROGSUFFIX): $(lwcc_cpp_objs) lwlib lwcc-cpplib @echo Linking $@ - @$(CC) -o $@ $(lwcc_cpp_objs) $(LDFLAGS) + @$(CC) -o $@ $(lwcc_cpp_objs) lwcc/libcpp.a $(LDFLAGS) + +.INTERMEDIATE: lwcc-cpplib +lwcc-cpplib: lwcc/libcpp.a +lwcc/libcpp.a: $(lwcc_cpplib_objs) + @echo Linking $@ + @$(AR) rc $@ $(lwcc_cpplib_objs) + @$(RANLIB) $@ #.PHONY: lwlib .INTERMEDIATE: lwlib @@ -170,8 +184,8 @@ clean: $(cleantargs) @echo "Cleaning up" @rm -f lwlib/liblw.a lwasm/lwasm$(PROGSUFFIX) lwlink/lwlink$(PROGSUFFIX) lwlink/lwobjdump$(PROGSUFFIX) lwar/lwar$(PROGSUFFIX) - @rm -f lwcc/lwcc$(PROGSUFFIX) lwcc/lwcc-cpp$(PROGSUFFIX) - @rm -f $(lwcc_driver_ojbs) $(lwcc_cpp_objs) + @rm -f lwcc/lwcc$(PROGSUFFIX) lwcc/lwcc-cpp$(PROGSUFFIX) lwcc/libcpp.a + @rm -f $(lwcc_driver_objs) $(lwcc_cpp_objs) $(lwcc_cpplib_objs) @rm -f $(lwasm_objs) $(lwlink_objs) $(lwar_objs) $(lwlib_objs) $(lwobjdump_objs) @rm -f $(extra_clean) @rm -f */*.exe @@ -180,7 +194,7 @@ realclean: clean $(realcleantargs) @echo "Cleaning up even more" @rm -f $(lwasm_deps) $(lwlink_deps) $(lwar_deps) $(lwlib_deps) $(lwobjdump_deps) - @rm -f $(lwcc_driver_deps) $(lwcc_cpp_deps) + @rm -f $(lwcc_driver_deps) $(lwcc_cpp_deps) $(lwcc_cpplib_deps) @rm -f docs/manual/*.html docs/manual/*.pdf print-%:
--- a/lwcc/cpp.c Sat Sep 21 12:27:48 2013 -0600 +++ b/lwcc/cpp.c Sat Sep 21 13:33:54 2013 -0600 @@ -27,9 +27,9 @@ #include <lw_alloc.h> #include <lw_string.h> #include <lw_stringlist.h> - +#include <lw_strpool.h> #include "cpp.h" -#include "strpool.h" + struct token *preproc_lex_next_token(struct preproc_info *); @@ -51,8 +51,8 @@ pp = lw_alloc(sizeof(struct preproc_info)); memset(pp, 0, sizeof(struct preproc_info)); - pp -> strpool = strpool_create(); - pp -> fn = strpool_strdup(pp -> strpool, fn); + pp -> strpool = lw_strpool_create(); + pp -> fn = lw_strpool_strdup(pp -> strpool, fn); pp -> fp = fp; pp -> ra = CPP_NOUNG; pp -> unget = CPP_NOUNG; @@ -138,7 +138,7 @@ preproc_next_token(pp); token_free(pp -> curtok); } - strpool_free(pp -> strpool); + lw_strpool_free(pp -> strpool); lw_free(pp); }
--- a/lwcc/cpp.h Sat Sep 21 12:27:48 2013 -0600 +++ b/lwcc/cpp.h Sat Sep 21 13:33:54 2013 -0600 @@ -69,7 +69,7 @@ int lexstrloc; // ditto struct preproc_info *n; // next in file stack struct preproc_info *filestack; // stack of saved files during include - struct strpool *strpool; + struct lw_strpool *strpool; lw_stringlist_t quotelist; lw_stringlist_t inclist; };
--- a/lwcc/lex.c Sat Sep 21 12:27:48 2013 -0600 +++ b/lwcc/lex.c Sat Sep 21 13:33:54 2013 -0600 @@ -23,9 +23,9 @@ #include <stdio.h> #include <lw_alloc.h> +#include <lw_strbuf.h> #include "cpp.h" -#include "strbuf.h" #include "token.h" /* fetch a raw input byte from the current file. Will return CPP_EOF if @@ -360,7 +360,7 @@ int ttype = TOK_NONE; int c, c2; int cl; - struct strbuf *strbuf; + struct lw_strbuf *strbuf; struct token *t = NULL; struct preproc_info *fs; @@ -616,7 +616,7 @@ /* character constant - turns into a uint */ chrlit: cl = 0; - strbuf = strbuf_new(); + strbuf = lw_strbuf_new(); for (;;) { c = preproc_lex_fetch_byte(pp); @@ -625,23 +625,23 @@ cl++; if (c == '\\') { - strbuf_add(strbuf, '\\'); + lw_strbuf_add(strbuf, '\\'); c = preproc_lex_fetch_byte(pp); if (c == CPP_EOF || c == CPP_EOL) { if (!pp -> lexstr) preproc_throw_error(pp, "Invalid character constant"); ttype = TOK_ERROR; - strval = strbuf_end(strbuf); + strval = lw_strbuf_end(strbuf); goto out; } cl++; - strbuf_add(strbuf, c); + lw_strbuf_add(strbuf, c); continue; } - strbuf_add(strbuf, c); + lw_strbuf_add(strbuf, c); } - strval = strbuf_end(strbuf); + strval = lw_strbuf_end(strbuf); if (cl == 0) { ttype = TOK_ERROR; @@ -655,15 +655,15 @@ case '"': strlit: /* string literal */ - strbuf = strbuf_new(); - strbuf_add(strbuf, '"'); + strbuf = lw_strbuf_new(); + lw_strbuf_add(strbuf, '"'); for (;;) { c = preproc_lex_fetch_byte(pp); if (c == CPP_EOF || c == CPP_EOL) { ttype = TOK_ERROR; - strval = strbuf_end(strbuf); + strval = lw_strbuf_end(strbuf); if (!pp -> lexstr) preproc_throw_error(pp, "Invalid string constant"); goto out; @@ -672,24 +672,24 @@ break; if (c == '\\') { - strbuf_add(strbuf, '\\'); + lw_strbuf_add(strbuf, '\\'); c = preproc_lex_fetch_byte(pp); if (c == CPP_EOF || c == CPP_EOL) { ttype = TOK_ERROR; if (!pp -> lexstr) preproc_throw_error(pp, "Invalid string constant"); - strval = strbuf_end(strbuf); + strval = lw_strbuf_end(strbuf); goto out; } cl++; - strbuf_add(strbuf, c); + lw_strbuf_add(strbuf, c); continue; } - strbuf_add(strbuf, c); + lw_strbuf_add(strbuf, c); } - strbuf_add(strbuf, '"'); - strval = strbuf_end(strbuf); + lw_strbuf_add(strbuf, '"'); + strval = lw_strbuf_end(strbuf); ttype = TOK_STR_LIT; goto out; @@ -718,20 +718,20 @@ case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': /* we have an identifier here */ - strbuf = strbuf_new(); - strbuf_add(strbuf, c); + strbuf = lw_strbuf_new(); + lw_strbuf_add(strbuf, c); for (;;) { c = preproc_lex_fetch_byte(pp); if ((c == '_') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { - strbuf_add(strbuf, c); + lw_strbuf_add(strbuf, c); continue; } else { - strbuf_add(strbuf, 0); - strval = strbuf_end(strbuf); + lw_strbuf_add(strbuf, 0); + strval = lw_strbuf_end(strbuf); break; } } @@ -743,8 +743,8 @@ c = preproc_lex_fetch_byte(pp); if (c >= '0' && c <= '9') { - strbuf = strbuf_new(); - strbuf_add(strbuf, '.'); + strbuf = lw_strbuf_new(); + lw_strbuf_add(strbuf, '.'); goto numlit; } else if (c == '.') @@ -763,28 +763,28 @@ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - strbuf = strbuf_new(); + strbuf = lw_strbuf_new(); numlit: ttype = TOK_NUMBER; - strbuf_add(strbuf, c); + lw_strbuf_add(strbuf, c); for (;;) { c = preproc_lex_fetch_byte(pp); if (!((c == '_') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) break; - strbuf_add(strbuf, c); + lw_strbuf_add(strbuf, c); if (c == 'e' || c == 'E' || c == 'p' || c == 'P') { c = preproc_lex_fetch_byte(pp); if (c == '+' || c == '-') { - strbuf_add(strbuf, c); + lw_strbuf_add(strbuf, c); continue; } preproc_lex_unfetch_byte(pp, c); } } - strval = strbuf_end(strbuf); + strval = lw_strbuf_end(strbuf); preproc_lex_unfetch_byte(pp, c); goto out;
--- a/lwcc/preproc.c Sat Sep 21 12:27:48 2013 -0600 +++ b/lwcc/preproc.c Sat Sep 21 13:33:54 2013 -0600 @@ -27,10 +27,10 @@ #include <lw_alloc.h> #include <lw_string.h> +#include <lw_strbuf.h> +#include <lw_strpool.h> #include "cpp.h" -#include "strbuf.h" -#include "strpool.h" #include "symbol.h" #include "token.h" @@ -38,6 +38,8 @@ static void process_directive(struct preproc_info *); static long eval_expr(struct preproc_info *); extern struct token *preproc_lex_next_token(struct preproc_info *); +static long preproc_numval(struct preproc_info *, struct token *); +static int eval_escape(char **); struct token *preproc_next_processed_token(struct preproc_info *pp) @@ -424,11 +426,11 @@ char *streol(struct preproc_info *pp) { - struct strbuf *s; + struct lw_strbuf *s; struct token *ct; int i; - s = strbuf_new(); + s = lw_strbuf_new(); do { ct = preproc_next_token(pp); @@ -437,10 +439,10 @@ while (ct -> ttype != TOK_EOL) { for (i = 0; ct -> strval[i]; i++) - strbuf_add(s, ct -> strval[i]); + lw_strbuf_add(s, ct -> strval[i]); ct = preproc_next_token(pp); } - return strbuf_end(s); + return lw_strbuf_end(s); } static void dir_error(struct preproc_info *pp) @@ -544,7 +546,7 @@ struct token *ct; int sys = 0; char *fn; - struct strbuf *strbuf; + struct lw_strbuf *strbuf; int i; struct preproc_info *fs; @@ -561,7 +563,7 @@ } else if (ct -> ttype == TOK_LT) { - strbuf = strbuf_new(); + strbuf = lw_strbuf_new(); for (;;) { int c; @@ -570,23 +572,23 @@ { preproc_lex_unfetch_byte(pp, c); preproc_throw_error(pp, "Bad #include"); - lw_free(strbuf_end(strbuf)); + lw_free(lw_strbuf_end(strbuf)); break; } if (c == '>') break; - strbuf_add(strbuf, c); + lw_strbuf_add(strbuf, c); } ct = preproc_next_token_nws(pp); if (ct -> ttype != TOK_EOL) { preproc_throw_error(pp, "Bad #include"); skip_eol(pp); - lw_free(strbuf_end(strbuf)); + lw_free(lw_strbuf_end(strbuf)); return; } sys = 1; - fn = strbuf_end(strbuf); + fn = lw_strbuf_end(strbuf); goto doinc; } else @@ -598,7 +600,7 @@ goto usrinc; else if (ct -> ttype == TOK_LT) { - strbuf = strbuf_new(); + strbuf = lw_strbuf_new(); for (;;) { ct = preproc_next_processed_token(pp); @@ -607,12 +609,12 @@ if (ct -> ttype == TOK_EOL) { preproc_throw_error(pp, "Bad #include"); - lw_free(strbuf_end(strbuf)); + lw_free(lw_strbuf_end(strbuf)); return; } for (i = 0; ct -> strval[i]; ct++) { - strbuf_add(strbuf, ct -> strval[i]); + lw_strbuf_add(strbuf, ct -> strval[i]); } } ct = preproc_next_processed_token_nws(pp); @@ -620,11 +622,11 @@ { preproc_throw_error(pp, "Bad #include"); skip_eol(pp); - lw_free(strbuf_end(strbuf)); + lw_free(lw_strbuf_end(strbuf)); return; } sys = 1; - fn = strbuf_end(strbuf); + fn = lw_strbuf_end(strbuf); goto doinc; } else @@ -653,7 +655,7 @@ fs -> n = pp -> filestack; pp -> curtok = NULL; pp -> filestack = fs; - pp -> fn = strpool_strdup(pp -> strpool, fn); + pp -> fn = lw_strpool_strdup(pp -> strpool, fn); lw_free(fn); pp -> fp = fp; pp -> ra = CPP_NOUNG; @@ -770,6 +772,36 @@ if (ct -> ttype == TOK_EOL) return; + if (ct -> ttype == TOK_NUMBER) + { + // this is probably a file marker from a previous run of the preprocessor + char *fn; + struct lw_strbuf *sb; + + i = preproc_numval(pp, ct); + ct = preproc_next_token_nws(pp); + if (ct -> ttype != TOK_STR_LIT) + goto baddir; + pp -> lineno = i; + sb = lw_strbuf_new(); + for (fn = ct -> strval; *fn && *fn != '"'; ) + { + if (*fn == '\\') + { + lw_strbuf_add(sb, eval_escape(&fn)); + } + else + { + lw_strbuf_add(sb, *fn++); + } + } + fn = lw_strbuf_end(sb); + pp -> fn = lw_strpool_strdup(pp -> strpool, fn); + lw_free(fn); + skip_eol(pp); + return; + } + if (ct -> ttype != TOK_IDENT) goto baddir; @@ -800,7 +832,6 @@ } static long eval_expr_real(struct preproc_info *, int); -static long preproc_numval(struct preproc_info *, struct token *); static long eval_term_real(struct preproc_info *pp) { @@ -1165,12 +1196,12 @@ */ static char *stringify(struct token_list *tli) { - struct strbuf *s; + struct lw_strbuf *s; int ws = 0; struct token *tl = tli -> head; - s = strbuf_new(); - strbuf_add(s, '"'); + s = lw_strbuf_new(); + lw_strbuf_add(s, '"'); while (tl && tl -> ttype == TOK_WSPACE) tl = tl -> next; @@ -1184,21 +1215,21 @@ } if (ws) { - strbuf_add(s, ' '); + lw_strbuf_add(s, ' '); } for (ws = 0; tl -> strval[ws]; ws++) { if (tl -> ttype == TOK_STR_LIT || tl -> ttype == TOK_CHR_LIT) { if (tl -> strval[ws] == '"' || tl -> strval[ws] == '\\') - strbuf_add(s, '\\'); + lw_strbuf_add(s, '\\'); } } ws = 0; } - strbuf_add(s, '"'); - return strbuf_end(s); + lw_strbuf_add(s, '"'); + return lw_strbuf_end(s); } static int macro_arg(struct symtab_e *s, char *str) @@ -1339,26 +1370,26 @@ // check for built in macros if (strcmp(mname, "__FILE__") == 0) { - struct strbuf *sb; + struct lw_strbuf *sb; - sb = strbuf_new(); - strbuf_add(sb, '"'); + sb = lw_strbuf_new(); + lw_strbuf_add(sb, '"'); for (tstr = (char *)(pp -> fn); *tstr; tstr++) { if (*tstr == 32 || (*tstr > 34 && *tstr < 127)) { - strbuf_add(sb, *tstr); + lw_strbuf_add(sb, *tstr); } else { - strbuf_add(sb, '\\'); - strbuf_add(sb, (*tstr >> 6) + '0'); - strbuf_add(sb, ((*tstr >> 3) & 7) + '0'); - strbuf_add(sb, (*tstr & 7) + '0'); + lw_strbuf_add(sb, '\\'); + lw_strbuf_add(sb, (*tstr >> 6) + '0'); + lw_strbuf_add(sb, ((*tstr >> 3) & 7) + '0'); + lw_strbuf_add(sb, (*tstr & 7) + '0'); } } - strbuf_add(sb, '"'); - tstr = strbuf_end(sb); + lw_strbuf_add(sb, '"'); + tstr = lw_strbuf_end(sb); preproc_unget_token(pp, token_create(TOK_STR_LIT, tstr, pp -> lineno, pp -> column, pp -> fn)); lw_free(tstr); return 1;
--- a/lwcc/strbuf.c Sat Sep 21 12:27:48 2013 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* -lwcc/strbuf.c - -Copyright © 2013 William Astle - -This file is part of LWTOOLS. - -LWTOOLS is free software: you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <stdlib.h> - -#include <lw_alloc.h> - -#include "strbuf.h" - -struct strbuf *strbuf_new(void) -{ - struct strbuf *strbuf; - - strbuf = lw_alloc(sizeof(struct strbuf)); - strbuf -> str = NULL; - strbuf -> bo = 0; - strbuf -> bl = 0; - return strbuf; -} - -void strbuf_add(struct strbuf *strbuf, int c) -{ - if (strbuf -> bo >= strbuf -> bl) - { - strbuf -> bl += 100; - strbuf -> str = lw_realloc(strbuf -> str, strbuf -> bl); - } - strbuf -> str[strbuf -> bo++] = c; -} - -char *strbuf_end(struct strbuf *strbuf) -{ - char *rv; - - strbuf_add(strbuf, 0); - rv = strbuf -> str; - lw_free(strbuf); - return rv; -}
--- a/lwcc/strbuf.h Sat Sep 21 12:27:48 2013 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* -lwcc/strbuf.h - -Copyright © 2013 William Astle - -This file is part of LWTOOLS. - -LWTOOLS is free software: you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef strbuf_h_seen___ -#define strbuf_h_seen___ - -struct strbuf -{ - char *str; - int bl; - int bo; -}; - -extern struct strbuf *strbuf_new(void); -extern void strbuf_add(struct strbuf *, int); -extern char *strbuf_end(struct strbuf *); - -#endif // strbufh_seen___
--- a/lwcc/strpool.c Sat Sep 21 12:27:48 2013 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* -lwcc/strpool.c - -Copyright © 2013 William Astle - -This file is part of LWTOOLS. - -LWTOOLS is free software: you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <stdlib.h> -#include <string.h> - -#include <lw_alloc.h> -#include <lw_string.h> - -#include "strpool.h" - -struct strpool *strpool_create(void) -{ - struct strpool *sp; - - sp = lw_alloc(sizeof(struct strpool)); - sp -> nstrs = 0; - sp -> strs = NULL; - return sp; -} - -extern void strpool_free(struct strpool *sp) -{ - int i; - - for (i = 0; i < sp -> nstrs; i++) - lw_free(sp -> strs[i]); - lw_free(sp -> strs); - lw_free(sp); -} - -char *strpool_strdup(struct strpool *sp, const char *s) -{ - int i; - - if (!s) - return NULL; - - /* first do a fast scan for a pointer match */ - for (i = 0; i < sp -> nstrs; i++) - if (sp -> strs[i] == s) - return sp -> strs[i]; - - /* no match - do a slow scan for a string match */ - for (i = 0; i < sp -> nstrs; i++) - if (strcmp(sp -> strs[i], s) == 0) - return sp -> strs[i]; - - /* no match - create a new string entry */ - sp -> strs = lw_realloc(sp -> strs, sizeof(char *) * (sp -> nstrs + 1)); - sp -> strs[sp -> nstrs] = lw_strdup(s); - sp -> nstrs++; - return sp -> strs[sp -> nstrs - 1]; -}
--- a/lwcc/strpool.h Sat Sep 21 12:27:48 2013 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* -lwcc/strpool.h - -Copyright © 2013 William Astle - -This file is part of LWTOOLS. - -LWTOOLS is free software: you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef strpool_h_seen___ -#define strpool_h_seen___ - -struct strpool -{ - int nstrs; - char **strs; -}; - -extern struct strpool *strpool_create(void); -extern void strpool_free(struct strpool *); -extern char *strpool_strdup(struct strpool *, const char *); - -#endif // strpool.h_seen___
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwlib/lw_strbuf.c Sat Sep 21 13:33:54 2013 -0600 @@ -0,0 +1,56 @@ +/* +lwlib/lw_strbuf.c + +Copyright © 2013 William Astle + +This file is part of LWTOOLS. + +LWTOOLS is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> + +#include "lw_alloc.h" +#include "lw_strbuf.h" + +struct lw_strbuf *lw_strbuf_new(void) +{ + struct lw_strbuf *lw_strbuf; + + lw_strbuf = lw_alloc(sizeof(struct lw_strbuf)); + lw_strbuf -> str = NULL; + lw_strbuf -> bo = 0; + lw_strbuf -> bl = 0; + return lw_strbuf; +} + +void lw_strbuf_add(struct lw_strbuf *lw_strbuf, int c) +{ + if (lw_strbuf -> bo >= lw_strbuf -> bl) + { + lw_strbuf -> bl += 100; + lw_strbuf -> str = lw_realloc(lw_strbuf -> str, lw_strbuf -> bl); + } + lw_strbuf -> str[lw_strbuf -> bo++] = c; +} + +char *lw_strbuf_end(struct lw_strbuf *lw_strbuf) +{ + char *rv; + + lw_strbuf_add(lw_strbuf, 0); + rv = lw_strbuf -> str; + lw_free(lw_strbuf); + return rv; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwlib/lw_strbuf.h Sat Sep 21 13:33:54 2013 -0600 @@ -0,0 +1,36 @@ +/* +lwlib/lw_strbuf.h + +Copyright © 2013 William Astle + +This file is part of LWTOOLS. + +LWTOOLS is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef ___lw_strbuf_h_seen___ +#define ___lw_strbuf_h_seen___ + +struct lw_strbuf +{ + char *str; + int bl; + int bo; +}; + +extern struct lw_strbuf *lw_strbuf_new(void); +extern void lw_strbuf_add(struct lw_strbuf *, int); +extern char *lw_strbuf_end(struct lw_strbuf *); + +#endif // ___lw_strbuf_h_seen___
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwlib/lw_strpool.c Sat Sep 21 13:33:54 2013 -0600 @@ -0,0 +1,71 @@ +/* +lwlib/lw_strpool.c + +Copyright © 2013 William Astle + +This file is part of LWTOOLS. + +LWTOOLS is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <string.h> + +#include "lw_alloc.h" +#include "lw_string.h" +#include "lw_strpool.h" + +struct lw_strpool *lw_strpool_create(void) +{ + struct lw_strpool *sp; + + sp = lw_alloc(sizeof(struct lw_strpool)); + sp -> nstrs = 0; + sp -> strs = NULL; + return sp; +} + +extern void lw_strpool_free(struct lw_strpool *sp) +{ + int i; + + for (i = 0; i < sp -> nstrs; i++) + lw_free(sp -> strs[i]); + lw_free(sp -> strs); + lw_free(sp); +} + +char *lw_strpool_strdup(struct lw_strpool *sp, const char *s) +{ + int i; + + if (!s) + return NULL; + + /* first do a fast scan for a pointer match */ + for (i = 0; i < sp -> nstrs; i++) + if (sp -> strs[i] == s) + return sp -> strs[i]; + + /* no match - do a slow scan for a string match */ + for (i = 0; i < sp -> nstrs; i++) + if (strcmp(sp -> strs[i], s) == 0) + return sp -> strs[i]; + + /* no match - create a new string entry */ + sp -> strs = lw_realloc(sp -> strs, sizeof(char *) * (sp -> nstrs + 1)); + sp -> strs[sp -> nstrs] = lw_strdup(s); + sp -> nstrs++; + return sp -> strs[sp -> nstrs - 1]; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwlib/lw_strpool.h Sat Sep 21 13:33:54 2013 -0600 @@ -0,0 +1,35 @@ +/* +lwlib/lw_strpool.h + +Copyright © 2013 William Astle + +This file is part of LWTOOLS. + +LWTOOLS is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef ___lw_strpool_h_seen___ +#define ___lw_strpool_h_seen___ + +struct lw_strpool +{ + int nstrs; + char **strs; +}; + +extern struct lw_strpool *lw_strpool_create(void); +extern void lw_strpool_free(struct lw_strpool *); +extern char *lw_strpool_strdup(struct lw_strpool *, const char *); + +#endif // ___lw_strpool_h_seen____