sprintf.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /*
  6. * File: sprintf.c
  7. * Description:
  8. * This is a test program for the PR_snprintf() functions defined
  9. * in prprf.c. This test program is based on ns/nspr/tests/sprintf.c,
  10. * revision 1.10.
  11. * Modification History:
  12. * 20-May-1997 AGarcia replaced printf statment to return PASS\n. This is to be used by the
  13. * regress tool parsing routine.
  14. ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
  15. * recognize the return code from tha main program.
  16. */
  17. #include "prinit.h"
  18. #include "prprf.h"
  19. #include "prlog.h"
  20. #include "prlong.h"
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. static char sbuf[20000];
  25. /*
  26. ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
  27. ** Make sure the results are identical
  28. */
  29. static void test_i(char *pattern, int i)
  30. {
  31. char *s;
  32. char buf[200];
  33. int n;
  34. /* try all three routines */
  35. s = PR_smprintf(pattern, i);
  36. PR_ASSERT(s != 0);
  37. n = PR_snprintf(buf, sizeof(buf), pattern, i);
  38. PR_ASSERT(n <= sizeof(buf));
  39. sprintf(sbuf, pattern, i);
  40. /* compare results */
  41. if ((strncmp(s, buf, sizeof(buf)) != 0) ||
  42. (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
  43. fprintf(stderr,
  44. "pattern='%s' i=%d\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n",
  45. pattern, i, s, buf, sbuf);
  46. PR_smprintf_free(s);
  47. exit(-1);
  48. }
  49. PR_smprintf_free(s);
  50. }
  51. static void TestI(void)
  52. {
  53. static int nums[] = {
  54. 0, 1, -1, 10, -10,
  55. 32767, -32768,
  56. };
  57. static char *signs[] = {
  58. "",
  59. "0", "-", "+", " ",
  60. "0-", "0+", "0 ", "-0", "-+", "- ",
  61. "+0", "+-", "+ ", " 0", " -", " +",
  62. "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +",
  63. "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +",
  64. "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -",
  65. " 0-", " 0+", " -0", " -+", " +0", " +-",
  66. "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-",
  67. "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0",
  68. "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0",
  69. " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0",
  70. };
  71. static char *precs[] = {
  72. "", "3", "5", "43",
  73. "7.3", "7.5", "7.11", "7.43",
  74. };
  75. static char *formats[] = {
  76. "d", "o", "x", "u",
  77. "hd", "ho", "hx", "hu"
  78. };
  79. int f, s, n, p;
  80. char fmt[20];
  81. for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
  82. for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
  83. for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
  84. fmt[0] = '%';
  85. fmt[1] = 0;
  86. if (signs[s]) {
  87. strcat(fmt, signs[s]);
  88. }
  89. if (precs[p]) {
  90. strcat(fmt, precs[p]);
  91. }
  92. if (formats[f]) {
  93. strcat(fmt, formats[f]);
  94. }
  95. for (n = 0; n < PR_ARRAY_SIZE(nums); n++) {
  96. test_i(fmt, nums[n]);
  97. }
  98. }
  99. }
  100. }
  101. }
  102. /************************************************************************/
  103. /*
  104. ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
  105. ** Make sure the results are identical
  106. */
  107. static void test_l(char *pattern, char *spattern, PRInt32 l)
  108. {
  109. char *s;
  110. char buf[200];
  111. int n;
  112. /* try all three routines */
  113. s = PR_smprintf(pattern, l);
  114. PR_ASSERT(s != 0);
  115. n = PR_snprintf(buf, sizeof(buf), pattern, l);
  116. PR_ASSERT(n <= sizeof(buf));
  117. sprintf(sbuf, spattern, l);
  118. /* compare results */
  119. if ((strncmp(s, buf, sizeof(buf)) != 0) ||
  120. (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
  121. fprintf(stderr,
  122. "pattern='%s' l=%ld\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n",
  123. pattern, l, s, buf, sbuf);
  124. PR_smprintf_free(s);
  125. exit(-1);
  126. }
  127. PR_smprintf_free(s);
  128. }
  129. static void TestL(void)
  130. {
  131. static PRInt32 nums[] = {
  132. 0,
  133. 1,
  134. -1,
  135. 10,
  136. -10,
  137. 32767,
  138. -32768,
  139. PR_INT32(0x7fffffff), /* 2147483647L */
  140. -1 - PR_INT32(0x7fffffff) /* -2147483648L */
  141. };
  142. static char *signs[] = {
  143. "",
  144. "0", "-", "+", " ",
  145. "0-", "0+", "0 ", "-0", "-+", "- ",
  146. "+0", "+-", "+ ", " 0", " -", " +",
  147. "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +",
  148. "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +",
  149. "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -",
  150. " 0-", " 0+", " -0", " -+", " +0", " +-",
  151. "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-",
  152. "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0",
  153. "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0",
  154. " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0",
  155. };
  156. static char *precs[] = {
  157. "", "3", "5", "43",
  158. ".3", ".43",
  159. "7.3", "7.5", "7.11", "7.43",
  160. };
  161. static char *formats[] = { "ld", "lo", "lx", "lu" };
  162. #if PR_BYTES_PER_INT == 4
  163. static char *sformats[] = { "d", "o", "x", "u" };
  164. #elif PR_BYTES_PER_LONG == 4
  165. static char *sformats[] = { "ld", "lo", "lx", "lu" };
  166. #else
  167. #error Neither int nor long is 4 bytes on this platform
  168. #endif
  169. int f, s, n, p;
  170. char fmt[40], sfmt[40];
  171. for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
  172. for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
  173. for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
  174. fmt[0] = '%';
  175. fmt[1] = 0;
  176. if (signs[s]) {
  177. strcat(fmt, signs[s]);
  178. }
  179. if (precs[p]) {
  180. strcat(fmt, precs[p]);
  181. }
  182. strcpy(sfmt, fmt);
  183. if (formats[f]) {
  184. strcat(fmt, formats[f]);
  185. }
  186. if (sformats[f]) {
  187. strcat(sfmt, sformats[f]);
  188. }
  189. for (n = 0; n < PR_ARRAY_SIZE(nums); n++) {
  190. test_l(fmt, sfmt, nums[n]);
  191. }
  192. }
  193. }
  194. }
  195. }
  196. /************************************************************************/
  197. /*
  198. ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
  199. ** Make sure the results are identical
  200. */
  201. static void test_ll(char *pattern, char *spattern, PRInt64 l)
  202. {
  203. char *s;
  204. char buf[200];
  205. int n;
  206. /* try all three routines */
  207. s = PR_smprintf(pattern, l);
  208. PR_ASSERT(s != 0);
  209. n = PR_snprintf(buf, sizeof(buf), pattern, l);
  210. PR_ASSERT(n <= sizeof(buf));
  211. #if defined(HAVE_LONG_LONG)
  212. sprintf(sbuf, spattern, l);
  213. /* compare results */
  214. if ((strncmp(s, buf, sizeof(buf)) != 0) ||
  215. (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
  216. #if PR_BYTES_PER_LONG == 8
  217. #define FORMAT_SPEC "%ld"
  218. #elif defined(WIN16)
  219. #define FORMAT_SPEC "%Ld"
  220. #elif defined(WIN32)
  221. #define FORMAT_SPEC "%I64d"
  222. #else
  223. #define FORMAT_SPEC "%lld"
  224. #endif
  225. fprintf(stderr,
  226. "pattern='%s' ll=" FORMAT_SPEC "\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n",
  227. pattern, l, s, buf, sbuf);
  228. printf("FAIL\n");
  229. PR_smprintf_free(s);
  230. exit(-1);
  231. }
  232. PR_smprintf_free(s);
  233. #else
  234. /* compare results */
  235. if ((strncmp(s, buf, sizeof(buf)) != 0)) {
  236. fprintf(stderr,
  237. "pattern='%s'\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n",
  238. pattern, s, buf, sbuf);
  239. printf("FAIL\n");
  240. PR_smprintf_free(s);
  241. exit(-1);
  242. }
  243. PR_smprintf_free(s);
  244. #endif
  245. }
  246. static void TestLL(void)
  247. {
  248. static PRInt64 nums[] = {
  249. LL_INIT(0, 0),
  250. LL_INIT(0, 1),
  251. LL_INIT(0xffffffff, 0xffffffff), /* -1 */
  252. LL_INIT(0, 10),
  253. LL_INIT(0xffffffff, 0xfffffff6), /* -10 */
  254. LL_INIT(0, 32767),
  255. LL_INIT(0xffffffff, 0xffff8000), /* -32768 */
  256. LL_INIT(0, 0x7fffffff), /* 2147483647 */
  257. LL_INIT(0xffffffff, 0x80000000), /* -2147483648 */
  258. LL_INIT(0x7fffffff, 0xffffffff), /* 9223372036854775807 */
  259. LL_INIT(0x80000000, 0), /* -9223372036854775808 */
  260. PR_INT64(0),
  261. PR_INT64(1),
  262. PR_INT64(-1),
  263. PR_INT64(10),
  264. PR_INT64(-10),
  265. PR_INT64(32767),
  266. PR_INT64(-32768),
  267. PR_INT64(2147483647),
  268. PR_INT64(-2147483648),
  269. PR_INT64(9223372036854775807),
  270. PR_INT64(-9223372036854775808)
  271. };
  272. static char *signs[] = {
  273. "",
  274. "0", "-", "+", " ",
  275. "0-", "0+", "0 ", "-0", "-+", "- ",
  276. "+0", "+-", "+ ", " 0", " -", " +",
  277. "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +",
  278. "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +",
  279. "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -",
  280. " 0-", " 0+", " -0", " -+", " +0", " +-",
  281. "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-",
  282. "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0",
  283. "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0",
  284. " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0",
  285. };
  286. static char *precs[] = {
  287. "", "3", "5", "43",
  288. ".3", ".43",
  289. "7.3", "7.5", "7.11", "7.43",
  290. };
  291. static char *formats[] = { "lld", "llo", "llx", "llu" };
  292. #if PR_BYTES_PER_LONG == 8
  293. static char *sformats[] = { "ld", "lo", "lx", "lu" };
  294. #elif defined(WIN16)
  295. /* Watcom uses the format string "%Ld" instead of "%lld". */
  296. static char *sformats[] = { "Ld", "Lo", "Lx", "Lu" };
  297. #elif defined(WIN32)
  298. static char *sformats[] = { "I64d", "I64o", "I64x", "I64u" };
  299. #else
  300. static char *sformats[] = { "lld", "llo", "llx", "llu" };
  301. #endif
  302. int f, s, n, p;
  303. char fmt[40], sfmt[40];
  304. for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
  305. for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
  306. for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
  307. fmt[0] = '%';
  308. fmt[1] = 0;
  309. if (signs[s]) {
  310. strcat(fmt, signs[s]);
  311. }
  312. if (precs[p]) {
  313. strcat(fmt, precs[p]);
  314. }
  315. strcpy(sfmt, fmt);
  316. if (formats[f]) {
  317. strcat(fmt, formats[f]);
  318. }
  319. if (sformats[f]) {
  320. strcat(sfmt, sformats[f]);
  321. }
  322. for (n = 0; n < PR_ARRAY_SIZE(nums); n++) {
  323. test_ll(fmt, sfmt, nums[n]);
  324. }
  325. }
  326. }
  327. }
  328. }
  329. /************************************************************************/
  330. /*
  331. ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
  332. ** Make sure the results are identical
  333. */
  334. static void test_s(char *pattern, char *ss)
  335. {
  336. char *s;
  337. unsigned char before[8];
  338. char buf[200];
  339. unsigned char after[8];
  340. int n;
  341. memset(before, 0xBB, 8);
  342. memset(after, 0xAA, 8);
  343. /* try all three routines */
  344. s = PR_smprintf(pattern, ss);
  345. PR_ASSERT(s != 0);
  346. n = PR_snprintf(buf, sizeof(buf), pattern, ss);
  347. PR_ASSERT(n <= sizeof(buf));
  348. sprintf(sbuf, pattern, ss);
  349. for (n = 0; n < 8; n++) {
  350. PR_ASSERT(before[n] == 0xBB);
  351. PR_ASSERT(after[n] == 0xAA);
  352. }
  353. /* compare results */
  354. if ((strncmp(s, buf, sizeof(buf)) != 0) ||
  355. (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
  356. fprintf(stderr,
  357. "pattern='%s' ss=%.20s\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n",
  358. pattern, ss, s, buf, sbuf);
  359. printf("FAIL\n");
  360. PR_smprintf_free(s);
  361. exit(-1);
  362. }
  363. PR_smprintf_free(s);
  364. }
  365. static void TestS(void)
  366. {
  367. static char *strs[] = {
  368. "",
  369. "a",
  370. "abc",
  371. "abcde",
  372. "abcdefABCDEF",
  373. "abcdefghijklmnopqrstuvwxyz0123456789!@#$"
  374. "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$"
  375. "abcdefghijklmnopqrstuvwxyz0123456789!@#$",
  376. };
  377. /* '0' is not relevant to printing strings */
  378. static char *signs[] = {
  379. "",
  380. "-", "+", " ",
  381. "-+", "- ", "+-", "+ ", " -", " +",
  382. "-+ ", "- +", "+- ", "+ -", " -+", " +-",
  383. };
  384. static char *precs[] = {
  385. "", "3", "5", "43",
  386. ".3", ".43",
  387. "7.3", "7.5", "7.11", "7.43",
  388. };
  389. static char *formats[] = { "s" };
  390. int f, s, n, p;
  391. char fmt[40];
  392. for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
  393. for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
  394. for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
  395. fmt[0] = '%';
  396. fmt[1] = 0;
  397. if (signs[s]) {
  398. strcat(fmt+strlen(fmt), signs[s]);
  399. }
  400. if (precs[p]) {
  401. strcat(fmt+strlen(fmt), precs[p]);
  402. }
  403. if (formats[f]) {
  404. strcat(fmt+strlen(fmt), formats[f]);
  405. }
  406. for (n = 0; n < PR_ARRAY_SIZE(strs); n++) {
  407. test_s(fmt, strs[n]);
  408. }
  409. }
  410. }
  411. }
  412. }
  413. /************************************************************************/
  414. int main(int argc, char **argv)
  415. {
  416. PR_STDIO_INIT();
  417. TestI();
  418. TestL();
  419. TestLL();
  420. TestS();
  421. printf("PASS\n");
  422. return 0;
  423. }