diff --git a/src/chaos.c b/src/chaos.c index 615113656..925545369 100644 --- a/src/chaos.c +++ b/src/chaos.c @@ -54,6 +54,7 @@ static const terrain_type *chaosterrain(void) } if (numtypes > 0) { types = malloc(sizeof(terrain_type *) * numtypes); + if (!types) abort(); numtypes = 0; for (terrain = terrains(); terrain != NULL; terrain = terrain->next) { if ((terrain->flags & LAND_REGION) && terrain->herbs) { diff --git a/src/creport.c b/src/creport.c index 3ac9dffe9..71c283e89 100644 --- a/src/creport.c +++ b/src/creport.c @@ -17,9 +17,12 @@ without prior permission by the authors of Eressea. /* tweakable features */ #define RENDER_CRMESSAGES -#define BUFFERSIZE 32768 #define RESOURCECOMPAT +#define BUFFERSIZE 32768 +/* riesig, wegen spionage-messages :-( */ +static char g_bigbuf[BUFFERSIZE]; + #include /* modules include */ @@ -132,9 +135,12 @@ static const char *translate(const char *key, const char *value) t = junkyard; junkyard = junkyard->next; } - else + else { t = malloc(sizeof(translation)); + if (!t) abort(); + } t->key = str_strdup(key); + if (!t->key) abort(); t->value = value; t->next = translation_table[kk]; translation_table[kk] = t; @@ -264,13 +270,12 @@ cr_output_curses(struct stream *out, const faction * viewer, const void *obj, ob msg = msg_curse(c, obj, typ, self); if (msg) { - char buf[BUFFERSIZE]; if (!header) { header = 1; stream_printf(out, "EFFECTS\n"); } - nr_render(msg, viewer->locale, buf, sizeof(buf), viewer); - stream_printf(out, "\"%s\"\n", buf); + nr_render(msg, viewer->locale, g_bigbuf, sizeof(g_bigbuf), viewer); + stream_printf(out, "\"%s\"\n", g_bigbuf); msg_release(msg); } a = a->next; @@ -571,28 +576,26 @@ static void render_messages(FILE * F, faction * f, message_list * msgs) { struct mlist *m = msgs->begin; while (m) { - char crbuffer[BUFFERSIZE]; /* gross, wegen spionage-messages :-( */ bool printed = false; const struct message_type *mtype = m->msg->type; unsigned int hash = mtype->key; #ifdef RENDER_CRMESSAGES - char nrbuffer[1024 * 32]; - nrbuffer[0] = '\0'; - if (nr_render(m->msg, f->locale, nrbuffer, sizeof(nrbuffer), f) > 0) { + g_bigbuf[0] = '\0'; + if (nr_render(m->msg, f->locale, g_bigbuf, sizeof(g_bigbuf), f) > 0) { fprintf(F, "MESSAGE %d\n", message_id(m->msg)); fprintf(F, "%u;type\n", hash); - fwritestr(F, nrbuffer); + fwritestr(F, g_bigbuf); fputs(";rendered\n", F); printed = true; } #endif - crbuffer[0] = '\0'; - if (cr_render(m->msg, crbuffer, (const void *)f) == 0) { - if (crbuffer[0]) { + g_bigbuf[0] = '\0'; + if (cr_render(m->msg, g_bigbuf, (const void *)f) == 0) { + if (g_bigbuf[0]) { if (!printed) { fprintf(F, "MESSAGE %d\n", message_id(m->msg)); } - fputs(crbuffer, F); + fputs(g_bigbuf, F); } } else { @@ -605,6 +608,7 @@ static void render_messages(FILE * F, faction * f, message_list * msgs) kmt = kmt->nexthash; if (kmt == NULL) { kmt = (struct known_mtype *)malloc(sizeof(struct known_mtype)); + if (!kmt) abort(); kmt->nexthash = mtypehash[ihash]; kmt->mtype = mtype; mtypehash[ihash] = kmt; @@ -1218,7 +1222,7 @@ cr_borders(const region * r, const faction * f, seen_mode mode, FILE * F) void cr_output_resources(stream *out, const faction * f, const region *r, bool see_unit) { - char cbuf[BUFFERSIZE], *pos = cbuf; + char *pos = g_bigbuf; resource_report result[MAX_RAWMATERIALS]; int n, size = report_resources(r, result, MAX_RAWMATERIALS, f, see_unit); @@ -1251,8 +1255,8 @@ void cr_output_resources(stream *out, const faction * f, const region *r, bool s result[n].level); } } - if (pos != cbuf) { - swrite(cbuf, 1, pos - cbuf, out); + if (pos != g_bigbuf) { + swrite(g_bigbuf, 1, pos - g_bigbuf, out); } } diff --git a/src/kernel/config.h b/src/kernel/config.h index 95df10ae9..7789cd36d 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -31,8 +31,8 @@ extern "C" { struct param; struct _dictionary_; -#define DISPLAYSIZE 8192 /* max. L�nge einer Beschreibung, incl trailing 0 */ -#define ORDERSIZE (DISPLAYSIZE*2) /* max. length of an order */ +#define DISPLAYSIZE 4096 /* max. L�nge einer Beschreibung, incl trailing 0 */ +#define ORDERSIZE 4096 /* max. length of an order */ #define NAMESIZE 128 /* max. L�nge eines Namens, incl trailing 0 */ #define IDSIZE 16 /* max. L�nge einer no (als String), incl trailing 0 */ #define OBJECTIDSIZE (NAMESIZE+5+IDSIZE) /* max. L�nge der Strings, die diff --git a/src/report.c b/src/report.c index 04e5408ad..11146a8d5 100644 --- a/src/report.c +++ b/src/report.c @@ -1521,29 +1521,78 @@ static int count_allies_cb(struct allies *all, faction *af, int status, void *ud struct show_s { sbstring sbs; + stream *out; const faction *f; int num_allies; + int num_listed; + size_t maxlen; }; +void pump_paragraph(sbstring *sbp, stream *out, size_t maxlen, bool isfinal) +{ + while (sbs_length(sbp) > maxlen) { + char *pos, *begin = sbp->begin; + while (*begin && isspace(*begin)) { + /* eat whitespace */ + ++begin; + } + pos = begin; + while (pos) { + char *next = strchr(pos+1, ' '); + if (next == NULL) { + if (isfinal) { + swrite(begin, 1, sbp->end - begin, out); + newline(out); + } + return; + } + else if (next > begin + maxlen) { + size_t len = pos - begin; + swrite(begin, 1, len, out); + newline(out); + + while (*pos && isspace(*pos)) { + ++pos; + ++len; + } + assert(len <= INT_MAX); + sbs_cut(sbp, (int)len); + break; + } + pos = next; + } + } + if (isfinal) { + char *pos = sbp->begin; + while (*pos && isspace(*pos)) { + /* eat whitespace */ + ++pos; + } + swrite(pos, 1, sbp->end - pos, out); + newline(out); + } +} + static int show_allies_cb(struct allies *all, faction *af, int status, void *udata) { struct show_s * show = (struct show_s *)udata; const faction * f = show->f; - + sbstring *sbp = &show->sbs; int mode = alliance_status(f, af, status); - --show->num_allies; - if (sbs_length(&show->sbs) > 0) { - /* not the first entry */ - if (0 == show->num_allies) { - sbs_strcat(&show->sbs, LOC(f->locale, "list_and")); + + if (show->num_listed++ != 0) { + if (show->num_listed == show->num_allies) { + /* last entry */ + sbs_strcat(sbp, LOC(f->locale, "list_and")); } else { - sbs_strcat(&show->sbs, ", "); + /* neither first entry nor last*/ + sbs_strcat(sbp, ", "); } } - sbs_strcat(&show->sbs, factionname(af)); - sbs_strcat(&show->sbs, " ("); + sbs_strcat(sbp, factionname(af)); + sbs_strcat(sbp, " ("); if ((mode & HELP_ALL) == HELP_ALL) { - sbs_strcat(&show->sbs, LOC(f->locale, parameters[P_ANY])); + sbs_strcat(sbp, LOC(f->locale, parameters[P_ANY])); } else { int h, hh = 0; @@ -1573,58 +1622,60 @@ static int show_allies_cb(struct allies *all, faction *af, int status, void *uda } if (p != MAXPARAMS) { if (hh) { - sbs_strcat(&show->sbs, ", "); + sbs_strcat(sbp, ", "); } - sbs_strcat(&show->sbs, LOC(f->locale, parameters[p])); + sbs_strcat(sbp, LOC(f->locale, parameters[p])); hh = 1; } } } - sbs_strcat(&show->sbs, ")"); + if (show->num_allies == show->num_listed) { + sbs_strcat(sbp, ")."); + pump_paragraph(sbp, show->out, show->maxlen, true); + } + else { + sbs_strcat(sbp, ")"); + pump_paragraph(sbp, show->out, show->maxlen, false); + } return 0; } -static void -show_allies(const faction * f, struct allies * allies, char *buf, size_t size) +void report_allies(struct stream *out, size_t maxlen, const struct faction * f, struct allies * allies, const char *prefix) { int num_allies = 0; + + assert(maxlen <= REPORTWIDTH); allies_walk(allies, count_allies_cb, &num_allies); if (num_allies > 0) { struct show_s show; + char buf[REPORTWIDTH * 2]; show.f = f; + show.out = out; show.num_allies = num_allies; - sbs_init(&show.sbs, buf, size); + show.num_listed = 0; + show.maxlen = maxlen; + sbs_init(&show.sbs, buf, sizeof(buf)); + sbs_strcpy(&show.sbs, prefix); allies_walk(allies, show_allies_cb, &show); - sbs_strcat(&show.sbs, "."); } } static void allies(struct stream *out, const faction * f) { const group *g = f->groups; - char buf[16384]; + char prefix[64]; if (f->allies) { - int bytes; - size_t size = sizeof(buf); - bytes = snprintf(buf, size, "%s ", LOC(f->locale, "faction_help")); - size -= bytes; - show_allies(f, f->allies, buf + bytes, size); - paragraph(out, buf, 0, 0, 0); - newline(out); + snprintf(prefix, sizeof(prefix), "%s ", LOC(f->locale, "faction_help")); + report_allies(out, REPORTWIDTH, f, f->allies, prefix); } while (g) { if (g->allies) { - int bytes; - size_t size = sizeof(buf); - bytes = snprintf(buf, size, "%s %s ", g->name, LOC(f->locale, "group_help")); - size -= bytes; - show_allies(f, g->allies, buf + bytes, size); - paragraph(out, buf, 0, 0, 0); - newline(out); + snprintf(prefix, sizeof(prefix), "%s %s ", g->name, LOC(f->locale, "group_help")); + report_allies(out, REPORTWIDTH, f, g->allies, prefix); } g = g->next; } diff --git a/src/report.h b/src/report.h index bb3629497..307dba38b 100644 --- a/src/report.h +++ b/src/report.h @@ -14,21 +14,27 @@ #define H_GC_REPORT #include +#include #ifdef __cplusplus extern "C" { #endif struct stream; + struct sbstring; struct spellbook_entry; struct region; struct faction; struct locale; + struct allies; + void register_nr(void); void report_cleanup(void); void write_spaces(struct stream *out, size_t num); void report_travelthru(struct stream *out, struct region * r, const struct faction * f); void report_region(struct stream *out, const struct region * r, struct faction * f); + void report_allies(struct stream *out, size_t maxlen, const struct faction * f, struct allies * allies, const char *prefix); + void pump_paragraph(struct sbstring *sbp, struct stream *out, size_t maxlen, bool isfinal); void nr_spell_syntax(char *buf, size_t size, struct spellbook_entry * sbe, const struct locale *lang); void nr_spell(struct stream *out, struct spellbook_entry * sbe, const struct locale *lang); diff --git a/src/report.test.c b/src/report.test.c index 3c49b14fc..84f2f070d 100644 --- a/src/report.test.c +++ b/src/report.test.c @@ -3,6 +3,7 @@ #include "move.h" #include "travelthru.h" +#include #include #include #include @@ -143,6 +144,58 @@ static void test_report_region(CuTest *tc) { test_teardown(); } +static void test_report_allies(CuTest *tc) { + stream out = { 0 }; + char buf[1024]; + char exp[1024]; + size_t len, linebreak = 72; + struct locale *lang; + faction *f, *f1, *f2, *f3; + + test_setup(); + lang = test_create_locale(); + locale_setstring(lang, "list_and", " und "); + mstream_init(&out); + f = test_create_faction(NULL); + f->locale = lang; + f1 = test_create_faction(NULL); + f2 = test_create_faction(NULL); + f3 = test_create_faction(NULL); + snprintf(exp, sizeof(exp), "Wir helfen %s (%s).\n", + factionname(f1), + LOC(lang, parameters[P_GUARD])); + ally_set(&f->allies, f1, HELP_GUARD); + report_allies(&out, linebreak, f, f->allies, "Wir helfen "); + out.api->rewind(out.handle); + len = out.api->read(out.handle, buf, sizeof(buf)); + buf[len] = 0; + CuAssertStrEquals(tc, exp, buf); + + out.api->rewind(out.handle); + ally_set(&f->allies, f2, HELP_GIVE); + ally_set(&f->allies, f3, HELP_ALL); + snprintf(exp, sizeof(exp), "Wir helfen %s (%s), %s (%s)", + factionname(f1), + LOC(lang, parameters[P_GUARD]), + factionname(f2), + LOC(lang, parameters[P_GIVE])); + linebreak = strlen(exp); + snprintf(exp, sizeof(exp), "Wir helfen %s (%s), %s (%s)\nund %s (%s).\n", + factionname(f1), + LOC(lang, parameters[P_GUARD]), + factionname(f2), + LOC(lang, parameters[P_GIVE]), + factionname(f3), + LOC(lang, parameters[P_ANY])); + report_allies(&out, linebreak, f, f->allies, "Wir helfen "); + out.api->rewind(out.handle); + len = out.api->read(out.handle, buf, sizeof(buf)); + buf[len] = 0; + CuAssertStrEquals(tc, exp, buf); + + test_teardown(); +} + static void test_report_travelthru(CuTest *tc) { stream out = { 0 }; char buf[1024]; @@ -302,6 +355,7 @@ CuSuite *get_report_suite(void) SUITE_ADD_TEST(suite, test_write_many_spaces); SUITE_ADD_TEST(suite, test_report_travelthru); SUITE_ADD_TEST(suite, test_report_region); + SUITE_ADD_TEST(suite, test_report_allies); SUITE_ADD_TEST(suite, test_write_spell_syntax); return suite; } diff --git a/src/util/crmessage.c b/src/util/crmessage.c index 3e3b05177..e59ea474a 100644 --- a/src/util/crmessage.c +++ b/src/util/crmessage.c @@ -63,6 +63,7 @@ void tsf_register(const char *name, tostring_f fun) } if (tsf == NULL) { tsf = malloc(sizeof(tsf_list)); + if (!tsf) abort(); tsf->fun = fun; tsf->name = name; tsf->next = tostringfs; @@ -102,12 +103,14 @@ void crt_register(const struct message_type *mtype) } if (!crt) { crt = malloc(sizeof(crmessage_type)); + if (!crt) abort(); crt->mtype = mtype; crt->next = crtypes[hash]; crtypes[hash] = crt; if (mtype->nparameters > 0) { int i; crt->renderers = malloc(sizeof(tostring_f) * mtype->nparameters); + if (!crt->renderers) abort(); /* can be scrapped for memory vs. speed */ for (i = 0; i != mtype->nparameters; ++i) { crt->renderers[i] = tsf_find(mtype->types[i]->name); diff --git a/src/util/goodies.c b/src/util/goodies.c index fcfaa1013..a673e6e55 100644 --- a/src/util/goodies.c +++ b/src/util/goodies.c @@ -32,8 +32,11 @@ int *intlist_init(void) int *intlist_add(int *i_p, int i) { + void *tmp; i_p[0]++; - i_p = realloc(i_p, (i_p[0] + 1) * sizeof(int)); + tmp = realloc(i_p, (i_p[0] + 1) * sizeof(int)); + if (!tmp) abort(); + i_p = (int *)tmp; i_p[i_p[0]] = i; return (i_p); diff --git a/src/util/language.c b/src/util/language.c index afc9d01d0..de31075cc 100644 --- a/src/util/language.c +++ b/src/util/language.c @@ -83,7 +83,7 @@ locale *get_or_create_locale(const char *name) return *lp; } } - *lp = l = (locale *)calloc(sizeof(locale), 1); + *lp = l = (locale *)calloc(1, sizeof(locale)); assert_alloc(l); l->hashkey = hkey; l->name = str_strdup(name); @@ -206,6 +206,7 @@ void locale_setstring(locale * lang, const char *key, const char *value) } if (!find) { find = calloc(1, sizeof(struct locale_str)); + if (!find) abort(); find->nexthash = lang->strings[id]; lang->strings[id] = find; find->hashkey = hkey; diff --git a/src/util/lists.c b/src/util/lists.c index 81f9c9ab2..97e782795 100644 --- a/src/util/lists.c +++ b/src/util/lists.c @@ -120,6 +120,7 @@ unsigned int listlen(void *l) void addstrlist(strlist ** SP, const char *s) { strlist *slist = malloc(sizeof(strlist)); + if (!slist) abort(); slist->next = NULL; slist->s = str_strdup(s); addlist(SP, slist); diff --git a/src/util/log.c b/src/util/log.c index fd50ec700..26f745a3b 100644 --- a/src/util/log.c +++ b/src/util/log.c @@ -52,6 +52,7 @@ static log_t *loggers; log_t *log_create(int flags, void *data, log_fun call) { log_t *lgr = malloc(sizeof(log_t)); + if (!lgr) abort(); lgr->log = call; lgr->flags = flags; lgr->data = data; @@ -147,7 +148,7 @@ static const char *log_prefix(int level) { static int check_dupe(const char *format, int level) { static int last_type; /* STATIC_XCALL: used across calls */ - static char last_message[32]; /* STATIC_XCALL: used across calls */ + static char last_message[32] = { 0 }; /* STATIC_XCALL: used across calls */ static int dupes = 0; /* STATIC_XCALL: used across calls */ if (strncmp(last_message, format, sizeof(last_message)) == 0) { /* TODO: C6054: String 'last_message' might not be zero - terminated. */ diff --git a/src/util/message.c b/src/util/message.c index 47a8eb7af..fc645f3a2 100644 --- a/src/util/message.c +++ b/src/util/message.c @@ -41,6 +41,7 @@ register_argtype(const char *name, void(*free_arg) (variant), variant(*copy_arg) (variant), variant_type type) { arg_type *atype = (arg_type *)malloc(sizeof(arg_type)); + if (!atype) abort(); atype->name = name; atype->next = argtypes; atype->release = free_arg; @@ -90,7 +91,9 @@ message_type *mt_create(message_type * mtype, const char *args[], int nparameter int i; mtype->nparameters = nparameters; mtype->pnames = (char **)malloc(sizeof(char *) * nparameters); + if (!mtype->pnames) abort(); mtype->types = (arg_type **)malloc(sizeof(arg_type *) * nparameters); + if (!mtype->types) abort(); for (i = 0; args[i]; ++i) { const char *x = args[i]; const char *spos = strchr(x, ':'); @@ -103,8 +106,8 @@ message_type *mt_create(message_type * mtype, const char *args[], int nparameter assert(atype); } else { - char *cp; - cp = malloc(spos - x + 1); + char *cp = malloc(spos - x + 1); + if (!cp) abort(); memcpy(cp, x, spos - x); cp[spos - x] = '\0'; mtype->pnames[i] = cp; @@ -162,8 +165,10 @@ message_type *mt_new(const char *name, const char *section) return NULL; } mtype = (message_type *)malloc(sizeof(message_type)); + if (!mtype) abort(); mtype->key = 0; mtype->name = str_strdup(name); + if (!mtype->name) abort(); mtype->section = section_find(section); if (!mtype->section) { mtype->section = section_add(section); @@ -219,7 +224,6 @@ static void free_arg(const arg_type * atype, variant data) message *msg_create(const struct message_type *mtype, variant args[]) { - int i; message *msg; assert(mtype != NULL); @@ -228,11 +232,17 @@ message *msg_create(const struct message_type *mtype, variant args[]) return NULL; } msg = (message *)malloc(sizeof(message)); + if (!msg) abort(); msg->type = mtype; - msg->parameters = (variant *)(mtype->nparameters ? calloc(mtype->nparameters, sizeof(variant)) : NULL); msg->refcount = 1; - for (i = 0; i != mtype->nparameters; ++i) { - msg->parameters[i] = copy_arg(mtype->types[i], args[i]); + msg->parameters = NULL; + if (mtype->nparameters > 0) { + int i; + msg->parameters = (variant *)(mtype->nparameters ? calloc(mtype->nparameters, sizeof(variant)) : NULL); + if (!msg->parameters) abort(); + for (i = 0; i != mtype->nparameters; ++i) { + msg->parameters[i] = copy_arg(mtype->types[i], args[i]); + } } if (msg_log_create) msg_log_create(msg); diff --git a/src/util/nrmessage.c b/src/util/nrmessage.c index 1fdde6935..564abecb7 100644 --- a/src/util/nrmessage.c +++ b/src/util/nrmessage.c @@ -33,7 +33,19 @@ typedef struct nrmessage_type { } nrmessage_type; #define NRT_MAXHASH 1021 -static nrmessage_type *nrtypes[NRT_MAXHASH]; +static nrmessage_type *nrtypes[NRT_MAXHASH] = { 0 }; + +void free_nrmesssages(void) { + int i; + for (i = 0; i != NRT_MAXHASH; ++i) { + while (nrtypes[i]) { + nrmessage_type *nr = nrtypes[i]; + nrtypes[i] = nr->next; + free(nr->vars); + free(nr); + } + } +} const char *nrt_string(const struct message_type *mtype, const struct locale *lang) @@ -81,7 +93,8 @@ nrt_register(const struct message_type *mtype) int i; char zNames[256]; char *c = zNames; - nrt = malloc(sizeof(nrmessage_type)); + nrt = calloc(1, sizeof(nrmessage_type)); + if (!nrt) abort(); nrt->mtype = mtype; nrt->next = nrtypes[hash]; nrtypes[hash] = nrt; @@ -92,6 +105,7 @@ nrt_register(const struct message_type *mtype) c += str_strlcpy(c, mtype->pnames[i], sizeof(zNames)-(c-zNames)); } nrt->vars = str_strdup(zNames); + if (!nrt->vars) abort(); } } @@ -115,16 +129,3 @@ size_t size, const void *userdata) buffer[0] = 0; return 0; } - -void free_nrmesssages(void) { - int i; - for (i = 0; i != NRT_MAXHASH; ++i) { - while (nrtypes[i]) { - nrmessage_type *nr = nrtypes[i]; - nrtypes[i] = nr->next; - free(nr->vars); - free(nr); - } - } -} - diff --git a/src/util/parser.c b/src/util/parser.c index edcb5e3d6..f0090fdf3 100644 --- a/src/util/parser.c +++ b/src/util/parser.c @@ -58,6 +58,7 @@ void init_tokens_ex(const char *initstr, void *data, void (*dtor)(void *)) { if (states == NULL) { states = calloc(1, sizeof(parser_state)); + if (!states) abort(); } else if (states->dtor) { states->dtor(states->data); @@ -74,6 +75,7 @@ void init_tokens_str(const char *initstr) { void parser_pushstate(void) { parser_state *new_state = calloc(1, sizeof(parser_state)); + if (!new_state) abort(); new_state->current_token = NULL; new_state->next = states; states = new_state; diff --git a/src/util/pofile.c b/src/util/pofile.c index e1126ba0e..131994c37 100644 --- a/src/util/pofile.c +++ b/src/util/pofile.c @@ -74,7 +74,8 @@ int pofile_read(const char *filename, int (*callback)(const char *msgid, const c line = read_line(F); while (line) { char token[8]; - int err = sscanf(line, "%8s", token); + int err = sscanf(line, "%7s", token); + token[7] = 0; if (err == 1) { char *text = NULL; size_t size = 0, len = strlen(token); diff --git a/src/util/rand.c b/src/util/rand.c index f409cd0bb..3ab4490ab 100644 --- a/src/util/rand.c +++ b/src/util/rand.c @@ -132,6 +132,7 @@ void random_source_inject_array(double inject[], int size) { if (values) free(values); values = malloc(sizeof(double) * size); + if (!values) abort(); for (i=0; i < size; ++i) { values[i] = inject[i]; } diff --git a/src/util/strings.c b/src/util/strings.c index 4eac7856e..77a2a3186 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -300,6 +300,19 @@ void sbs_strcpy(struct sbstring *sbs, const char *str) sbs->end = sbs->begin + len; } +void sbs_cut(sbstring *sbp, int bytes) +{ + if (bytes > 0) { + size_t len = sbs_length(sbp) - bytes; + memmove(sbp->begin, sbp->begin + bytes, len + 1); + sbp->end = sbp->begin + len; + } + else if (bytes < 0) { + size_t len = sbs_length(sbp) + bytes; + sbp->end = sbp->begin + len; + } +} + size_t sbs_length(const struct sbstring *sbs) { return sbs->end - sbs->begin; diff --git a/src/util/strings.h b/src/util/strings.h index bf6299332..c61b81754 100644 --- a/src/util/strings.h +++ b/src/util/strings.h @@ -53,6 +53,7 @@ extern "C" { void sbs_strcat(struct sbstring *sbs, const char *str); void sbs_strncat(struct sbstring *sbs, const char *str, size_t size); void sbs_strcpy(struct sbstring *sbs, const char *str); + void sbs_cut(struct sbstring *sbp, int bytes); size_t sbs_length(const struct sbstring *sbs); /* benchmark for units: diff --git a/src/util/umlaut.c b/src/util/umlaut.c index 00252fb02..c070acb55 100644 --- a/src/util/umlaut.c +++ b/src/util/umlaut.c @@ -118,6 +118,7 @@ char * transliterate(char * out, size_t size, const char * in) tnode * mknode(void) { tnode * node = (tnode *)calloc(1, sizeof(tnode)); + if (!node) abort(); node->refcount = 1; return node; } @@ -179,6 +180,7 @@ void addtoken(tnode ** root, const char *str, variant id) } ref = (tref *)malloc(sizeof(tref)); + if (!ref) abort(); ref->ucs = ucs; ref->node = node; ref->nexthash = tk->next[index]; @@ -221,11 +223,10 @@ void addtoken(tnode ** root, const char *str, variant id) } } -void freetokens(tnode * root) +void freetokens(tnode * node) { - tnode * node = root; int i; - for (i = 0; node && i != NODEHASHSIZE; ++i) { + for (i = 0; i != NODEHASHSIZE; ++i) { if (node->next[i]) { tref * ref = node->next[i]; while (ref) { @@ -237,6 +238,7 @@ void freetokens(tnode * root) node->next[i] = 0; } } + /* TODO: warning C6011: Dereferencing NULL pointer 'node'. */ if (--node->refcount == 0) { free(node); }