BRL-CAD
bu_vls_vprintf.c
Go to the documentation of this file.
1 /* T E S T _ V L S _ V P R I N T F. C
2  * BRL-CAD
3  *
4  * Copyright (c) 2011-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <signal.h>
27 #include <string.h>
28 #include <ctype.h>
29 
30 #include "bu.h"
31 #include "../vls_internals.h"
32 #include "./test_internals.h"
33 
34 
35 /* Test against sprintf */
36 int
37 test_vls(const char *fmt, ...)
38 {
39  int status = CTEST_PASS; /* okay */
40  struct bu_vls vls = BU_VLS_INIT_ZERO;
41  char output[80] = {0};
42  char buffer[1024] = {0};
43  va_list ap;
44 
45  va_start(ap, fmt);
46  /* use the libc version */
47  vsprintf(buffer, fmt, ap);
48  va_end(ap);
49 
50  va_start(ap, fmt);
51  /* use BRL-CAD bu_vls version for comparison */
52  bu_vls_vprintf(&vls, fmt, ap);
53  va_end(ap);
54 
55  snprintf(output, sizeof(output), "%-24s -> '%s'", fmt, bu_vls_addr(&vls));
56  if (BU_STR_EQUAL(buffer, bu_vls_addr(&vls))
57  && strlen(buffer) == bu_vls_strlen(&vls)) {
58  printf("%-*s[PASS]\n", 60, output);
59  } else {
60  printf("%-*s[FAIL] (should be: '%s')\n", 60, output, buffer);
61  status = CTEST_FAIL;
62  }
63 
64  bu_vls_free(&vls);
65 
66  return status;
67 }
68 
69 
70 int
72 {
73  int status = CTEST_PASS; /* assume okay */
74  int i, flags;
75  vflags_t f;
76 
77  for (i = 0; i < 255; ++i) {
78  unsigned char c = (unsigned char)i;
79  if (!isprint(c))
80  continue;
81  flags = format_part_status(c);
82  if (flags & VP_VALID) {
83  /* we need a valid part handler */
84  int vp_part = flags & VP_PARTS;
85 
86  /* for the moment we only have one such handler */
87  if (vp_part ^ VP_LENGTH_MOD) /* same as !(vp_part & VP_LENGTH_MOD) */
88  continue;
89 
90  if (!handle_format_part(vp_part, &f, c, VP_NOPRINT)) {
91  /* tell user */
92  printf("Unhandled valid char '%c' [FAIL]\n", c);
93  status = CTEST_FAIL;
94  }
95  } else if (flags & VP_OBSOLETE) {
96  /* we need an obsolete part handler */
97  if (!handle_obsolete_format_char(c, VP_NOPRINT)) {
98  /* tell user */
99  printf("Unhandled obsolete char '%c' [FAIL]\n", c);
100  status = CTEST_FAIL;
101  }
102  }
103  }
104 
105  return status;
106 }
107 
108 
109 int
110 main(int argc, char *argv[])
111 {
112 
113  int test_num = 0;
114  int f = 0;
115  int p = 0;
116  const char *word = "Lawyer";
117 
118  if (argc < 2) {
119  fprintf(stderr,"Usage: %s test_num\n", argv[0]);
120  return 1;
121  }
122 
123  sscanf(argv[1], "%d", &test_num);
124 
125 
126  switch (test_num) {
127  case 1:
128  /* check that we handle all known format chars */
129  return check_format_chars();
130  case 2:
131  return test_vls("");
132  case 3:
133  return test_vls("\n");
134  case 4:
135  return test_vls("hello");
136  case 5:
137  return test_vls("%s", "hello");
138  case 6:
139  return test_vls("%d", 123);
140  case 7:
141  return test_vls("%u", -123);
142  case 8:
143  return test_vls("%e %E", 1.23, -3.21);
144  case 9:
145  return test_vls("%g %G", 1.23, -3.21);
146  case 10:
147  return test_vls("%x %X", 1.23, -3.21);
148  case 11:
149  return test_vls("%x %X", 123, -321);
150  case 12:
151  return test_vls("%o", 1.23);
152  case 13:
153  return test_vls("%c%c%c", '1', '2', '3');
154  case 14:
155  return test_vls("%p", (void *)argv);
156  case 15:
157  return test_vls("%%%d%%", argc);
158  /* various lengths */
159  case 16:
160  return test_vls("%zu %zd", (size_t)123, (ssize_t)-123);
161  case 17:
162  return test_vls("%jd %td", (intmax_t)123, (ptrdiff_t)-123);
163  /* various widths */
164  case 18:
165  return test_vls("he%*so", 2, "ll");
166  case 19:
167  return test_vls("he%*so", 2, "llll");
168  case 20:
169  return test_vls("he%*so", 4, "ll");
170  /* various precisions */
171  case 21:
172  return test_vls("he%.*so", 2, "ll");
173  case 22:
174  return test_vls("he%.-1-o", 123);
175  case 23:
176  return test_vls("%6.-3f", 123);
177  /* various flags */
178  case 24:
179  return test_vls("%010d", 123);
180  case 25:
181  return test_vls("%#-.10lx", 123);
182  case 26:
183  return test_vls("%#lf", 123.0);
184  /* two-character length modifiers */
185  case 27:
186  return test_vls("he%10dllo", 123);
187  case 28:
188  return test_vls("he%-10ullo", 123);
189  case 29:
190  return test_vls("he%#-12.10tullo", (ptrdiff_t)0x1234);
191  case 30:
192  return test_vls("he%+-6.3ld%-+3.6dllo", 123, 321);
193  case 31:
194  return test_vls("he%.10dllo", 123);
195  case 32:
196  return test_vls("he%.-10ullo", 123);
197  case 33:
198  return test_vls("%hd %hhd", 123, -123);
199  /* combinations, e.g., bug ID 3475562, fixed at rev 48958 */
200  /* left justify, right justify, in wider fields than the strings */
201  case 34:
202  f = p = 2;
203  return test_vls("|%-*.*s|%*.*s|", f, p, "t", f, p, "t");
204  case 35:
205  f = p = 2;
206  return test_vls("|%*s|%-*s|", f, "test", f, "test");
207  case 36:
208  f = p = 2;
209  return test_vls("|%*s|%-*s|", f, word, f, word);
210  /* min field width; max string length ('precision'); string */
211  case 37:
212  f = 2; p = 4;
213  printf("fw=%d, prec=%d, '%s': '%%%d.%ds'\n", f, p, word, f, p);
214  return test_vls("%*.*s", f, p, word);
215  case 38:
216  f = 4; p = 2;
217  printf("fw=%d, prec=%d, '%s': '%%%d.%ds'\n", f, p, word, f, p);
218  return test_vls("%*.*s", f, p, word);
219  case 39:
220  f = 4; p = 8;
221  printf("fw=%d, prec=%d, '%s': '%%%d.%ds'\n", f, p, word, f, p);
222  return test_vls("%*.*s", f, p, word);
223  case 40:
224  f = 0; p = 8;
225  printf("fw=%d, prec=%d, '%s': '%%%d.%ds'\n", f, p, word, f, p);
226  return test_vls("%*.*s", f, p, word);
227  case 41:
228  f = 8; p = 0;
229  printf("fw=%d, prec=%d, '%s': '%%%d.%ds'\n", f, p, word, f, p);
230  return test_vls("%*.*s", f, p, word);
231  case 42:
232  /* mged bug at rev 48989 */
233  f = 8; p = 0;
234  printf("fw=%d, '%s': '%%%ds'\n", f, word, f);
235  return test_vls("%*s", f, word);
236  /* same but left justify */
237  case 43:
238  f = 2; p = 4;
239  printf("fw=%d, prec=%d, '%s': '%%-%d.%ds'\n", f, p, word, f, p);
240  return test_vls("%-*.*s", f, p, word);
241  case 44:
242  f = 4; p = 2;
243  printf("fw=%d, prec=%d, '%s': '%%-%d.%ds'\n", f, p, word, f, p);
244  return test_vls("%-*.*s", f, p, word);
245  case 45:
246  f = 4; p = 8;
247  printf("fw=%d, prec=%d, '%s': '%%-%d.%ds'\n", f, p, word, f, p);
248  return test_vls("%-*.*s", f, p, word);
249  case 46:
250  f = 0; p = 8;
251  printf("fw=%d, prec=%d, '%s': '%%-%d.%ds'\n", f, p, word, f, p);
252  return test_vls("%-*.*s", f, p, word);
253  case 47:
254  f = 8; p = 0;
255  printf("fw=%d, prec=%d, '%s': '%%-%d.%ds'\n", f, p, word, f, p);
256  return test_vls("%-*.*s", f, p, word);
257  /* from "various types" */
258  case 48:
259  return test_vls("%f %F", 1.23, -3.21);
260  /* from "two-character length modifiers" */
261  case 49:
262  return test_vls("%ld %lld", 123, -123LL);
263  /* unsigned variant */
264  case 50:
265  return test_vls("%lu %llu", 123, 123ULL);
266  /* from "two-character length modifiers" */
267  case 51:
268  return test_vls("%ld %lld", 123, -123);
269  /* unsigned variant */
270  case 52:
271  return test_vls("%lu %llu", 123, 123);
272  case 53:
273  return test_vls("%hd %hhd", 123, -123);
274  /* misc */
275  case 54:
276  return test_vls("% d % d", 123, -123);
277  case 55:
278  return test_vls("% 05d % d", 123, -123);
279  case 56:
280  return test_vls("%'d", 123000);
281  case 57:
282  return test_vls("%c", 'r');
283  case 58:
284  return test_vls("%20s", "right");
285  case 59:
286  return test_vls("%-20s", "left");
287  case 60:
288  return test_vls("%10.20s", "12345");
289  case 61:
290  return test_vls("%-10.20s", "12345");
291  case 62:
292  return test_vls("%10.20s", "123456789012345");
293  case 63:
294  return test_vls("%-10.20s", "123456789012345");
295  case 64:
296  return test_vls("%20.10s", "123456789012345");
297  case 65:
298  return test_vls("%-20.10s", "123456789012345");
299  case 66:
300  return test_vls("%010d", 1);
301  case 67:
302  return test_vls("%.030s", "1234567890123456789012345678901234567890");
303 
304  /* this test needs a relook
305  return test_vls("%H", 123);
306  */
307 
308  /* obsolete but usable */
309  /*
310  test_vls("%S", (wchar_t *)"hello");
311  test_vls("%qd %qd", 123, -123);
312  */
313 
314  /* EXPECTED FAILURES (don't use in production code):
315  *
316  * Notes:
317  *
318  * 1. For these tests have the return value increment 'expfails'.
319  * 2. Test with both 'make vsl-regress' and 'make regress' because
320  * some other tests use this function in unpredictable ways.
321  * 3. After a test is fixed, change the return value to increment
322  * 'fails', move it to the EXPECTED PASS group above, and add
323  * some info about it as necessary to help those who may be
324  * forced to revisit this.
325  *
326  */
327 
328  /* obsolete - expected failures
329  case 10000:
330  return !test_vls("%C", 'N');
331  case 10001:
332  return !test_vls("%D %D", 123, -123);
333  case 10002:
334  return !test_vls("%O %O", 123, -123);
335  case 10003:
336  return !test_vls("%U %U", 123, -123);a
337  */
338  }
339 
340  return CTEST_FAIL;
341 }
342 
343 
344 /*
345  * Local Variables:
346  * mode: C
347  * tab-width: 8
348  * indent-tabs-mode: t
349  * c-file-style: "stroustrup"
350  * End:
351  * ex: shiftwidth=4 tabstop=8
352  */
ptrdiff_t ssize_t
Definition: common.h:119
int handle_obsolete_format_char(const char c, const int print)
Definition: vls_vprintf.c:269
#define VP_VALID
Definition: vls_internals.h:35
Header file for the BRL-CAD common definitions.
const int CTEST_FAIL
int handle_format_part(const int vp_part, vflags_t *f, const char c, const int print)
Definition: vls_vprintf.c:172
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
#define VP_LENGTH_MOD
Definition: vls_internals.h:32
size_t bu_vls_strlen(const struct bu_vls *vp)
Definition: vls.c:189
int test_vls(const char *fmt,...)
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
void bu_vls_vprintf(struct bu_vls *vls, const char *fmt, va_list ap)
Definition: vls_vprintf.c:380
int main(int argc, char *argv[])
int check_format_chars(void)
#define VP_OBSOLETE
Definition: vls_internals.h:36
int format_part_status(const char c)
Definition: vls_vprintf.c:86
bn_poly_t output[3]
Definition: bn_poly_add.c:36
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
Definition: vls.h:56
const int CTEST_PASS
#define VP_PARTS
Definition: vls_internals.h:37
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126