#include "config.h" #include #include /** * xstring - bounded string builder with three valued comparator * * xstring handles string concatenation to a buffer, flagging truncation. * Additions can be transactional, where the addition wholly succeeds or the buffer is reterminated at its prior length. * Once flagged, no further additions are allowed. * Clearing reuses the buffer from the beginning. * * When comparing two xstrings, the truncation state is taken into account. * If either is truncated, an equality test returns unknown (-1). * Testing if x contains y returns unknown (-1) if y is truncated. * If x is whole, the test returns true (1) or false (0) appropriately. * If x is truncated, the test returns true (1) if the known portion of x contains y, and unknown (-1) otherwise. * * The structure members are intended for direct access. * * Example: * // demo - break long lines * #include * #include * #include * #include * #include * #include * #include * #include * * #include "ccan/xstring/xstring.h" * * #define MAXLEN 80 * #define MARGIN 10 * int main(int argc, char *argv[]) * { * char buf[BUFSIZ]; * xstring _x, *x = &_x; * struct stat sb; * int fd, span, lnlen; * char *map, *p, *q; * * xstrInit(x, buf, sizeof(buf), 0); * assert(sizeof(buf) > MAXLEN); * * if (argc != 2) return 1; * * if ((fd = open(argv[1], O_RDONLY)) == -1) * err(1, "open"); * if (fstat(fd, &sb) == -1) * err(1, "stat"); * if ((map = mmap(NULL, sb.st_size + 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0)) == MAP_FAILED) * err(1, "mmap"); * map[sb.st_size] = '\n'; * * for (p = map, lnlen = 0; p < map + sb.st_size; ) { * span = strcspn(p, " \t\n") + 1; * * if (lnlen + span > MAXLEN) { * span = MAXLEN - lnlen; * xstrAddSubsT(x, p, span, "\n", 1, NULL); * } * else * xstrAddSubT(x, p, span); * * if (x->truncated) { * fputs(x->str, stdout); * xstrClear(x); * continue; // p unchanged * } * * q = x->str + x->len - 1; * if (lnlen + MARGIN > MAXLEN) * *q = '\n'; * * lnlen = *q == '\n' ? 0 : lnlen + span; * p += span; * } * * if (x->len) * fputs(x->str, stdout); * * return 0; * } * * License: APACHE-2 * Author: Dan Good */ int main(int argc, char *argv[]) { /* Expect exactly one argument */ if (argc != 2) return 1; if (strcmp(argv[1], "depends") == 0) return 0; if (strcmp(argv[1], "testdepends") == 0) { printf("ccan/failtest\n"); return 0; } return 1; }