PageRenderTime 49ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/libtu/snprintf_2.2/test.c

http://mimic.googlecode.com/
C | 689 lines | 553 code | 88 blank | 48 comment | 150 complexity | ceb1a64e1a143bf0afbc045ef3bb8b40 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /*
  2. * test.c - test a portable implementation of snprintf
  3. *
  4. * AUTHOR
  5. * Mark Martinec <mark.martinec@ijs.si>, April 1999.
  6. *
  7. * Copyright 1999, Mark Martinec. All rights reserved.
  8. *
  9. * TERMS AND CONDITIONS
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the "Frontier Artistic License" which comes
  12. * with this Kit.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty
  16. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. * See the Frontier Artistic License for more details.
  18. *
  19. * You should have received a copy of the Frontier Artistic License
  20. * with this Kit in the file named LICENSE.txt .
  21. * If not, I'll be glad to provide one.
  22. *
  23. * NOTE: This test program is a QUICK and DIRTY tool
  24. * ===== used while testing and benchmarking my portable snprintf.
  25. * Certain data types are not fully supported, certain test
  26. * cases were fabricated during testing by modifying the code
  27. * or running it by specifying test parameters in the command line.
  28. *
  29. * You are on your own if you want to use this test program!
  30. */
  31. /* If no command arguments are specified do the exhaustive test.
  32. * This takes a long time. You may want to reduce the fw and fp
  33. * upper limits in the for loops.
  34. * You may also reduce the number of test elements in the array iargs.
  35. */
  36. #include <sys/types.h>
  37. #include <string.h>
  38. #include <stdlib.h>
  39. #include <stdio.h>
  40. #include <stdarg.h>
  41. #include <assert.h>
  42. #include <time.h>
  43. #if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF)
  44. # if defined(NEED_SNPRINTF_ONLY)
  45. # undef NEED_SNPRINTF_ONLY
  46. # endif
  47. # if !defined(PREFER_PORTABLE_SNPRINTF)
  48. # define PREFER_PORTABLE_SNPRINTF
  49. # endif
  50. #endif
  51. #ifdef HAVE_SNPRINTF
  52. extern int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);
  53. #else
  54. extern int snprintf(char *, size_t, const char *, /*args*/ ...);
  55. extern int vsnprintf(char *, size_t, const char *, va_list);
  56. #endif
  57. #ifndef HAVE_SNPRINTF
  58. #define portable_snprintf snprintf
  59. #define portable_vsnprintf vsnprintf
  60. #endif
  61. #ifndef CLOCKS_PER_SEC
  62. #define CLOCKS_PER_SEC 100
  63. #endif
  64. #define min(a,b) ((a)<(b) ? (a) : (b))
  65. #define max(a,b) ((a)>(b) ? (a) : (b))
  66. extern int asprintf (char **ptr, const char *fmt, /*args*/ ...);
  67. extern int vasprintf (char **ptr, const char *fmt, va_list ap);
  68. extern int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...);
  69. extern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap);
  70. #ifndef NEED_SNPRINTF_ONLY
  71. int wrap_vsnprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);
  72. int wrap_vsnprintf(char *str, size_t str_m, const char *fmt, ...) {
  73. va_list ap;
  74. int str_l;
  75. va_start(ap, fmt);
  76. str_l = vsnprintf(str, str_m, fmt, ap);
  77. va_end(ap);
  78. return str_l;
  79. }
  80. #endif
  81. #ifdef NEED_VASPRINTF
  82. int wrap_vasprintf(char **ptr, const char *fmt, /*args*/ ...);
  83. int wrap_vasprintf(char **ptr, const char *fmt, ...) {
  84. va_list ap;
  85. int str_l;
  86. va_start(ap, fmt);
  87. str_l = vasprintf(ptr, fmt, ap);
  88. va_end(ap);
  89. return str_l;
  90. }
  91. #endif
  92. #ifdef NEED_VASNPRINTF
  93. int wrap_vasnprintf(char **ptr, size_t str_m, const char *fmt, /*args*/ ...);
  94. int wrap_vasnprintf(char **ptr, size_t str_m, const char *fmt, ...) {
  95. va_list ap;
  96. int str_l;
  97. va_start(ap, fmt);
  98. str_l = vasnprintf(ptr, str_m, fmt, ap);
  99. va_end(ap);
  100. return str_l;
  101. }
  102. #endif
  103. int main(int argc, char *argv[]) {
  104. char str1[256], str2[256];
  105. #ifdef HAVE_SNPRINTF
  106. char str3[256];
  107. #endif
  108. int len1, len2, len3;
  109. int bad = 0;
  110. size_t str_m = 20; /* declared str size */
  111. if (0) {
  112. /* benchmarking */
  113. const int cnt = 100000;
  114. size_t size;
  115. char str[40000];
  116. time_t t0,t;
  117. int j,len,l1,l2;
  118. char *p;
  119. int breakpoint;
  120. size = 18000;
  121. printf("\n\nsize = %d\n", (int)size);
  122. p = malloc(size); assert(p);
  123. memset(p,'h',size); p[size-1] = '\0';
  124. t0 = clock();
  125. printf("\ndetermine breakeven point to see when it is worth\n");
  126. printf("calling memcpy and when to do inline string copy\n");
  127. printf("str_l, memcpy, inline\n");
  128. for (breakpoint=0; breakpoint<=35; breakpoint++) {
  129. register size_t nnn = (size_t)breakpoint;
  130. printf("%5ld", nnn);
  131. for (j=10*cnt; j>0; j--) memcpy(str, p, nnn);
  132. t = clock(); printf(" %1.3f", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  133. for (j=10*cnt; j>0; j--) {
  134. register size_t nn = (size_t)breakpoint;
  135. if (nn > 0) {
  136. register char *dd; register const char *ss;
  137. for (ss=p, dd=str; nn>0; nn--) *dd++ = *ss++;
  138. }
  139. }
  140. t = clock(); printf(" %1.3f\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  141. }
  142. printf("\nmeasuring time to SKIP a long format with no conversions\n");
  143. p[0] = '%'; p[1] = 's';
  144. for (j=cnt; j>0; j--) l1=portable_snprintf(NULL,(size_t)0,p,"1234567890");
  145. t = clock(); printf("t_port_nul = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  146. for (j=cnt; j>0; j--) l2=portable_snprintf(str,(size_t)8,p,"1234567890");
  147. t = clock(); printf("t_port = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  148. assert(l1==l2);
  149. p[0] = p[1] = 'h';
  150. printf("\nmeasuring time to copy a long format with no conversions\n");
  151. for (j=cnt; j>0; j--) l1=portable_snprintf(NULL,(size_t)0,p);
  152. t = clock(); printf("t_port_nul = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  153. for (j=cnt; j>0; j--) l2=portable_snprintf(str,sizeof(str),p);
  154. t = clock(); printf("t_port = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  155. assert(l1==l2);
  156. for (j=cnt; j>0; j--) sprintf(str,p);
  157. t = clock(); printf("t_sys = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  158. printf("\nmeasuring time to copy a long format with one conversion\n");
  159. p[size-10] = '%';
  160. for (j=cnt; j>0; j--) l1=portable_snprintf(NULL,(size_t)0,p);
  161. t = clock(); printf("t_port_nul = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  162. for (j=cnt; j>0; j--) l2=portable_snprintf(str,sizeof(str),p);
  163. t = clock(); printf("t_port = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  164. assert(l1==l2);
  165. for (j=cnt; j>0; j--) sprintf(str,p);
  166. t = clock(); printf("t_sys = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  167. printf("\nmeasuring string argument copy speed\n");
  168. for (j=cnt; j>0; j--) l1=portable_snprintf(NULL,(size_t)0,"%.18000s",p);
  169. t = clock(); printf("t_port_nul = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  170. for (j=cnt; j>0; j--) l2=portable_snprintf(str,sizeof(str),"%.18000s",p);
  171. t = clock(); printf("t_port = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  172. assert(l1==l2);
  173. for (j=cnt; j>0; j--) sprintf(str,"%.18000s",p);
  174. t = clock(); printf("t_sys = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  175. printf("\nmeasuring left padding speed\n");
  176. p[0] = '\0';
  177. for (j=cnt; j>0; j--) l1=portable_snprintf(NULL,(size_t)0,"%-18000s",p);
  178. t = clock(); printf("t_port_nul = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  179. for (j=cnt; j>0; j--) l2=portable_snprintf(str,sizeof(str),"%-18000s",p);
  180. t = clock(); printf("t_port = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  181. assert(l1==l2);
  182. for (j=cnt; j>0; j--) sprintf(str,"%-18000s",p);
  183. t = clock(); printf("t_sys = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  184. printf("\nmeasuring right padding speed\n");
  185. p[0] = '\0';
  186. for (j=cnt; j>0; j--) l1=portable_snprintf(NULL,(size_t)0,"%18000s",p);
  187. t = clock(); printf("t_port_nul = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  188. for (j=cnt; j>0; j--) l2=portable_snprintf(str,sizeof(str),"%18000s",p);
  189. t = clock(); printf("t_port = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  190. assert(l1==l2);
  191. for (j=cnt; j>0; j--) sprintf(str,"%18000s",p);
  192. t = clock(); printf("t_sys = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  193. printf("\nmeasuring zero padding speed\n");
  194. for (j=cnt; j>0; j--) l1=portable_snprintf(NULL,(size_t)0,"%018000d",1);
  195. t = clock(); printf("t_port_nul = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  196. for (j=cnt; j>0; j--) l2=portable_snprintf(str,sizeof(str),"%018000d",1);
  197. t = clock(); printf("t_port = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  198. assert(l1==l2);
  199. for (j=cnt; j>0; j--) sprintf(str,"%018000d",1);
  200. t = clock(); printf("t_sys = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  201. printf("\nmeasuring system's sprintf to efficiently handle truncated strings\n");
  202. memset(p,'h',size); p[size-1] = '\0';
  203. t0 = clock();
  204. for (j=cnt; j>0; j--) len = strlen(p);
  205. printf("len = %d\n", len);
  206. t = clock(); printf("t_strlen = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  207. /* test if the system sprintf scans the whole string (e.g. by strlen)
  208. * before recognizing this was a bad idea since the format specified
  209. * a truncated string precision, e.g. "%.8s" .
  210. */
  211. for (j=cnt; j>0; j--) sprintf(str,"%.2s",p);
  212. t = clock(); printf("t_sys = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  213. #ifdef HAVE_SNPRINTF
  214. for (j=cnt; j>0; j--) snprintf(str,sizeof(str),"%.2s",p);
  215. t = clock(); printf("t_sys = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  216. #endif
  217. for (j=cnt; j>0; j--) portable_snprintf(str,sizeof(str),"%.2s",p);
  218. t = clock(); printf("t_port = %1.3f s\n", (float)(t-t0)/CLOCKS_PER_SEC); t0 = t;
  219. free(p);
  220. return 0;
  221. }
  222. /* preliminary halfhearted test */
  223. {
  224. const char fmt[] = "Bla%.4s%05iHE%%%-50sTail";
  225. char *ptr4=0, *ptr5=0, *ptr6=0, *ptr7=0;
  226. int len1f;
  227. char str_full[256];
  228. printf("\npreliminary test: snprintf\n");
  229. len1 = snprintf(str1, str_m, fmt, "abcdef",-12,"str");
  230. len1f = snprintf(str_full, sizeof(str_full), fmt, "abcdef",-12,"str");
  231. assert(len1f==len1);
  232. assert(memcmp(str1,str_full,min(len1,str_m-1)) == 0);
  233. assert(str1[str_m-1] == '\0');
  234. assert(str_full[sizeof(str_full)-1] == '\0');
  235. #ifndef NEED_SNPRINTF_ONLY
  236. printf("preliminary test: vsnprintf\n");
  237. len2 = wrap_vsnprintf(str2, str_m, fmt, "abcdef",-12,"str");
  238. assert(len2==len1);
  239. assert(memcmp(str1,str2,min(len1+1,str_m)) == 0);
  240. assert(str2[str_m-1] == '\0');
  241. #endif
  242. #ifdef NEED_ASPRINTF
  243. printf("preliminary test: asprintf\n");
  244. len4 = asprintf(&ptr4, fmt, "abcdef",-12,"str");
  245. assert(ptr4);
  246. assert(len4==len1);
  247. assert(memcmp(str_full,ptr4,min(len4+1,sizeof(str_full))) == 0);
  248. assert(ptr4[len4] == '\0');
  249. #endif
  250. #ifdef NEED_ASNPRINTF
  251. printf("preliminary test: asnprintf\n");
  252. len5 = asnprintf(&ptr5, str_m, fmt, "abcdef",-12,"str");
  253. assert(ptr5);
  254. assert(len5==len1);
  255. assert(memcmp(str1,ptr5,min(len5+1,str_m)) == 0);
  256. assert(ptr5[len5] == '\0');
  257. #endif
  258. #ifdef NEED_VASPRINTF
  259. printf("preliminary test: vasprintf\n");
  260. len6 = wrap_vasprintf(&ptr6, fmt, "abcdef",-12,"str");
  261. assert(ptr6);
  262. assert(len6==len1);
  263. assert(memcmp(str_full,ptr6,min(len6+1,sizeof(str_full))) == 0);
  264. assert(ptr6[len6] == '\0');
  265. #endif
  266. #ifdef NEED_VASNPRINTF
  267. printf("preliminary test: vasnprintf\n");
  268. len7 = wrap_vasnprintf(&ptr7, str_m, fmt, "abcdef",-12,"str");
  269. assert(ptr7);
  270. assert(len7==len1);
  271. assert(memcmp(str1,ptr7,min(len7+1,str_m)) == 0);
  272. assert(ptr7[len7] == '\0');
  273. #endif
  274. if (ptr4) free(ptr4);
  275. if (ptr5) free(ptr5);
  276. if (ptr6) free(ptr6);
  277. if (ptr7) free(ptr7);
  278. }
  279. /* second preliminary halfhearted test */
  280. {
  281. printf("\nsecond preliminary test:\n");
  282. printf("test 0a\n");
  283. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  284. len1 = snprintf(str1, sizeof(str1), "");
  285. len2 = sprintf (str2, "");
  286. assert(len1==len2);
  287. assert(memcmp(str1,str2,(size_t)len1) == 0);
  288. printf("test 0b\n");
  289. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  290. len1 = snprintf(str1, sizeof(str1), "YK");
  291. len2 = sprintf (str2, "YK");
  292. assert(len1==len2);
  293. assert(memcmp(str1,str2,(size_t)len1) == 0);
  294. printf("test 1\n");
  295. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  296. len1 = snprintf(str1, sizeof(str1), "%+d",0);
  297. len2 = sprintf (str2, "%+d",0);
  298. assert(len1==len2);
  299. assert(memcmp(str1,str2,(size_t)len1) == 0);
  300. printf("test 2\n");
  301. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  302. len1 = snprintf(str1, sizeof(str1), "%.2147483647s", "13");
  303. len2 = sprintf (str2, "%.2147483647s", "13");
  304. printf("len1=%d, len2=%d\n", len1,len2);
  305. assert(len1==len2);
  306. assert(memcmp(str1,str2,(size_t)len1) == 0);
  307. printf("test 3a\n");
  308. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  309. len1 = snprintf(str1, sizeof(str1), "%.2147483648s", "13");
  310. len2 = sprintf (str2, "%.2147483648s", "13");
  311. printf("len1=%d, len2=%d\n", len1,len2);
  312. assert(len1==len2);
  313. assert(memcmp(str1,str2,(size_t)len1) == 0);
  314. printf("test 3b\n");
  315. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  316. len1 = snprintf(str1, sizeof(str1), "%.2147483649s", "13");
  317. len2 = sprintf (str2, "%.2147483649s", "13");
  318. printf("len1=%d, len2=%d\n", len1,len2);
  319. assert(len1==len2);
  320. assert(memcmp(str1,str2,(size_t)len1) == 0);
  321. printf("test 4\n");
  322. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  323. len1 = snprintf(str1, sizeof(str1), "%-.2147483647s", "13");
  324. len2 = sprintf (str2, "%-.2147483647s", "13");
  325. printf("len1=%d, len2=%d\n", len1,len2);
  326. assert(len1==len2);
  327. assert(memcmp(str1,str2,(size_t)len1) == 0);
  328. printf("test 5\n");
  329. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  330. len1 = snprintf(str1, sizeof(str1), "%-.2147483648s", "13");
  331. len2 = sprintf (str2, "%-.2147483648s", "13");
  332. printf("len1=%d, len2=%d\n", len1,len2);
  333. assert(len1==len2);
  334. assert(memcmp(str1,str2,(size_t)len1) == 0);
  335. printf("test 6\n");
  336. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  337. len1 = snprintf(str1, sizeof(str1), "%.4294967295s", "13");
  338. len2 = sprintf (str2, "%.4294967295s", "13");
  339. printf("len1=%d, len2=%d\n", len1,len2);
  340. assert(len1==len2);
  341. assert(memcmp(str1,str2,(size_t)len1) == 0);
  342. printf("test 7\n");
  343. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  344. len1 = snprintf(str1, sizeof(str1), "%.4294967296s", "13");
  345. len2 = sprintf (str2, "%.4294967296s", "13");
  346. printf("len1=%d, len2=%d\n", len1,len2);
  347. assert(len1==len2);
  348. assert(memcmp(str1,str2,(size_t)len1) == 0);
  349. printf("test 12\n");
  350. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  351. len1 = snprintf(str1, sizeof(str1), "%.*s", 2147483647,"13");
  352. len2 = sprintf (str2, "%.*s", 2147483647,"13");
  353. printf("len1=%d, len2=%d\n", len1,len2);
  354. assert(len1==len2);
  355. assert(memcmp(str1,str2,(size_t)len1) == 0);
  356. printf("test 13\n");
  357. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  358. len1 = snprintf(str1, sizeof(str1), "%.*s", 2147483648U,"13");
  359. len2 = sprintf (str2, "%.*s", 2147483648U,"13");
  360. printf("len1=%d, len2=%d\n", len1,len2);
  361. assert(len1==len2);
  362. assert(memcmp(str1,str2,(size_t)len1) == 0);
  363. printf("test 14\n");
  364. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  365. len1 = snprintf(str1, sizeof(str1), "%-.*s", 2147483647,"13");
  366. len2 = sprintf (str2, "%-.*s", 2147483647,"13");
  367. printf("len1=%d, len2=%d\n", len1,len2);
  368. assert(len1==len2);
  369. assert(memcmp(str1,str2,(size_t)len1) == 0);
  370. printf("test 15\n");
  371. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  372. len1 = snprintf(str1, sizeof(str1), "%-.*s", 2147483648U,"13");
  373. len2 = sprintf (str2, "%-.*s", 2147483648U,"13");
  374. printf("len1=%d, len2=%d\n", len1,len2);
  375. assert(len1==len2);
  376. assert(memcmp(str1,str2,(size_t)len1) == 0);
  377. printf("test 16\n");
  378. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  379. len1 = snprintf(str1, sizeof(str1), "%.*s", 4294967295U,"13");
  380. len2 = sprintf (str2, "%.*s", 4294967295U,"13");
  381. printf("len1=%d, len2=%d\n", len1,len2);
  382. assert(len1==len2);
  383. assert(memcmp(str1,str2,(size_t)len1) == 0);
  384. printf("test 17\n");
  385. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  386. len1 = snprintf(str1, sizeof(str1), "%.*s", 4294967296U,"13");
  387. /* len2 = sprintf (str2, "%.*s", 4294967296U,"13"); */ /* core dumps on HPUX */
  388. /* assert(len1==len2);
  389. * assert(memcmp(str1,str2,(size_t)len1) == 0);
  390. */
  391. printf("test 95\n");
  392. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  393. len1 = snprintf(str1, sizeof(str1), "%c",'A');
  394. len2 = sprintf (str2, "%c",'A');
  395. assert(len1==len2);
  396. assert(memcmp(str1,str2,(size_t)len1) == 0);
  397. printf("test 96\n");
  398. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  399. len1 = snprintf(str1, sizeof(str1), "%10c",'A');
  400. len2 = sprintf (str2, "%10c",'A');
  401. assert(len1==len2);
  402. assert(memcmp(str1,str2,(size_t)len1) == 0);
  403. printf("test 97\n");
  404. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  405. len1 = snprintf(str1, sizeof(str1), "%-10c",'A');
  406. len2 = sprintf (str2, "%-10c",'A');
  407. assert(len1==len2);
  408. assert(memcmp(str1,str2,(size_t)len1) == 0);
  409. printf("test 98\n");
  410. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  411. len1 = snprintf(str1, sizeof(str1), "%.10c",'A');
  412. len2 = sprintf (str2, "%.10c",'A');
  413. assert(len1==len2);
  414. assert(memcmp(str1,str2,(size_t)len1) == 0);
  415. printf("test 99\n");
  416. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  417. len1 = snprintf(str1, sizeof(str1), "%-.10c",'A');
  418. len2 = sprintf (str2, "%-.10c",'A');
  419. assert(len1==len2);
  420. assert(memcmp(str1,str2,(size_t)len1) == 0);
  421. printf("test 100\n");
  422. memset(str1,'x',sizeof(str1)); memset(str2,'x',sizeof(str2));
  423. len1 = snprintf(str1, (size_t)8, "blaBhb%shehe%cX","ABCD",'1');
  424. len2 = sprintf (str2, "blaBhb%shehe%cX","ABCD",'1');
  425. assert(len1==len2);
  426. assert(memcmp(str1,str2,(size_t)7) == 0);
  427. assert(str1[7] == '\0');
  428. assert(memcmp(str1+14,str2+16,(size_t)(len1-16)) == 0);
  429. }
  430. /* testing for correctness and compatibility */
  431. if (argc >= 3) {
  432. char *c; int alldigits = 1;
  433. for (c=argv[2]; *c; c++)
  434. if (! (*c == '-' || (*c >= '0' && *c <= '9'))) alldigits = 0;
  435. if (alldigits) {
  436. int j = atoi(argv[2]);
  437. len1 = portable_snprintf(str1, str_m, argv[1], j, 3);
  438. len2 = sprintf(str2, argv[1], j, 3);
  439. #ifdef HAVE_SNPRINTF
  440. len3 = snprintf(str3, str_m, argv[1], j, 3);
  441. #endif
  442. } else {
  443. len1 = portable_snprintf(str1, str_m, argv[1], argv[2], 3);
  444. len2 = sprintf(str2, argv[1], argv[2], 3);
  445. #ifdef HAVE_SNPRINTF
  446. len3 = snprintf(str3, str_m, argv[1], argv[2], 3);
  447. #endif
  448. }
  449. printf("portable: |%s| len = %d\n", str1, len1);
  450. printf("sys sprintf: |%s| len = %d\n", str2, len2);
  451. #ifdef HAVE_SNPRINTF
  452. printf("sys snprintf: |%s| len = %d\n", str3, len3);
  453. #endif
  454. } else { /* exhaustive testing */
  455. const char flags[] = "+- 0#"; /* set of test flags (including '\0')*/
  456. int flags_l = strlen(flags);
  457. const char fspec[] = "scdpoxXuiy"; /* set of test formats (including '\0') */
  458. int fspec_l = strlen(fspec);
  459. #ifdef SNPRINTF_LONGLONG_SUPPORT
  460. const char datatype[] = " hl2"; /* set of datatypes */
  461. #else
  462. const char datatype[] = " hl"; /* set of datatypes */
  463. #endif
  464. int datatype_l = strlen(datatype);
  465. const long int iargs[] = /* set of numeric test arguments */
  466. { 0,1,9,10,28,99,100,127,128,129,998,1000,32767,32768,32769,
  467. -1,-9,-10,-28,-99,-100,-127,-128,-129,
  468. -998,-1000,-32767,-32768,-32769 };
  469. int iargs_l = sizeof(iargs)/sizeof(iargs[0]);
  470. const char *sargs[] = /* set of string test arguments */
  471. { "", "a", "0", "-ab", "abcde", "abcdefghijk mnopqrstuv" };
  472. int sargs_l = sizeof(sargs)/sizeof(sargs[0]);
  473. char fmt[256];
  474. int fmt_l;
  475. int a, fs, fl1, fl2, fl3, fl4, fl5, fw, fp, dt;
  476. for (fs=0; fs<=fspec_l; fs++) { /* format specifier */
  477. int strtype = (fspec[fs] == 's' || fspec[fs] == '%');
  478. int args_l = (strtype ? sargs_l : iargs_l);
  479. for (fw= -1; fw<=3; fw++) { /* minimal field width */
  480. printf("Trying format %%");
  481. if (fw >= 0) printf("%d", fw);
  482. if (fspec[fs]) putchar(fspec[fs]);
  483. putchar('\n');
  484. for (fp= -2; fp<=3; fp++) { /* format field precision */
  485. /* data type modifiers */
  486. for (dt=0; dt < ((strtype||fspec[fs]=='c') ? 1 : datatype_l); dt++) {
  487. int dataty = datatype[dt];
  488. if (fspec[fs] == 'D' || fspec[fs] == 'U' || fspec[fs] == 'O')
  489. dataty = 'l';
  490. if (fspec[fs] == 'p' && dataty == '2') continue;
  491. for (fl1=0; fl1<=flags_l; fl1++) { /* flags */
  492. for (fl2=0; fl2<=flags_l; fl2++) {
  493. for (fl3=0; fl3<=flags_l; fl3++) {
  494. for (fl4=0; fl4<=flags_l; fl4++) {
  495. for (fl5=0; fl5<=flags_l; fl5++) {
  496. for (a=0; a<args_l; a++) { /* test arguments */
  497. fmt_l = 0; fmt[fmt_l++] = '%';
  498. if (flags[fl1]) fmt[fmt_l++] = flags[fl1];
  499. if (flags[fl2]) fmt[fmt_l++] = flags[fl2];
  500. if (flags[fl3]) fmt[fmt_l++] = flags[fl3];
  501. if (flags[fl4]) fmt[fmt_l++] = flags[fl4];
  502. if (flags[fl5]) fmt[fmt_l++] = flags[fl5];
  503. if (fw >= 0) fmt_l += sprintf(fmt+fmt_l, "%d", fw);
  504. if (fp >= -1) {
  505. fmt[fmt_l++] = '.';
  506. if (fp >= 0) fmt_l += sprintf(fmt+fmt_l, "%d", fp);
  507. }
  508. if (dataty == '2')
  509. { fmt[fmt_l++] = 'l'; fmt[fmt_l++] = 'l'; }
  510. else if (dataty != ' ')
  511. { fmt[fmt_l++] = dataty; }
  512. if (fspec[fs]) fmt[fmt_l++] = fspec[fs];
  513. fmt[fmt_l++] = '\0';
  514. if (a==0 && fl1==flags_l && fl2==flags_l && fl3==flags_l
  515. && fl4==flags_l && fl5==flags_l) printf("%s\n", fmt);
  516. #ifdef HAVE_SNPRINTF
  517. memset(str1,'G',sizeof(str1));
  518. memset(str2,'G',sizeof(str2));
  519. memset(str3,'G',sizeof(str3));
  520. #endif
  521. len1 = len2 = len3 = 0;
  522. if (strtype) {
  523. len1 = portable_snprintf(str1, str_m, fmt, sargs[a]);
  524. len2 = sprintf(str2, fmt, sargs[a]);
  525. #ifdef HAVE_SNPRINTF
  526. len3 = snprintf(str3, str_m, fmt, sargs[a]);
  527. #endif
  528. } else if (fspec[fs] == 'p') {
  529. len1 = portable_snprintf(str1, str_m, fmt, (void *)iargs[a]);
  530. len2 = sprintf(str2, fmt, (void *)iargs[a]);
  531. #ifdef HAVE_SNPRINTF
  532. len3 = snprintf(str3, str_m, fmt, (void *)iargs[a]);
  533. #endif
  534. } else {
  535. switch (dataty) {
  536. case '\0':
  537. len1 = portable_snprintf(str1, str_m, fmt, (int) iargs[a]);
  538. len2 = sprintf(str2, fmt, (int) iargs[a]);
  539. #ifdef HAVE_SNPRINTF
  540. len3 = snprintf(str3, str_m, fmt, (int) iargs[a]);
  541. #endif
  542. break;
  543. case 'h':
  544. len1 = portable_snprintf(str1, str_m, fmt, (short int)iargs[a]);
  545. len2 = sprintf(str2, fmt, (short int)iargs[a]);
  546. #ifdef HAVE_SNPRINTF
  547. len3 = snprintf(str3, str_m, fmt, (short int)iargs[a]);
  548. #endif
  549. break;
  550. case 'l':
  551. len1 = portable_snprintf(str1, str_m, fmt, (long int)iargs[a]);
  552. len2 = sprintf(str2, fmt, (long int)iargs[a]);
  553. #ifdef HAVE_SNPRINTF
  554. len3 = snprintf(str3, str_m, fmt, (long int)iargs[a]);
  555. #endif
  556. break;
  557. #ifdef SNPRINTF_LONGLONG_SUPPORT
  558. case '2':
  559. len1 = portable_snprintf(str1, str_m, fmt, (long long int)iargs[a]);
  560. len2 = sprintf(str2, fmt, (long long int)iargs[a]);
  561. #ifdef HAVE_SNPRINTF
  562. len3 = snprintf(str3, str_m, fmt, (long long int)iargs[a]);
  563. #endif
  564. break;
  565. #endif
  566. }
  567. }
  568. if (0) {
  569. #ifdef HAVE_SNPRINTF
  570. } else if (len1 != len3 ||
  571. memcmp(str1,str3,min(len1+20,sizeof(str1))) != 0) {
  572. bad = 1;
  573. if (strtype) printf("\n2: %s, <%s>\n", fmt, sargs[a]);
  574. else printf("\n2: %s, %ld\n", fmt, iargs[a]);
  575. printf("portable: |%s| len = %d\n", str1, len1);
  576. printf("sys sprintf: |%s| len = %d\n", str2, len2);
  577. printf("sys snprintf: |%s| len = %d\n", str3, len3);
  578. #else
  579. } else if (len1 != len2 ||
  580. (len1>0 && memcmp(str1,str2,min(len1,str_m)-1) != 0)) {
  581. bad = 1;
  582. if (strtype) printf("\n1: %s, <%s>\n", fmt, sargs[a]);
  583. else printf("\n1: %s, %ld\n", fmt, iargs[a]);
  584. printf("portable: |%s| len = %d\n", str1, len1);
  585. printf("sys sprintf: |%s| len = %d\n", str2, len2);
  586. #endif
  587. }
  588. if (bad) return(1);
  589. }
  590. }
  591. }
  592. }
  593. }
  594. }
  595. }
  596. }
  597. }
  598. }
  599. }
  600. return (bad?1:0);
  601. }