+ c ++;
+ } else
+ r = append(r, &rl, &c, 1);
+ } else if (*c == '\'') {
+ state = STATE_CHAR;
+ r = append(r, &rl, &c, 1);
+ } else if (*c == 0)
+ done = 1;
+ else
+ r = append(r, &rl, &c, 1);
+
+ break;
+
+ case STATE_COMMENT_C:
+
+ if (!strncmp(c, "*/", 2)) {
+ state = STATE_TEXT;
+ r = append(r, &rl, &c, 2);
+ } else if (!strncmp(c, "%STRINGPOOLSTART%", 17)) {
+ enabled = 1;
+ pool_started_line = nline;
+ r = append(r, &rl, &c, 17);
+ } else if (!strncmp(c, "%STRINGPOOLSTOP%", 16)) {
+ enabled = 0;
+ r = append(r, &rl, &c, 16);
+ } else if (*c == 0)
+ done = 1;
+ else
+ r = append(r, &rl, &c, 1);
+
+ break;
+
+ case STATE_COMMENT_CPP:
+
+ if (*c == '\n' || *c == '\r') {
+ state = STATE_TEXT;
+ r = append(r, &rl, &c, 1);
+ } else if (!strncmp(c, "%STRINGPOOLSTART%", 17)) {
+ enabled = 1;
+ pool_started_line = nline;
+ r = append(r, &rl, &c, 17);
+ } else if (!strncmp(c, "%STRINGPOOLSTOP%", 16)) {
+ enabled = 0;
+ r = append(r, &rl, &c, 16);
+ } else if (*c == 0) {
+ state = STATE_TEXT;
+ done = 1;
+ } else
+ r = append(r, &rl, &c, 1);
+
+ break;
+
+ case STATE_STRING:
+ case STATE_CHAR:
+
+ if ((*c == '\'' && state == STATE_CHAR) || (*c == '"' && state == STATE_STRING)) {
+
+ if (state == STATE_STRING && enabled) {
+ struct item *i;
+ i = malloc(sizeof(struct item));
+
+ if (!i)
+ abort();
+
+ i->cnt = cnt;
+ i->cntl = cntl;
+
+ cnt = NULL;
+ cntl = 0;
+
+ i->text = r;
+ i->size = rl;
+
+ r = NULL;
+ rl = 0;
+
+ i->next = NULL;
+ i->suffix_of = NULL;
+
+ if (last)
+ last->next = i;
+ else
+ first = i;
+
+ last = i;
+
+ c++;
+
+ } else
+ r = append(r, &rl, &c, 1);
+
+ state = STATE_TEXT;
+
+ } else if (*c == '\\') {
+
+ char d;
+ char l = 2;
+
+ switch (c[1]) {
+
+ case '\\':
+ case '"':
+ case '\'':
+ case '?':
+ d = c[1];
+ break;
+ case 'n':
+ d = '\n';
+ break;
+ case 'r':
+ d = '\r';
+ break;
+ case 'b':
+ d = '\b';
+ break;
+ case 't':
+ d = '\t';
+ break;
+ case 'f':
+ d = '\f';
+ break;
+ case 'a':
+ d = '\a';
+ break;
+ case 'v':
+ d = '\v';
+ break;
+ case 'x': {
+ int k;
+ if ((k = parse_hex(c+2, &d)) < 0) {
+ fprintf(stderr, "%s:%u: Parse failure: invalid hexadecimal escape sequence.\n", fname, nline);
+ goto fail;
+ }
+ l = 2 + k;
+ break;
+ }
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7': {
+ int k;
+ if ((k = parse_oct(c+1, &d)) < 0) {
+ fprintf(stderr, "%s:%u: Parse failure: invalid octal escape sequence.\n", fname, nline);
+ goto fail;
+ }
+ l = 1 + k;
+ break;
+ }
+ default:
+ fprintf(stderr, "%s:%u: Parse failure: invalid escape sequence.\n", fname, nline);
+ goto fail;
+ }
+
+ if (state == STATE_STRING && enabled) {
+ char *x = &d;
+ r = append(r, &rl, &x, 1);
+ c += l;
+ } else
+ r = append(r, &rl, &c, l);
+ } else if (*c == 0) {
+ fprintf(stderr, "%s:%u: Parse failure: multiline strings suck.\n", fname, nline);
+ goto fail;
+ } else
+ r = append(r, &rl, &c, 1);
+
+ break;