tweaks from feedback - thanks
[ccan] / ccan / xstring / _info
1 #include "config.h"
2 #include <stdio.h>
3 #include <string.h>
4
5 /**
6  * xstring - bounded string builder with three valued comparator
7  *
8  * xstring handles string concatenation to a buffer, flagging truncation.
9  * Additions can be transactional, where the addition wholly succeeds or the buffer is reterminated at its prior length.
10  * Once flagged, no further additions are allowed.
11  * Clearing reuses the buffer from the beginning.
12  *
13  * When comparing two xstrings, the truncation state is taken into account.
14  * If either is truncated, an equality test returns unknown (-1).
15  * Testing if x contains y returns unknown (-1) if y is truncated.
16  * If x is whole, the test returns true (1) or false (0) appropriately.
17  * If x is truncated, the test returns true (1) if the known portion of x contains y, and unknown (-1) otherwise.
18  *
19  * The structure members are intended for direct access.
20  *
21  * Example:
22  *      // demo - break long lines
23  *      #include <string.h>
24  *      #include <stdio.h>
25  *      #include <unistd.h>
26  *      #include <err.h>
27  *      #include <fcntl.h>
28  *      #include <sys/types.h>
29  *      #include <sys/stat.h>
30  *      #include <sys/mman.h>
31  *
32  *      #include "ccan/xstring/xstring.h"
33  *
34  *      #define MAXLEN 80
35  *      #define MARGIN 10
36  *      int main(int argc, char *argv[])
37  *      {
38  *              char buf[BUFSIZ];
39  *              xstring _x, *x = &_x;
40  *              struct stat sb;
41  *              int fd, span, lnlen;
42  *              char *map, *p, *q;
43  *
44  *              xstrInit(x, buf, sizeof(buf), 0);
45  *              assert(sizeof(buf) > MAXLEN);
46  *
47  *              if (argc != 2) return 1;
48  *
49  *              if ((fd = open(argv[1], O_RDONLY)) == -1)
50  *                      err(1, "open");
51  *              if (fstat(fd, &sb) == -1)
52  *                      err(1, "stat");
53  *              if ((map = mmap(NULL, sb.st_size + 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
54  *                      err(1, "mmap");
55  *              map[sb.st_size] = '\n';
56  *
57  *              for (p = map, lnlen = 0; p < map + sb.st_size; ) {
58  *                      span = strcspn(p, " \t\n") + 1;
59  *
60  *                      if (lnlen + span > MAXLEN) {
61  *                              span = MAXLEN - lnlen;
62  *                              xstrAddSubsT(x, p, span, "\n", 1, NULL);
63  *                      }
64  *                      else
65  *                              xstrAddSubT(x, p, span);
66  *
67  *                      if (x->truncated) {
68  *                              fputs(x->str, stdout);
69  *                              xstrClear(x);
70  *                              continue; // p unchanged
71  *                      }
72  *
73  *                      q = x->str + x->len - 1;
74  *                      if (lnlen + MARGIN > MAXLEN)
75  *                              *q = '\n';
76  *
77  *                      lnlen = *q == '\n' ? 0 : lnlen + span;
78  *                      p += span;
79  *              }
80  *
81  *              if (x->len)
82  *                      fputs(x->str, stdout);
83  *
84  *              return 0;
85  *      }
86  *
87  * License: APACHE-2
88  * Author: Dan Good <dan@dancancode.com>
89  */
90 int main(int argc, char *argv[])
91 {
92         /* Expect exactly one argument */
93         if (argc != 2)
94                 return 1;
95
96         if (strcmp(argv[1], "depends") == 0)
97                 return 0;
98         if (strcmp(argv[1], "testdepends") == 0) {
99                 printf("ccan/failtest\n");
100                 return 0;
101         }
102
103         return 1;
104 }