Back to index

lightning-sunbird  0.9+nobinonly
sprintf.c
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /*
00039  * File:      sprintf.c
00040  * Description:
00041  *     This is a test program for the PR_snprintf() functions defined
00042  *     in prprf.c.  This test program is based on ns/nspr/tests/sprintf.c,
00043  *     revision 1.10.
00044  * Modification History:
00045  *     20-May-1997 AGarcia replaced printf statment to return PASS\n. This is to be used by the
00046  *                          regress tool parsing routine.
00047  ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
00048  *                   recognize the return code from tha main program.
00049  */
00050 
00051 #include "prinit.h"
00052 #include "prprf.h"
00053 #include "prlog.h"
00054 #include "prlong.h"
00055 #include <string.h>
00056 #include <stdio.h>
00057 #include <stdlib.h>
00058 
00059 #define countof(a) (sizeof(a)/sizeof(a[0]))
00060 
00061 static char sbuf[20000];
00062 
00063 
00064 /*
00065 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
00066 ** Make sure the results are identical
00067 */
00068 static void test_i(char *pattern, int i)
00069 {
00070     char *s;
00071     char buf[200];
00072     int n;
00073 
00074     /* try all three routines */
00075     s = PR_smprintf(pattern, i);
00076     PR_ASSERT(s != 0);
00077     n = PR_snprintf(buf, sizeof(buf), pattern, i);
00078     PR_ASSERT(n <= sizeof(buf));
00079     sprintf(sbuf, pattern, i);
00080 
00081     /* compare results */
00082     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
00083        (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
00084        fprintf(stderr,
00085           "pattern='%s' i=%d\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
00086           pattern, i, s, buf, sbuf);
00087           PR_smprintf_free(s);
00088        exit(-1);
00089     }
00090        PR_smprintf_free(s);
00091 }
00092 
00093 static void TestI(void)
00094 {
00095     static int nums[] = {
00096        0, 1, -1, 10, -10,
00097        32767, -32768,
00098     };
00099     static char *signs[] = {
00100        "",
00101        "0",   "-",   "+", " ",
00102        "0-",  "0+",  "0 ",  "-0",  "-+",  "- ",
00103        "+0",  "+-",  "+ ",  " 0",  " -",  " +",
00104        "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +",
00105        "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +",
00106        "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -",
00107        " 0-", " 0+", " -0", " -+", " +0", " +-",
00108        "0-+ ",       "0- +",       "0+- ",       "0+ -",       "0 -+",       "0 +-",
00109        "-0+ ",       "-0 +",       "-+0 ",       "-+ 0",       "- 0+",       "- +0",
00110        "+0- ",       "+0 -",       "+-0 ",       "+- 0",       "+ 0-",       "+ -0",
00111        " 0-+",       " 0+-",       " -0+",       " -+0",       " +0-",       " +-0",
00112     };
00113     static char *precs[] = {
00114        "", "3", "5", "43",
00115        "7.3", "7.5", "7.11", "7.43",
00116     };
00117     static char *formats[] = {
00118        "d", "o", "x", "u",
00119        "hd", "ho", "hx", "hu"
00120     };
00121     int f, s, n, p;
00122     char fmt[20];
00123 
00124     for (f = 0; f < countof(formats); f++) {
00125        for (s = 0; s < countof(signs); s++) {
00126            for (p = 0; p < countof(precs); p++) {
00127               fmt[0] = '%';
00128               fmt[1] = 0;
00129               if (signs[s]) strcat(fmt, signs[s]);
00130               if (precs[p]) strcat(fmt, precs[p]);
00131               if (formats[f]) strcat(fmt, formats[f]);
00132               for (n = 0; n < countof(nums); n++) {
00133                   test_i(fmt, nums[n]);
00134               }
00135            }
00136        }
00137     }
00138 }
00139 
00140 /************************************************************************/
00141 
00142 /*
00143 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
00144 ** Make sure the results are identical
00145 */
00146 static void test_l(char *pattern, char *spattern, PRInt32 l)
00147 {
00148     char *s;
00149     char buf[200];
00150     int n;
00151 
00152     /* try all three routines */
00153     s = PR_smprintf(pattern, l);
00154     PR_ASSERT(s != 0);
00155     n = PR_snprintf(buf, sizeof(buf), pattern, l);
00156     PR_ASSERT(n <= sizeof(buf));
00157     sprintf(sbuf, spattern, l);
00158 
00159     /* compare results */
00160     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
00161        (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
00162        fprintf(stderr,
00163           "pattern='%s' l=%ld\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
00164           pattern, l, s, buf, sbuf);
00165        PR_smprintf_free(s);
00166        exit(-1);
00167     }
00168        PR_smprintf_free(s);
00169 }
00170 
00171 static void TestL(void)
00172 {
00173     static PRInt32 nums[] = {
00174        0,
00175        1,
00176        -1,
00177        10,
00178        -10,
00179        32767,
00180        -32768,
00181        PR_INT32(0x7fffffff), /* 2147483647L */
00182        -1 - PR_INT32(0x7fffffff)  /* -2147483648L */
00183     };
00184     static char *signs[] = {
00185        "",
00186        "0",   "-",   "+", " ",
00187        "0-",  "0+",  "0 ",  "-0",  "-+",  "- ",
00188        "+0",  "+-",  "+ ",  " 0",  " -",  " +",
00189        "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +",
00190        "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +",
00191        "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -",
00192        " 0-", " 0+", " -0", " -+", " +0", " +-",
00193        "0-+ ",       "0- +",       "0+- ",       "0+ -",       "0 -+",       "0 +-",
00194        "-0+ ",       "-0 +",       "-+0 ",       "-+ 0",       "- 0+",       "- +0",
00195        "+0- ",       "+0 -",       "+-0 ",       "+- 0",       "+ 0-",       "+ -0",
00196        " 0-+",       " 0+-",       " -0+",       " -+0",       " +0-",       " +-0",
00197     };
00198     static char *precs[] = {
00199        "", "3", "5", "43",
00200        ".3", ".43",
00201        "7.3", "7.5", "7.11", "7.43",
00202     };
00203     static char *formats[] = { "ld", "lo", "lx", "lu" };
00204 
00205 #if PR_BYTES_PER_INT == 4
00206     static char *sformats[] = { "d", "o", "x", "u" };
00207 #elif PR_BYTES_PER_LONG == 4
00208     static char *sformats[] = { "ld", "lo", "lx", "lu" };
00209 #else
00210 #error Neither int nor long is 4 bytes on this platform
00211 #endif
00212 
00213     int f, s, n, p;
00214     char fmt[40], sfmt[40];
00215 
00216     for (f = 0; f < countof(formats); f++) {
00217        for (s = 0; s < countof(signs); s++) {
00218            for (p = 0; p < countof(precs); p++) {
00219               fmt[0] = '%';
00220               fmt[1] = 0;
00221               if (signs[s]) strcat(fmt, signs[s]);
00222               if (precs[p]) strcat(fmt, precs[p]);
00223               strcpy(sfmt, fmt);
00224               if (formats[f]) strcat(fmt, formats[f]);
00225               if (sformats[f]) strcat(sfmt, sformats[f]);
00226               for (n = 0; n < countof(nums); n++) {
00227                   test_l(fmt, sfmt, nums[n]);
00228               }
00229            }
00230        }
00231     }
00232 }
00233 
00234 /************************************************************************/
00235 
00236 /*
00237 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
00238 ** Make sure the results are identical
00239 */
00240 static void test_ll(char *pattern, char *spattern, PRInt64 l)
00241 {
00242     char *s;
00243     char buf[200];
00244     int n;
00245 
00246     /* try all three routines */
00247     s = PR_smprintf(pattern, l);
00248     PR_ASSERT(s != 0);
00249     n = PR_snprintf(buf, sizeof(buf), pattern, l);
00250     PR_ASSERT(n <= sizeof(buf));
00251 #if defined(HAVE_LONG_LONG)
00252     sprintf(sbuf, spattern, l);
00253 
00254     /* compare results */
00255     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
00256        (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
00257 #if PR_BYTES_PER_LONG == 8
00258 #define FORMAT_SPEC "%ld"
00259 #elif defined(WIN16)
00260 #define FORMAT_SPEC "%Ld"
00261 #elif defined(WIN32)
00262 #define FORMAT_SPEC "%I64d"
00263 #else
00264 #define FORMAT_SPEC "%lld"
00265 #endif
00266        fprintf(stderr,
00267            "pattern='%s' ll=" FORMAT_SPEC "\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
00268            pattern, l, s, buf, sbuf);
00269        printf("FAIL\n");
00270        PR_smprintf_free(s);
00271        exit(-1);
00272     }
00273        PR_smprintf_free(s);
00274 #else
00275     /* compare results */
00276     if ((strncmp(s, buf, sizeof(buf)) != 0)) {
00277        fprintf(stderr,
00278            "pattern='%s'\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
00279            pattern, s, buf, sbuf);
00280        printf("FAIL\n");
00281        PR_smprintf_free(s);
00282         exit(-1);
00283     }
00284        PR_smprintf_free(s);
00285 #endif
00286 }
00287 
00288 static void TestLL(void)
00289 {
00290     static PRInt64 nums[] = {
00291        LL_INIT(0, 0),
00292        LL_INIT(0, 1),
00293        LL_INIT(0xffffffff, 0xffffffff),  /* -1 */
00294        LL_INIT(0, 10),
00295        LL_INIT(0xffffffff, 0xfffffff6),  /* -10 */
00296        LL_INIT(0, 32767),
00297        LL_INIT(0xffffffff, 0xffff8000),  /* -32768 */
00298        LL_INIT(0, 0x7fffffff),  /* 2147483647 */
00299        LL_INIT(0xffffffff, 0x80000000),  /* -2147483648 */
00300        LL_INIT(0x7fffffff, 0xffffffff),  /* 9223372036854775807 */
00301        LL_INIT(0x80000000, 0)            /* -9223372036854775808 */
00302     };
00303 
00304     static char *signs[] = {
00305        "",
00306        "0",   "-",   "+", " ",
00307        "0-",  "0+",  "0 ",  "-0",  "-+",  "- ",
00308        "+0",  "+-",  "+ ",  " 0",  " -",  " +",
00309        "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +",
00310        "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +",
00311        "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -",
00312        " 0-", " 0+", " -0", " -+", " +0", " +-",
00313        "0-+ ",       "0- +",       "0+- ",       "0+ -",       "0 -+",       "0 +-",
00314        "-0+ ",       "-0 +",       "-+0 ",       "-+ 0",       "- 0+",       "- +0",
00315        "+0- ",       "+0 -",       "+-0 ",       "+- 0",       "+ 0-",       "+ -0",
00316        " 0-+",       " 0+-",       " -0+",       " -+0",       " +0-",       " +-0",
00317     };
00318     static char *precs[] = {
00319        "", "3", "5", "43",
00320        ".3", ".43",
00321        "7.3", "7.5", "7.11", "7.43",
00322     };
00323     static char *formats[] = { "lld", "llo", "llx", "llu" };
00324 
00325 #if PR_BYTES_PER_LONG == 8
00326     static char *sformats[] = { "ld", "lo", "lx", "lu" };
00327 #elif defined(WIN16)
00328     /* Watcom uses the format string "%Ld" instead of "%lld". */
00329     static char *sformats[] = { "Ld", "Lo", "Lx", "Lu" };
00330 #elif defined(WIN32)
00331     static char *sformats[] = { "I64d", "I64o", "I64x", "I64u" };
00332 #else
00333     static char *sformats[] = { "lld", "llo", "llx", "llu" };
00334 #endif
00335 
00336     int f, s, n, p;
00337     char fmt[40], sfmt[40];
00338 
00339     for (f = 0; f < countof(formats); f++) {
00340        for (s = 0; s < countof(signs); s++) {
00341            for (p = 0; p < countof(precs); p++) {
00342               fmt[0] = '%';
00343               fmt[1] = 0;
00344               if (signs[s]) strcat(fmt, signs[s]);
00345               if (precs[p]) strcat(fmt, precs[p]);
00346               strcpy(sfmt, fmt);
00347               if (formats[f]) strcat(fmt, formats[f]);
00348               if (sformats[f]) strcat(sfmt, sformats[f]);
00349               for (n = 0; n < countof(nums); n++) {
00350                   test_ll(fmt, sfmt, nums[n]);
00351               }
00352            }
00353        }
00354     }
00355 }
00356 
00357 /************************************************************************/
00358 
00359 /*
00360 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
00361 ** Make sure the results are identical
00362 */
00363 static void test_s(char *pattern, char *ss)
00364 {
00365     char *s;
00366     unsigned char before[8];
00367     char buf[200];
00368     unsigned char after[8];
00369     int n;
00370 
00371     memset(before, 0xBB, 8);
00372     memset(after, 0xAA, 8);
00373 
00374     /* try all three routines */
00375     s = PR_smprintf(pattern, ss);
00376     PR_ASSERT(s != 0);
00377     n = PR_snprintf(buf, sizeof(buf), pattern, ss);
00378     PR_ASSERT(n <= sizeof(buf));
00379     sprintf(sbuf, pattern, ss);
00380 
00381     for (n = 0; n < 8; n++) {
00382        PR_ASSERT(before[n] == 0xBB);
00383        PR_ASSERT(after[n] == 0xAA);
00384     }
00385 
00386     /* compare results */
00387     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
00388        (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
00389        fprintf(stderr,
00390           "pattern='%s' ss=%.20s\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
00391           pattern, ss, s, buf, sbuf);
00392        printf("FAIL\n");
00393        PR_smprintf_free(s);
00394        exit(-1);
00395     }
00396        PR_smprintf_free(s);
00397 }
00398 
00399 static void TestS(void)
00400 {
00401     static char *strs[] = {
00402        "",
00403        "a",
00404        "abc",
00405        "abcde",
00406        "abcdefABCDEF",
00407        "abcdefghijklmnopqrstuvwxyz0123456789!@#$"
00408            "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$"
00409            "abcdefghijklmnopqrstuvwxyz0123456789!@#$",
00410     };
00411     /* '0' is not relevant to printing strings */
00412     static char *signs[] = {
00413        "",
00414        "-",   "+",   " ",
00415        "-+",  "- ",  "+-",  "+ ",  " -",  " +",
00416        "-+ ", "- +", "+- ", "+ -", " -+", " +-",
00417     };
00418     static char *precs[] = {
00419        "", "3", "5", "43",
00420        ".3", ".43",
00421        "7.3", "7.5", "7.11", "7.43",
00422     };
00423     static char *formats[] = { "s" };
00424     int f, s, n, p;
00425     char fmt[40];
00426 
00427     for (f = 0; f < countof(formats); f++) {
00428        for (s = 0; s < countof(signs); s++) {
00429            for (p = 0; p < countof(precs); p++) {
00430               fmt[0] = '%';
00431               fmt[1] = 0;
00432               if (signs[s]) strcat(fmt+strlen(fmt), signs[s]);
00433               if (precs[p]) strcat(fmt+strlen(fmt), precs[p]);
00434               if (formats[f]) strcat(fmt+strlen(fmt), formats[f]);
00435               for (n = 0; n < countof(strs); n++) {
00436                   test_s(fmt, strs[n]);
00437               }
00438            }
00439        }
00440     }
00441 }
00442 
00443 /************************************************************************/
00444 
00445 int main(int argc, char **argv)
00446 {
00447     PR_STDIO_INIT();
00448     TestI();
00449     TestL();
00450     TestLL();
00451     TestS();
00452     printf("PASS\n");
00453     return 0;
00454 }