summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2013-04-15 18:35:36 +0100
committerChris Liddell <chris.liddell@artifex.com>2013-05-07 09:15:48 +0100
commite64ac4c83a4ae07dc15c4cacd7b60cba6294899a (patch)
treeda281911407c5bc8c8fcd77c81bf9815d520bb34
parent07ba8bea8e98084a156edac611a4ae92545edf06 (diff)
Bug 693843: Add a gs_sprintf() function, and supporting code
Same as sprintf() but certain to be unaffected by localization. Utilizes the "trio" string library, also added here. There is one modification to trio, in trio.c and labelled with "/* GS Modification */" - by default, trio is a little aggressive in the point it switches to exponent notation, and the patch brings is more line with what we need/expect. trio also includes a sscanf() function which we can utilise if required. See the gs-sprintf branch for the individual commits - especially those in the trio source, should a trio update ever be pulled in. This causes rounding differences in the pdfwrite/ps2write output in a number of the cluster files. They all appear to be pixel variations.
-rw-r--r--common/msvc_top.mak2
-rw-r--r--common/ugcc_top.mak1
-rw-r--r--gs/Makefile.in3
-rw-r--r--gs/base/fapiufst.c2
-rw-r--r--gs/base/gdevdevn.c6
-rw-r--r--gs/base/gdevp14.c8
-rw-r--r--gs/base/gp_macio.c10
-rw-r--r--gs/base/gp_mswin.c10
-rw-r--r--gs/base/gp_wgetv.c6
-rw-r--r--gs/base/gs.mak2
-rw-r--r--gs/base/gsalloc.c2
-rw-r--r--gs/base/gsdevice.c6
-rw-r--r--gs/base/gsdparam.c4
-rw-r--r--gs/base/gsfcmap.c2
-rw-r--r--gs/base/gsicc_create.c2
-rw-r--r--gs/base/gsicc_manage.c12
-rw-r--r--gs/base/gsiodisk.c10
-rw-r--r--gs/base/gspmdrv.c32
-rw-r--r--gs/base/gssprintf.c60
-rw-r--r--gs/base/gssprintf.h33
-rw-r--r--gs/base/gxblend.c12
-rw-r--r--gs/base/gxblend1.c2
-rw-r--r--gs/base/gxclmem.c2
-rw-r--r--gs/base/gxhintn.c2
-rw-r--r--gs/base/gxpath.c2
-rw-r--r--gs/base/gxpcmap.c4
-rw-r--r--gs/base/lib.mak12
-rw-r--r--gs/base/md5main.c2
-rw-r--r--gs/base/mkromfs.c2
-rw-r--r--gs/base/sdcparam.c6
-rw-r--r--gs/base/sjbig2.c2
-rw-r--r--gs/base/spprint.c10
-rw-r--r--gs/base/stdio_.h9
-rw-r--r--gs/base/trio.mak57
-rw-r--r--gs/base/unix-gcc.mak3
-rw-r--r--gs/base/unixansi.mak3
-rw-r--r--gs/base/winlib.mak1
-rw-r--r--gs/base/wrfont.c4
-rw-r--r--gs/base/write_t1.c10
-rw-r--r--gs/base/write_t2.c2
-rw-r--r--gs/contrib/eplaser/gdevescv.c98
-rw-r--r--gs/contrib/gdevcd8.c4
-rw-r--r--gs/contrib/gdevdj9.c2
-rw-r--r--gs/contrib/gdevhl12.c2
-rw-r--r--gs/contrib/gdevxes.c6
-rw-r--r--gs/contrib/gomni.c8
-rw-r--r--gs/contrib/japanese/dviprlib.c28
-rw-r--r--gs/contrib/japanese/gdevfmlbp.c6
-rw-r--r--gs/contrib/japanese/gdevfmpr.c4
-rw-r--r--gs/contrib/japanese/gdevj100.c8
-rw-r--r--gs/contrib/japanese/gdevlbp3.c4
-rw-r--r--gs/contrib/japanese/gdevmag.c4
-rw-r--r--gs/contrib/japanese/gdevnpdl.c18
-rw-r--r--gs/contrib/lips4/gdevl4r.c10
-rw-r--r--gs/contrib/lips4/gdevl4v.c88
-rw-r--r--gs/contrib/pcl3/src/gdevpcl3.c2
-rw-r--r--gs/cups/gdevcups.c3
-rw-r--r--gs/devices/gdev3b1.c2
-rw-r--r--gs/devices/gdev8510.c2
-rw-r--r--gs/devices/gdevccr.c6
-rw-r--r--gs/devices/gdevdjet.c16
-rw-r--r--gs/devices/gdevijs.c16
-rw-r--r--gs/devices/gdevl31s.c6
-rw-r--r--gs/devices/gdevpng.c2
-rw-r--r--gs/devices/gdevsppr.c2
-rw-r--r--gs/devices/gdevsun.c2
-rw-r--r--gs/devices/gdevtifs.c4
-rw-r--r--gs/devices/gdevtsep.c10
-rw-r--r--gs/devices/gdevupd.c18
-rw-r--r--gs/devices/gdevwpr2.c8
-rw-r--r--gs/devices/gdevxini.c2
-rw-r--r--gs/devices/vector/gdevpdf.c52
-rw-r--r--gs/devices/vector/gdevpdfb.c2
-rw-r--r--gs/devices/vector/gdevpdfe.c4
-rw-r--r--gs/devices/vector/gdevpdfg.c8
-rw-r--r--gs/devices/vector/gdevpdfi.c2
-rw-r--r--gs/devices/vector/gdevpdfm.c8
-rw-r--r--gs/devices/vector/gdevpdfo.c4
-rw-r--r--gs/devices/vector/gdevpdfr.c6
-rw-r--r--gs/devices/vector/gdevpdft.c4
-rw-r--r--gs/devices/vector/gdevpdfu.c30
-rw-r--r--gs/devices/vector/gdevpdfv.c6
-rw-r--r--gs/devices/vector/gdevpdtb.c4
-rw-r--r--gs/devices/vector/gdevpdtc.c4
-rw-r--r--gs/devices/vector/gdevpdtf.c2
-rw-r--r--gs/devices/vector/gdevpdti.c2
-rw-r--r--gs/devices/vector/gdevpdtt.c2
-rw-r--r--gs/devices/vector/gdevpdtw.c2
-rw-r--r--gs/devices/vector/gdevps.c8
-rw-r--r--gs/devices/vector/gdevpsf1.c4
-rw-r--r--gs/devices/vector/gdevpsf2.c2
-rw-r--r--gs/devices/vector/gdevsvg.c26
-rw-r--r--gs/devices/vector/gdevtxtw.c22
-rw-r--r--gs/devices/vector/gdevxps.c24
-rw-r--r--gs/psi/dmmain.c4
-rw-r--r--gs/psi/dpmain.c50
-rw-r--r--gs/psi/dscparse.c8
-rw-r--r--gs/psi/dwimg.c5
-rw-r--r--gs/psi/dwmainc.c2
-rw-r--r--gs/psi/dxmain.c2
-rw-r--r--gs/psi/int.mak2
-rw-r--r--gs/psi/iparam.c2
-rw-r--r--gs/psi/iutil.c14
-rw-r--r--gs/psi/iutil2.c2
-rw-r--r--gs/psi/msvc.mak4
-rw-r--r--gs/psi/zbfont.c4
-rw-r--r--gs/psi/zdouble.c8
-rw-r--r--gs/psi/zfapi.c8
-rw-r--r--gs/psi/zfont2.c2
-rw-r--r--gs/trio/CHANGES785
-rw-r--r--gs/trio/FILES33
-rw-r--r--gs/trio/Makefile.in73
-rw-r--r--gs/trio/README38
-rwxr-xr-xgs/trio/autogen.sh3
-rw-r--r--gs/trio/compare.c53
-rw-r--r--gs/trio/configure.in54
-rw-r--r--gs/trio/doc/doc.h172
-rw-r--r--gs/trio/doc/doc_dynamic.h31
-rw-r--r--gs/trio/doc/doc_printf.h532
-rw-r--r--gs/trio/doc/doc_register.h384
-rw-r--r--gs/trio/doc/doc_scanf.h120
-rw-r--r--gs/trio/doc/doc_static.h61
-rw-r--r--gs/trio/doc/footer.html4
-rw-r--r--gs/trio/doc/header.html8
-rw-r--r--gs/trio/doc/trio.cfg873
-rw-r--r--gs/trio/doc/trio.css35
-rw-r--r--gs/trio/example.c543
-rw-r--r--gs/trio/html/group___dynamic_strings.html300
-rw-r--r--gs/trio/html/group___printf.html1404
-rw-r--r--gs/trio/html/group___scanf.html766
-rw-r--r--gs/trio/html/group___special_quantities.html377
-rw-r--r--gs/trio/html/group___static_strings.html1864
-rw-r--r--gs/trio/html/group___user_defined.html391
-rw-r--r--gs/trio/html/index.html89
-rw-r--r--gs/trio/html/modules.html23
-rw-r--r--gs/trio/html/trio.css35
-rwxr-xr-xgs/trio/install-sh250
-rwxr-xr-xgs/trio/maketgz46
-rw-r--r--gs/trio/regression.c1640
-rw-r--r--gs/trio/strio.h73
-rw-r--r--gs/trio/trio.c7771
-rw-r--r--gs/trio/trio.h235
-rw-r--r--gs/trio/triodef.h336
-rw-r--r--gs/trio/trionan.c1257
-rw-r--r--gs/trio/trionan.h183
-rw-r--r--gs/trio/triop.h472
-rw-r--r--gs/trio/triostr.c2385
-rw-r--r--gs/trio/triostr.h681
-rw-r--r--main/pcl6_gcc.mak3
-rw-r--r--main/pcl6_msvc.mak4
-rw-r--r--pcl/pcfontpg.c4
-rw-r--r--pcl/pcht.c2
-rw-r--r--pcl/pcstatus.c10
-rw-r--r--pl/dwimg.c2
-rw-r--r--pl/dwmainc.c4
-rw-r--r--pl/pjparse.c2
-rw-r--r--pl/plmain.c10
-rw-r--r--pxl/pxerrors.c14
-rw-r--r--pxl/pxfont.c2
-rw-r--r--pxl/pxpthr.c2
-rw-r--r--svg/svg_msvc.mak4
-rw-r--r--xps/xps_msvc.mak4
-rw-r--r--xps/xpsttf.c2
-rw-r--r--xps/xpszip.c16
164 files changed, 25077 insertions, 484 deletions
diff --git a/common/msvc_top.mak b/common/msvc_top.mak
index ba8b0cfe6..d48980d08 100644
--- a/common/msvc_top.mak
+++ b/common/msvc_top.mak
@@ -125,6 +125,7 @@ $(GENDIR)/ldgs.tr: FORCE
125 TIFFSRCDIR="$(TIFFSRCDIR)" TIFFCONFDIR="$(TIFFCONFDIR)" \ 125 TIFFSRCDIR="$(TIFFSRCDIR)" TIFFCONFDIR="$(TIFFCONFDIR)" \
126 TIFFCONFIG_SUFFIX="$(TIFFCONFIG_SUFFIX)" \ 126 TIFFCONFIG_SUFFIX="$(TIFFCONFIG_SUFFIX)" \
127 TIFFPLATFORM="$(TIFFPLATFORM)" \ 127 TIFFPLATFORM="$(TIFFPLATFORM)" \
128 TRIOSRCDIR="$(TRIOSRCDIR)" \
128 JSRCDIR="$(JSRCDIR)" \ 129 JSRCDIR="$(JSRCDIR)" \
129 ZSRCDIR="$(ZSRCDIR)" ZGENDIR="$(ZGENDIR)" ZOBJDIR="$(ZOBJDIR)" ZLIB_NAME="$(ZLIB_NAME)" SHARE_ZLIB="$(SHARE_ZLIB)" \ 130 ZSRCDIR="$(ZSRCDIR)" ZGENDIR="$(ZGENDIR)" ZOBJDIR="$(ZOBJDIR)" ZLIB_NAME="$(ZLIB_NAME)" SHARE_ZLIB="$(SHARE_ZLIB)" \
130 PSSRCDIR=$(PSSRCDIR) PSGENDIR=$(GENDIR) \ 131 PSSRCDIR=$(PSSRCDIR) PSGENDIR=$(GENDIR) \
@@ -178,6 +179,7 @@ $(GENDIR)/ldgs.tr: FORCE
178 TIFFSRCDIR="$(TIFFSRCDIR)" TIFFCONFDIR="$(TIFFCONFDIR)" \ 179 TIFFSRCDIR="$(TIFFSRCDIR)" TIFFCONFDIR="$(TIFFCONFDIR)" \
179 TIFFCONFIG_SUFFIX="$(TIFFCONFIG_SUFFIX)" \ 180 TIFFCONFIG_SUFFIX="$(TIFFCONFIG_SUFFIX)" \
180 TIFFPLATFORM="$(TIFFPLATFORM)" \ 181 TIFFPLATFORM="$(TIFFPLATFORM)" \
182 TRIOSRCDIR="$(TRIOSRCDIR)" \
181 JSRCDIR="$(JSRCDIR)" \ 183 JSRCDIR="$(JSRCDIR)" \
182 ZSRCDIR="$(ZSRCDIR)" ZGENDIR="$(ZGENDIR)" ZOBJDIR="$(ZOBJDIR)" ZLIB_NAME="$(ZLIB_NAME)" SHARE_ZLIB="$(SHARE_ZLIB)" \ 184 ZSRCDIR="$(ZSRCDIR)" ZGENDIR="$(ZGENDIR)" ZOBJDIR="$(ZOBJDIR)" ZLIB_NAME="$(ZLIB_NAME)" SHARE_ZLIB="$(SHARE_ZLIB)" \
183 PSSRCDIR=$(PSSRCDIR) PSGENDIR=$(GENDIR) \ 185 PSSRCDIR=$(PSSRCDIR) PSGENDIR=$(GENDIR) \
diff --git a/common/ugcc_top.mak b/common/ugcc_top.mak
index 024f044e5..7d30bac9e 100644
--- a/common/ugcc_top.mak
+++ b/common/ugcc_top.mak
@@ -49,6 +49,7 @@ WHICH_CMS=lcms2
49 49
50include $(GLSRCDIR)/unixhead.mak 50include $(GLSRCDIR)/unixhead.mak
51include $(GLSRCDIR)/gs.mak 51include $(GLSRCDIR)/gs.mak
52include $(GLSRCDIR)/trio.mak
52include $(GLSRCDIR)/lib.mak 53include $(GLSRCDIR)/lib.mak
53include $(PSSRCDIR)/int.mak 54include $(PSSRCDIR)/int.mak
54include $(GLSRCDIR)/jpeg.mak 55include $(GLSRCDIR)/jpeg.mak
diff --git a/gs/Makefile.in b/gs/Makefile.in
index 2b1cff601..eee822c91 100644
--- a/gs/Makefile.in
+++ b/gs/Makefile.in
@@ -306,6 +306,8 @@ LCUPSISRCDIR=cups
306CUPS_CC=$(CC) 306CUPS_CC=$(CC)
307 307
308 308
309TRIOSRCDIR=trio
310
309# Define how to build the library archives. (These are not used in any 311# Define how to build the library archives. (These are not used in any
310# standard configuration.) 312# standard configuration.)
311 313
@@ -587,6 +589,7 @@ MAKEDIRSTOP=
587INSTALL_CONTRIB=@INSTALL_CONTRIB@ 589INSTALL_CONTRIB=@INSTALL_CONTRIB@
588include $(GLSRCDIR)/unixhead.mak 590include $(GLSRCDIR)/unixhead.mak
589include $(GLSRCDIR)/gs.mak 591include $(GLSRCDIR)/gs.mak
592include $(GLSRCDIR)/trio.mak
590# psromfs.mak must precede lib.mak 593# psromfs.mak must precede lib.mak
591include $(PSSRCDIR)/psromfs.mak 594include $(PSSRCDIR)/psromfs.mak
592include $(GLSRCDIR)/lib.mak 595include $(GLSRCDIR)/lib.mak
diff --git a/gs/base/fapiufst.c b/gs/base/fapiufst.c
index 309e60814..f7f79abcc 100644
--- a/gs/base/fapiufst.c
+++ b/gs/base/fapiufst.c
@@ -699,7 +699,7 @@ pack_long(LPUB8 * p, UL32 v)
699static inline void 699static inline void
700pack_float(LPUB8 * p, float v) 700pack_float(LPUB8 * p, float v)
701{ 701{
702 sprintf((char *)(*p), "%f", v); 702 gs_sprintf((char *)(*p), "%f", v);
703 *p += strlen((const char *)*p) + 1; 703 *p += strlen((const char *)*p) + 1;
704} 704}
705 705
diff --git a/gs/base/gdevdevn.c b/gs/base/gdevdevn.c
index 4211463ca..729410c68 100644
--- a/gs/base/gdevdevn.c
+++ b/gs/base/gdevdevn.c
@@ -2118,7 +2118,7 @@ spotcmyk_print_page(gx_device_printer * pdev, FILE * prn_stream)
2118 2118
2119 /* Open the output files for the spot colors */ 2119 /* Open the output files for the spot colors */
2120 for(i = 0; i < nspot; i++) { 2120 for(i = 0; i < nspot; i++) {
2121 sprintf(spotname, "%ss%d", pdevn->fname, i); 2121 gs_sprintf(spotname, "%ss%d", pdevn->fname, i);
2122 spot_file[i] = gp_fopen(spotname, "wb"); 2122 spot_file[i] = gp_fopen(spotname, "wb");
2123 if (spot_file[i] == NULL) { 2123 if (spot_file[i] == NULL) {
2124 code = gs_error_VMerror; 2124 code = gs_error_VMerror;
@@ -2157,7 +2157,7 @@ spotcmyk_print_page(gx_device_printer * pdev, FILE * prn_stream)
2157 return code; 2157 return code;
2158 } 2158 }
2159 for(i = 0; i < nspot; i++) { 2159 for(i = 0; i < nspot; i++) {
2160 sprintf(spotname, "%ss%d", pdevn->fname, i); 2160 gs_sprintf(spotname, "%ss%d", pdevn->fname, i);
2161 code = devn_write_pcx_file(pdev, spotname, 1, bpc, linelength[i]); 2161 code = devn_write_pcx_file(pdev, spotname, 1, bpc, linelength[i]);
2162 if (code < 0) 2162 if (code < 0)
2163 return code; 2163 return code;
@@ -2491,7 +2491,7 @@ devn_write_pcx_file(gx_device_printer * pdev, char * filename, int ncomp,
2491 in = gp_fopen(filename, "rb"); 2491 in = gp_fopen(filename, "rb");
2492 if (!in) 2492 if (!in)
2493 return_error(gs_error_invalidfileaccess); 2493 return_error(gs_error_invalidfileaccess);
2494 sprintf(outname, "%s.pcx", filename); 2494 gs_sprintf(outname, "%s.pcx", filename);
2495 out = gp_fopen(outname, "wb"); 2495 out = gp_fopen(outname, "wb");
2496 if (!out) { 2496 if (!out) {
2497 fclose(in); 2497 fclose(in);
diff --git a/gs/base/gdevp14.c b/gs/base/gdevp14.c
index 26206fd58..a40ec93db 100644
--- a/gs/base/gdevp14.c
+++ b/gs/base/gdevp14.c
@@ -6466,7 +6466,7 @@ get_param_compressed_color_list_elem(pdf14_clist_device * pdev,
6466 pkeyname_list_elem->next = *pkeyname_list; 6466 pkeyname_list_elem->next = *pkeyname_list;
6467 pkeyname_list_elem->key_name = keyname_buf; 6467 pkeyname_list_elem->key_name = keyname_buf;
6468 *pkeyname_list = pkeyname_list_elem; 6468 *pkeyname_list = pkeyname_list_elem;
6469 sprintf(keyname_buf, "%s_%d", keyname, i); 6469 gs_sprintf(keyname_buf, "%s_%d", keyname, i);
6470 get_param_compressed_color_list_elem(pdev, plist, 6470 get_param_compressed_color_list_elem(pdev, plist,
6471 pcomp_list->u.sub_level_ptrs[i], keyname_buf, 6471 pcomp_list->u.sub_level_ptrs[i], keyname_buf,
6472 pkeyname_list); 6472 pkeyname_list);
@@ -6537,7 +6537,7 @@ put_param_compressed_color_list_elem(gx_device * pdev,
6537 char buff[50]; 6537 char buff[50];
6538 compressed_color_list_t * sub_list_ptr; 6538 compressed_color_list_t * sub_list_ptr;
6539 6539
6540 sprintf(buff, "%s_%d", keyname, i); 6540 gs_sprintf(buff, "%s_%d", keyname, i);
6541 put_param_compressed_color_list_elem(pdev, plist, 6541 put_param_compressed_color_list_elem(pdev, plist,
6542 &sub_list_ptr, buff, num_comps - 1); 6542 &sub_list_ptr, buff, num_comps - 1);
6543 pcomp_list->u.sub_level_ptrs[i] = sub_list_ptr; 6543 pcomp_list->u.sub_level_ptrs[i] = sub_list_ptr;
@@ -6599,7 +6599,7 @@ get_param_spot_color_names(pdf14_clist_device * pdev,
6599 pkeyname_list_elem->next = *pkeyname_list; 6599 pkeyname_list_elem->next = *pkeyname_list;
6600 pkeyname_list_elem->key_name = keyname_buf; 6600 pkeyname_list_elem->key_name = keyname_buf;
6601 *pkeyname_list = pkeyname_list_elem; 6601 *pkeyname_list = pkeyname_list_elem;
6602 sprintf(keyname_buf, "PDF14SpotName_%d", i); 6602 gs_sprintf(keyname_buf, "PDF14SpotName_%d", i);
6603 str.size = separations->names[i].size; 6603 str.size = separations->names[i].size;
6604 str.data = separations->names[i].data; 6604 str.data = separations->names[i].data;
6605 str.persistent = false; 6605 str.persistent = false;
@@ -6635,7 +6635,7 @@ put_param_pdf14_spot_names(gx_device * pdev,
6635 char buff[20]; 6635 char buff[20];
6636 byte * sep_name; 6636 byte * sep_name;
6637 6637
6638 sprintf(buff, "PDF14SpotName_%d", i); 6638 gs_sprintf(buff, "PDF14SpotName_%d", i);
6639 code = param_read_string(plist, buff, &str); 6639 code = param_read_string(plist, buff, &str);
6640 switch (code) { 6640 switch (code) {
6641 default: 6641 default:
diff --git a/gs/base/gp_macio.c b/gs/base/gp_macio.c
index ef6f3ae0c..16e99596e 100644
--- a/gs/base/gp_macio.c
+++ b/gs/base/gp_macio.c
@@ -166,7 +166,7 @@ getenv(const char * env) {
166 convertSpecToPath(&pFile, fpath, 256); 166 convertSpecToPath(&pFile, fpath, 256);
167// sprintf(fpath,"%s",fpath); 167// sprintf(fpath,"%s",fpath);
168 p = (char*)malloc((size_t) ( 4*strlen(fpath) + 40)); 168 p = (char*)malloc((size_t) ( 4*strlen(fpath) + 40));
169 sprintf(p,"%s,%sGhostscript:lib,%sGhostscript:fonts", 169 gs_sprintf(p,"%s,%sGhostscript:lib,%sGhostscript:fonts",
170 (char *)&fpath[0],(char *)&fpath[0], 170 (char *)&fpath[0],(char *)&fpath[0],
171 (char *)&fpath[0] ); 171 (char *)&fpath[0] );
172 172
@@ -406,9 +406,9 @@ gp_open_scratch_file (const gs_memory_t *mem,
406 } 406 }
407 FSMakeFSSpec(foundVRefNum, foundDirID,thepfname, &fSpec); 407 FSMakeFSSpec(foundVRefNum, foundDirID,thepfname, &fSpec);
408 convertSpecToPath(&fSpec, thefname, sizeof(thefname) - 1); 408 convertSpecToPath(&fSpec, thefname, sizeof(thefname) - 1);
409 sprintf(fname,"%s",thefname); 409 gs_sprintf(fname,"%s",thefname);
410 } else { 410 } else {
411 sprintf((char*)&thefname[0],"%s\0",fname); 411 gs_sprintf((char*)&thefname[0],"%s\0",fname);
412 memmove((char*)&thepfname[1],(char *)&thefname[0],strlen(thefname)); 412 memmove((char*)&thepfname[1],(char *)&thefname[0],strlen(thefname));
413 thepfname[0]=strlen(thefname); 413 thepfname[0]=strlen(thefname);
414 } 414 }
@@ -539,9 +539,9 @@ gp_fopen (const char * fname, const char * mode) {
539//(*pgsdll_callback) (GSDLL_STDOUT, thefname, strlen(fname)); 539//(*pgsdll_callback) (GSDLL_STDOUT, thefname, strlen(fname));
540 if ( strrchr(fname,':') == NULL ) 540 if ( strrchr(fname,':') == NULL )
541// sprintf((char *)&thefname[0],"%s%s\0",g_homeDir,fname); 541// sprintf((char *)&thefname[0],"%s%s\0",g_homeDir,fname);
542 sprintf((char *)&thefname[0],"%s%s\0","",fname); 542 gs_sprintf((char *)&thefname[0],"%s%s\0","",fname);
543 else 543 else
544 sprintf((char*)&thefname[0],"%s\0",fname); 544 gs_sprintf((char*)&thefname[0],"%s\0",fname);
545 545
546 fid = fopen(thefname,mode); 546 fid = fopen(thefname,mode);
547 547
diff --git a/gs/base/gp_mswin.c b/gs/base/gp_mswin.c
index aaa59bd5c..bd38f85df 100644
--- a/gs/base/gp_mswin.c
+++ b/gs/base/gp_mswin.c
@@ -321,7 +321,7 @@ get_queues(void)
321 char buf[256]; 321 char buf[256];
322 322
323 free(enumbuffer); 323 free(enumbuffer);
324 sprintf(buf, "EnumPrinters() failed, error code = %d", GetLastError()); 324 gs_sprintf(buf, "EnumPrinters() failed, error code = %d", GetLastError());
325 MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 325 MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP);
326 return NULL; 326 return NULL;
327 } 327 }
@@ -428,7 +428,7 @@ gp_printfile_win32(const char *filename, char *port)
428 if (!gp_OpenPrinter(port, &printer)) { 428 if (!gp_OpenPrinter(port, &printer)) {
429 char buf[256]; 429 char buf[256];
430 430
431 sprintf(buf, "OpenPrinter() failed for \042%s\042, error code = %d", port, GetLastError()); 431 gs_sprintf(buf, "OpenPrinter() failed for \042%s\042, error code = %d", port, GetLastError());
432 MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 432 MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP);
433 free(buffer); 433 free(buffer);
434 return FALSE; 434 return FALSE;
@@ -441,7 +441,7 @@ gp_printfile_win32(const char *filename, char *port)
441 if (!StartDocPrinter(printer, 1, (LPBYTE) & di)) { 441 if (!StartDocPrinter(printer, 1, (LPBYTE) & di)) {
442 char buf[256]; 442 char buf[256];
443 443
444 sprintf(buf, "StartDocPrinter() failed, error code = %d", GetLastError()); 444 gs_sprintf(buf, "StartDocPrinter() failed, error code = %d", GetLastError());
445 MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 445 MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP);
446 AbortPrinter(printer); 446 AbortPrinter(printer);
447 free(buffer); 447 free(buffer);
@@ -462,7 +462,7 @@ gp_printfile_win32(const char *filename, char *port)
462 if (!EndDocPrinter(printer)) { 462 if (!EndDocPrinter(printer)) {
463 char buf[256]; 463 char buf[256];
464 464
465 sprintf(buf, "EndDocPrinter() failed, error code = %d", GetLastError()); 465 gs_sprintf(buf, "EndDocPrinter() failed, error code = %d", GetLastError());
466 MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 466 MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP);
467 AbortPrinter(printer); 467 AbortPrinter(printer);
468 return FALSE; 468 return FALSE;
@@ -470,7 +470,7 @@ gp_printfile_win32(const char *filename, char *port)
470 if (!ClosePrinter(printer)) { 470 if (!ClosePrinter(printer)) {
471 char buf[256]; 471 char buf[256];
472 472
473 sprintf(buf, "ClosePrinter() failed, error code = %d", GetLastError()); 473 gs_sprintf(buf, "ClosePrinter() failed, error code = %d", GetLastError());
474 MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 474 MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP);
475 return FALSE; 475 return FALSE;
476 } 476 }
diff --git a/gs/base/gp_wgetv.c b/gs/base/gp_wgetv.c
index 7eb29a81a..895d03613 100644
--- a/gs/base/gp_wgetv.c
+++ b/gs/base/gp_wgetv.c
@@ -199,9 +199,9 @@ gp_getenv(const char *name, char *ptr, int *plen)
199 char key[256]; 199 char key[256];
200 char dotversion[16]; 200 char dotversion[16];
201 201
202 sprintf(dotversion, "%d.%02d", (int)(gs_revision / 100), 202 gs_sprintf(dotversion, "%d.%02d", (int)(gs_revision / 100),
203 (int)(gs_revision % 100)); 203 (int)(gs_revision % 100));
204 sprintf(key, "Software\\%s\\%s", gs_productfamily, dotversion); 204 gs_sprintf(key, "Software\\%s\\%s", gs_productfamily, dotversion);
205#else 205#else
206 wchar_t key[256]; 206 wchar_t key[256];
207 wchar_t dotversion[16]; 207 wchar_t dotversion[16];
@@ -242,7 +242,7 @@ gp_serialnumber(void)
242#ifdef GS_NO_UTF8 242#ifdef GS_NO_UTF8
243 char key[256]; 243 char key[256];
244 244
245 sprintf(key, "Software\\Microsoft\\MSLicensing\\HardwareID"); 245 gs_sprintf(key, "Software\\Microsoft\\MSLicensing\\HardwareID");
246#else /* GS_NO_UTF8 */ 246#else /* GS_NO_UTF8 */
247 wchar_t key[256]; 247 wchar_t key[256];
248 248
diff --git a/gs/base/gs.mak b/gs/base/gs.mak
index 3bc808b64..9354889aa 100644
--- a/gs/base/gs.mak
+++ b/gs/base/gs.mak
@@ -239,6 +239,8 @@ LCUPSGENDIR=$(GLGENDIR)
239LCUPSOBJDIR=$(GLOBJDIR) 239LCUPSOBJDIR=$(GLOBJDIR)
240LCUPSIGENDIR=$(GLGENDIR) 240LCUPSIGENDIR=$(GLGENDIR)
241LCUPSIOBJDIR=$(GLOBJDIR) 241LCUPSIOBJDIR=$(GLOBJDIR)
242
243TRIOOBJDIR=$(GLOBJDIR)
242#**************** END PATCHES 244#**************** END PATCHES
243 245
244GSGEN=$(GLGENDIR)$(D) 246GSGEN=$(GLGENDIR)$(D)
diff --git a/gs/base/gsalloc.c b/gs/base/gsalloc.c
index 7daab4c84..87503a33b 100644
--- a/gs/base/gsalloc.c
+++ b/gs/base/gsalloc.c
@@ -2116,7 +2116,7 @@ debug_dump_contents(const gs_memory_t *mem, const byte * bot,
2116 } 2116 }
2117 continue; 2117 continue;
2118 } 2118 }
2119 sprintf(label, "0x%lx:", (ulong) block); 2119 gs_sprintf(label, "0x%lx:", (ulong) block);
2120 debug_indent(mem, indent); 2120 debug_indent(mem, indent);
2121 dmputs(mem, label); 2121 dmputs(mem, label);
2122 for (i = 0; i < block_size; ++i) { 2122 for (i = 0; i < block_size; ++i) {
diff --git a/gs/base/gsdevice.c b/gs/base/gsdevice.c
index ed2d1aff8..805666660 100644
--- a/gs/base/gsdevice.c
+++ b/gs/base/gsdevice.c
@@ -1020,11 +1020,11 @@ gx_device_open_output_file(const gx_device * dev, char *fname,
1020 while (*fmt != 'l' && *fmt != '%') 1020 while (*fmt != 'l' && *fmt != '%')
1021 --fmt; 1021 --fmt;
1022 if (*fmt == 'l') 1022 if (*fmt == 'l')
1023 sprintf(pfname, parsed.fname, count1); 1023 gs_sprintf(pfname, parsed.fname, count1);
1024 else 1024 else
1025 sprintf(pfname, parsed.fname, (int)count1); 1025 gs_sprintf(pfname, parsed.fname, (int)count1);
1026 } else if (parsed.len && strchr(parsed.fname, '%')) /* filename with "%%" but no "%nnd" */ 1026 } else if (parsed.len && strchr(parsed.fname, '%')) /* filename with "%%" but no "%nnd" */
1027 sprintf(pfname, parsed.fname); 1027 gs_sprintf(pfname, parsed.fname);
1028 else 1028 else
1029 pfname[0] = 0; /* 0 to use "fname", not "pfname" */ 1029 pfname[0] = 0; /* 0 to use "fname", not "pfname" */
1030 if (pfname[0]) { 1030 if (pfname[0]) {
diff --git a/gs/base/gsdparam.c b/gs/base/gsdparam.c
index 8d696d635..3c708de50 100644
--- a/gs/base/gsdparam.c
+++ b/gs/base/gsdparam.c
@@ -380,7 +380,7 @@ gdev_write_input_media(int index, gs_param_dict * pdict,
380 int code; 380 int code;
381 gs_param_string as; 381 gs_param_string as;
382 382
383 sprintf(key, "%d", index); 383 gs_sprintf(key, "%d", index);
384 mdict.size = 4; 384 mdict.size = 4;
385 code = param_begin_write_dict(pdict->list, key, &mdict, false); 385 code = param_begin_write_dict(pdict->list, key, &mdict, false);
386 if (code < 0) 386 if (code < 0)
@@ -468,7 +468,7 @@ gdev_write_output_media(int index, gs_param_dict * pdict,
468 gs_param_dict mdict; 468 gs_param_dict mdict;
469 int code; 469 int code;
470 470
471 sprintf(key, "%d", index); 471 gs_sprintf(key, "%d", index);
472 mdict.size = 4; 472 mdict.size = 4;
473 code = param_begin_write_dict(pdict->list, key, &mdict, false); 473 code = param_begin_write_dict(pdict->list, key, &mdict, false);
474 if (code < 0) 474 if (code < 0)
diff --git a/gs/base/gsfcmap.c b/gs/base/gsfcmap.c
index d0c965f97..d56afff80 100644
--- a/gs/base/gsfcmap.c
+++ b/gs/base/gsfcmap.c
@@ -567,7 +567,7 @@ gs_cmap_ToUnicode_alloc(gs_memory_t *mem, int id, int num_codes, int key_size, g
567 char sid[10], *pref = "aux-"; 567 char sid[10], *pref = "aux-";
568 int sid_len, pref_len = strlen(pref); 568 int sid_len, pref_len = strlen(pref);
569 569
570 sprintf(sid, "%d", id); 570 gs_sprintf(sid, "%d", id);
571 sid_len = strlen(sid); 571 sid_len = strlen(sid);
572 name_len = pref_len + sid_len; 572 name_len = pref_len + sid_len;
573 cmap_name = gs_alloc_string(mem, name_len, "gs_cmap_ToUnicode_alloc"); 573 cmap_name = gs_alloc_string(mem, name_len, "gs_cmap_ToUnicode_alloc");
diff --git a/gs/base/gsicc_create.c b/gs/base/gsicc_create.c
index 08022b5e0..b4f479c56 100644
--- a/gs/base/gsicc_create.c
+++ b/gs/base/gsicc_create.c
@@ -453,7 +453,7 @@ save_profile(unsigned char *buffer, char filename[], int buffer_size)
453 char full_file_name[50]; 453 char full_file_name[50];
454 FILE *fid; 454 FILE *fid;
455 455
456 sprintf(full_file_name,"%d)Profile_%s.icc",icc_debug_index,filename); 456 gs_sprintf(full_file_name,"%d)Profile_%s.icc",icc_debug_index,filename);
457 fid = gp_fopen(full_file_name,"wb"); 457 fid = gp_fopen(full_file_name,"wb");
458 fwrite(buffer,sizeof(unsigned char),buffer_size,fid); 458 fwrite(buffer,sizeof(unsigned char),buffer_size,fid);
459 fclose(fid); 459 fclose(fid);
diff --git a/gs/base/gsicc_manage.c b/gs/base/gsicc_manage.c
index d1a0a1a80..aeb3257ae 100644
--- a/gs/base/gsicc_manage.c
+++ b/gs/base/gsicc_manage.c
@@ -551,8 +551,8 @@ gsicc_set_srcgtag_struct(gsicc_manager_t *icc_manager, const char* pname,
551 srcgtag = gsicc_new_srcgtag_profile(mem); 551 srcgtag = gsicc_new_srcgtag_profile(mem);
552 /* Now parse through the data opening the profiles that are needed */ 552 /* Now parse through the data opening the profiles that are needed */
553 /* First create the format that we should read for the key */ 553 /* First create the format that we should read for the key */
554 sprintf(str_format_key, "%%%ds", GSICC_SRCGTAG_MAX_KEY); 554 gs_sprintf(str_format_key, "%%%ds", GSICC_SRCGTAG_MAX_KEY);
555 sprintf(str_format_file, "%%%ds", FILENAME_MAX); 555 gs_sprintf(str_format_file, "%%%ds", FILENAME_MAX);
556 curr_ptr = buffer_ptr; 556 curr_ptr = buffer_ptr;
557 /* Initialize that we want color management. Then if profile is not 557 /* Initialize that we want color management. Then if profile is not
558 present we know we did not want anything special done with that 558 present we know we did not want anything special done with that
@@ -1312,13 +1312,13 @@ gsicc_set_device_profile_colorants(gx_device *dev, char *name_str)
1312 DEFAULT_ICC_PROCESS_LENGTH - 1; /* -1 due to no comma at end */ 1312 DEFAULT_ICC_PROCESS_LENGTH - 1; /* -1 due to no comma at end */
1313 name_str = (char*) gs_alloc_bytes(dev->memory, total_len+1, 1313 name_str = (char*) gs_alloc_bytes(dev->memory, total_len+1,
1314 "gsicc_set_device_profile_colorants"); 1314 "gsicc_set_device_profile_colorants");
1315 sprintf(name_str, DEFAULT_ICC_PROCESS); 1315 gs_sprintf(name_str, DEFAULT_ICC_PROCESS);
1316 for (kk = 0; kk < num_comps-5; kk++) { 1316 for (kk = 0; kk < num_comps-5; kk++) {
1317 sprintf(temp_str,"ICC_COLOR_%d,",kk); 1317 gs_sprintf(temp_str,"ICC_COLOR_%d,",kk);
1318 strcat(name_str,temp_str); 1318 strcat(name_str,temp_str);
1319 } 1319 }
1320 /* Last one no comma */ 1320 /* Last one no comma */
1321 sprintf(temp_str,"ICC_COLOR_%d",kk); 1321 gs_sprintf(temp_str,"ICC_COLOR_%d",kk);
1322 strcat(name_str,temp_str); 1322 strcat(name_str,temp_str);
1323 } 1323 }
1324 str_len = strlen(name_str); 1324 str_len = strlen(name_str);
@@ -2374,7 +2374,7 @@ dump_icc_buffer(int buffersize, char filename[],byte *Buffer)
2374 char full_file_name[50]; 2374 char full_file_name[50];
2375 FILE *fid; 2375 FILE *fid;
2376 2376
2377 sprintf(full_file_name,"%d)%s_debug.icc",global_icc_index,filename); 2377 gs_sprintf(full_file_name,"%d)%s_debug.icc",global_icc_index,filename);
2378 fid = gp_fopen(full_file_name,"wb"); 2378 fid = gp_fopen(full_file_name,"wb");
2379 fwrite(Buffer,sizeof(unsigned char),buffersize,fid); 2379 fwrite(Buffer,sizeof(unsigned char),buffersize,fid);
2380 fclose(fid); 2380 fclose(fid);
diff --git a/gs/base/gsiodisk.c b/gs/base/gsiodisk.c
index 45162ad3b..ed6266262 100644
--- a/gs/base/gsiodisk.c
+++ b/gs/base/gsiodisk.c
@@ -415,7 +415,7 @@ MapFileOpen(const char * rootpath, const char * filename, const char * attribute
415 415
416 if (strlen(rootpath) + strlen(filename) >= BUFFER_LENGTH) 416 if (strlen(rootpath) + strlen(filename) >= BUFFER_LENGTH)
417 return NULL; 417 return NULL;
418 sprintf(fullname, "%s%s", rootpath, filename); 418 gs_sprintf(fullname, "%s%s", rootpath, filename);
419 return gp_fopen(fullname, attributes); 419 return gp_fopen(fullname, attributes);
420} 420}
421 421
@@ -516,7 +516,7 @@ MapFileUnlink(const char * rootpath, const char * filename)
516 516
517 if (strlen(rootpath) + strlen(filename) >= BUFFER_LENGTH) 517 if (strlen(rootpath) + strlen(filename) >= BUFFER_LENGTH)
518 return; 518 return;
519 sprintf(fullname, "%s%s", rootpath, filename); 519 gs_sprintf(fullname, "%s%s", rootpath, filename);
520 unlink(fullname); 520 unlink(fullname);
521} 521}
522 522
@@ -537,8 +537,8 @@ MapFileRename(const char * rootpath, const char * newfilename, const char * oldf
537 return; 537 return;
538 if (strlen(rootpath) + strlen(newfilename) >= BUFFER_LENGTH) 538 if (strlen(rootpath) + strlen(newfilename) >= BUFFER_LENGTH)
539 return; 539 return;
540 sprintf(oldfullname, "%s%s", rootpath, oldfilename); 540 gs_sprintf(oldfullname, "%s%s", rootpath, oldfilename);
541 sprintf(newfullname, "%s%s", rootpath, newfilename); 541 gs_sprintf(newfullname, "%s%s", rootpath, newfilename);
542 rename(oldfullname, newfullname); 542 rename(oldfullname, newfullname);
543} 543}
544 544
@@ -711,7 +711,7 @@ map_file_name_get(const char * root_name, const char * Fname, char * osname)
711 if (d != -1) { 711 if (d != -1) {
712 /* 20 characters are enough for even a 64 bit integer */ 712 /* 20 characters are enough for even a 64 bit integer */
713 if ((strlen(root_name) + 20) < BUFFER_LENGTH) { 713 if ((strlen(root_name) + 20) < BUFFER_LENGTH) {
714 sprintf(osname, "%s%d", root_name, d); 714 gs_sprintf(osname, "%s%d", root_name, d);
715 return true; 715 return true;
716 } 716 }
717 } 717 }
diff --git a/gs/base/gspmdrv.c b/gs/base/gspmdrv.c
index 873a6b585..0ef1d0cca 100644
--- a/gs/base/gspmdrv.c
+++ b/gs/base/gspmdrv.c
@@ -345,11 +345,11 @@ write_profile(void)
345{ 345{
346 char profile[64]; 346 char profile[64];
347 347
348 sprintf(profile, "%d %d", option.img_origin.x, option.img_origin.y); 348 gs_sprintf(profile, "%d %d", option.img_origin.x, option.img_origin.y);
349 PrfWriteProfileString(HINI_USERPROFILE, section, "Origin", profile); 349 PrfWriteProfileString(HINI_USERPROFILE, section, "Origin", profile);
350 sprintf(profile, "%d %d", option.img_size.x, option.img_size.y); 350 gs_sprintf(profile, "%d %d", option.img_size.x, option.img_size.y);
351 PrfWriteProfileString(HINI_USERPROFILE, section, "Size", profile); 351 PrfWriteProfileString(HINI_USERPROFILE, section, "Size", profile);
352 sprintf(profile, "%d", option.img_max); 352 gs_sprintf(profile, "%d", option.img_max);
353 PrfWriteProfileString(HINI_USERPROFILE, section, "Maximized", profile); 353 PrfWriteProfileString(HINI_USERPROFILE, section, "Maximized", profile);
354} 354}
355 355
@@ -489,26 +489,26 @@ init_display(int argc, char *argv[])
489 find_hwnd_gs(argv[2]); 489 find_hwnd_gs(argv[2]);
490 490
491 if (!rc) { 491 if (!rc) {
492 sprintf(name, SHARED_NAME, argv[2]); 492 gs_sprintf(name, SHARED_NAME, argv[2]);
493 rc = DosGetNamedSharedMem((PVOID *) & bitmap.pbmi, name, PAG_READ | PAG_WRITE); 493 rc = DosGetNamedSharedMem((PVOID *) & bitmap.pbmi, name, PAG_READ | PAG_WRITE);
494 if (rc) { 494 if (rc) {
495 sprintf(buf, "Failed to open: bmp shared memory \"%s\" rc = %d", argv[0], rc); 495 gs_sprintf(buf, "Failed to open: bmp shared memory \"%s\" rc = %d", argv[0], rc);
496 error_message(buf); 496 error_message(buf);
497 } 497 }
498 } 498 }
499 if (!rc) { 499 if (!rc) {
500 sprintf(name, SYNC_NAME, argv[2]); 500 gs_sprintf(name, SYNC_NAME, argv[2]);
501 rc = DosOpenEventSem(name, &update_event_sem); 501 rc = DosOpenEventSem(name, &update_event_sem);
502 if (rc) { 502 if (rc) {
503 sprintf(buf, "Failed to open: update event semaphore \"%s\" rc = %d", argv[1], rc); 503 gs_sprintf(buf, "Failed to open: update event semaphore \"%s\" rc = %d", argv[1], rc);
504 error_message(buf); 504 error_message(buf);
505 } 505 }
506 } 506 }
507 if (!rc) { 507 if (!rc) {
508 sprintf(name, MUTEX_NAME, argv[2]); 508 gs_sprintf(name, MUTEX_NAME, argv[2]);
509 rc = DosOpenMutexSem(name, &bmp_mutex_sem); 509 rc = DosOpenMutexSem(name, &bmp_mutex_sem);
510 if (rc) { 510 if (rc) {
511 sprintf(buf, "Failed to open: bmp mutex semaphore \"%s\" rc = %d", argv[1], rc); 511 gs_sprintf(buf, "Failed to open: bmp mutex semaphore \"%s\" rc = %d", argv[1], rc);
512 error_message(buf); 512 error_message(buf);
513 } 513 }
514 } 514 }
@@ -535,19 +535,19 @@ init_bitmap(int argc, char *argv[])
535 if ((rc = DosOpen(argv[2], &hf, &action, 0, FILE_NORMAL, FILE_OPEN, 535 if ((rc = DosOpen(argv[2], &hf, &action, 0, FILE_NORMAL, FILE_OPEN,
536 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYREADWRITE, 0)) 536 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYREADWRITE, 0))
537 != (APIRET) 0) { 537 != (APIRET) 0) {
538 sprintf(buf, "Error opening: %s", argv[2]); 538 gs_sprintf(buf, "Error opening: %s", argv[2]);
539 error_message(buf); 539 error_message(buf);
540 return rc; 540 return rc;
541 } 541 }
542 rc = DosSetFilePtr(hf, 0, FILE_END, &length); 542 rc = DosSetFilePtr(hf, 0, FILE_END, &length);
543 if (rc) { 543 if (rc) {
544 sprintf(buf, "failed seeking to EOF: error = %d", rc); 544 gs_sprintf(buf, "failed seeking to EOF: error = %d", rc);
545 error_message(buf); 545 error_message(buf);
546 return rc; 546 return rc;
547 } 547 }
548 rc = DosSetFilePtr(hf, 0, FILE_BEGIN, &count); 548 rc = DosSetFilePtr(hf, 0, FILE_BEGIN, &count);
549 if (rc) { 549 if (rc) {
550 sprintf(buf, "failed seeking to BOF: error = %d", rc); 550 gs_sprintf(buf, "failed seeking to BOF: error = %d", rc);
551 error_message(buf); 551 error_message(buf);
552 return rc; 552 return rc;
553 }; 553 };
@@ -555,14 +555,14 @@ init_bitmap(int argc, char *argv[])
555 /* allocate memory for bitmap */ 555 /* allocate memory for bitmap */
556 if ((rc = DosAllocMem((PPVOID) & bbuffer, length, PAG_READ | PAG_WRITE | PAG_COMMIT)) 556 if ((rc = DosAllocMem((PPVOID) & bbuffer, length, PAG_READ | PAG_WRITE | PAG_COMMIT))
557 != (APIRET) 0) { 557 != (APIRET) 0) {
558 sprintf(buf, "failed allocating memory"); 558 gs_sprintf(buf, "failed allocating memory");
559 error_message(buf); 559 error_message(buf);
560 return rc; 560 return rc;
561 } 561 }
562 rc = DosRead(hf, bbuffer, length, &count); 562 rc = DosRead(hf, bbuffer, length, &count);
563 DosClose(hf); 563 DosClose(hf);
564 if (rc) { 564 if (rc) {
565 sprintf(buf, "failed reading bitmap, error = %u, count = %u", rc, count); 565 gs_sprintf(buf, "failed reading bitmap, error = %u, count = %u", rc, count);
566 error_message(buf); 566 error_message(buf);
567 return rc; 567 return rc;
568 } 568 }
@@ -573,7 +573,7 @@ init_bitmap(int argc, char *argv[])
573 scan_bitmap(&bitmap); 573 scan_bitmap(&bitmap);
574 bitmap.valid = TRUE; 574 bitmap.valid = TRUE;
575 575
576 sprintf(buf, "bitmap width = %d, height = %d", bitmap.width, bitmap.height); 576 gs_sprintf(buf, "bitmap width = %d, height = %d", bitmap.width, bitmap.height);
577 message_box(buf, 0); 577 message_box(buf, 0);
578 return rc; 578 return rc;
579} 579}
@@ -805,7 +805,7 @@ make_bitmap(BMAP * pbm, ULONG left, ULONG bottom, ULONG right, ULONG top, ULONG
805 char buf[256]; 805 char buf[256];
806 806
807 eid = WinGetLastError(hab); 807 eid = WinGetLastError(hab);
808 sprintf(buf, "make_bitmap: GpiDrawBits rc = %08x, eid = %08x", rc, eid); 808 gs_sprintf(buf, "make_bitmap: GpiDrawBits rc = %08x, eid = %08x", rc, eid);
809 message_box(buf, 0); 809 message_box(buf, 0);
810 } 810 }
811 } 811 }
diff --git a/gs/base/gssprintf.c b/gs/base/gssprintf.c
new file mode 100644
index 000000000..3d053bd1c
--- /dev/null
+++ b/gs/base/gssprintf.c
@@ -0,0 +1,60 @@
1/* Copyright (C) 2001-2012 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14*/
15
16
17/* Simple interface to a sprintf/sscanf without locale */
18#include "gssprintf.h"
19#include "trio.h"
20#include "triop.h"
21#include "triodef.h"
22#include "trionan.h"
23#include "triostr.h"
24
25int
26gs_vsnprintf(char *buf, int n, const char *format, va_list ap)
27{
28 return(trio_vsnprintf(buf, n, format, ap));
29}
30
31int
32gs_snprintf(char *buf, int n, const char *format, ...)
33{
34 int len;
35 va_list ap;
36
37 va_start(ap, format);
38 len = trio_vsnprintf(buf, n, format, ap);
39 va_end(ap);
40 return len;
41}
42
43int
44gs_vsprintf(char *buf, const char *format, va_list ap)
45{
46 return(trio_vsprintf(buf, format, ap));
47}
48
49int
50gs_sprintf(char *buf, const char *format, ...)
51{
52 int len;
53 va_list ap;
54
55 va_start(ap, format);
56 len = trio_vsprintf(buf, format, ap);
57 va_end(ap);
58
59 return(len);
60}
diff --git a/gs/base/gssprintf.h b/gs/base/gssprintf.h
new file mode 100644
index 000000000..049bdc179
--- /dev/null
+++ b/gs/base/gssprintf.h
@@ -0,0 +1,33 @@
1/* Copyright (C) 2001-2012 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14*/
15
16#ifndef gssprintf_INCLUDED
17# define gssprintf_INCLUDED
18
19#include <stdarg.h>
20
21int
22gs_vsnprintf(char *zBuf, int n, const char *zFormat, va_list ap);
23
24int
25gs_snprintf(char *zBuf, int n, const char *zFormat, ...);
26
27int
28gs_vsprintf(char *zBuf, const char *zFormat, va_list ap);
29
30int
31gs_sprintf(char *zBuf, const char *zFormat, ...);
32
33#endif
diff --git a/gs/base/gxblend.c b/gs/base/gxblend.c
index c87f6c996..9e06e8bfb 100644
--- a/gs/base/gxblend.c
+++ b/gs/base/gxblend.c
@@ -1574,7 +1574,7 @@ dump_raw_buffer(int num_rows, int width, int n_chan,
1574 /* FIXME: GRAY + ALPHA + SHAPE + TAGS will be interpreted as RGB + ALPHA */ 1574 /* FIXME: GRAY + ALPHA + SHAPE + TAGS will be interpreted as RGB + ALPHA */
1575 if ((n_chan == 2) || (n_chan == 3)) { 1575 if ((n_chan == 2) || (n_chan == 3)) {
1576 int x; 1576 int x;
1577 sprintf(full_file_name,"%02d)%s.pam",global_index,filename); 1577 gs_sprintf(full_file_name,"%02d)%s.pam",global_index,filename);
1578 fid = gp_fopen(full_file_name,"wb"); 1578 fid = gp_fopen(full_file_name,"wb");
1579 fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE GRAYSCALE_ALPHA\nENDHDR\n", 1579 fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE GRAYSCALE_ALPHA\nENDHDR\n",
1580 width, num_rows); 1580 width, num_rows);
@@ -1584,7 +1584,7 @@ dump_raw_buffer(int num_rows, int width, int n_chan,
1584 fputc(Buffer[z*plane_stride + y*rowstride + x], fid); 1584 fputc(Buffer[z*plane_stride + y*rowstride + x], fid);
1585 fclose(fid); 1585 fclose(fid);
1586 if (n_chan == 3) { 1586 if (n_chan == 3) {
1587 sprintf(full_file_name,"%02d)%s_shape.pam",global_index,filename); 1587 gs_sprintf(full_file_name,"%02d)%s_shape.pam",global_index,filename);
1588 fid = gp_fopen(full_file_name,"wb"); 1588 fid = gp_fopen(full_file_name,"wb");
1589 fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 1\nMAXVAL 255\nTUPLTYPE GRAYSCALE\nENDHDR\n", 1589 fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 1\nMAXVAL 255\nTUPLTYPE GRAYSCALE\nENDHDR\n",
1590 width, num_rows); 1590 width, num_rows);
@@ -1596,7 +1596,7 @@ dump_raw_buffer(int num_rows, int width, int n_chan,
1596 } 1596 }
1597 if ((n_chan == 4) || (n_chan == 5) || (n_chan == 6)) { 1597 if ((n_chan == 4) || (n_chan == 5) || (n_chan == 6)) {
1598 int x; 1598 int x;
1599 sprintf(full_file_name,"%02d)%s.pam",global_index,filename); 1599 gs_sprintf(full_file_name,"%02d)%s.pam",global_index,filename);
1600 fid = gp_fopen(full_file_name,"wb"); 1600 fid = gp_fopen(full_file_name,"wb");
1601 fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n", 1601 fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n",
1602 width, num_rows); 1602 width, num_rows);
@@ -1606,7 +1606,7 @@ dump_raw_buffer(int num_rows, int width, int n_chan,
1606 fputc(Buffer[z*plane_stride + y*rowstride + x], fid); 1606 fputc(Buffer[z*plane_stride + y*rowstride + x], fid);
1607 fclose(fid); 1607 fclose(fid);
1608 if (n_chan > 4) { 1608 if (n_chan > 4) {
1609 sprintf(full_file_name,"%02d)%s_shape.pam",global_index,filename); 1609 gs_sprintf(full_file_name,"%02d)%s_shape.pam",global_index,filename);
1610 fid = gp_fopen(full_file_name,"wb"); 1610 fid = gp_fopen(full_file_name,"wb");
1611 fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 1\nMAXVAL 255\nTUPLTYPE GRAYSCALE\nENDHDR\n", 1611 fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 1\nMAXVAL 255\nTUPLTYPE GRAYSCALE\nENDHDR\n",
1612 width, num_rows); 1612 width, num_rows);
@@ -1616,7 +1616,7 @@ dump_raw_buffer(int num_rows, int width, int n_chan,
1616 fclose(fid); 1616 fclose(fid);
1617 } 1617 }
1618 if (n_chan == 6) { 1618 if (n_chan == 6) {
1619 sprintf(full_file_name,"%02d)%s_tags.pam",global_index,filename); 1619 gs_sprintf(full_file_name,"%02d)%s_tags.pam",global_index,filename);
1620 fid = gp_fopen(full_file_name,"wb"); 1620 fid = gp_fopen(full_file_name,"wb");
1621 fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 1\nMAXVAL 255\nTUPLTYPE GRAYSCALE\nENDHDR\n", 1621 fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 1\nMAXVAL 255\nTUPLTYPE GRAYSCALE\nENDHDR\n",
1622 width, num_rows); 1622 width, num_rows);
@@ -1629,7 +1629,7 @@ dump_raw_buffer(int num_rows, int width, int n_chan,
1629 } 1629 }
1630#endif 1630#endif
1631 max_bands = ( n_chan < 57 ? n_chan : 56); /* Photoshop handles at most 56 bands */ 1631 max_bands = ( n_chan < 57 ? n_chan : 56); /* Photoshop handles at most 56 bands */
1632 sprintf(full_file_name,"%02d)%s_%dx%dx%d.raw",global_index,filename,width,num_rows,max_bands); 1632 gs_sprintf(full_file_name,"%02d)%s_%dx%dx%d.raw",global_index,filename,width,num_rows,max_bands);
1633 fid = gp_fopen(full_file_name,"wb"); 1633 fid = gp_fopen(full_file_name,"wb");
1634 1634
1635 for (z = 0; z < max_bands; ++z) { 1635 for (z = 0; z < max_bands; ++z) {
diff --git a/gs/base/gxblend1.c b/gs/base/gxblend1.c
index 16e2b2d33..6818d6fe4 100644
--- a/gs/base/gxblend1.c
+++ b/gs/base/gxblend1.c
@@ -648,7 +648,7 @@ dump_planar_rgba(gs_memory_t *mem, const pdf14_buf *pbuf)
648 info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; 648 info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
649 649
650 /* add comment */ 650 /* add comment */
651 sprintf(software_text, "%s %d.%02d", gs_product, 651 gs_sprintf(software_text, "%s %d.%02d", gs_product,
652 (int)(gs_revision / 100), (int)(gs_revision % 100)); 652 (int)(gs_revision / 100), (int)(gs_revision % 100));
653 text_png.compression = -1; /* uncompressed */ 653 text_png.compression = -1; /* uncompressed */
654 text_png.key = (char *)software_key; /* not const, unfortunately */ 654 text_png.key = (char *)software_key; /* not const, unfortunately */
diff --git a/gs/base/gxclmem.c b/gs/base/gxclmem.c
index 29f2545d2..9243d4c22 100644
--- a/gs/base/gxclmem.c
+++ b/gs/base/gxclmem.c
@@ -401,7 +401,7 @@ memfile_fopen(char fname[gp_file_name_sizeof], const char *fmode,
401 401
402 /* Return the address of this memfile as a string for use in future clist_fopen calls */ 402 /* Return the address of this memfile as a string for use in future clist_fopen calls */
403 fname[0] = 0xff; /* a flag that this is a memfile name */ 403 fname[0] = 0xff; /* a flag that this is a memfile name */
404 sprintf(fname+1, "%p", f); 404 gs_sprintf(fname+1, "%p", f);
405 405
406#ifdef DEBUG 406#ifdef DEBUG
407 tot_compressed = 0; 407 tot_compressed = 0;
diff --git a/gs/base/gxhintn.c b/gs/base/gxhintn.c
index 23ab818e5..37a7e86d1 100644
--- a/gs/base/gxhintn.c
+++ b/gs/base/gxhintn.c
@@ -387,7 +387,7 @@ static void t1_hinter__paint_glyph(t1_hinter * self, bool aligned)
387 387
388 for(j = beg_pole; j <= end_pole; j++) { 388 for(j = beg_pole; j <= end_pole; j++) {
389 vd_circle(X(j), Y(j), 3, RGB(0,0,255)); 389 vd_circle(X(j), Y(j), 3, RGB(0,0,255));
390 sprintf(buf, "%d", j); 390 gs_sprintf(buf, "%d", j);
391 vd_text(self->pole[j].gx, self->pole[j].gy, buf, RGB(0,0,0)); 391 vd_text(self->pole[j].gx, self->pole[j].gy, buf, RGB(0,0,0));
392 if (self->pole[j + 1].type == offcurve) 392 if (self->pole[j + 1].type == offcurve)
393 j+=2; 393 j+=2;
diff --git a/gs/base/gxpath.c b/gs/base/gxpath.c
index dc97511a1..244263542 100644
--- a/gs/base/gxpath.c
+++ b/gs/base/gxpath.c
@@ -1035,7 +1035,7 @@ gx_print_segment(const gs_memory_t *mem, const segment * pseg)
1035 double py = fixed2float(pseg->pt.y); 1035 double py = fixed2float(pseg->pt.y);
1036 char out[80]; 1036 char out[80];
1037 1037
1038 sprintf(out, "0x%lx<0x%lx,0x%lx>:%u", 1038 gs_sprintf(out, "0x%lx<0x%lx,0x%lx>:%u",
1039 (ulong) pseg, (ulong) pseg->prev, (ulong) pseg->next, pseg->notes); 1039 (ulong) pseg, (ulong) pseg->prev, (ulong) pseg->next, pseg->notes);
1040 switch (pseg->type) { 1040 switch (pseg->type) {
1041 case s_start:{ 1041 case s_start:{
diff --git a/gs/base/gxpcmap.c b/gs/base/gxpcmap.c
index 42adc4af5..febcc07a9 100644
--- a/gs/base/gxpcmap.c
+++ b/gs/base/gxpcmap.c
@@ -1148,10 +1148,10 @@ dump_raw_pattern(int height, int width, int n_chan, int depth,
1148 is_planar = dev_proc(mdev, dev_spec_op)(mdev, gxdso_is_native_planar, NULL, 0) > 0; 1148 is_planar = dev_proc(mdev, dev_spec_op)(mdev, gxdso_is_native_planar, NULL, 0) > 0;
1149 max_bands = ( n_chan < 57 ? n_chan : 56); /* Photoshop handles at most 56 bands */ 1149 max_bands = ( n_chan < 57 ? n_chan : 56); /* Photoshop handles at most 56 bands */
1150 if (is_planar) { 1150 if (is_planar) {
1151 sprintf(full_file_name,"%d)PATTERN_PLANE_%dx%dx%d.raw",global_pat_index, 1151 gs_sprintf(full_file_name,"%d)PATTERN_PLANE_%dx%dx%d.raw",global_pat_index,
1152 width,height,max_bands); 1152 width,height,max_bands);
1153 } else { 1153 } else {
1154 sprintf(full_file_name,"%d)PATTERN_CHUNK_%dx%dx%d.raw",global_pat_index, 1154 gs_sprintf(full_file_name,"%d)PATTERN_CHUNK_%dx%dx%d.raw",global_pat_index,
1155 width,height,max_bands); 1155 width,height,max_bands);
1156 } 1156 }
1157 fid = gp_fopen(full_file_name,"wb"); 1157 fid = gp_fopen(full_file_name,"wb");
diff --git a/gs/base/lib.mak b/gs/base/lib.mak
index 91cbcf515..653243d7e 100644
--- a/gs/base/lib.mak
+++ b/gs/base/lib.mak
@@ -105,6 +105,9 @@ std_h=$(GLSRC)std.h $(arch_h) $(stdpre_h)
105 105
106vmsmath_h=$(GLSRC)vmsmath.h 106vmsmath_h=$(GLSRC)vmsmath.h
107 107
108# declare here for use by string__h
109gssprintf_h=$(GLSRC)gssprintf.h
110
108dos__h=$(GLSRC)dos_.h 111dos__h=$(GLSRC)dos_.h
109ctype__h=$(GLSRC)ctype_.h $(std_h) 112ctype__h=$(GLSRC)ctype_.h $(std_h)
110dirent__h=$(GLSRC)dirent_.h $(std_h) $(gconfig__h) 113dirent__h=$(GLSRC)dirent_.h $(std_h) $(gconfig__h)
@@ -117,7 +120,7 @@ math__h=$(GLSRC)math_.h $(std_h) $(vmsmath_h)
117memory__h=$(GLSRC)memory_.h $(std_h) 120memory__h=$(GLSRC)memory_.h $(std_h)
118setjmp__h=$(GLSRC)setjmp_.h 121setjmp__h=$(GLSRC)setjmp_.h
119stat__h=$(GLSRC)stat_.h $(std_h) 122stat__h=$(GLSRC)stat_.h $(std_h)
120stdio__h=$(GLSRC)stdio_.h $(std_h) 123stdio__h=$(GLSRC)stdio_.h $(std_h) $(gssprintf_h)
121string__h=$(GLSRC)string_.h $(std_h) 124string__h=$(GLSRC)string_.h $(std_h)
122time__h=$(GLSRC)time_.h $(std_h) $(gconfig__h) 125time__h=$(GLSRC)time_.h $(std_h) $(gconfig__h)
123unistd__h=$(GLSRC)unistd_.h $(std_h) 126unistd__h=$(GLSRC)unistd_.h $(std_h)
@@ -158,6 +161,7 @@ gx_h=$(GLSRC)gx.h $(stdio__h) $(gdebug_h)\
158 $(gsio_h) $(gsmemory_h) $(gstypes_h) $(gserrors_h) 161 $(gsio_h) $(gsmemory_h) $(gstypes_h) $(gserrors_h)
159gxsync_h=$(GLSRC)gxsync.h $(gpsync_h) $(gsmemory_h) 162gxsync_h=$(GLSRC)gxsync.h $(gpsync_h) $(gsmemory_h)
160gxclthrd_h=$(GLSRC)gxclthrd.h $(gxsync_h) 163gxclthrd_h=$(GLSRC)gxclthrd.h $(gxsync_h)
164
161# Out of order 165# Out of order
162gsmemlok_h=$(GLSRC)gsmemlok.h $(gsmemory_h) $(gxsync_h) 166gsmemlok_h=$(GLSRC)gsmemlok.h $(gsmemory_h) $(gxsync_h)
163gsnotify_h=$(GLSRC)gsnotify.h $(gsstype_h) 167gsnotify_h=$(GLSRC)gsnotify.h $(gsstype_h)
@@ -327,6 +331,10 @@ $(AUX)gsutil.$(OBJ) : $(GLSRC)gsutil.c $(AK) $(memory__h) $(string__h)\
327 $(gsrect_h) $(gsuid_h) $(gsutil_h) $(gzstate_h) $(gxdcolor_h) $(MAKEDIRS) 331 $(gsrect_h) $(gsuid_h) $(gsutil_h) $(gzstate_h) $(gxdcolor_h) $(MAKEDIRS)
328 $(GLCCAUX) $(AUXO_)gsutil.$(OBJ) $(C_) $(GLSRC)gsutil.c 332 $(GLCCAUX) $(AUXO_)gsutil.$(OBJ) $(C_) $(GLSRC)gsutil.c
329 333
334$(GLOBJ)gssprintf.$(OBJ) : $(GLSRC)gssprintf.c $(gssprintf_h) $(triodef_h) $(trio_h) \
335$(triop_h) $(triostr_h) $(trionan_h)
336 $(GLCC) $(I_)$(TRIOSRCDIR)$(_I) $(GLO_)gssprintf.$(OBJ) $(C_) $(GLSRC)gssprintf.c
337
330# MD5 digest 338# MD5 digest
331md5_h=$(GLSRC)md5.h 339md5_h=$(GLSRC)md5.h
332# We have to use a slightly different compilation approach in order to 340# We have to use a slightly different compilation approach in order to
@@ -1314,7 +1322,7 @@ LIB10s=$(GLOBJ)gsmalloc.$(OBJ) $(GLOBJ)memento.$(OBJ) $(GLOBJ)gsmatrix.$(OBJ)
1314LIB11s=$(GLOBJ)gsmemory.$(OBJ) $(GLOBJ)gsmemret.$(OBJ) $(GLOBJ)gsmisc.$(OBJ) $(GLOBJ)gsnotify.$(OBJ) $(GLOBJ)gslibctx.$(OBJ) 1322LIB11s=$(GLOBJ)gsmemory.$(OBJ) $(GLOBJ)gsmemret.$(OBJ) $(GLOBJ)gsmisc.$(OBJ) $(GLOBJ)gsnotify.$(OBJ) $(GLOBJ)gslibctx.$(OBJ)
1315LIB12s=$(GLOBJ)gspaint.$(OBJ) $(GLOBJ)gsparam.$(OBJ) $(GLOBJ)gspath.$(OBJ) 1323LIB12s=$(GLOBJ)gspaint.$(OBJ) $(GLOBJ)gsparam.$(OBJ) $(GLOBJ)gspath.$(OBJ)
1316LIB13s=$(GLOBJ)gsserial.$(OBJ) $(GLOBJ)gsstate.$(OBJ) $(GLOBJ)gstext.$(OBJ)\ 1324LIB13s=$(GLOBJ)gsserial.$(OBJ) $(GLOBJ)gsstate.$(OBJ) $(GLOBJ)gstext.$(OBJ)\
1317 $(GLOBJ)gsutil.$(OBJ) 1325 $(GLOBJ)gsutil.$(OBJ) $(TRIOOBJS) $(GLOBJ)gssprintf.$(OBJ)
1318LIB1x=$(GLOBJ)gxacpath.$(OBJ) $(GLOBJ)gxbcache.$(OBJ) $(GLOBJ)gxccache.$(OBJ) 1326LIB1x=$(GLOBJ)gxacpath.$(OBJ) $(GLOBJ)gxbcache.$(OBJ) $(GLOBJ)gxccache.$(OBJ)
1319LIB2x=$(GLOBJ)gxccman.$(OBJ) $(GLOBJ)gxchar.$(OBJ) $(GLOBJ)gxcht.$(OBJ) 1327LIB2x=$(GLOBJ)gxccman.$(OBJ) $(GLOBJ)gxchar.$(OBJ) $(GLOBJ)gxcht.$(OBJ)
1320LIB3x=$(GLOBJ)gxclip.$(OBJ) $(GLOBJ)gxcmap.$(OBJ) $(GLOBJ)gxcpath.$(OBJ) 1328LIB3x=$(GLOBJ)gxclip.$(OBJ) $(GLOBJ)gxcmap.$(OBJ) $(GLOBJ)gxcpath.$(OBJ)
diff --git a/gs/base/md5main.c b/gs/base/md5main.c
index 43cfd11ea..6454879ad 100644
--- a/gs/base/md5main.c
+++ b/gs/base/md5main.c
@@ -87,7 +87,7 @@ do_test(void)
87 gs_md5_append(&state, (const gs_md5_byte_t *)test[i], strlen(test[i])); 87 gs_md5_append(&state, (const gs_md5_byte_t *)test[i], strlen(test[i]));
88 gs_md5_finish(&state, digest); 88 gs_md5_finish(&state, digest);
89 for (di = 0; di < 16; ++di) 89 for (di = 0; di < 16; ++di)
90 sprintf(hex_output + di * 2, "%02x", digest[di]); 90 gs_sprintf(hex_output + di * 2, "%02x", digest[di]);
91 if (strcmp(hex_output, test[i + 1])) { 91 if (strcmp(hex_output, test[i + 1])) {
92 printf("MD5 (\"%s\") = ", test[i]); 92 printf("MD5 (\"%s\") = ", test[i]);
93 puts(hex_output); 93 puts(hex_output);
diff --git a/gs/base/mkromfs.c b/gs/base/mkromfs.c
index 937081790..96f2169d7 100644
--- a/gs/base/mkromfs.c
+++ b/gs/base/mkromfs.c
@@ -66,6 +66,8 @@
66 66
67/* prevent gp.h redefining fopen */ 67/* prevent gp.h redefining fopen */
68#define fopen fopen 68#define fopen fopen
69/* prevent gp.h redefining sprintf */
70#define sprintf sprintf
69 71
70#include "stdpre.h" 72#include "stdpre.h"
71#include "stdint_.h" 73#include "stdint_.h"
diff --git a/gs/base/sdcparam.c b/gs/base/sdcparam.c
index 314211704..5ef62b482 100644
--- a/gs/base/sdcparam.c
+++ b/gs/base/sdcparam.c
@@ -200,7 +200,7 @@ s_DCT_get_quantization_tables(gs_param_list * plist,
200 gs_param_string str; 200 gs_param_string str;
201 gs_param_float_array fa; 201 gs_param_float_array fa;
202 202
203 sprintf(key, "%d", i); 203 gs_sprintf(key, "%d", i);
204 if (QFactor == 1.0) { 204 if (QFactor == 1.0) {
205 code = quant_param_string(&str, DCTSIZE2, 205 code = quant_param_string(&str, DCTSIZE2,
206 table_ptrs[comp_info[i].quant_tbl_no]->quantval, 206 table_ptrs[comp_info[i].quant_tbl_no]->quantval,
@@ -474,7 +474,7 @@ s_DCT_put_quantization_tables(gs_param_list * plist, stream_DCT_state * pdct,
474 char istr[5]; /* i converted to string key */ 474 char istr[5]; /* i converted to string key */
475 UINT16 values[DCTSIZE2]; 475 UINT16 values[DCTSIZE2];
476 476
477 sprintf(istr, "%d", i); 477 gs_sprintf(istr, "%d", i);
478 code = quant_params(quant_tables.list, istr, DCTSIZE2, values, 478 code = quant_params(quant_tables.list, istr, DCTSIZE2, values,
479 pdct->QFactor); 479 pdct->QFactor);
480 if (code < 0) 480 if (code < 0)
@@ -566,7 +566,7 @@ s_DCT_put_huffman_tables(gs_param_list * plist, stream_DCT_state * pdct,
566 UINT8 counts[16], values[256]; 566 UINT8 counts[16], values[256];
567 567
568 /* Collect the Huffman parameters. */ 568 /* Collect the Huffman parameters. */
569 sprintf(istr, "%d", i); 569 gs_sprintf(istr, "%d", i);
570 code = s_DCT_byte_params(huff_tables.list, istr, 0, 16, counts); 570 code = s_DCT_byte_params(huff_tables.list, istr, 0, 16, counts);
571 if (code < 0) 571 if (code < 0)
572 return code; 572 return code;
diff --git a/gs/base/sjbig2.c b/gs/base/sjbig2.c
index 18b72f5de..961e362c1 100644
--- a/gs/base/sjbig2.c
+++ b/gs/base/sjbig2.c
@@ -65,7 +65,7 @@ s_jbig2decode_error(void *error_callback_data, const char *msg, Jbig2Severity se
65 default: type = "unknown message:"; break;; 65 default: type = "unknown message:"; break;;
66 } 66 }
67 if (seg_idx == -1) segment[0] = '\0'; 67 if (seg_idx == -1) segment[0] = '\0';
68 else sprintf(segment, "(segment 0x%02x)", seg_idx); 68 else gs_sprintf(segment, "(segment 0x%02x)", seg_idx);
69 69
70 if (state) 70 if (state)
71 { 71 {
diff --git a/gs/base/spprint.c b/gs/base/spprint.c
index 0d66006a4..b60ddceca 100644
--- a/gs/base/spprint.c
+++ b/gs/base/spprint.c
@@ -83,7 +83,7 @@ pprintd1(stream * s, const char *format, int v)
83 if (*fp == 0 || fp[1] != 'd') /* shouldn't happen! */ 83 if (*fp == 0 || fp[1] != 'd') /* shouldn't happen! */
84 lprintf1("Bad format in pprintd1: %s\n", format); 84 lprintf1("Bad format in pprintd1: %s\n", format);
85#endif 85#endif
86 sprintf(str, "%d", v); 86 gs_sprintf(str, "%d", v);
87 pputs_short(s, str); 87 pputs_short(s, str);
88 return pprintf_scan(s, fp + 2); 88 return pprintf_scan(s, fp + 2);
89} 89}
@@ -115,12 +115,12 @@ pprintg1(stream * s, const char *format, floatp v)
115 if (*fp == 0 || fp[1] != 'g') /* shouldn't happen! */ 115 if (*fp == 0 || fp[1] != 'g') /* shouldn't happen! */
116 lprintf1("Bad format in pprintg: %s\n", format); 116 lprintf1("Bad format in pprintg: %s\n", format);
117#endif 117#endif
118 sprintf(str, "%f", 1.5); 118 gs_sprintf(str, "%f", 1.5);
119 dot = str[1]; /* locale-dependent */ 119 dot = str[1]; /* locale-dependent */
120 sprintf(str, "%g", v); 120 gs_sprintf(str, "%g", v);
121 if (strchr(str, 'e')) { 121 if (strchr(str, 'e')) {
122 /* Bad news. Try again using f-format. */ 122 /* Bad news. Try again using f-format. */
123 sprintf(str, (fabs(v) > 1 ? "%1.1f" : "%1.8f"), v); 123 gs_sprintf(str, (fabs(v) > 1 ? "%1.1f" : "%1.8f"), v);
124 } 124 }
125 /* Juggling locales isn't thread-safe. Posix me harder. */ 125 /* Juggling locales isn't thread-safe. Posix me harder. */
126 if (dot != '.') { 126 if (dot != '.') {
@@ -165,7 +165,7 @@ pprintld1(stream * s, const char *format, long v)
165 if (*fp == 0 || fp[1] != 'l' || fp[2] != 'd') /* shouldn't happen! */ 165 if (*fp == 0 || fp[1] != 'l' || fp[2] != 'd') /* shouldn't happen! */
166 lprintf1("Bad format in pprintld: %s\n", format); 166 lprintf1("Bad format in pprintld: %s\n", format);
167#endif 167#endif
168 sprintf(str, "%ld", v); 168 gs_sprintf(str, "%ld", v);
169 pputs_short(s, str); 169 pputs_short(s, str);
170 return pprintf_scan(s, fp + 3); 170 return pprintf_scan(s, fp + 3);
171} 171}
diff --git a/gs/base/stdio_.h b/gs/base/stdio_.h
index b372feb37..66c945839 100644
--- a/gs/base/stdio_.h
+++ b/gs/base/stdio_.h
@@ -77,6 +77,15 @@ int unlink(const char *);
77int snprintf(char *buffer, size_t count, const char *format , ...); 77int snprintf(char *buffer, size_t count, const char *format , ...);
78#endif 78#endif
79 79
80/* for our non-localizing (v)s(n)printf() functions */
81/* only *really* required for floating point conversions */
82#include "gssprintf.h"
83
84#ifndef sprintf
85#define sprintf DO_NOT_USE_SPRINTF
86#endif
87
88
80#ifndef fopen 89#ifndef fopen
81#define fopen DO_NOT_USE_FOPEN 90#define fopen DO_NOT_USE_FOPEN
82#endif 91#endif
diff --git a/gs/base/trio.mak b/gs/base/trio.mak
new file mode 100644
index 000000000..071ddd847
--- /dev/null
+++ b/gs/base/trio.mak
@@ -0,0 +1,57 @@
1# Copyright (C) 2001-2012 Artifex Software, Inc.
2# All Rights Reserved.
3#
4# This software is provided AS-IS with no warranty, either express or
5# implied.
6#
7# This software is distributed under license and may not be copied,
8# modified or distributed except as expressly authorized under the terms
9# of the license contained in the file LICENSE in this distribution.
10#
11# Refer to licensing information at http://www.artifex.com or contact
12# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13# CA 94903, U.S.A., +1(415)492-9861, for further information.
14#
15# makefile for trio - locale-less s(n)printf/s(n)canf
16#
17# Users of this makefile must define the following:
18# TRIO_CFLAGS - Compiler flags for building the source,
19# TRIOSRCDIR - the expat source top-level directory,
20# TIOOBJDIR - directory for object files.
21
22# Define the name of this makefile
23TRIO_MAK=$(GLSRCDIR)$(D)trio.mak
24
25# local aliases
26TRIOSRC=$(TRIOSRCDIR)$(D)
27TRIOOBJ=$(TRIOOBJDIR)$(D)
28TRIOO_=$(O_)$(TRIOOBJ)
29
30TRIOCFLAGS=$(CFLAGS) $(TRIO_CFLAGS) $(D_)TRIO_EMBED_STRING$(_D) $(D_)TRIO_FEATURE_CLOSURE=0$(_D) \
31$(D_)TRIO_FEATURE_DYNAMICSTRING=0$(_D) $(D_)TRIO_MINIMAL=0$(_D) \
32$(D_)TRIO_FEATURE_USER_DEFINED=0$(_D) $(D_)TRIO_EXTENSION=0$(_D)\
33$(D_)TRIO_FUNC_TO_FLOAT$(_D) $(I_)$(TRIOSRCDIR)$(_I) \
34$(D_)TRIO_MALLOC=no_malloc$(_D) $(D_)TRIO_REALLOC=no_realloc$(_D) $(D_)TRIO_FREE=no_free$(_D)
35
36
37# NB: we can't use the normal $(CC_) here because msvccmd.mak
38# adds /Za which conflicts with the trio source.
39TRIOCC=$(CC) $(TRIOCFLAGS)
40
41TRIOOBJS=$(TRIOOBJ)triostr.$(OBJ) $(TRIOOBJ)trio.$(OBJ) $(TRIOOBJ)trionan.$(OBJ)
42
43triodef_h=$(TRIOSRC)triodef.h
44trio_h=$(TRIOSRC)trio.h
45triop_h=$(TRIOSRC)triop.h
46triostr_h=$(TRIOSRC)triostr.h
47
48TRIOHDRS=$(triodef_h) $(trio_h) $(triop_h) $(triostr_h)
49
50$(TRIOOBJ)triostr.$(OBJ) : $(TRIOSRC)triostr.c $(TRIOHDRS) $(TRIO_MAK)
51 $(TRIOCC) $(TRIOO_)triostr.$(OBJ) $(C_) $(TRIOSRC)triostr.c
52
53$(TRIOOBJ)trio.$(OBJ) : $(TRIOSRC)trio.c $(TRIOHDRS) $(TRIO_MAK)
54 $(TRIOCC) $(TRIOO_)trio.$(OBJ) $(C_) $(TRIOSRC)trio.c
55
56$(TRIOOBJ)trionan.$(OBJ) : $(TRIOSRC)trionan.c $(TRIOHDRS) $(TRIO_MAK)
57 $(TRIOCC) $(TRIOO_)trionan.$(OBJ) $(C_) $(TRIOSRC)trionan.c
diff --git a/gs/base/unix-gcc.mak b/gs/base/unix-gcc.mak
index 6e35052d9..6fbd5c5ae 100644
--- a/gs/base/unix-gcc.mak
+++ b/gs/base/unix-gcc.mak
@@ -169,6 +169,8 @@ TIFFPLATFORM=unix
169TIFFCONFIG_SUFFIX=.unix 169TIFFCONFIG_SUFFIX=.unix
170LIBTIFF_NAME=tiff 170LIBTIFF_NAME=tiff
171 171
172TRIOSRCDIR=trio
173
172# Define the directory where the zlib sources are stored. 174# Define the directory where the zlib sources are stored.
173# See zlib.mak for more information. 175# See zlib.mak for more information.
174 176
@@ -465,6 +467,7 @@ MAKEDIRSTOP=directories
465 467
466include $(GLSRCDIR)/unixhead.mak 468include $(GLSRCDIR)/unixhead.mak
467include $(GLSRCDIR)/gs.mak 469include $(GLSRCDIR)/gs.mak
470include $(GLSRCDIR)/trio.mak
468# psromfs.mak must precede lib.mak 471# psromfs.mak must precede lib.mak
469include $(PSSRCDIR)/psromfs.mak 472include $(PSSRCDIR)/psromfs.mak
470include $(GLSRCDIR)/lib.mak 473include $(GLSRCDIR)/lib.mak
diff --git a/gs/base/unixansi.mak b/gs/base/unixansi.mak
index fa6d57b6f..8b903404f 100644
--- a/gs/base/unixansi.mak
+++ b/gs/base/unixansi.mak
@@ -156,6 +156,8 @@ TIFFPLATFORM=unix
156TIFFCONFIG_SUFFIX=.unix 156TIFFCONFIG_SUFFIX=.unix
157LIBTIFF_NAME=tiff 157LIBTIFF_NAME=tiff
158 158
159TRIOSRCDIR=trio
160
159# Define the directory where the zlib sources are stored. 161# Define the directory where the zlib sources are stored.
160# See zlib.mak for more information. 162# See zlib.mak for more information.
161 163
@@ -396,6 +398,7 @@ CC_SHARED=$(CC_)
396 398
397include $(GLSRCDIR)/unixhead.mak 399include $(GLSRCDIR)/unixhead.mak
398include $(GLSRCDIR)/gs.mak 400include $(GLSRCDIR)/gs.mak
401include $(GLSRCDIR)/trio.mak
399# psromfs.mak must precede lib.mak 402# psromfs.mak must precede lib.mak
400include $(PSSRCDIR)/psromfs.mak 403include $(PSSRCDIR)/psromfs.mak
401include $(GLSRCDIR)/lib.mak 404include $(GLSRCDIR)/lib.mak
diff --git a/gs/base/winlib.mak b/gs/base/winlib.mak
index 3a1d7882a..0e27d2d70 100644
--- a/gs/base/winlib.mak
+++ b/gs/base/winlib.mak
@@ -133,6 +133,7 @@ BEGINFILES=$(GLGENDIR)\ccf32.tr\
133#!include $(COMMONDIR)/pcdefs.mak 133#!include $(COMMONDIR)/pcdefs.mak
134#!include $(COMMONDIR)/generic.mak 134#!include $(COMMONDIR)/generic.mak
135!include $(GLSRCDIR)\gs.mak 135!include $(GLSRCDIR)\gs.mak
136!include $(GLSRCDIR)\trio.mak
136!include $(GLSRCDIR)\lib.mak 137!include $(GLSRCDIR)\lib.mak
137!include $(GLSRCDIR)\freetype.mak 138!include $(GLSRCDIR)\freetype.mak
138!if "$(UFST_BRIDGE)"=="1" 139!if "$(UFST_BRIDGE)"=="1"
diff --git a/gs/base/wrfont.c b/gs/base/wrfont.c
index 69b8ee806..fbac8adac 100644
--- a/gs/base/wrfont.c
+++ b/gs/base/wrfont.c
@@ -72,7 +72,7 @@ WRF_wfloat(WRF_output * a_output, double a_float)
72{ 72{
73 char buffer[32]; 73 char buffer[32];
74 74
75 sprintf(buffer, "%f", a_float); 75 gs_sprintf(buffer, "%f", a_float);
76 WRF_wstring(a_output, buffer); 76 WRF_wstring(a_output, buffer);
77} 77}
78 78
@@ -81,6 +81,6 @@ WRF_wint(WRF_output * a_output, long a_int)
81{ 81{
82 char buffer[32]; 82 char buffer[32];
83 83
84 sprintf(buffer, "%ld", a_int); 84 gs_sprintf(buffer, "%ld", a_int);
85 WRF_wstring(a_output, buffer); 85 WRF_wstring(a_output, buffer);
86} 86}
diff --git a/gs/base/write_t1.c b/gs/base/write_t1.c
index 4cffac49f..85e7ea09b 100644
--- a/gs/base/write_t1.c
+++ b/gs/base/write_t1.c
@@ -300,7 +300,7 @@ write_main_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output,
300 if (x) 300 if (x)
301 entries++; 301 entries++;
302 302
303 sprintf(Buffer, "/FontInfo %d dict dup begin\n", entries); 303 gs_sprintf(Buffer, "/FontInfo %d dict dup begin\n", entries);
304 WRF_wstring(a_output, Buffer); 304 WRF_wstring(a_output, Buffer);
305 x = a_fapi_font->get_word(a_fapi_font, 305 x = a_fapi_font->get_word(a_fapi_font,
306 gs_fapi_font_feature_BlendAxisTypes_count, 306 gs_fapi_font_feature_BlendAxisTypes_count,
@@ -330,7 +330,7 @@ write_main_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output,
330 x1 = a_fapi_font->get_float(a_fapi_font, 330 x1 = a_fapi_font->get_float(a_fapi_font,
331 gs_fapi_font_feature_BlendDesignPositionsArrayValue, 331 gs_fapi_font_feature_BlendDesignPositionsArrayValue,
332 i * 8 + j); 332 i * 8 + j);
333 sprintf(Buffer, "%f ", x1); 333 gs_sprintf(Buffer, "%f ", x1);
334 WRF_wstring(a_output, Buffer); 334 WRF_wstring(a_output, Buffer);
335 } 335 }
336 WRF_wstring(a_output, "]"); 336 WRF_wstring(a_output, "]");
@@ -352,12 +352,12 @@ write_main_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output,
352 x1 = a_fapi_font->get_float(a_fapi_font, 352 x1 = a_fapi_font->get_float(a_fapi_font,
353 gs_fapi_font_feature_BlendDesignPositionsArrayValue, 353 gs_fapi_font_feature_BlendDesignPositionsArrayValue,
354 i * 64 + j * 64); 354 i * 64 + j * 64);
355 sprintf(Buffer, "%f ", x1); 355 gs_sprintf(Buffer, "%f ", x1);
356 WRF_wstring(a_output, Buffer); 356 WRF_wstring(a_output, Buffer);
357 x1 = a_fapi_font->get_float(a_fapi_font, 357 x1 = a_fapi_font->get_float(a_fapi_font,
358 gs_fapi_font_feature_BlendDesignPositionsArrayValue, 358 gs_fapi_font_feature_BlendDesignPositionsArrayValue,
359 i * 64 + j * 64 + 1); 359 i * 64 + j * 64 + 1);
360 sprintf(Buffer, "%f ", x1); 360 gs_sprintf(Buffer, "%f ", x1);
361 WRF_wstring(a_output, Buffer); 361 WRF_wstring(a_output, Buffer);
362 WRF_wstring(a_output, "]"); 362 WRF_wstring(a_output, "]");
363 } 363 }
@@ -397,7 +397,7 @@ write_main_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output,
397 for (i = 0; i < x; i++) { 397 for (i = 0; i < x; i++) {
398 x1 = a_fapi_font->get_float(a_fapi_font, 398 x1 = a_fapi_font->get_float(a_fapi_font,
399 gs_fapi_font_feature_WeightVector, i); 399 gs_fapi_font_feature_WeightVector, i);
400 sprintf(Buffer, "%f ", x1); 400 gs_sprintf(Buffer, "%f ", x1);
401 WRF_wstring(a_output, Buffer); 401 WRF_wstring(a_output, Buffer);
402 } 402 }
403 WRF_wstring(a_output, "] def\n"); 403 WRF_wstring(a_output, "] def\n");
diff --git a/gs/base/write_t2.c b/gs/base/write_t2.c
index dfe4738ea..e66ba6934 100644
--- a/gs/base/write_t2.c
+++ b/gs/base/write_t2.c
@@ -70,7 +70,7 @@ write_type2_float(WRF_output * a_output, double a_float)
70 int high = true; 70 int high = true;
71 char c = 0; 71 char c = 0;
72 72
73 sprintf(buffer, "%f", a_float); 73 gs_sprintf(buffer, "%f", a_float);
74 WRF_wbyte(a_output, 30); 74 WRF_wbyte(a_output, 30);
75 for (;;) { 75 for (;;) {
76 char n = 0; 76 char n = 0;
diff --git a/gs/contrib/eplaser/gdevescv.c b/gs/contrib/eplaser/gdevescv.c
index 274e863fd..a3ba9bcae 100644
--- a/gs/contrib/eplaser/gdevescv.c
+++ b/gs/contrib/eplaser/gdevescv.c
@@ -545,7 +545,7 @@ escv_vector_dopath(gx_device_vector * vdev, const gx_path * ppath,
545 y = fixed2float(vs[1]) / scale.y; 545 y = fixed2float(vs[1]) / scale.y;
546 546
547 /* ¥µ¥Ö¥Ñ¥¹³«»ÏÌ¿Îá p1 */ 547 /* ¥µ¥Ö¥Ñ¥¹³«»ÏÌ¿Îá p1 */
548 (void)sprintf(obuf, ESC_GS "0;%d;%dmvpG", (int)x, (int)y); 548 (void)gs_sprintf(obuf, ESC_GS "0;%d;%dmvpG", (int)x, (int)y);
549 lputs(s, obuf); 549 lputs(s, obuf);
550 550
551 if (first) 551 if (first)
@@ -556,11 +556,11 @@ escv_vector_dopath(gx_device_vector * vdev, const gx_path * ppath,
556 cnt = 1; 556 cnt = 1;
557 for (pseg = cenum.pseg; pseg != 0 && pseg->type == s_line; cnt++, pseg = pseg->next); 557 for (pseg = cenum.pseg; pseg != 0 && pseg->type == s_line; cnt++, pseg = pseg->next);
558 558
559 (void)sprintf(obuf, ESC_GS "0;%d", cnt); 559 (void)gs_sprintf(obuf, ESC_GS "0;%d", cnt);
560 lputs(s, obuf); 560 lputs(s, obuf);
561 561
562 do { 562 do {
563 (void)sprintf(obuf, ";%d;%d", 563 (void)gs_sprintf(obuf, ";%d;%d",
564 (int)(fixed2float(vs[0]) / scale.x), 564 (int)(fixed2float(vs[0]) / scale.x),
565 (int)(fixed2float(vs[1]) / scale.y)); 565 (int)(fixed2float(vs[1]) / scale.y));
566 lputs(s, obuf); 566 lputs(s, obuf);
@@ -577,11 +577,11 @@ escv_vector_dopath(gx_device_vector * vdev, const gx_path * ppath,
577 case gs_pe_curveto: 577 case gs_pe_curveto:
578 cnt = 1; 578 cnt = 1;
579 for (pseg = cenum.pseg; pseg != 0 && pseg->type == s_curve; cnt++, pseg = pseg->next); 579 for (pseg = cenum.pseg; pseg != 0 && pseg->type == s_curve; cnt++, pseg = pseg->next);
580 (void)sprintf(obuf, ESC_GS "0;%d", cnt * 3); 580 (void)gs_sprintf(obuf, ESC_GS "0;%d", cnt * 3);
581 lputs(s, obuf); 581 lputs(s, obuf);
582 582
583 do { 583 do {
584 (void)sprintf(obuf, ";%d;%d;%d;%d;%d;%d", 584 (void)gs_sprintf(obuf, ";%d;%d;%d;%d;%d;%d",
585 (int)(fixed2float(vs[0]) / scale.x), (int)(fixed2float(vs[1]) / scale.y), 585 (int)(fixed2float(vs[0]) / scale.x), (int)(fixed2float(vs[1]) / scale.y),
586 (int)(fixed2float(vs[2]) / scale.x), (int)(fixed2float(vs[3]) / scale.y), 586 (int)(fixed2float(vs[2]) / scale.x), (int)(fixed2float(vs[3]) / scale.y),
587 (int)(fixed2float(vs[4]) / scale.x), (int)(fixed2float(vs[5]) / scale.y)); 587 (int)(fixed2float(vs[4]) / scale.x), (int)(fixed2float(vs[5]) / scale.y));
@@ -637,7 +637,7 @@ escv_vector_dorect(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1,
637 637
638 scale = vdev->scale; 638 scale = vdev->scale;
639 639
640 (void)sprintf(obuf, ESC_GS "0;%d;%d;%d;%d;0;0rrpG", 640 (void)gs_sprintf(obuf, ESC_GS "0;%d;%d;%d;%d;0;0rrpG",
641 (int)(fixed2float(x0) / scale.x), 641 (int)(fixed2float(x0) / scale.x),
642 (int)(fixed2float(y0) / scale.y), 642 (int)(fixed2float(y0) / scale.y),
643 (int)(fixed2float(x1) / scale.x), 643 (int)(fixed2float(x1) / scale.x),
@@ -1116,7 +1116,7 @@ escv_beginpage(gx_device_vector * vdev)
1116 lputs(s, " PU=15"); 1116 lputs(s, " PU=15");
1117 } 1117 }
1118 } else if (pdev->cassetFeed) { 1118 } else if (pdev->cassetFeed) {
1119 (void)sprintf(ebuf, " PU=%d", pdev->cassetFeed); 1119 (void)gs_sprintf(ebuf, " PU=%d", pdev->cassetFeed);
1120 lputs(s, ebuf); 1120 lputs(s, ebuf);
1121 } else { 1121 } else {
1122 lputs(s, " PU=AU"); 1122 lputs(s, " PU=AU");
@@ -1146,14 +1146,14 @@ escv_beginpage(gx_device_vector * vdev)
1146 1146
1147 /* lp8000c not have QT */ 1147 /* lp8000c not have QT */
1148 if (strcmp(pdev->dname, "lp8000c") == 0) { 1148 if (strcmp(pdev->dname, "lp8000c") == 0) {
1149 (void)sprintf(ebuf, " QT=1 CO=%d", pdev->NumCopies); 1149 (void)gs_sprintf(ebuf, " QT=1 CO=%d", pdev->NumCopies);
1150 } else { 1150 } else {
1151 if (pdev->Collate) { 1151 if (pdev->Collate) {
1152 /* CO is 1, when set QT */ 1152 /* CO is 1, when set QT */
1153 (void)sprintf(ebuf, " QT=%d CO=1", pdev->NumCopies); 1153 (void)gs_sprintf(ebuf, " QT=%d CO=1", pdev->NumCopies);
1154 } else { 1154 } else {
1155 /* QT is 1, when not specified QT */ 1155 /* QT is 1, when not specified QT */
1156 (void)sprintf(ebuf, " QT=1 CO=%d", pdev->NumCopies); 1156 (void)gs_sprintf(ebuf, " QT=1 CO=%d", pdev->NumCopies);
1157 } 1157 }
1158 } 1158 }
1159 lputs(s, ebuf); 1159 lputs(s, ebuf);
@@ -1162,7 +1162,7 @@ escv_beginpage(gx_device_vector * vdev)
1162 } 1162 }
1163 1163
1164 if (pdev->toner_density) { 1164 if (pdev->toner_density) {
1165 (void)sprintf(ebuf, " DL=%d", pdev->toner_density); 1165 (void)gs_sprintf(ebuf, " DL=%d", pdev->toner_density);
1166 lputs(s, ebuf); 1166 lputs(s, ebuf);
1167 } 1167 }
1168 1168
@@ -1320,7 +1320,7 @@ escv_setlinewidth(gx_device_vector * vdev, floatp width)
1320 /* ESC/Page ¤Ç¤ÏÀþÉý¡¿½ªÃ¼¡¿ÀܹçÉô¤ÎÀßÄê¤Ï£±¤Ä¤Î¥³¥Þ¥ó¥É¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤¿¤áÊÝ»ý¤·¤Æ¤ª¤¯¡£ */ 1320 /* ESC/Page ¤Ç¤ÏÀþÉý¡¿½ªÃ¼¡¿ÀܹçÉô¤ÎÀßÄê¤Ï£±¤Ä¤Î¥³¥Þ¥ó¥É¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤¿¤áÊÝ»ý¤·¤Æ¤ª¤¯¡£ */
1321 pdev -> lwidth = width; 1321 pdev -> lwidth = width;
1322 1322
1323 (void)sprintf(obuf, ESC_GS "%d;%d;%dlwG", 1323 (void)gs_sprintf(obuf, ESC_GS "%d;%d;%dlwG",
1324 (int)(pdev -> lwidth), 1324 (int)(pdev -> lwidth),
1325 (int)(pdev -> cap), 1325 (int)(pdev -> cap),
1326 (int)(pdev -> join)); 1326 (int)(pdev -> join));
@@ -1341,7 +1341,7 @@ escv_setlinecap(gx_device_vector * vdev, gs_line_cap cap)
1341 1341
1342 if (pdev -> cap >= 3) return -1; 1342 if (pdev -> cap >= 3) return -1;
1343 1343
1344 (void)sprintf(obuf, ESC_GS "%d;%d;%dlwG", 1344 (void)gs_sprintf(obuf, ESC_GS "%d;%d;%dlwG",
1345 (int)(pdev -> lwidth), 1345 (int)(pdev -> lwidth),
1346 (int)(pdev -> cap), 1346 (int)(pdev -> cap),
1347 (int)(pdev -> join)); 1347 (int)(pdev -> join));
@@ -1372,7 +1372,7 @@ escv_setlinejoin(gx_device_vector * vdev, gs_line_join join)
1372 return -1; 1372 return -1;
1373 } 1373 }
1374 1374
1375 (void)sprintf(obuf, ESC_GS "%d;%d;%dlwG", 1375 (void)gs_sprintf(obuf, ESC_GS "%d;%d;%dlwG",
1376 (int)(pdev -> lwidth), 1376 (int)(pdev -> lwidth),
1377 (int)(pdev -> cap), 1377 (int)(pdev -> cap),
1378 (int)(pdev -> join)); 1378 (int)(pdev -> join));
@@ -1394,14 +1394,14 @@ escv_setmiterlimit(gx_device_vector * vdev, floatp limit)
1394 if (pdev -> join != 3) { 1394 if (pdev -> join != 3) {
1395 /* ¶¯À©Åª¤ËÀܹçÉô»ØÄê¤ò¹Ô¤¦ */ 1395 /* ¶¯À©Åª¤ËÀܹçÉô»ØÄê¤ò¹Ô¤¦ */
1396 pdev -> join = 3; 1396 pdev -> join = 3;
1397 (void)sprintf(obuf, ESC_GS "%d;%d;%dlwG", 1397 (void)gs_sprintf(obuf, ESC_GS "%d;%d;%dlwG",
1398 (int)(pdev -> lwidth), 1398 (int)(pdev -> lwidth),
1399 (int)(pdev -> cap), 1399 (int)(pdev -> cap),
1400 (int)(pdev -> join)); 1400 (int)(pdev -> join));
1401 lputs(s, obuf); 1401 lputs(s, obuf);
1402 } 1402 }
1403 1403
1404 (void)sprintf(obuf, ESC_GS "1;%dmlG", (int)limit); 1404 (void)gs_sprintf(obuf, ESC_GS "1;%dmlG", (int)limit);
1405 lputs(s, obuf); 1405 lputs(s, obuf);
1406 1406
1407 return 0; 1407 return 0;
@@ -1433,7 +1433,7 @@ escv_setfillcolor(gx_device_vector * vdev,
1433 1433
1434 if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ 1434 if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */
1435 1435
1436 (void)sprintf(obuf, /*ESC_GS "1owE"*/ ESC_GS "0;0;100spE" ESC_GS "1;0;%ldccE" ,color); 1436 (void)gs_sprintf(obuf, /*ESC_GS "1owE"*/ ESC_GS "0;0;100spE" ESC_GS "1;0;%ldccE" ,color);
1437 lputs(s, obuf); 1437 lputs(s, obuf);
1438 1438
1439 if (vdev->x_pixels_per_inch == 1200) { 1439 if (vdev->x_pixels_per_inch == 1200) {
@@ -1447,7 +1447,7 @@ escv_setfillcolor(gx_device_vector * vdev,
1447 } else { /* ESC/Page-Color */ 1447 } else { /* ESC/Page-Color */
1448 1448
1449 /* ¥Ñ¥¿¡¼¥ó£Ï£Î»ØÄê¡¿¥½¥ê¥Ã¥É¥Ñ¥¿¡¼¥ó»ØÄê */ 1449 /* ¥Ñ¥¿¡¼¥ó£Ï£Î»ØÄê¡¿¥½¥ê¥Ã¥É¥Ñ¥¿¡¼¥ó»ØÄê */
1450 (void)sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE", 1450 (void)gs_sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE",
1451 (unsigned char)(color >> 16 & 0xff), 1451 (unsigned char)(color >> 16 & 0xff),
1452 (unsigned char)(color >> 8 & 0xff), 1452 (unsigned char)(color >> 8 & 0xff),
1453 (unsigned char)(color & 0xff)); 1453 (unsigned char)(color & 0xff));
@@ -1477,7 +1477,7 @@ escv_setstrokecolor(gx_device_vector * vdev,
1477 1477
1478 pdev->current_color = color; 1478 pdev->current_color = color;
1479 1479
1480 (void)sprintf(obuf, /*ESC_GS "1owE"*/ ESC_GS "0;0;100spE" ESC_GS "1;1;%ldccE" , color); 1480 (void)gs_sprintf(obuf, /*ESC_GS "1owE"*/ ESC_GS "0;0;100spE" ESC_GS "1;1;%ldccE" , color);
1481 lputs(s, obuf); 1481 lputs(s, obuf);
1482 1482
1483 if (vdev->x_pixels_per_inch == 1200) { 1483 if (vdev->x_pixels_per_inch == 1200) {
@@ -1494,7 +1494,7 @@ escv_setstrokecolor(gx_device_vector * vdev,
1494 1494
1495 pdev->current_color = color; 1495 pdev->current_color = color;
1496 /* ¥Ñ¥¿¡¼¥ó£Ï£Î¿§»ØÄê¡¿¥½¥ê¥Ã¥É¥Ñ¥¿¡¼¥ó»ØÄê */ 1496 /* ¥Ñ¥¿¡¼¥ó£Ï£Î¿§»ØÄê¡¿¥½¥ê¥Ã¥É¥Ñ¥¿¡¼¥ó»ØÄê */
1497 (void)sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE" ESC_GS "2;2;1;0;0cpE", 1497 (void)gs_sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE" ESC_GS "2;2;1;0;0cpE",
1498 (unsigned char)(color >> 16 & 0xff), 1498 (unsigned char)(color >> 16 & 0xff),
1499 (unsigned char)(color >> 8 & 0xff), 1499 (unsigned char)(color >> 8 & 0xff),
1500 (unsigned char)(color & 0xff)); 1500 (unsigned char)(color & 0xff));
@@ -1538,11 +1538,11 @@ escv_setdash(gx_device_vector * vdev, const float *pattern, uint count, floatp o
1538 if (count) { 1538 if (count) {
1539 if (count == 1) { 1539 if (count == 1) {
1540#if GS_VERSION_MAJOR == 5 1540#if GS_VERSION_MAJOR == 5
1541 (void)sprintf(obuf, ESC_GS "1;%d;%ddlG", 1541 (void)gs_sprintf(obuf, ESC_GS "1;%d;%ddlG",
1542 (int)(pattern[0] * scale / vdev->x_pixels_per_inch + 0.5), 1542 (int)(pattern[0] * scale / vdev->x_pixels_per_inch + 0.5),
1543 (int)(pattern[0] * scale / vdev->x_pixels_per_inch + 0.5)); 1543 (int)(pattern[0] * scale / vdev->x_pixels_per_inch + 0.5));
1544#else 1544#else
1545 (void)sprintf(obuf, ESC_GS "1;%d;%ddlG", (int) pattern[0], (int) pattern[0]); 1545 (void)gs_sprintf(obuf, ESC_GS "1;%d;%ddlG", (int) pattern[0], (int) pattern[0]);
1546#endif 1546#endif
1547 lputs(s, obuf); 1547 lputs(s, obuf);
1548 } else { 1548 } else {
@@ -1554,10 +1554,10 @@ escv_setdash(gx_device_vector * vdev, const float *pattern, uint count, floatp o
1554 lputs(s, ESC_GS "1"); 1554 lputs(s, ESC_GS "1");
1555 for (i = 0; i < count; ++i) { 1555 for (i = 0; i < count; ++i) {
1556#if GS_VERSION_MAJOR == 5 1556#if GS_VERSION_MAJOR == 5
1557 (void)sprintf(obuf, ";%d", (int)(pattern[i] * scale / vdev->x_pixels_per_inch + 0.5)); 1557 (void)gs_sprintf(obuf, ";%d", (int)(pattern[i] * scale / vdev->x_pixels_per_inch + 0.5));
1558 1558
1559#else 1559#else
1560 (void)sprintf(obuf, ";%d", (int) pattern[i]); 1560 (void)gs_sprintf(obuf, ";%d", (int) pattern[i]);
1561#endif 1561#endif
1562 lputs(s, obuf); 1562 lputs(s, obuf);
1563 } 1563 }
@@ -1608,7 +1608,7 @@ escv_moveto(gx_device_vector * vdev,
1608 char obuf[64]; 1608 char obuf[64];
1609 1609
1610 /* ¥µ¥Ö¥Ñ¥¹³«»ÏÌ¿Îá */ 1610 /* ¥µ¥Ö¥Ñ¥¹³«»ÏÌ¿Îá */
1611 (void)sprintf(obuf, ESC_GS "0;%d;%dmvpG", (int)x1, (int)y1); 1611 (void)gs_sprintf(obuf, ESC_GS "0;%d;%dmvpG", (int)x1, (int)y1);
1612 lputs(s, obuf); 1612 lputs(s, obuf);
1613 1613
1614 return 0; 1614 return 0;
@@ -1622,7 +1622,7 @@ escv_lineto(gx_device_vector * vdev,
1622 gx_device_escv *pdev = (gx_device_escv *) vdev; 1622 gx_device_escv *pdev = (gx_device_escv *) vdev;
1623 char obuf[64]; 1623 char obuf[64];
1624 1624
1625 (void)sprintf(obuf, ESC_GS "0;1;%d;%dlnpG", (int)x1, (int)y1); 1625 (void)gs_sprintf(obuf, ESC_GS "0;1;%d;%dlnpG", (int)x1, (int)y1);
1626 lputs(s, obuf); 1626 lputs(s, obuf);
1627 pdev->ispath = 1; 1627 pdev->ispath = 1;
1628 1628
@@ -1639,7 +1639,7 @@ escv_curveto(gx_device_vector * vdev, floatp x0, floatp y0,
1639 char obuf[128]; 1639 char obuf[128];
1640 1640
1641 /* ¥Ù¥¸¥§¶ÊÀþ */ 1641 /* ¥Ù¥¸¥§¶ÊÀþ */
1642 (void)sprintf(obuf, ESC_GS "0;3;%d;%d;%d;%d;%d;%dbzpG", 1642 (void)gs_sprintf(obuf, ESC_GS "0;3;%d;%d;%d;%d;%d;%dbzpG",
1643 (int)x1, (int)y1, (int)x2, (int)y2, (int)x3, (int)y3); 1643 (int)x1, (int)y1, (int)x2, (int)y2, (int)x3, (int)y3);
1644 lputs(s, obuf); 1644 lputs(s, obuf);
1645 pdev->ispath = 1; 1645 pdev->ispath = 1;
@@ -2176,7 +2176,7 @@ escv_copy_mono(gx_device * dev, const byte * data,
2176 if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ 2176 if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */
2177 2177
2178 /* lputs(s, ESC_GS "1owE");*/ 2178 /* lputs(s, ESC_GS "1owE");*/
2179 (void)sprintf(obuf, ESC_GS "1;1;%ldccE", c_color); 2179 (void)gs_sprintf(obuf, ESC_GS "1;1;%ldccE", c_color);
2180 lputs(s, obuf); 2180 lputs(s, obuf);
2181 2181
2182 if (vdev->x_pixels_per_inch == 1200) { 2182 if (vdev->x_pixels_per_inch == 1200) {
@@ -2263,7 +2263,7 @@ escv_copy_mono(gx_device * dev, const byte * data,
2263 } else { /* ESC/Page-Color */ 2263 } else { /* ESC/Page-Color */
2264 2264
2265 /* ¥Ñ¥¿¡¼¥ó£Ï£Î»ØÄê¡¿¥½¥ê¥Ã¥É¥Ñ¥¿¡¼¥ó»ØÄê */ 2265 /* ¥Ñ¥¿¡¼¥ó£Ï£Î»ØÄê¡¿¥½¥ê¥Ã¥É¥Ñ¥¿¡¼¥ó»ØÄê */
2266 (void)sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE", 2266 (void)gs_sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE",
2267 (unsigned char)(c_color >> 16 & 0xff), 2267 (unsigned char)(c_color >> 16 & 0xff),
2268 (unsigned char)(c_color >> 8 & 0xff), 2268 (unsigned char)(c_color >> 8 & 0xff),
2269 (unsigned char)(c_color & 0xff)); 2269 (unsigned char)(c_color & 0xff));
@@ -2388,7 +2388,7 @@ escv_fill_mask(gx_device * dev,
2388 if (!gx_dc_is_pure(pdcolor)) return_error(gs_error_rangecheck); 2388 if (!gx_dc_is_pure(pdcolor)) return_error(gs_error_rangecheck);
2389 pdev->current_color = color; 2389 pdev->current_color = color;
2390 2390
2391 (void)sprintf(obuf, ESC_GS "0;0;100spE" ESC_GS "1;1;%ldccE" ,color); 2391 (void)gs_sprintf(obuf, ESC_GS "0;0;100spE" ESC_GS "1;1;%ldccE" ,color);
2392 lputs(s, obuf); 2392 lputs(s, obuf);
2393 2393
2394 if (vdev->x_pixels_per_inch == 1200) { 2394 if (vdev->x_pixels_per_inch == 1200) {
@@ -2428,7 +2428,7 @@ escv_fill_mask(gx_device * dev,
2428 memcpy(buf + i * width_bytes, data + (data_x >> 3) + i * raster, width_bytes); 2428 memcpy(buf + i * width_bytes, data + (data_x >> 3) + i * raster, width_bytes);
2429 } 2429 }
2430 2430
2431 (void)sprintf(obuf, ESC_GS "%d;%d;%d;%d;0db{F", num_bytes, (int)(id & VCACHE), w, h); 2431 (void)gs_sprintf(obuf, ESC_GS "%d;%d;%d;%d;0db{F", num_bytes, (int)(id & VCACHE), w, h);
2432 lputs(s, obuf); 2432 lputs(s, obuf);
2433 put_bytes(s, buf, num_bytes); 2433 put_bytes(s, buf, num_bytes);
2434 2434
@@ -2436,9 +2436,9 @@ escv_fill_mask(gx_device * dev,
2436 pdev -> id_cache[id & VCACHE] = id; 2436 pdev -> id_cache[id & VCACHE] = id;
2437 } 2437 }
2438 2438
2439 (void)sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y); 2439 (void)gs_sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y);
2440 lputs(s, obuf); 2440 lputs(s, obuf);
2441 (void)sprintf(obuf, ESC_GS "%lddbF", id & VCACHE); 2441 (void)gs_sprintf(obuf, ESC_GS "%lddbF", id & VCACHE);
2442 lputs(s, obuf); 2442 lputs(s, obuf);
2443 2443
2444 return 0; 2444 return 0;
@@ -2603,7 +2603,7 @@ escv_begin_image(gx_device * dev,
2603 if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ 2603 if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */
2604 2604
2605 /* lputs(s, ESC_GS "1owE");*/ 2605 /* lputs(s, ESC_GS "1owE");*/
2606 (void)sprintf(obuf, ESC_GS "1;1;%ldccE", color); 2606 (void)gs_sprintf(obuf, ESC_GS "1;1;%ldccE", color);
2607 lputs(s, obuf); 2607 lputs(s, obuf);
2608 2608
2609 if (vdev->x_pixels_per_inch == 1200) { 2609 if (vdev->x_pixels_per_inch == 1200) {
@@ -2908,7 +2908,7 @@ static void escv_write_begin(gx_device *dev, int bits, int x, int y, int sw, int
2908 2908
2909 if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ 2909 if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */
2910 2910
2911 (void)sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y); 2911 (void)gs_sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y);
2912 lputs(s, obuf); 2912 lputs(s, obuf);
2913 2913
2914 comp = 10; 2914 comp = 10;
@@ -2916,34 +2916,34 @@ static void escv_write_begin(gx_device *dev, int bits, int x, int y, int sw, int
2916 if (bits == 1) { 2916 if (bits == 1) {
2917 if (strcmp(pdev->dname, "lp1800") == 0 || 2917 if (strcmp(pdev->dname, "lp1800") == 0 ||
2918 strcmp(pdev->dname, "lp9600") == 0) { 2918 strcmp(pdev->dname, "lp9600") == 0) {
2919 (void)sprintf(obuf, ESC_GS "0bcI"); 2919 (void)gs_sprintf(obuf, ESC_GS "0bcI");
2920 }else{ 2920 }else{
2921 (void)sprintf(obuf, ESC_GS "5;%d;%d;%d;%d;%dsrI", sw, sh, dw, dh, roll); 2921 (void)gs_sprintf(obuf, ESC_GS "5;%d;%d;%d;%d;%dsrI", sw, sh, dw, dh, roll);
2922 } 2922 }
2923 } else if (bits == 4) { 2923 } else if (bits == 4) {
2924 if (pdev -> c4map) { 2924 if (pdev -> c4map) {
2925 pdev -> c4map = FALSE; 2925 pdev -> c4map = FALSE;
2926 } 2926 }
2927 (void)sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); 2927 (void)gs_sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll);
2928 } else if (bits == 8) { 2928 } else if (bits == 8) {
2929 if (pdev -> c8map) { 2929 if (pdev -> c8map) {
2930 pdev -> c8map = FALSE; 2930 pdev -> c8map = FALSE;
2931 } 2931 }
2932 (void)sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); 2932 (void)gs_sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll);
2933 } else { 2933 } else {
2934 /* 24 bit */ 2934 /* 24 bit */
2935 (void)sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); 2935 (void)gs_sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll);
2936 } 2936 }
2937 2937
2938 } else { /* ESC/Page-Color */ 2938 } else { /* ESC/Page-Color */
2939 2939
2940 (void)sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y); 2940 (void)gs_sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y);
2941 lputs(s, obuf); 2941 lputs(s, obuf);
2942 2942
2943 comp = 0; 2943 comp = 0;
2944 2944
2945 if (bits == 1) { 2945 if (bits == 1) {
2946 (void)sprintf(obuf, ESC_GS "2;201;1;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); 2946 (void)gs_sprintf(obuf, ESC_GS "2;201;1;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll);
2947 } else if (bits == 4) { 2947 } else if (bits == 4) {
2948 if (pdev -> c4map) { 2948 if (pdev -> c4map) {
2949 /* ¥«¥é¡¼¥Þ¥Ã¥×ÅÐÏ¿ */ 2949 /* ¥«¥é¡¼¥Þ¥Ã¥×ÅÐÏ¿ */
@@ -2959,7 +2959,7 @@ static void escv_write_begin(gx_device *dev, int bits, int x, int y, int sw, int
2959 gs_free_object(vdev->memory, tmp, "escv_write_begin(tmp4)"); 2959 gs_free_object(vdev->memory, tmp, "escv_write_begin(tmp4)");
2960 pdev -> c4map = FALSE; 2960 pdev -> c4map = FALSE;
2961 } 2961 }
2962 (void)sprintf(obuf, ESC_GS "2;203;2;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); 2962 (void)gs_sprintf(obuf, ESC_GS "2;203;2;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll);
2963 } else if (bits == 8) { 2963 } else if (bits == 8) {
2964 if (pdev -> c8map) { 2964 if (pdev -> c8map) {
2965 /* ¥«¥é¡¼¥Þ¥Ã¥×ÅÐÏ¿ */ 2965 /* ¥«¥é¡¼¥Þ¥Ã¥×ÅÐÏ¿ */
@@ -2975,10 +2975,10 @@ static void escv_write_begin(gx_device *dev, int bits, int x, int y, int sw, int
2975 gs_free_object(vdev->memory, tmp, "escv_write_begin(tmp)"); 2975 gs_free_object(vdev->memory, tmp, "escv_write_begin(tmp)");
2976 pdev -> c8map = FALSE; 2976 pdev -> c8map = FALSE;
2977 } 2977 }
2978 (void)sprintf(obuf, ESC_GS "2;204;4;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); 2978 (void)gs_sprintf(obuf, ESC_GS "2;204;4;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll);
2979 } else { 2979 } else {
2980 /* 24 bit */ 2980 /* 24 bit */
2981 (void)sprintf(obuf, ESC_GS "2;102;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); 2981 (void)gs_sprintf(obuf, ESC_GS "2;102;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll);
2982 } 2982 }
2983 2983
2984 } /* ESC/Page-Color */ 2984 } /* ESC/Page-Color */
@@ -3045,12 +3045,12 @@ static void escv_write_data(gx_device *dev, int bits, char *buf, int bsize, int
3045 if(bits == 1){ 3045 if(bits == 1){
3046 if (strcmp(pdev->dname, "lp1800") == 0 || \ 3046 if (strcmp(pdev->dname, "lp1800") == 0 || \
3047 strcmp(pdev->dname, "lp9600") == 0) { 3047 strcmp(pdev->dname, "lp9600") == 0) {
3048 (void)sprintf(obuf, ESC_GS "%d;1;%d;%d;0db{I", bsize, w, ras); 3048 (void)gs_sprintf(obuf, ESC_GS "%d;1;%d;%d;0db{I", bsize, w, ras);
3049 }else{ 3049 }else{
3050 (void)sprintf(obuf, ESC_GS "%d;%du{I", bsize, ras); 3050 (void)gs_sprintf(obuf, ESC_GS "%d;%du{I", bsize, ras);
3051 } 3051 }
3052 }else{ 3052 }else{
3053 (void)sprintf(obuf, ESC_GS "%d;%dcu{I", bsize, ras); 3053 (void)gs_sprintf(obuf, ESC_GS "%d;%dcu{I", bsize, ras);
3054 } 3054 }
3055 lputs(s, obuf); 3055 lputs(s, obuf);
3056 3056
@@ -3077,7 +3077,7 @@ static void escv_write_data(gx_device *dev, int bits, char *buf, int bsize, int
3077 buf = tmps; 3077 buf = tmps;
3078 } 3078 }
3079 3079
3080 (void)sprintf(obuf, ESC_GS "%d;%dcu{I", bsize, ras); 3080 (void)gs_sprintf(obuf, ESC_GS "%d;%dcu{I", bsize, ras);
3081 lputs(s, obuf); 3081 lputs(s, obuf);
3082 put_bytes(s, buf, bsize); 3082 put_bytes(s, buf, bsize);
3083 3083
diff --git a/gs/contrib/gdevcd8.c b/gs/contrib/gdevcd8.c
index e26768e34..cb2be3690 100644
--- a/gs/contrib/gdevcd8.c
+++ b/gs/contrib/gdevcd8.c
@@ -2439,7 +2439,7 @@ do_gcr(int bytecount, byte * inbyte, const byte kvalues[256],
2439#if 0 2439#if 0
2440 if ((*cyan > 0) && (*magenta > 0) && (*yellow > 0)) 2440 if ((*cyan > 0) && (*magenta > 0) && (*yellow > 0))
2441 { 2441 {
2442 sprintf(output, "%3d %3d %3d %3d - ", *cyan, *magenta, *yellow, *black); 2442 gs_sprintf(output, "%3d %3d %3d %3d - ", *cyan, *magenta, *yellow, *black);
2443 debug_print_string(output, strlen(output)); 2443 debug_print_string(output, strlen(output));
2444 } 2444 }
2445#endif /* 0 */ 2445#endif /* 0 */
@@ -2486,7 +2486,7 @@ do_gcr(int bytecount, byte * inbyte, const byte kvalues[256],
2486#if 0 2486#if 0
2487 if (ucr > 0) 2487 if (ucr > 0)
2488 { 2488 {
2489 sprintf(output, "%3d %3d %3d %3d - %5d\n", *cyan, *magenta, *yellow, *black, ucr); 2489 gs_sprintf(output, "%3d %3d %3d %3d - %5d\n", *cyan, *magenta, *yellow, *black, ucr);
2490 debug_print_string(output, strlen(output)); 2490 debug_print_string(output, strlen(output));
2491 } 2491 }
2492#endif /* 0 */ 2492#endif /* 0 */
diff --git a/gs/contrib/gdevdj9.c b/gs/contrib/gdevdj9.c
index 18b0d8349..8956b14e0 100644
--- a/gs/contrib/gdevdj9.c
+++ b/gs/contrib/gdevdj9.c
@@ -2563,7 +2563,7 @@ static int cdj970_write_header (gx_device *pdev, FILE * prn_stream)
2563 2563
2564 memset (startbuffer, 0, 1260); 2564 memset (startbuffer, 0, 1260);
2565 2565
2566 sprintf (&(startbuffer[600]), "\033E\033%%-12345X@PJL JOB NAME = \"GHOST BY RENE HARSCH\"\n@PJL ENTER LANGUAGE=PCL3GUI\n"); 2566 gs_sprintf (&(startbuffer[600]), "\033E\033%%-12345X@PJL JOB NAME = \"GHOST BY RENE HARSCH\"\n@PJL ENTER LANGUAGE=PCL3GUI\n");
2567 2567
2568 fwrite (startbuffer, sizeof(char), 678, prn_stream); 2568 fwrite (startbuffer, sizeof(char), 678, prn_stream);
2569 2569
diff --git a/gs/contrib/gdevhl12.c b/gs/contrib/gdevhl12.c
index db5855581..cda2ef7dd 100644
--- a/gs/contrib/gdevhl12.c
+++ b/gs/contrib/gdevhl12.c
@@ -662,7 +662,7 @@ hl1250_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
662 (-120, 0) compared to the one in the ljet4 driver (-180, 36) 662 (-120, 0) compared to the one in the ljet4 driver (-180, 36)
663 (X, Y coordinates here are specified in 1/720-inch units). */ 663 (X, Y coordinates here are specified in 1/720-inch units). */
664 664
665 sprintf(page_init, "\033&l-120U\033*r0F\033&u%dD%s", y_dpi, tray_pcl); 665 gs_sprintf(page_init, "\033&l-120U\033*r0F\033&u%dD%s", y_dpi, tray_pcl);
666 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, 666 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
667 y_dpi, PCL_LJ4_FEATURES, 667 y_dpi, PCL_LJ4_FEATURES,
668 page_init, page_init, false); 668 page_init, page_init, false);
diff --git a/gs/contrib/gdevxes.c b/gs/contrib/gdevxes.c
index a75a914d9..f7eea65c0 100644
--- a/gs/contrib/gdevxes.c
+++ b/gs/contrib/gdevxes.c
@@ -173,7 +173,7 @@ sixel_print_page(gx_device_printer *pdev, FILE *prn_stream, const char *init)
173 if ( tmp[l] == last ) { 173 if ( tmp[l] == last ) {
174 count++; 174 count++;
175 if (count==32767) { 175 if (count==32767) {
176 run[sprintf(run, "%d", count)]='\0'; 176 run[gs_sprintf(run, "%d", count)]='\0';
177 for (t=run; *t; t++)fputc( *t, prn_stream ); 177 for (t=run; *t; t++)fputc( *t, prn_stream );
178 fputc( last, prn_stream ); 178 fputc( last, prn_stream );
179 last = '\0'; 179 last = '\0';
@@ -186,7 +186,7 @@ sixel_print_page(gx_device_printer *pdev, FILE *prn_stream, const char *init)
186 case 0: break; 186 case 0: break;
187 case 1: fputc( last, prn_stream ); 187 case 1: fputc( last, prn_stream );
188 break; 188 break;
189 default:run[sprintf(run, "%d", count)]='\0'; 189 default:run[gs_sprintf(run, "%d", count)]='\0';
190 for (t=run; *t; t++) fputc( *t, prn_stream ); 190 for (t=run; *t; t++) fputc( *t, prn_stream );
191 fputc( last, prn_stream ); 191 fputc( last, prn_stream );
192 break; 192 break;
@@ -203,7 +203,7 @@ sixel_print_page(gx_device_printer *pdev, FILE *prn_stream, const char *init)
203 case 0: break; 203 case 0: break;
204 case 1: fputc( last, prn_stream ); 204 case 1: fputc( last, prn_stream );
205 break; 205 break;
206 default:run[sprintf(run, "%d", count)]='\0'; 206 default:run[gs_sprintf(run, "%d", count)]='\0';
207 for (t=run; *t; t++) fputc( *t, prn_stream ); 207 for (t=run; *t; t++) fputc( *t, prn_stream );
208 fputc( last, prn_stream ); 208 fputc( last, prn_stream );
209 break; 209 break;
diff --git a/gs/contrib/gomni.c b/gs/contrib/gomni.c
index 427c9a5c5..ab7b5ef3d 100644
--- a/gs/contrib/gomni.c
+++ b/gs/contrib/gomni.c
@@ -790,7 +790,7 @@ SetupDevice (gx_device *pgxdev, gs_param_list *plist)
790 "Devicestring"); 790 "Devicestring");
791 if (pszDeviceLib) 791 if (pszDeviceLib)
792 { 792 {
793 sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cOmnilib); 793 gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cOmnilib);
794 794
795 pDev->hmodOmni = g_module_open (pszDeviceLib, (GModuleFlags)0); 795 pDev->hmodOmni = g_module_open (pszDeviceLib, (GModuleFlags)0);
796 796
@@ -817,7 +817,7 @@ SetupDevice (gx_device *pgxdev, gs_param_list *plist)
817 "Devicestring"); 817 "Devicestring");
818 if (pszDeviceLib) 818 if (pszDeviceLib)
819 { 819 {
820 sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cOmnilib); 820 gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cOmnilib);
821 821
822 pModule = g_module_open (pszDeviceLib, (GModuleFlags)0); 822 pModule = g_module_open (pszDeviceLib, (GModuleFlags)0);
823 823
@@ -1053,7 +1053,7 @@ SetupDevice (gx_device *pgxdev, gs_param_list *plist)
1053 1053
1054 if (pszDeviceLib) 1054 if (pszDeviceLib)
1055 { 1055 {
1056 sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cDialogName); 1056 gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cDialogName);
1057 1057
1058 if (fDebugOutput) dprintf1 ("attempting to load - %s\n", pszDeviceLib); 1058 if (fDebugOutput) dprintf1 ("attempting to load - %s\n", pszDeviceLib);
1059 1059
@@ -1079,7 +1079,7 @@ SetupDevice (gx_device *pgxdev, gs_param_list *plist)
1079 1079
1080 if (pszDeviceLib) 1080 if (pszDeviceLib)
1081 { 1081 {
1082 sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cDialogName); 1082 gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cDialogName);
1083 1083
1084 pModule = g_module_open (pszDeviceLib, (GModuleFlags)0); 1084 pModule = g_module_open (pszDeviceLib, (GModuleFlags)0);
1085 1085
diff --git a/gs/contrib/japanese/dviprlib.c b/gs/contrib/japanese/dviprlib.c
index 6b5963936..608bd15f5 100644
--- a/gs/contrib/japanese/dviprlib.c
+++ b/gs/contrib/japanese/dviprlib.c
@@ -106,7 +106,7 @@ dviprt_read_S_cfg(dviprt_cfg_t *pcfg,dviprt_cfg_i *pinfo)
106 goto not_cfg; 106 goto not_cfg;
107 pcfg->version = rbuf[2] | ((uint)rbuf[3] << 8); 107 pcfg->version = rbuf[2] | ((uint)rbuf[3] << 8);
108 if (pcfg->version > CFG_VERSION) { 108 if (pcfg->version > CFG_VERSION) {
109 sprintf(dviprt_message_buffer, 109 gs_sprintf(dviprt_message_buffer,
110 "This *.CFG file is too new version(ver.%u).\n",pcfg->version); 110 "This *.CFG file is too new version(ver.%u).\n",pcfg->version);
111 dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1); 111 dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1);
112 return CFG_ERROR_OTHER; 112 return CFG_ERROR_OTHER;
@@ -129,7 +129,7 @@ dviprt_read_S_cfg(dviprt_cfg_t *pcfg,dviprt_cfg_i *pinfo)
129 if (n >= CFG_INTEGER_TYPE_COUNT) { 129 if (n >= CFG_INTEGER_TYPE_COUNT) {
130 ptype = "integer"; 130 ptype = "integer";
131 unknown_no: 131 unknown_no:
132 sprintf(dviprt_message_buffer, 132 gs_sprintf(dviprt_message_buffer,
133 "Unknown %s type value No.%d is found.\n",ptype,n); 133 "Unknown %s type value No.%d is found.\n",ptype,n);
134 dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1); 134 dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1);
135 return CFG_ERROR_OTHER; 135 return CFG_ERROR_OTHER;
@@ -346,7 +346,7 @@ dviprt_read_QR_cfg(dviprt_cfg_t *pcfg,dviprt_cfg_i *pinfo)
346 ptr++; 346 ptr++;
347 break; 347 break;
348 default: 348 default:
349 sprintf(dviprt_message_buffer,"Unknown format %02X",type); 349 gs_sprintf(dviprt_message_buffer,"Unknown format %02X",type);
350 dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1); 350 dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1);
351 goto ex_func; 351 goto ex_func;
352 } 352 }
@@ -587,7 +587,7 @@ dviprt_readsrc(char *fname,dviprt_cfg_t *pcfg,uchar *pcodebuf,int codebuf_s,
587 while (*pbuf && isspace(*pbuf)) pbuf++; 587 while (*pbuf && isspace(*pbuf)) pbuf++;
588 if (pitem->spec_f) { 588 if (pitem->spec_f) {
589 dviprt_printcfgerror(&info,NULL,0); 589 dviprt_printcfgerror(&info,NULL,0);
590 sprintf(dviprt_message_buffer, 590 gs_sprintf(dviprt_message_buffer,
591 "Item `%s' is specified twice.\n",pitem->name); 591 "Item `%s' is specified twice.\n",pitem->name);
592 dviprt_printmessage(dviprt_message_buffer,-1); 592 dviprt_printmessage(dviprt_message_buffer,-1);
593 code = CFG_ERROR_SYNTAX; 593 code = CFG_ERROR_SYNTAX;
@@ -691,7 +691,7 @@ dviprt_readsrc(char *fname,dviprt_cfg_t *pcfg,uchar *pcodebuf,int codebuf_s,
691 code = 0; 691 code = 0;
692 for (pitem = dviprt_items;pitem->name;pitem++) { 692 for (pitem = dviprt_items;pitem->name;pitem++) {
693 if (!pitem->spec_f && pitem->req_f) { 693 if (!pitem->spec_f && pitem->req_f) {
694 sprintf(dviprt_message_buffer,"%s not found.\n",pitem->name); 694 gs_sprintf(dviprt_message_buffer,"%s not found.\n",pitem->name);
695 dviprt_printcfgerror(&info,dviprt_message_buffer,-1); 695 dviprt_printcfgerror(&info,dviprt_message_buffer,-1);
696 code++; 696 code++;
697 } 697 }
@@ -749,14 +749,14 @@ dviprt_readsrc(char *fname,dviprt_cfg_t *pcfg,uchar *pcodebuf,int codebuf_s,
749 749
750 for (pitem = dviprt_items;pitem->type>=0;pitem++) { 750 for (pitem = dviprt_items;pitem->type>=0;pitem++) {
751 if (pitem->spec_f == 0) { 751 if (pitem->spec_f == 0) {
752 sprintf(dviprt_message_buffer,": %s:",pitem->name); 752 gs_sprintf(dviprt_message_buffer,": %s:",pitem->name);
753 switch (pitem->type) { 753 switch (pitem->type) {
754 case T_INTEGER: 754 case T_INTEGER:
755 if (pcfg->integer[pitem->no] >= 0) { 755 if (pcfg->integer[pitem->no] >= 0) {
756 uint v = pcfg->integer[pitem->no]; 756 uint v = pcfg->integer[pitem->no];
757 dviprt_printmessage(fname,-1); 757 dviprt_printmessage(fname,-1);
758 dviprt_printmessage(dviprt_message_buffer,-1); 758 dviprt_printmessage(dviprt_message_buffer,-1);
759 sprintf(dviprt_message_buffer," %d\n",v); 759 gs_sprintf(dviprt_message_buffer," %d\n",v);
760 dviprt_printmessage(dviprt_message_buffer,-1); 760 dviprt_printmessage(dviprt_message_buffer,-1);
761 } 761 }
762 break; 762 break;
@@ -802,7 +802,7 @@ dviprt_set_integer(dviprt_cfg_item_t *pitem,uchar *buf,dviprt_cfg_t *pcfg,
802 out_of_range: 802 out_of_range:
803 dviprt_printtokenerror(pinfo,buf,strlen(buf),ERROR_OUTOFRANGE); 803 dviprt_printtokenerror(pinfo,buf,strlen(buf),ERROR_OUTOFRANGE);
804 dviprt_printcfgerror(pinfo,"",-1); 804 dviprt_printcfgerror(pinfo,"",-1);
805 sprintf(dviprt_message_buffer, 805 gs_sprintf(dviprt_message_buffer,
806 "(%u <= value <= %u).\n",(uint)min,(uint)max); 806 "(%u <= value <= %u).\n",(uint)min,(uint)max);
807 dviprt_printmessage(dviprt_message_buffer,-1); 807 dviprt_printmessage(dviprt_message_buffer,-1);
808 return CFG_ERROR_RANGE; 808 return CFG_ERROR_RANGE;
@@ -1108,10 +1108,10 @@ dviprt_set_rpexpr(dviprt_cfg_item_t *pitem,uchar *pbuf,int len,dviprt_cfg_t *pcf
1108 pitem->no != CFG_AFTER_BIT_IMAGE) { 1108 pitem->no != CFG_AFTER_BIT_IMAGE) {
1109 unavailable_value: 1109 unavailable_value:
1110 dviprt_printcfgerror(pinfo,"",-1); 1110 dviprt_printcfgerror(pinfo,"",-1);
1111 sprintf(dviprt_message_buffer,"Variable `%c' in ",(int)*pbuf); 1111 gs_sprintf(dviprt_message_buffer,"Variable `%c' in ",(int)*pbuf);
1112 dviprt_printmessage(dviprt_message_buffer,-1); 1112 dviprt_printmessage(dviprt_message_buffer,-1);
1113 dviprt_printmessage(pbuf,(int)(pend-pbuf)); 1113 dviprt_printmessage(pbuf,(int)(pend-pbuf));
1114 sprintf(dviprt_message_buffer," cannot be used in %s.\n",pitem->name); 1114 gs_sprintf(dviprt_message_buffer," cannot be used in %s.\n",pitem->name);
1115 dviprt_printmessage(dviprt_message_buffer,-1); 1115 dviprt_printmessage(dviprt_message_buffer,-1);
1116 return CFG_ERROR_RANGE; 1116 return CFG_ERROR_RANGE;
1117 } 1117 }
@@ -1144,7 +1144,7 @@ dviprt_set_rpexpr(dviprt_cfg_item_t *pitem,uchar *pbuf,int len,dviprt_cfg_t *pcf
1144 case '^': op = CFG_OP_XOR; break; 1144 case '^': op = CFG_OP_XOR; break;
1145 default: 1145 default:
1146 dviprt_printcfgerror(pinfo,NULL,0); 1146 dviprt_printcfgerror(pinfo,NULL,0);
1147 sprintf(dviprt_message_buffer,"Unknown operator %c in ",(int)*pbuf); 1147 gs_sprintf(dviprt_message_buffer,"Unknown operator %c in ",(int)*pbuf);
1148 dviprt_printmessage(dviprt_message_buffer,-1); 1148 dviprt_printmessage(dviprt_message_buffer,-1);
1149 dviprt_printmessage(pbuf,(int)(pend-pbuf)); 1149 dviprt_printmessage(pbuf,(int)(pend-pbuf));
1150 dviprt_printmessage(".\n",-1); 1150 dviprt_printmessage(".\n",-1);
@@ -1520,7 +1520,7 @@ dviprt_printcfgerrorheader(dviprt_cfg_i *pinfo)
1520 dviprt_printmessage(fn,-1); 1520 dviprt_printmessage(fn,-1);
1521 dviprt_printmessage(": ",-1); 1521 dviprt_printmessage(": ",-1);
1522 if (pinfo->line_no>0) { 1522 if (pinfo->line_no>0) {
1523 sprintf(dviprt_message_buffer,"%d: ",pinfo->line_no); 1523 gs_sprintf(dviprt_message_buffer,"%d: ",pinfo->line_no);
1524 dviprt_printmessage(dviprt_message_buffer,-1); 1524 dviprt_printmessage(dviprt_message_buffer,-1);
1525 } 1525 }
1526 } 1526 }
@@ -2210,9 +2210,9 @@ dviprt_output_expr(dviprt_print *pprint,int numb,uint width,uint dsize)
2210 if (cols == 0) 2210 if (cols == 0)
2211 strcpy(fmtbuf,"%"); 2211 strcpy(fmtbuf,"%");
2212 else 2212 else
2213 sprintf(fmtbuf,"%%0%d",cols); 2213 gs_sprintf(fmtbuf,"%%0%d",cols);
2214 strcat(fmtbuf,f); 2214 strcat(fmtbuf,f);
2215 sprintf(valbuf,fmtbuf,stack[stack_p]); 2215 gs_sprintf(valbuf,fmtbuf,stack[stack_p]);
2216 cols = strlen(valbuf); 2216 cols = strlen(valbuf);
2217 if (fmt & CFG_FMT_ISO_BIT) 2217 if (fmt & CFG_FMT_ISO_BIT)
2218 valbuf[cols-1] |= 0x10; 2218 valbuf[cols-1] |= 0x10;
diff --git a/gs/contrib/japanese/gdevfmlbp.c b/gs/contrib/japanese/gdevfmlbp.c
index f4f892e4d..0b2ee79c6 100644
--- a/gs/contrib/japanese/gdevfmlbp.c
+++ b/gs/contrib/japanese/gdevfmlbp.c
@@ -112,7 +112,7 @@ gdev_fmlbp_paper_size(gx_device_printer *dev, char *paper)
112 height_inches = t; 112 height_inches = t;
113 landscape = 1; 113 landscape = 1;
114 } 114 }
115 sprintf(paper, "%s;%d", 115 gs_sprintf(paper, "%s;%d",
116 (height_inches >= 15.9 ? PAPER_SIZE_A3 : 116 (height_inches >= 15.9 ? PAPER_SIZE_A3 :
117 height_inches >= 11.8 ? 117 height_inches >= 11.8 ?
118 (width_inches >= 9.2 ? PAPER_SIZE_B4 : PAPER_SIZE_LEGAL) : 118 (width_inches >= 9.2 ? PAPER_SIZE_B4 : PAPER_SIZE_LEGAL) :
@@ -136,7 +136,7 @@ static void goto_xy(FILE *prn_stream,int x,int y)
136 136
137 fputc(CEX,prn_stream); 137 fputc(CEX,prn_stream);
138 fputc('"',prn_stream); 138 fputc('"',prn_stream);
139 sprintf(buff,"%d",x); 139 gs_sprintf((char *)buff,"%d",x);
140 while (*p) 140 while (*p)
141 { 141 {
142 if (!*(p+1)) fputc((*p)+0x30,prn_stream); 142 if (!*(p+1)) fputc((*p)+0x30,prn_stream);
@@ -146,7 +146,7 @@ static void goto_xy(FILE *prn_stream,int x,int y)
146 } 146 }
147 147
148 p=buff; 148 p=buff;
149 sprintf(buff,"%d",y); 149 gs_sprintf((char *)buff,"%d",y);
150 while (*p) 150 while (*p)
151 { 151 {
152 if (!*(p+1)) fputc((*p)+0x40,prn_stream); 152 if (!*(p+1)) fputc((*p)+0x40,prn_stream);
diff --git a/gs/contrib/japanese/gdevfmpr.c b/gs/contrib/japanese/gdevfmpr.c
index 8bc0ada7d..d7b9244b3 100644
--- a/gs/contrib/japanese/gdevfmpr.c
+++ b/gs/contrib/japanese/gdevfmpr.c
@@ -184,13 +184,13 @@ fmpr_print_page(gx_device_printer *pdev, FILE *prn_stream)
184 } 184 }
185 out_beg -= (out_beg - out) % bytes_per_column; 185 out_beg -= (out_beg - out) % bytes_per_column;
186 186
187 sprintf(prn_buf, "\033[%da", 187 gs_sprintf(prn_buf, "\033[%da",
188 (out_beg - out) / bytes_per_column); 188 (out_beg - out) / bytes_per_column);
189 prn_puts(pdev, prn_buf); 189 prn_puts(pdev, prn_buf);
190 190
191 /* Dot graphics */ 191 /* Dot graphics */
192 size = out_end - out_beg + 1; 192 size = out_end - out_beg + 1;
193 sprintf(prn_buf, "\033Q%d W", size / bytes_per_column); 193 gs_sprintf(prn_buf, "\033Q%d W", size / bytes_per_column);
194 prn_puts(pdev, prn_buf); 194 prn_puts(pdev, prn_buf);
195 prn_write(pdev, out_beg, size); 195 prn_write(pdev, out_beg, size);
196 196
diff --git a/gs/contrib/japanese/gdevj100.c b/gs/contrib/japanese/gdevj100.c
index 4a517d978..cf708aed4 100644
--- a/gs/contrib/japanese/gdevj100.c
+++ b/gs/contrib/japanese/gdevj100.c
@@ -128,12 +128,12 @@ jj100_print_page(gx_device_printer *pdev, FILE *prn_stream)
128 128
129 /* Vertical tab to the appropriate position. */ 129 /* Vertical tab to the appropriate position. */
130 while(skip > 15) { 130 while(skip > 15) {
131 sprintf(prn_buf, "\037%c", 16 + 15); 131 gs_sprintf(prn_buf, "\037%c", 16 + 15);
132 fputs(prn_buf, pdev->file); 132 fputs(prn_buf, pdev->file);
133 skip -= 15; 133 skip -= 15;
134 } 134 }
135 if(skip > 0) { 135 if(skip > 0) {
136 sprintf(prn_buf, "\037%c", 16 + skip); 136 gs_sprintf(prn_buf, "\037%c", 16 + skip);
137 fputs(prn_buf, pdev->file); 137 fputs(prn_buf, pdev->file);
138 } 138 }
139 139
@@ -170,13 +170,13 @@ jj100_print_page(gx_device_printer *pdev, FILE *prn_stream)
170 out_beg -= (out_beg - out) % (bytes_per_column * 2); 170 out_beg -= (out_beg - out) % (bytes_per_column * 2);
171 171
172 /* Dot addressing */ 172 /* Dot addressing */
173 sprintf(prn_buf, "\033F%04d", 173 gs_sprintf(prn_buf, "\033F%04d",
174 (out_beg - out) / bytes_per_column / 2); 174 (out_beg - out) / bytes_per_column / 2);
175 fputs(prn_buf, pdev->file); 175 fputs(prn_buf, pdev->file);
176 176
177 /* Dot graphics */ 177 /* Dot graphics */
178 size = out_end - out_beg + 1; 178 size = out_end - out_beg + 1;
179 sprintf(prn_buf, "\034bP,48,%04d.", size / bytes_per_column); 179 gs_sprintf(prn_buf, "\034bP,48,%04d.", size / bytes_per_column);
180 fputs(prn_buf, pdev->file); 180 fputs(prn_buf, pdev->file);
181 fwrite(out_beg, 1, size, pdev->file); 181 fwrite(out_beg, 1, size, pdev->file);
182 182
diff --git a/gs/contrib/japanese/gdevlbp3.c b/gs/contrib/japanese/gdevlbp3.c
index 4c90a525e..eef8e0cf9 100644
--- a/gs/contrib/japanese/gdevlbp3.c
+++ b/gs/contrib/japanese/gdevlbp3.c
@@ -81,7 +81,7 @@ lbp310PrintPage(gx_device_printer *pDev, FILE *fp)
81 DataSize = CompressImage(pDev, &Box, fp, "\x1b[1;%d;%d;11;%d;.r"); 81 DataSize = CompressImage(pDev, &Box, fp, "\x1b[1;%d;%d;11;%d;.r");
82 82
83 /* ----==== Set size ====---- */ 83 /* ----==== Set size ====---- */
84 sprintf(Buf, "0%ld", DataSize); 84 gs_sprintf((char *)Buf, "0%ld", DataSize);
85 i = (DataSize+strlen(Buf)+1)&1; 85 i = (DataSize+strlen(Buf)+1)&1;
86 /* ----==== escape to LIPS ====---- */ 86 /* ----==== escape to LIPS ====---- */
87 fprintf(fp, "\x80%s\x80\x80\x80\x80\x0c",Buf+i); 87 fprintf(fp, "\x80%s\x80\x80\x80\x80\x0c",Buf+i);
@@ -110,7 +110,7 @@ lbp320PrintPage(gx_device_printer *pDev, FILE *fp)
110 DataSize = CompressImage(pDev, &Box, fp, "\x1b[1;%d;%d;11;%d;.&r"); 110 DataSize = CompressImage(pDev, &Box, fp, "\x1b[1;%d;%d;11;%d;.&r");
111 111
112 /* ----==== Set size ====---- */ 112 /* ----==== Set size ====---- */
113 sprintf(Buf, "000%ld", DataSize); 113 gs_sprintf((char *)Buf, "000%ld", DataSize);
114 i = (DataSize+strlen(Buf)+1)&3; 114 i = (DataSize+strlen(Buf)+1)&3;
115 /* ----==== escape to LIPS ====---- */ 115 /* ----==== escape to LIPS ====---- */
116 fprintf(fp, "\x80%s\x80\x80\x80\x80\x0c",Buf+i); 116 fprintf(fp, "\x80%s\x80\x80\x80\x80\x0c",Buf+i);
diff --git a/gs/contrib/japanese/gdevmag.c b/gs/contrib/japanese/gdevmag.c
index f75f7f57e..b61888c68 100644
--- a/gs/contrib/japanese/gdevmag.c
+++ b/gs/contrib/japanese/gdevmag.c
@@ -137,8 +137,8 @@ mag_print_page(gx_device_printer *pdev, int depth, FILE *file)
137 137
138 if (user == 0) user = "Unknown"; 138 if (user == 0) user = "Unknown";
139 strcpy(check,magic); 139 strcpy(check,magic);
140 sprintf(check+strlen(check),"%-18s",user); 140 gs_sprintf(check+strlen(check),"%-18s",user);
141 sprintf(check+31," Ghostscript with %s driver\x1a", pdev->dname); 141 gs_sprintf(check+31," Ghostscript with %s driver\x1a", pdev->dname);
142 142
143 /* check sizes of flag and pixel data. */ 143 /* check sizes of flag and pixel data. */
144 pixel_bytes = 0; 144 pixel_bytes = 0;
diff --git a/gs/contrib/japanese/gdevnpdl.c b/gs/contrib/japanese/gdevnpdl.c
index 80ee5d380..03783665d 100644
--- a/gs/contrib/japanese/gdevnpdl.c
+++ b/gs/contrib/japanese/gdevnpdl.c
@@ -592,31 +592,31 @@ npdl_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copi
592 /* Check paper size */ 592 /* Check paper size */
593 switch (npdl_get_paper_size((gx_device *) pdev)) { 593 switch (npdl_get_paper_size((gx_device *) pdev)) {
594 case PAPER_SIZE_POSTCARD: 594 case PAPER_SIZE_POSTCARD:
595 sprintf(paper_command, "PC"); 595 gs_sprintf(paper_command, "PC");
596 break; 596 break;
597 case PAPER_SIZE_A5: 597 case PAPER_SIZE_A5:
598 sprintf(paper_command, "A5"); 598 gs_sprintf(paper_command, "A5");
599 break; 599 break;
600 case PAPER_SIZE_A4: 600 case PAPER_SIZE_A4:
601 sprintf(paper_command, "A4"); 601 gs_sprintf(paper_command, "A4");
602 break; 602 break;
603 case PAPER_SIZE_A3: 603 case PAPER_SIZE_A3:
604 sprintf(paper_command, "A3"); 604 gs_sprintf(paper_command, "A3");
605 break; 605 break;
606 case PAPER_SIZE_B5: 606 case PAPER_SIZE_B5:
607 sprintf(paper_command, "B5"); 607 gs_sprintf(paper_command, "B5");
608 break; 608 break;
609 case PAPER_SIZE_B4: 609 case PAPER_SIZE_B4:
610 sprintf(paper_command, "B4"); 610 gs_sprintf(paper_command, "B4");
611 break; 611 break;
612 case PAPER_SIZE_LETTER: 612 case PAPER_SIZE_LETTER:
613 sprintf(paper_command, "LT"); 613 gs_sprintf(paper_command, "LT");
614 break; 614 break;
615 case PAPER_SIZE_ENV4: 615 case PAPER_SIZE_ENV4:
616 sprintf(paper_command, "ENV4"); 616 gs_sprintf(paper_command, "ENV4");
617 break; 617 break;
618 case PAPER_SIZE_BPOSTCARD: 618 case PAPER_SIZE_BPOSTCARD:
619 sprintf(paper_command, "UPPC"); 619 gs_sprintf(paper_command, "UPPC");
620 break; 620 break;
621 } 621 }
622 622
diff --git a/gs/contrib/lips4/gdevl4r.c b/gs/contrib/lips4/gdevl4r.c
index 12e3ce5f9..af0703986 100644
--- a/gs/contrib/lips4/gdevl4r.c
+++ b/gs/contrib/lips4/gdevl4r.c
@@ -775,9 +775,9 @@ lips2p_image_out(gx_device_printer * pdev, FILE * prn_stream, int x, int y, int
775 move_cap(pdev, prn_stream, x, y); 775 move_cap(pdev, prn_stream, x, y);
776 776
777 Len = lips_mode3format_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height); 777 Len = lips_mode3format_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height);
778 sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI, 778 gs_sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI,
779 width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch); 779 width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
780 sprintf(comp_str, "%c%d;%d;%d;9;%d.r", LIPS_CSI, 780 gs_sprintf(comp_str, "%c%d;%d;%d;9;%d.r", LIPS_CSI,
781 Len, width / 8, (int)pdev->x_pixels_per_inch, height); 781 Len, width / 8, (int)pdev->x_pixels_per_inch, height);
782 782
783 if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) { 783 if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
@@ -806,11 +806,11 @@ lips4_image_out(gx_device_printer * pdev, FILE * prn_stream, int x, int y, int w
806 Len = lips_packbits_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height); 806 Len = lips_packbits_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height);
807 Len_rle = lips_rle_encode(lprn->TmpBuf, lprn->CompBuf2, width / 8 * height); 807 Len_rle = lips_rle_encode(lprn->TmpBuf, lprn->CompBuf2, width / 8 * height);
808 808
809 sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI, 809 gs_sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI,
810 width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch); 810 width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
811 811
812 if (Len < Len_rle) { 812 if (Len < Len_rle) {
813 sprintf(comp_str, "%c%d;%d;%d;11;%d.r", LIPS_CSI, 813 gs_sprintf(comp_str, "%c%d;%d;%d;11;%d.r", LIPS_CSI,
814 Len, width / 8, (int)pdev->x_pixels_per_inch, height); 814 Len, width / 8, (int)pdev->x_pixels_per_inch, height);
815 if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) { 815 if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
816 fprintf(prn_stream, "%s", comp_str); 816 fprintf(prn_stream, "%s", comp_str);
@@ -821,7 +821,7 @@ lips4_image_out(gx_device_printer * pdev, FILE * prn_stream, int x, int y, int w
821 fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream); 821 fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
822 } 822 }
823 } else { 823 } else {
824 sprintf(comp_str, "%c%d;%d;%d;10;%d.r", LIPS_CSI, 824 gs_sprintf(comp_str, "%c%d;%d;%d;10;%d.r", LIPS_CSI,
825 Len, width / 8, (int)pdev->x_pixels_per_inch, height); 825 Len, width / 8, (int)pdev->x_pixels_per_inch, height);
826 if (Len_rle < width / 8 * height - strlen(comp_str) + strlen(raw_str)) { 826 if (Len_rle < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
827 fprintf(prn_stream, "%s", comp_str); 827 fprintf(prn_stream, "%s", comp_str);
diff --git a/gs/contrib/lips4/gdevl4v.c b/gs/contrib/lips4/gdevl4v.c
index ad3222613..aba7abaf2 100644
--- a/gs/contrib/lips4/gdevl4v.c
+++ b/gs/contrib/lips4/gdevl4v.c
@@ -459,17 +459,17 @@ lips4v_set_cap(gx_device * dev, int x, int y)
459 int dy = y - pdev->prev_y; 459 int dy = y - pdev->prev_y;
460 460
461 if (dx > 0) { 461 if (dx > 0) {
462 sprintf(cap, "%c%da", LIPS_CSI, dx); 462 gs_sprintf(cap, "%c%da", LIPS_CSI, dx);
463 lputs(s, cap); 463 lputs(s, cap);
464 } else if (dx < 0) { 464 } else if (dx < 0) {
465 sprintf(cap, "%c%dj", LIPS_CSI, -dx); 465 gs_sprintf(cap, "%c%dj", LIPS_CSI, -dx);
466 lputs(s, cap); 466 lputs(s, cap);
467 } 467 }
468 if (dy > 0) { 468 if (dy > 0) {
469 sprintf(cap, "%c%dk", LIPS_CSI, dy); 469 gs_sprintf(cap, "%c%dk", LIPS_CSI, dy);
470 lputs(s, cap); 470 lputs(s, cap);
471 } else if (dy < 0) { 471 } else if (dy < 0) {
472 sprintf(cap, "%c%de", LIPS_CSI, -dy); 472 gs_sprintf(cap, "%c%de", LIPS_CSI, -dy);
473 lputs(s, cap); 473 lputs(s, cap);
474 } 474 }
475 pdev->prev_x = x; 475 pdev->prev_x = x;
@@ -544,10 +544,10 @@ lips4v_copy_text_char(gx_device * dev, const byte * data,
544 if (download) { 544 if (download) {
545 if (ccode % 128 == 0 && ccode == pdev->count) { 545 if (ccode % 128 == 0 && ccode == pdev->count) {
546 /* ʸ»ú¥»¥Ã¥ÈÅÐÏ¿Êä½õÌ¿Îá */ 546 /* ʸ»ú¥»¥Ã¥ÈÅÐÏ¿Êä½õÌ¿Îá */
547 sprintf(cset_sub, "%c%dx%c", LIPS_DCS, ccode / 128, LIPS_ST); 547 gs_sprintf(cset_sub, "%c%dx%c", LIPS_DCS, ccode / 128, LIPS_ST);
548 lputs(s, cset_sub); 548 lputs(s, cset_sub);
549 /* ʸ»ú¥»¥Ã¥ÈÅÐÏ¿Ì¿Îá */ 549 /* ʸ»ú¥»¥Ã¥ÈÅÐÏ¿Ì¿Îá */
550 sprintf(cset, 550 gs_sprintf(cset,
551 "%c%d;1;0;0;3840;8;400;100;0;0;200;%d;%d;0;0;;;;;%d.p", 551 "%c%d;1;0;0;3840;8;400;100;0;0;200;%d;%d;0;0;;;;;%d.p",
552 LIPS_CSI, 552 LIPS_CSI,
553 size + 9, cell_length, /* Cell Width */ 553 size + 9, cell_length, /* Cell Width */
@@ -556,7 +556,7 @@ lips4v_copy_text_char(gx_device * dev, const byte * data,
556 lputs(s, cset); 556 lputs(s, cset);
557 } else { 557 } else {
558 /* 1ʸ»úÅÐÏ¿Ì¿Îá */ 558 /* 1ʸ»úÅÐÏ¿Ì¿Îá */
559 sprintf(cset, 559 gs_sprintf(cset,
560 "%c%d;%d;8;%d.q", LIPS_CSI, 560 "%c%d;%d;8;%d.q", LIPS_CSI,
561 size + 9, ccode / 128, (int)dev->x_pixels_per_inch); 561 size + 9, ccode / 128, (int)dev->x_pixels_per_inch);
562 lputs(s, cset); 562 lputs(s, cset);
@@ -575,13 +575,13 @@ lips4v_copy_text_char(gx_device * dev, const byte * data,
575 /* ʸ»ú¥»¥Ã¥È¡¦¥¢¥µ¥¤¥óÈÖ¹æÁªÂòÌ¿Îá2 */ 575 /* ʸ»ú¥»¥Ã¥È¡¦¥¢¥µ¥¤¥óÈÖ¹æÁªÂòÌ¿Îá2 */
576 if (download) { 576 if (download) {
577 if (pdev->current_font != ccode / 128) { 577 if (pdev->current_font != ccode / 128) {
578 sprintf(cset_number, "%c%d%%v", LIPS_CSI, ccode / 128); 578 gs_sprintf(cset_number, "%c%d%%v", LIPS_CSI, ccode / 128);
579 lputs(s, cset_number); 579 lputs(s, cset_number);
580 pdev->current_font = ccode / 128; 580 pdev->current_font = ccode / 128;
581 } 581 }
582 } else { 582 } else {
583 if (pdev->current_font != ccode / 128) { 583 if (pdev->current_font != ccode / 128) {
584 sprintf(cset_number, "%c%d%%v", LIPS_CSI, ccode / 128); 584 gs_sprintf(cset_number, "%c%d%%v", LIPS_CSI, ccode / 128);
585 lputs(s, cset_number); 585 lputs(s, cset_number);
586 pdev->current_font = ccode / 128; 586 pdev->current_font = ccode / 128;
587 } 587 }
@@ -592,7 +592,7 @@ lips4v_copy_text_char(gx_device * dev, const byte * data,
592 if (pdev->color_info.depth == 8) { 592 if (pdev->color_info.depth == 8) {
593 sputc(s, LIPS_CSI); 593 sputc(s, LIPS_CSI);
594 lputs(s, "?10;2;"); 594 lputs(s, "?10;2;");
595 sprintf(text_color, "%d", 595 gs_sprintf(text_color, "%d",
596 (int)(pdev->color_info.max_gray - pdev->current_color)); 596 (int)(pdev->color_info.max_gray - pdev->current_color));
597 } else { 597 } else {
598 int r = (pdev->current_color >> 16) * 1000.0 / 255.0; 598 int r = (pdev->current_color >> 16) * 1000.0 / 255.0;
@@ -601,7 +601,7 @@ lips4v_copy_text_char(gx_device * dev, const byte * data,
601 601
602 sputc(s, LIPS_CSI); 602 sputc(s, LIPS_CSI);
603 lputs(s, "?10;;"); 603 lputs(s, "?10;;");
604 sprintf(text_color, "%d;%d;%d", r, g, b); 604 gs_sprintf(text_color, "%d;%d;%d", r, g, b);
605 } 605 }
606 lputs(s, text_color); 606 lputs(s, text_color);
607 lputs(s, "%p"); 607 lputs(s, "%p");
@@ -717,16 +717,16 @@ lips4v_beginpage(gx_device_vector * vdev)
717 lputs(s, "@PJL SET RESOLUTION = QUICK\n"); 717 lputs(s, "@PJL SET RESOLUTION = QUICK\n");
718 lputs(s, l4v_file_header2); 718 lputs(s, l4v_file_header2);
719 if (pdev->toner_density) { 719 if (pdev->toner_density) {
720 sprintf(toner_d, "@PJL SET TONER-DENSITY=%d\n", 720 gs_sprintf(toner_d, "@PJL SET TONER-DENSITY=%d\n",
721 pdev->toner_density); 721 pdev->toner_density);
722 lputs(s, toner_d); 722 lputs(s, toner_d);
723 } 723 }
724 if (pdev->toner_saving_set) { 724 if (pdev->toner_saving_set) {
725 lputs(s, "@PJL SET TONER-SAVING="); 725 lputs(s, "@PJL SET TONER-SAVING=");
726 if (pdev->toner_saving) 726 if (pdev->toner_saving)
727 sprintf(toner_s, "ON\n"); 727 gs_sprintf(toner_s, "ON\n");
728 else 728 else
729 sprintf(toner_s, "OFF\n"); 729 gs_sprintf(toner_s, "OFF\n");
730 lputs(s, toner_s); 730 lputs(s, toner_s);
731 } 731 }
732 lputs(s, l4v_file_header3); 732 lputs(s, l4v_file_header3);
@@ -737,7 +737,7 @@ lips4v_beginpage(gx_device_vector * vdev)
737 return_error(gs_error_rangecheck); 737 return_error(gs_error_rangecheck);
738 738
739 /* set reaolution (dpi) */ 739 /* set reaolution (dpi) */
740 sprintf(dpi_char, "%d", dpi); 740 gs_sprintf(dpi_char, "%d", dpi);
741 lputs(s, dpi_char); 741 lputs(s, dpi_char);
742 742
743 if (pdev->color_info.depth == 8) 743 if (pdev->color_info.depth == 8)
@@ -746,7 +746,7 @@ lips4v_beginpage(gx_device_vector * vdev)
746 lputs(s, l4vcolor_file_header); 746 lputs(s, l4vcolor_file_header);
747 747
748 /* username */ 748 /* username */
749 sprintf(username, "%c2y%s%c", LIPS_DCS, pdev->Username, LIPS_ST); 749 gs_sprintf(username, "%c2y%s%c", LIPS_DCS, pdev->Username, LIPS_ST);
750 lputs(s, username); 750 lputs(s, username);
751 } 751 }
752 if (strcmp(pdev->mediaType, "PlainPaper") == 0) { 752 if (strcmp(pdev->mediaType, "PlainPaper") == 0) {
@@ -773,13 +773,13 @@ lips4v_beginpage(gx_device_vector * vdev)
773 && strcmp(pdev->mediaType, LIPS_MEDIATYPE_DEFAULT) != 0)) { 773 && strcmp(pdev->mediaType, LIPS_MEDIATYPE_DEFAULT) != 0)) {
774 /* Use ManualFeed */ 774 /* Use ManualFeed */
775 if (pdev->prev_feed_mode != 10) { 775 if (pdev->prev_feed_mode != 10) {
776 sprintf(feedmode, "%c10q", LIPS_CSI); 776 gs_sprintf(feedmode, "%c10q", LIPS_CSI);
777 lputs(s, feedmode); 777 lputs(s, feedmode);
778 pdev->prev_feed_mode = 10; 778 pdev->prev_feed_mode = 10;
779 } 779 }
780 } else { 780 } else {
781 if (pdev->prev_feed_mode != pdev->cassetFeed) { 781 if (pdev->prev_feed_mode != pdev->cassetFeed) {
782 sprintf(feedmode, "%c%dq", LIPS_CSI, pdev->cassetFeed); 782 gs_sprintf(feedmode, "%c%dq", LIPS_CSI, pdev->cassetFeed);
783 lputs(s, feedmode); 783 lputs(s, feedmode);
784 pdev->prev_feed_mode = pdev->cassetFeed; 784 pdev->prev_feed_mode = pdev->cassetFeed;
785 } 785 }
@@ -791,10 +791,10 @@ lips4v_beginpage(gx_device_vector * vdev)
791 if (pdev->prev_paper_size != paper_size) { 791 if (pdev->prev_paper_size != paper_size) {
792 if (paper_size == USER_SIZE) { 792 if (paper_size == USER_SIZE) {
793 /* modified by shige 06/27 2003 793 /* modified by shige 06/27 2003
794 sprintf(paper, "%c80;%d;%dp", LIPS_CSI, width * 10, height * 10); */ 794 gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, width * 10, height * 10); */
795 /* modified by shige 11/09 2003 795 /* modified by shige 11/09 2003
796 sprintf(paper, "%c80;%d;%dp", LIPS_CSI, height * 10, width * 10); */ 796 gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, height * 10, width * 10); */
797 sprintf(paper, "%c80;%d;%dp", LIPS_CSI, 797 gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI,
798 (height * 10 > LIPS_HEIGHT_MAX_720)? 798 (height * 10 > LIPS_HEIGHT_MAX_720)?
799 LIPS_HEIGHT_MAX_720 : (height * 10), 799 LIPS_HEIGHT_MAX_720 : (height * 10),
800 (width * 10 > LIPS_WIDTH_MAX_720)? 800 (width * 10 > LIPS_WIDTH_MAX_720)?
@@ -802,27 +802,27 @@ lips4v_beginpage(gx_device_vector * vdev)
802 lputs(s, paper); 802 lputs(s, paper);
803 } else if (paper_size == USER_SIZE + LANDSCAPE) { 803 } else if (paper_size == USER_SIZE + LANDSCAPE) {
804 /* modified by shige 06/27 2003 804 /* modified by shige 06/27 2003
805 sprintf(paper, "%c81;%d;%dp", LIPS_CSI, height * 10, width * 10); */ 805 gs_sprintf(paper, "%c81;%d;%dp", LIPS_CSI, height * 10, width * 10); */
806 /* modified by shige 11/09 2003 806 /* modified by shige 11/09 2003
807 sprintf(paper, "%c81;%d;%dp", LIPS_CSI, width * 10, height * 10); */ 807 gs_sprintf(paper, "%c81;%d;%dp", LIPS_CSI, width * 10, height * 10); */
808 sprintf(paper, "%c80;%d;%dp", LIPS_CSI, 808 gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI,
809 (width * 10 > LIPS_HEIGHT_MAX_720)? 809 (width * 10 > LIPS_HEIGHT_MAX_720)?
810 LIPS_HEIGHT_MAX_720 : (width * 10), 810 LIPS_HEIGHT_MAX_720 : (width * 10),
811 (height * 10 > LIPS_WIDTH_MAX_720)? 811 (height * 10 > LIPS_WIDTH_MAX_720)?
812 LIPS_WIDTH_MAX_720 : (height * 10)); 812 LIPS_WIDTH_MAX_720 : (height * 10));
813 lputs(s, paper); 813 lputs(s, paper);
814 } else { 814 } else {
815 sprintf(paper, "%c%dp", LIPS_CSI, paper_size); 815 gs_sprintf(paper, "%c%dp", LIPS_CSI, paper_size);
816 lputs(s, paper); 816 lputs(s, paper);
817 } 817 }
818 } else if (paper_size == USER_SIZE) { 818 } else if (paper_size == USER_SIZE) {
819 if (pdev->prev_paper_width != width || 819 if (pdev->prev_paper_width != width ||
820 pdev->prev_paper_height != height) 820 pdev->prev_paper_height != height)
821 /* modified by shige 06/27 2003 821 /* modified by shige 06/27 2003
822 sprintf(paper, "%c80;%d;%dp", LIPS_CSI, width * 10, height * 10); */ 822 gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, width * 10, height * 10); */
823 /* modified by shige 11/09 2003 823 /* modified by shige 11/09 2003
824 sprintf(paper, "%c80;%d;%dp", LIPS_CSI, height * 10, width * 10); */ 824 gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, height * 10, width * 10); */
825 sprintf(paper, "%c80;%d;%dp", LIPS_CSI, 825 gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI,
826 (height * 10 > LIPS_HEIGHT_MAX_720)? 826 (height * 10 > LIPS_HEIGHT_MAX_720)?
827 LIPS_HEIGHT_MAX_720 : (height * 10), 827 LIPS_HEIGHT_MAX_720 : (height * 10),
828 (width * 10 > LIPS_WIDTH_MAX_720)? 828 (width * 10 > LIPS_WIDTH_MAX_720)?
@@ -832,10 +832,10 @@ lips4v_beginpage(gx_device_vector * vdev)
832 if (pdev->prev_paper_width != width || 832 if (pdev->prev_paper_width != width ||
833 pdev->prev_paper_height != height) 833 pdev->prev_paper_height != height)
834 /* modified by shige 06/27 2003 834 /* modified by shige 06/27 2003
835 sprintf(paper, "%c81;%d;%dp", LIPS_CSI, height * 10, width * 10); */ 835 gs_sprintf(paper, "%c81;%d;%dp", LIPS_CSI, height * 10, width * 10); */
836 /* modified by shige 11/09 2003 836 /* modified by shige 11/09 2003
837 sprintf(paper, "%c81;%d;%dp", LIPS_CSI, width * 10, height * 10); */ 837 gs_sprintf(paper, "%c81;%d;%dp", LIPS_CSI, width * 10, height * 10); */
838 sprintf(paper, "%c80;%d;%dp", LIPS_CSI, 838 gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI,
839 (width * 10 > LIPS_HEIGHT_MAX_720)? 839 (width * 10 > LIPS_HEIGHT_MAX_720)?
840 LIPS_HEIGHT_MAX_720 : (width * 10), 840 LIPS_HEIGHT_MAX_720 : (width * 10),
841 (height * 10 > LIPS_WIDTH_MAX_720)? 841 (height * 10 > LIPS_WIDTH_MAX_720)?
@@ -847,32 +847,32 @@ lips4v_beginpage(gx_device_vector * vdev)
847 pdev->prev_paper_height = height; 847 pdev->prev_paper_height = height;
848 848
849 if (pdev->faceup) { 849 if (pdev->faceup) {
850 sprintf(faceup_char, "%c11;12;12~", LIPS_CSI); 850 gs_sprintf(faceup_char, "%c11;12;12~", LIPS_CSI);
851 lputs(s, faceup_char); 851 lputs(s, faceup_char);
852 } 852 }
853 /* N-up Printing Setting */ 853 /* N-up Printing Setting */
854 if (pdev->first_page) { 854 if (pdev->first_page) {
855 if (pdev->nup != 1) { 855 if (pdev->nup != 1) {
856 sprintf(nup_char, "%c%d1;;%do", LIPS_CSI, pdev->nup, paper_size); 856 gs_sprintf(nup_char, "%c%d1;;%do", LIPS_CSI, pdev->nup, paper_size);
857 lputs(s, nup_char); 857 lputs(s, nup_char);
858 } 858 }
859 } 859 }
860 /* Duplex Setting */ 860 /* Duplex Setting */
861 if (dupset && dup) { 861 if (dupset && dup) {
862 if (pdev->prev_duplex_mode == 0 || pdev->prev_duplex_mode == 1) { 862 if (pdev->prev_duplex_mode == 0 || pdev->prev_duplex_mode == 1) {
863 sprintf(duplex_char, "%c2;#x", LIPS_CSI); /* duplex */ 863 gs_sprintf(duplex_char, "%c2;#x", LIPS_CSI); /* duplex */
864 lputs(s, duplex_char); 864 lputs(s, duplex_char);
865 if (!tum) { 865 if (!tum) {
866 /* long edge binding */ 866 /* long edge binding */
867 if (pdev->prev_duplex_mode != 2) { 867 if (pdev->prev_duplex_mode != 2) {
868 sprintf(tumble_char, "%c0;#w", LIPS_CSI); 868 gs_sprintf(tumble_char, "%c0;#w", LIPS_CSI);
869 lputs(s, tumble_char); 869 lputs(s, tumble_char);
870 } 870 }
871 pdev->prev_duplex_mode = 2; 871 pdev->prev_duplex_mode = 2;
872 } else { 872 } else {
873 /* short edge binding */ 873 /* short edge binding */
874 if (pdev->prev_duplex_mode != 3) { 874 if (pdev->prev_duplex_mode != 3) {
875 sprintf(tumble_char, "%c2;#w", LIPS_CSI); 875 gs_sprintf(tumble_char, "%c2;#w", LIPS_CSI);
876 lputs(s, tumble_char); 876 lputs(s, tumble_char);
877 } 877 }
878 pdev->prev_duplex_mode = 3; 878 pdev->prev_duplex_mode = 3;
@@ -880,7 +880,7 @@ lips4v_beginpage(gx_device_vector * vdev)
880 } 880 }
881 } else if (dupset && !dup) { 881 } else if (dupset && !dup) {
882 if (pdev->prev_duplex_mode != 1) { 882 if (pdev->prev_duplex_mode != 1) {
883 sprintf(duplex_char, "%c0;#x", LIPS_CSI); /* simplex */ 883 gs_sprintf(duplex_char, "%c0;#x", LIPS_CSI); /* simplex */
884 lputs(s, duplex_char); 884 lputs(s, duplex_char);
885 } 885 }
886 pdev->prev_duplex_mode = 1; 886 pdev->prev_duplex_mode = 1;
@@ -893,9 +893,9 @@ lips4v_beginpage(gx_device_vector * vdev)
893 /* size unit (dpi) */ 893 /* size unit (dpi) */
894 sputc(s, LIPS_CSI); 894 sputc(s, LIPS_CSI);
895 lputs(s, "11h"); 895 lputs(s, "11h");
896 sprintf(unit, "%c?7;%d I", LIPS_CSI, (int)pdev->x_pixels_per_inch); 896 gs_sprintf(unit, "%c?7;%d I", LIPS_CSI, (int)pdev->x_pixels_per_inch);
897 lputs(s, unit); 897 lputs(s, unit);
898 sprintf(page_header, "%c[0&}#%c", LIPS_ESC, LIPS_IS2); 898 gs_sprintf(page_header, "%c[0&}#%c", LIPS_ESC, LIPS_IS2);
899 lputs(s, page_header); /* vector mode */ 899 lputs(s, page_header); /* vector mode */
900 900
901 lputs(s, "!0"); /* size unit (dpi) */ 901 lputs(s, "!0"); /* size unit (dpi) */
@@ -904,10 +904,10 @@ lips4v_beginpage(gx_device_vector * vdev)
904 sputc(s, LIPS_IS2); 904 sputc(s, LIPS_IS2);
905 905
906 if (pdev->color_info.depth == 8) { 906 if (pdev->color_info.depth == 8) {
907 sprintf(l4vmono_page_header, "!13%c$%c", LIPS_IS2, LIPS_IS2); 907 gs_sprintf(l4vmono_page_header, "!13%c$%c", LIPS_IS2, LIPS_IS2);
908 lputs(s, l4vmono_page_header); 908 lputs(s, l4vmono_page_header);
909 } else { 909 } else {
910 sprintf(l4vcolor_page_header, "!11%c$%c", LIPS_IS2, LIPS_IS2); 910 gs_sprintf(l4vcolor_page_header, "!11%c$%c", LIPS_IS2, LIPS_IS2);
911 lputs(s, l4vcolor_page_header); 911 lputs(s, l4vcolor_page_header);
912 } 912 }
913 913
@@ -1010,7 +1010,7 @@ lips4v_setlinecap(gx_device_vector * vdev, gs_line_cap cap)
1010 break; 1010 break;
1011 } 1011 }
1012 /* Àþü·Á¾õ»ØÄêÌ¿Îá */ 1012 /* Àþü·Á¾õ»ØÄêÌ¿Îá */
1013 sprintf(c, "}E%d%c", line_cap, LIPS_IS2); 1013 gs_sprintf(c, "}E%d%c", line_cap, LIPS_IS2);
1014 lputs(s, c); 1014 lputs(s, c);
1015 1015
1016 pdev->linecap = cap; 1016 pdev->linecap = cap;
@@ -1050,7 +1050,7 @@ lips4v_setlinejoin(gx_device_vector * vdev, gs_line_join join)
1050 break; 1050 break;
1051 } 1051 }
1052 1052
1053 sprintf(c, "}F%d%c", lips_join, LIPS_IS2); 1053 gs_sprintf(c, "}F%d%c", lips_join, LIPS_IS2);
1054 lputs(s, c); 1054 lputs(s, c);
1055 1055
1056 return 0; 1056 return 0;
@@ -1486,7 +1486,7 @@ lips4v_output_page(gx_device * dev, int num_copies, int flush)
1486 if (num_copies > 255) 1486 if (num_copies > 255)
1487 num_copies = 255; 1487 num_copies = 255;
1488 if (pdev->prev_num_copies != num_copies) { 1488 if (pdev->prev_num_copies != num_copies) {
1489 sprintf(str, "%c%dv", LIPS_CSI, num_copies); 1489 gs_sprintf(str, "%c%dv", LIPS_CSI, num_copies);
1490 lputs(s, str); 1490 lputs(s, str);
1491 pdev->prev_num_copies = num_copies; 1491 pdev->prev_num_copies = num_copies;
1492 } 1492 }
diff --git a/gs/contrib/pcl3/src/gdevpcl3.c b/gs/contrib/pcl3/src/gdevpcl3.c
index 1ef8b7fe7..81aceff4a 100644
--- a/gs/contrib/pcl3/src/gdevpcl3.c
+++ b/gs/contrib/pcl3/src/gdevpcl3.c
@@ -302,7 +302,7 @@ static void get_string_for_int(int in_value, const eprn_StringAndInt *table,
302 else { 302 else {
303 static char buffer[22]; /* Must be sufficient for an 'int' */ 303 static char buffer[22]; /* Must be sufficient for an 'int' */
304 304
305 sprintf(buffer, "%d", in_value); 305 gs_sprintf(buffer, "%d", in_value);
306 assert(strlen(buffer) < sizeof(buffer)); 306 assert(strlen(buffer) < sizeof(buffer));
307 out_value->data = (const byte *)buffer; 307 out_value->data = (const byte *)buffer;
308 out_value->size = strlen(buffer); 308 out_value->size = strlen(buffer);
diff --git a/gs/cups/gdevcups.c b/gs/cups/gdevcups.c
index 2381d3028..3747208f1 100644
--- a/gs/cups/gdevcups.c
+++ b/gs/cups/gdevcups.c
@@ -60,6 +60,9 @@
60 * cups_print_planar() - Print a page of planar pixels. 60 * cups_print_planar() - Print a page of planar pixels.
61 */ 61 */
62 62
63/* prevent gp.h redefining fopen */
64#define sprintf sprintf
65
63/* 66/*
64 * Include necessary headers... 67 * Include necessary headers...
65 */ 68 */
diff --git a/gs/devices/gdev3b1.c b/gs/devices/gdev3b1.c
index 4ad9065fe..4105dcb90 100644
--- a/gs/devices/gdev3b1.c
+++ b/gs/devices/gdev3b1.c
@@ -538,7 +538,7 @@ att3b1_do_output_page(gx_device *dev, int num_copies, int flush)
538 } 538 }
539 539
540 ut.ut_num = WTXTSLK1; 540 ut.ut_num = WTXTSLK1;
541 sprintf(ut.ut_text, 541 gs_sprintf(ut.ut_text,
542 "%s %d, top right (%d,%d), size (%d,%d), press '?' for help.", 542 "%s %d, top right (%d,%d), size (%d,%d), press '?' for help.",
543 flush ? "Showpage" : "Copypage", att3b1dev->page_num, xorigin, yorigin, 543 flush ? "Showpage" : "Copypage", att3b1dev->page_num, xorigin, yorigin,
544 att3b1dev->width, att3b1dev->height); 544 att3b1dev->width, att3b1dev->height);
diff --git a/gs/devices/gdev8510.c b/gs/devices/gdev8510.c
index 6f23e0791..5a0940213 100644
--- a/gs/devices/gdev8510.c
+++ b/gs/devices/gdev8510.c
@@ -129,7 +129,7 @@ m8510_output_run(gx_device_printer *pdev,
129 /* Transfer the line of data. */ 129 /* Transfer the line of data. */
130 count = out_end - out; 130 count = out_end - out;
131 if (count) { 131 if (count) {
132 sprintf(tmp, "\033g%03d", count/8); 132 gs_sprintf(tmp, "\033g%03d", count/8);
133 fwrite(tmp, 1, 5, prn_stream); 133 fwrite(tmp, 1, 5, prn_stream);
134 fwrite(out, 1, count, prn_stream); 134 fwrite(out, 1, count, prn_stream);
135 fwrite("\r", 1, 1, prn_stream); 135 fwrite("\r", 1, 1, prn_stream);
diff --git a/gs/devices/gdevccr.c b/gs/devices/gdevccr.c
index c7f126bf9..2f33680d7 100644
--- a/gs/devices/gdevccr.c
+++ b/gs/devices/gdevccr.c
@@ -208,9 +208,9 @@ static int alloc_rb( gs_memory_t *mem, cmyrow **rb, int rows)
208 int r; 208 int r;
209 for(r=0; r<rows; r++) 209 for(r=0; r<rows; r++)
210 { 210 {
211 sprintf((*rb)[r].cname, "C%02x", r); 211 gs_sprintf((*rb)[r].cname, "C%02x", r);
212 sprintf((*rb)[r].mname, "M%02x", r); 212 gs_sprintf((*rb)[r].mname, "M%02x", r);
213 sprintf((*rb)[r].yname, "Y%02x", r); 213 gs_sprintf((*rb)[r].yname, "Y%02x", r);
214 (*rb)[r].is_used=0; 214 (*rb)[r].is_used=0;
215 } 215 }
216 return 0; 216 return 0;
diff --git a/gs/devices/gdevdjet.c b/gs/devices/gdevdjet.c
index 186a95658..c4a8732de 100644
--- a/gs/devices/gdevdjet.c
+++ b/gs/devices/gdevdjet.c
@@ -325,9 +325,9 @@ hpjet_make_init(gx_device_printer *pdev, char *buf, const char *str)
325 else if (dev->MediaPosition_set && dev->MediaPosition >= 0) 325 else if (dev->MediaPosition_set && dev->MediaPosition >= 0)
326 paper_source = dev->MediaPosition; 326 paper_source = dev->MediaPosition;
327 if (paper_source >= 0) 327 if (paper_source >= 0)
328 sprintf(buf, "%s\033&l%dH", str, paper_source); 328 gs_sprintf(buf, "%s\033&l%dH", str, paper_source);
329 else 329 else
330 sprintf(buf, "%s", str); 330 gs_sprintf(buf, "%s", str);
331} 331}
332 332
333/* The DeskJet can compress (mode 2) */ 333/* The DeskJet can compress (mode 2) */
@@ -363,7 +363,7 @@ fs600_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
363 char base_init[60]; 363 char base_init[60];
364 char init[80]; 364 char init[80];
365 365
366 sprintf(base_init, "\033*r0F\033&u%dD", dots_per_inch); 366 gs_sprintf(base_init, "\033*r0F\033&u%dD", dots_per_inch);
367 hpjet_make_init(pdev, init, base_init); 367 hpjet_make_init(pdev, init, base_init);
368 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, 368 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
369 dots_per_inch, PCL_FS600_FEATURES, 369 dots_per_inch, PCL_FS600_FEATURES,
@@ -427,7 +427,7 @@ ljet3d_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
427 bool tumble=dev->Tumble; 427 bool tumble=dev->Tumble;
428 428
429 hpjet_make_init(pdev, init, "\033&l-180u36Z\033*r0F"); 429 hpjet_make_init(pdev, init, "\033&l-180u36Z\033*r0F");
430 sprintf(even_init, "\033&l180u36Z\033*r0F"); 430 gs_sprintf(even_init, "\033&l180u36Z\033*r0F");
431 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, 431 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
432 300, PCL_LJ3D_FEATURES, init, even_init, tumble); 432 300, PCL_LJ3D_FEATURES, init, even_init, tumble);
433} 433}
@@ -442,7 +442,7 @@ ljet4_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
442 char base_init[60]; 442 char base_init[60];
443 char init[80]; 443 char init[80];
444 444
445 sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch); 445 gs_sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
446 hpjet_make_init(pdev, init, base_init); 446 hpjet_make_init(pdev, init, base_init);
447 447
448 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, 448 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
@@ -474,9 +474,9 @@ ljet4d_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
474 in duplex mode we set this parameters for each odd page 474 in duplex mode we set this parameters for each odd page
475 (paper tray is set by "hpjet_make_init") 475 (paper tray is set by "hpjet_make_init")
476 */ 476 */
477 sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch); 477 gs_sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
478 hpjet_make_init(pdev, init, base_init); 478 hpjet_make_init(pdev, init, base_init);
479 sprintf(even_init, "\033&l180u36Z\033*r0F\033&u%dD", dots_per_inch); 479 gs_sprintf(even_init, "\033&l180u36Z\033*r0F\033&u%dD", dots_per_inch);
480 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, 480 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
481 dots_per_inch, PCL_LJ4D_FEATURES, 481 dots_per_inch, PCL_LJ4D_FEATURES,
482 init,even_init,tumble); 482 init,even_init,tumble);
@@ -491,7 +491,7 @@ ljet4pjl_print_page_copies(gx_device_printer *pdev, FILE *prn_stream,
491{ int dots_per_inch = (int)pdev->y_pixels_per_inch; 491{ int dots_per_inch = (int)pdev->y_pixels_per_inch;
492 char real_init[60]; 492 char real_init[60];
493 493
494 sprintf(real_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch); 494 gs_sprintf(real_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
495 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, 495 return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
496 dots_per_inch, PCL_LJ4PJL_FEATURES, 496 dots_per_inch, PCL_LJ4PJL_FEATURES,
497 real_init, real_init, false); 497 real_init, real_init, false);
diff --git a/gs/devices/gdevijs.c b/gs/devices/gdevijs.c
index 9961fa35e..690dfe594 100644
--- a/gs/devices/gdevijs.c
+++ b/gs/devices/gdevijs.c
@@ -674,7 +674,7 @@ gsijs_set_margin_params(gx_device_ijs *ijsdev)
674 } 674 }
675 675
676 if (code == 0) { 676 if (code == 0) {
677 sprintf (buf, "%gx%g", ijsdev->MediaSize[0] * (1.0 / 72), 677 gs_sprintf (buf, "%gx%g", ijsdev->MediaSize[0] * (1.0 / 72),
678 ijsdev->MediaSize[1] * (1.0 / 72)); 678 ijsdev->MediaSize[1] * (1.0 / 72));
679 code = ijs_client_set_param(ijsdev->ctx, 0, "PaperSize", 679 code = ijs_client_set_param(ijsdev->ctx, 0, "PaperSize",
680 buf, strlen(buf)); 680 buf, strlen(buf));
@@ -715,7 +715,7 @@ gsijs_set_margin_params(gx_device_ijs *ijsdev)
715 m[1] = ijsdev->MediaSize[1] * (1.0 / 72) - 715 m[1] = ijsdev->MediaSize[1] * (1.0 / 72) -
716 printable_top - printable_height; 716 printable_top - printable_height;
717 gx_device_set_margins((gx_device *)ijsdev, m, true); 717 gx_device_set_margins((gx_device *)ijsdev, m, true);
718 sprintf (buf, "%gx%g", printable_left, printable_top); 718 gs_sprintf (buf, "%gx%g", printable_left, printable_top);
719 code = ijs_client_set_param(ijsdev->ctx, 0, "TopLeft", 719 code = ijs_client_set_param(ijsdev->ctx, 0, "TopLeft",
720 buf, strlen(buf)); 720 buf, strlen(buf));
721 } 721 }
@@ -864,7 +864,7 @@ gsijs_open(gx_device *dev)
864 /* Note: dup() may not be portable to all interesting IJS 864 /* Note: dup() may not be portable to all interesting IJS
865 platforms. In that case, this branch should be #ifdef'ed out. 865 platforms. In that case, this branch should be #ifdef'ed out.
866 */ 866 */
867 sprintf(buf, "%d", fd); 867 gs_sprintf(buf, "%d", fd);
868 ijs_client_set_param(ijsdev->ctx, 0, "OutputFD", buf, strlen(buf)); 868 ijs_client_set_param(ijsdev->ctx, 0, "OutputFD", buf, strlen(buf));
869 close(fd); 869 close(fd);
870 } else { 870 } else {
@@ -1021,9 +1021,9 @@ gsijs_output_page(gx_device *dev, int num_copies, int flush)
1021 } 1021 }
1022 1022
1023 /* Required page parameters */ 1023 /* Required page parameters */
1024 sprintf(buf, "%d", n_chan); 1024 gs_sprintf(buf, "%d", n_chan);
1025 gsijs_client_set_param(ijsdev, "NumChan", buf); 1025 gsijs_client_set_param(ijsdev, "NumChan", buf);
1026 sprintf(buf, "%d", ijsdev->BitsPerSample); 1026 gs_sprintf(buf, "%d", ijsdev->BitsPerSample);
1027 gsijs_client_set_param(ijsdev, "BitsPerSample", buf); 1027 gsijs_client_set_param(ijsdev, "BitsPerSample", buf);
1028 1028
1029 /* This needs to become more sophisticated for DeviceN. */ 1029 /* This needs to become more sophisticated for DeviceN. */
@@ -1031,12 +1031,12 @@ gsijs_output_page(gx_device *dev, int num_copies, int flush)
1031 ((n_chan == 3) ? (krgb_mode ? ((k_bits == 1) ? "KRGB" : "KxRGB") : "DeviceRGB") : "DeviceGray")); 1031 ((n_chan == 3) ? (krgb_mode ? ((k_bits == 1) ? "KRGB" : "KxRGB") : "DeviceRGB") : "DeviceGray"));
1032 gsijs_client_set_param(ijsdev, "ColorSpace", buf); 1032 gsijs_client_set_param(ijsdev, "ColorSpace", buf);
1033 1033
1034 sprintf(buf, "%d", ijs_width); 1034 gs_sprintf(buf, "%d", ijs_width);
1035 gsijs_client_set_param(ijsdev, "Width", buf); 1035 gsijs_client_set_param(ijsdev, "Width", buf);
1036 sprintf(buf, "%d", ijs_height); 1036 gs_sprintf(buf, "%d", ijs_height);
1037 gsijs_client_set_param(ijsdev, "Height", buf); 1037 gsijs_client_set_param(ijsdev, "Height", buf);
1038 1038
1039 sprintf(buf, "%gx%g", xres, yres); 1039 gs_sprintf(buf, "%gx%g", xres, yres);
1040 gsijs_client_set_param(ijsdev, "Dpi", buf); 1040 gsijs_client_set_param(ijsdev, "Dpi", buf);
1041 1041
1042#ifdef KRGB_DEBUG 1042#ifdef KRGB_DEBUG
diff --git a/gs/devices/gdevl31s.c b/gs/devices/gdevl31s.c
index 290b12abf..e232bf343 100644
--- a/gs/devices/gdevl31s.c
+++ b/gs/devices/gdevl31s.c
@@ -185,9 +185,9 @@ lj3100sw_print_page_copies(gx_device_printer *pdev, FILE *prn_stream, int num_co
185 if (gdev_prn_file_is_new(pdev)) { 185 if (gdev_prn_file_is_new(pdev)) {
186 lj3100sw_output_section_header(prn_stream, 1, 0, 0); 186 lj3100sw_output_section_header(prn_stream, 1, 0, 0);
187 lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0x1b, 12); 187 lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0x1b, 12);
188 ptr += sprintf(ptr, "\r\nBD"); 188 ptr += gs_sprintf(ptr, "\r\nBD");
189 lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0, 5520); 189 lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0, 5520);
190 ptr += sprintf(ptr, "%s\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n", 190 ptr += gs_sprintf(ptr, "%s\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n",
191 "NJ", 191 "NJ",
192 "PQ", -1, 192 "PQ", -1,
193 "RE", high_resolution ? 6 : 2, 193 "RE", high_resolution ? 6 : 2,
@@ -199,7 +199,7 @@ lj3100sw_print_page_copies(gx_device_printer *pdev, FILE *prn_stream, int num_co
199 } 199 }
200 200
201 lj3100sw_output_section_header(prn_stream, 3, ppdev->NumCopies, 0); 201 lj3100sw_output_section_header(prn_stream, 3, ppdev->NumCopies, 0);
202 ptr += sprintf(ptr, "%s %d\r\n%s\r\n", 202 ptr += gs_sprintf(ptr, "%s %d\r\n%s\r\n",
203 "CM", 1, 203 "CM", 1,
204 "PD"); 204 "PD");
205 *ptr++ = 0; 205 *ptr++ = 0;
diff --git a/gs/devices/gdevpng.c b/gs/devices/gdevpng.c
index 68daf4445..bd7efa901 100644
--- a/gs/devices/gdevpng.c
+++ b/gs/devices/gdevpng.c
@@ -571,7 +571,7 @@ do_png_print_page(gx_device_png * pdev, FILE * file, bool monod)
571 } 571 }
572 /* add comment */ 572 /* add comment */
573 strncpy(software_key, "Software", sizeof(software_key)); 573 strncpy(software_key, "Software", sizeof(software_key));
574 sprintf(software_text, "%s %d.%02d", gs_product, 574 gs_sprintf(software_text, "%s %d.%02d", gs_product,
575 (int)(gs_revision / 100), (int)(gs_revision % 100)); 575 (int)(gs_revision / 100), (int)(gs_revision % 100));
576 text_png.compression = -1; /* uncompressed */ 576 text_png.compression = -1; /* uncompressed */
577 text_png.key = software_key; 577 text_png.key = software_key;
diff --git a/gs/devices/gdevsppr.c b/gs/devices/gdevsppr.c
index a62e94684..9fdbbaf72 100644
--- a/gs/devices/gdevsppr.c
+++ b/gs/devices/gdevsppr.c
@@ -101,7 +101,7 @@ err_code_string(int err_code)
101 { 101 {
102 if ((err_code<EMOTOR)||(err_code>ESERIAL)) 102 if ((err_code<EMOTOR)||(err_code>ESERIAL))
103 { 103 {
104 sprintf(err_buffer,"err_code out of range: %d",err_code); 104 gs_sprintf(err_buffer,"err_code out of range: %d",err_code);
105 return err_buffer; 105 return err_buffer;
106 } 106 }
107 return errmsg[err_code]; 107 return errmsg[err_code];
diff --git a/gs/devices/gdevsun.c b/gs/devices/gdevsun.c
index b3078b189..1ee520164 100644
--- a/gs/devices/gdevsun.c
+++ b/gs/devices/gdevsun.c
@@ -392,7 +392,7 @@ if ( gs_debug['X'] )
392 /* 392 /*
393 * Install the colormap. 393 * Install the colormap.
394 */ 394 */
395 sprintf(xdev->cmsname, "%s-%d", CMSNAME, getpid()); 395 gs_sprintf(xdev->cmsname, "%s-%d", CMSNAME, getpid());
396 pw_setcmsname(xdev->pw, xdev->cmsname); 396 pw_setcmsname(xdev->pw, xdev->cmsname);
397 pw_putcolormap(xdev->pw, 0, CMS_SIZE, 397 pw_putcolormap(xdev->pw, 0, CMS_SIZE,
398 xdev->red, xdev->green, xdev->blue); 398 xdev->red, xdev->green, xdev->blue);
diff --git a/gs/devices/gdevtifs.c b/gs/devices/gdevtifs.c
index 915d446a1..a39687f3f 100644
--- a/gs/devices/gdevtifs.c
+++ b/gs/devices/gdevtifs.c
@@ -449,7 +449,7 @@ int tiff_set_fields_for_printer(gx_device_printer *pdev,
449 449
450 strncpy(softwareValue, gs_product, maxSoftware); 450 strncpy(softwareValue, gs_product, maxSoftware);
451 softwareValue[maxSoftware - 1] = 0; 451 softwareValue[maxSoftware - 1] = 0;
452 sprintf(revs, " %1.2f", gs_revision / 100.0); 452 gs_sprintf(revs, " %1.2f", gs_revision / 100.0);
453 strncat(softwareValue, revs, 453 strncat(softwareValue, revs,
454 maxSoftware - strlen(softwareValue) - 1); 454 maxSoftware - strlen(softwareValue) - 1);
455 455
@@ -462,7 +462,7 @@ int tiff_set_fields_for_printer(gx_device_printer *pdev,
462 462
463 time(&t); 463 time(&t);
464 tms = *localtime(&t); 464 tms = *localtime(&t);
465 sprintf(dateTimeValue, "%04d:%02d:%02d %02d:%02d:%02d", 465 gs_sprintf(dateTimeValue, "%04d:%02d:%02d %02d:%02d:%02d",
466 tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, 466 tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday,
467 tms.tm_hour, tms.tm_min, tms.tm_sec); 467 tms.tm_hour, tms.tm_min, tms.tm_sec);
468 468
diff --git a/gs/devices/gdevtsep.c b/gs/devices/gdevtsep.c
index 3f1769c45..fdf40c2c6 100644
--- a/gs/devices/gdevtsep.c
+++ b/gs/devices/gdevtsep.c
@@ -1184,9 +1184,9 @@ tiffsep1_prn_close(gx_device * pdev)
1184 while (*fmt != 'l' && *fmt != '%') 1184 while (*fmt != 'l' && *fmt != '%')
1185 --fmt; 1185 --fmt;
1186 if (*fmt == 'l') 1186 if (*fmt == 'l')
1187 sprintf(compname, parsed.fname, count1); 1187 gs_sprintf(compname, parsed.fname, count1);
1188 else 1188 else
1189 sprintf(compname, parsed.fname, (int)count1); 1189 gs_sprintf(compname, parsed.fname, (int)count1);
1190 parsed.iodev->procs.delete_file(parsed.iodev, compname); 1190 parsed.iodev->procs.delete_file(parsed.iodev, compname);
1191 } else { 1191 } else {
1192 parsed.iodev->procs.delete_file(parsed.iodev, tfdev->fname); 1192 parsed.iodev->procs.delete_file(parsed.iodev, tfdev->fname);
@@ -1372,7 +1372,7 @@ create_separation_file_name(tiffsep_device * pdev, char * buffer,
1372 /* Max of 10 chars in %d format */ 1372 /* Max of 10 chars in %d format */
1373 if (max_size < base_filename_length + 11) 1373 if (max_size < base_filename_length + 11)
1374 return_error(gs_error_rangecheck); 1374 return_error(gs_error_rangecheck);
1375 sprintf(buffer + base_filename_length, "s%d", sep_num); 1375 gs_sprintf(buffer + base_filename_length, "s%d", sep_num);
1376 } 1376 }
1377 } 1377 }
1378 if (use_sep_name) 1378 if (use_sep_name)
@@ -2382,9 +2382,9 @@ tiffsep1_print_page(gx_device_printer * pdev, FILE * file)
2382 while (*fmt != 'l' && *fmt != '%') 2382 while (*fmt != 'l' && *fmt != '%')
2383 --fmt; 2383 --fmt;
2384 if (*fmt == 'l') 2384 if (*fmt == 'l')
2385 sprintf(compname, parsed.fname, count1); 2385 gs_sprintf(compname, parsed.fname, count1);
2386 else 2386 else
2387 sprintf(compname, parsed.fname, (int)count1); 2387 gs_sprintf(compname, parsed.fname, (int)count1);
2388 parsed.iodev->procs.delete_file(parsed.iodev, compname); 2388 parsed.iodev->procs.delete_file(parsed.iodev, compname);
2389 /* we always need an open printer (it will get deleted in tiffsep1_prn_close */ 2389 /* we always need an open printer (it will get deleted in tiffsep1_prn_close */
2390 if ((code = gdev_prn_open_printer((gx_device *)pdev, 1)) < 0) 2390 if ((code = gdev_prn_open_printer((gx_device *)pdev, 1)) < 0)
diff --git a/gs/devices/gdevupd.c b/gs/devices/gdevupd.c
index db4d85bac..89f76203e 100644
--- a/gs/devices/gdevupd.c
+++ b/gs/devices/gdevupd.c
@@ -6476,7 +6476,7 @@ upd_open_wrtrtl(upd_device *udev)
6476 if( (B_PAGEWIDTH & upd->flags) && 6476 if( (B_PAGEWIDTH & upd->flags) &&
6477 ((c == 0x73) || (c == 0x53)) ) { /* esc * r # S */ 6477 ((c == 0x73) || (c == 0x53)) ) { /* esc * r # S */
6478 6478
6479 sprintf(cv,"%d",upd->pwidth); 6479 gs_sprintf(cv,"%d",upd->pwidth);
6480 ncv = strlen(cv); 6480 ncv = strlen(cv);
6481 6481
6482 nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i); 6482 nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i);
@@ -6494,7 +6494,7 @@ upd_open_wrtrtl(upd_device *udev)
6494 } else if((B_PAGELENGTH & upd->flags) && 6494 } else if((B_PAGELENGTH & upd->flags) &&
6495 ((c == 0x74) || (c == 0x54)) ) { /* esc * r # T */ 6495 ((c == 0x74) || (c == 0x54)) ) { /* esc * r # T */
6496 6496
6497 sprintf(cv,"%d",upd->pheight); 6497 gs_sprintf(cv,"%d",upd->pheight);
6498 ncv = strlen(cv); 6498 ncv = strlen(cv);
6499 6499
6500 nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i); 6500 nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i);
@@ -6523,7 +6523,7 @@ upd_open_wrtrtl(upd_device *udev)
6523 if( (B_RESOLUTION & upd->flags) && 6523 if( (B_RESOLUTION & upd->flags) &&
6524 ((c == 0x72) || (c == 0x52)) ) { /* esc * t # R */ 6524 ((c == 0x72) || (c == 0x52)) ) { /* esc * t # R */
6525 6525
6526 sprintf(cv,"%d",(int) 6526 gs_sprintf(cv,"%d",(int)
6527 ((udev->y_pixels_per_inch < udev->x_pixels_per_inch ? 6527 ((udev->y_pixels_per_inch < udev->x_pixels_per_inch ?
6528 udev->x_pixels_per_inch : udev->y_pixels_per_inch) 6528 udev->x_pixels_per_inch : udev->y_pixels_per_inch)
6529 +0.5)); 6529 +0.5));
@@ -6730,7 +6730,7 @@ upd_open_wrtrtl(upd_device *udev)
6730 6730
6731 if(B_PAGELENGTH & upd->flags) { /* insert new number */ 6731 if(B_PAGELENGTH & upd->flags) { /* insert new number */
6732 6732
6733 sprintf(cv,"%d",(int) 6733 gs_sprintf(cv,"%d",(int)
6734 (720.0 * udev->height / udev->y_pixels_per_inch + 0.5)); 6734 (720.0 * udev->height / udev->y_pixels_per_inch + 0.5));
6735 ncv = strlen(cv); 6735 ncv = strlen(cv);
6736 6736
@@ -6795,7 +6795,7 @@ upd_open_wrtrtl(upd_device *udev)
6795 6795
6796 if(B_PAGEWIDTH & upd->flags) { /* insert new number */ 6796 if(B_PAGEWIDTH & upd->flags) { /* insert new number */
6797 6797
6798 sprintf(cv,"%d",(int) 6798 gs_sprintf(cv,"%d",(int)
6799 (720.0 * udev->width / udev->x_pixels_per_inch + 0.5)); 6799 (720.0 * udev->width / udev->x_pixels_per_inch + 0.5));
6800 ncv = strlen(cv); 6800 ncv = strlen(cv);
6801 6801
@@ -6890,7 +6890,7 @@ upd_open_wrtrtl(upd_device *udev)
6890 6890
6891 if(B_RESOLUTION & upd->flags) { /* insert new number */ 6891 if(B_RESOLUTION & upd->flags) { /* insert new number */
6892 6892
6893 sprintf(cv,"%d",(int) 6893 gs_sprintf(cv,"%d",(int)
6894 ((udev->y_pixels_per_inch < udev->x_pixels_per_inch ? 6894 ((udev->y_pixels_per_inch < udev->x_pixels_per_inch ?
6895 udev->x_pixels_per_inch : udev->y_pixels_per_inch) 6895 udev->x_pixels_per_inch : udev->y_pixels_per_inch)
6896 +0.5)); 6896 +0.5));
@@ -6945,7 +6945,7 @@ It must hold:
6945 char tmp[16]; 6945 char tmp[16];
6946 6946
6947 if(0 < upd->strings[S_YMOVE].size) { 6947 if(0 < upd->strings[S_YMOVE].size) {
6948 sprintf(tmp,"%d",upd->pheight); 6948 gs_sprintf(tmp,"%d",upd->pheight);
6949 ny = upd->strings[S_YMOVE].size + strlen(tmp); 6949 ny = upd->strings[S_YMOVE].size + strlen(tmp);
6950 } else { 6950 } else {
6951 ny = 1 + upd->string_a[SA_WRITECOMP].data[upd->ocomp-1].size; 6951 ny = 1 + upd->string_a[SA_WRITECOMP].data[upd->ocomp-1].size;
@@ -7006,14 +7006,14 @@ upd_wrtrtl(upd_p upd, FILE *out)
7006 */ 7006 */
7007 if(upd->yscan != upd->yprinter) { /* Adjust Y-Position */ 7007 if(upd->yscan != upd->yprinter) { /* Adjust Y-Position */
7008 if(1 < upd->strings[S_YMOVE].size) { 7008 if(1 < upd->strings[S_YMOVE].size) {
7009 sprintf((char *)upd->outbuf+ioutbuf, 7009 gs_sprintf((char *)upd->outbuf+ioutbuf,
7010 (const char *) upd->strings[S_YMOVE].data, 7010 (const char *) upd->strings[S_YMOVE].data,
7011 upd->yscan - upd->yprinter); 7011 upd->yscan - upd->yprinter);
7012 ioutbuf += strlen((char *)upd->outbuf+ioutbuf); 7012 ioutbuf += strlen((char *)upd->outbuf+ioutbuf);
7013 } else { 7013 } else {
7014 while(upd->yscan > upd->yprinter) { 7014 while(upd->yscan > upd->yprinter) {
7015 for(icomp = 0; icomp < upd->ocomp; ++icomp) { 7015 for(icomp = 0; icomp < upd->ocomp; ++icomp) {
7016 sprintf((char *)upd->outbuf+ioutbuf, 7016 gs_sprintf((char *)upd->outbuf+ioutbuf,
7017 (const char *) upd->string_a[SA_WRITECOMP].data[icomp].data,0); 7017 (const char *) upd->string_a[SA_WRITECOMP].data[icomp].data,0);
7018 ioutbuf += strlen((char *)upd->outbuf+ioutbuf); 7018 ioutbuf += strlen((char *)upd->outbuf+ioutbuf);
7019 } 7019 }
diff --git a/gs/devices/gdevwpr2.c b/gs/devices/gdevwpr2.c
index 5e8ddb1f0..28935b61b 100644
--- a/gs/devices/gdevwpr2.c
+++ b/gs/devices/gdevwpr2.c
@@ -548,7 +548,7 @@ win_pr2_print_page(gx_device_printer * pdev, FILE * file)
548 } 548 }
549 549
550 if (!wdev->nocancel) { 550 if (!wdev->nocancel) {
551 sprintf(dlgtext, "Printing page %d", (int)(pdev->PageCount) + 1); 551 gs_sprintf(dlgtext, "Printing page %d", (int)(pdev->PageCount) + 1);
552 SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PRINTING), dlgtext); 552 SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PRINTING), dlgtext);
553 ShowWindow(wdev->hDlgModeless, SW_SHOW); 553 ShowWindow(wdev->hDlgModeless, SW_SHOW);
554 } 554 }
@@ -577,7 +577,7 @@ win_pr2_print_page(gx_device_printer * pdev, FILE * file)
577 577
578 if (!wdev->nocancel) { 578 if (!wdev->nocancel) {
579 /* inform user of progress */ 579 /* inform user of progress */
580 sprintf(dlgtext, "%d%% done", (int)(y * 100L / scan_lines)); 580 gs_sprintf(dlgtext, "%d%% done", (int)(y * 100L / scan_lines));
581 SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PCDONE), dlgtext); 581 SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PCDONE), dlgtext);
582 } 582 }
583 /* process message loop */ 583 /* process message loop */
@@ -1488,9 +1488,9 @@ win_pr2_print_setup_interaction(gx_device_win_pr2 * wdev, int mode)
1488 1488
1489 wdev->user_changed_settings = TRUE; 1489 wdev->user_changed_settings = TRUE;
1490 if (wdev->use_old_spool_name) { 1490 if (wdev->use_old_spool_name) {
1491 sprintf(wdev->fname, "\\\\spool\\%s", (char*)(devnames)+(devnames->wDeviceOffset)); 1491 gs_sprintf(wdev->fname, "\\\\spool\\%s", (char*)(devnames)+(devnames->wDeviceOffset));
1492 } else { 1492 } else {
1493 sprintf(wdev->fname, "%%printer%%%s", (char*)(devnames)+(devnames->wDeviceOffset)); 1493 gs_sprintf(wdev->fname, "%%printer%%%s", (char*)(devnames)+(devnames->wDeviceOffset));
1494 } 1494 }
1495 1495
1496 if (mode == 3) { 1496 if (mode == 3) {
diff --git a/gs/devices/gdevxini.c b/gs/devices/gdevxini.c
index f94ccfc4c..9bbefdfab 100644
--- a/gs/devices/gdevxini.c
+++ b/gs/devices/gdevxini.c
@@ -377,7 +377,7 @@ gdev_x_open(gx_device_X * xdev)
377 char gstr[40]; 377 char gstr[40];
378 int bitmask; 378 int bitmask;
379 379
380 sprintf(gstr, "%dx%d+%d+%d", sizehints.width, 380 gs_sprintf(gstr, "%dx%d+%d+%d", sizehints.width,
381 sizehints.height, sizehints.x, sizehints.y); 381 sizehints.height, sizehints.x, sizehints.y);
382 bitmask = XWMGeometry(xdev->dpy, DefaultScreen(xdev->dpy), 382 bitmask = XWMGeometry(xdev->dpy, DefaultScreen(xdev->dpy),
383 xdev->geometry, gstr, xdev->borderWidth, 383 xdev->geometry, gstr, xdev->borderWidth,
diff --git a/gs/devices/vector/gdevpdf.c b/gs/devices/vector/gdevpdf.c
index 86422a5eb..5b8750799 100644
--- a/gs/devices/vector/gdevpdf.c
+++ b/gs/devices/vector/gdevpdf.c
@@ -301,7 +301,7 @@ pdf_initialize_ids(gx_device_pdf * pdev)
301 timeoffset = any_abs(timeoffset) / 60; 301 timeoffset = any_abs(timeoffset) / 60;
302 tms = *localtime(&t); 302 tms = *localtime(&t);
303 303
304 sprintf(buf, "(D:%04d%02d%02d%02d%02d%02d%c%02d\'%02d\')", 304 gs_sprintf(buf, "(D:%04d%02d%02d%02d%02d%02d%c%02d\'%02d\')",
305 tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, 305 tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday,
306 tms.tm_hour, tms.tm_min, tms.tm_sec, 306 tms.tm_hour, tms.tm_min, tms.tm_sec,
307 timesign, timeoffset / 60, timeoffset % 60); 307 timesign, timeoffset / 60, timeoffset % 60);
@@ -1277,7 +1277,7 @@ static int write_xref_section(gx_device_pdf *pdev, FILE *tfile, int64_t start, i
1277 * chances of needing to write white space to pad the file out. 1277 * chances of needing to write white space to pad the file out.
1278 */ 1278 */
1279 if (!pdev->Linearise) { 1279 if (!pdev->Linearise) {
1280 sprintf(str, "%010"PRId64" 00000 n \n", pos); 1280 gs_sprintf(str, "%010"PRId64" 00000 n \n", pos);
1281 stream_puts(pdev->strm, str); 1281 stream_puts(pdev->strm, str);
1282 } 1282 }
1283 if (Offsets) 1283 if (Offsets)
@@ -1310,7 +1310,7 @@ rewrite_object(gx_device_pdf *const pdev, pdf_linearisation_t *linear_params, in
1310 code = fread(&c, 1, 1, linear_params->sfile); 1310 code = fread(&c, 1, 1, linear_params->sfile);
1311 read++; 1311 read++;
1312 } while (c != '\n' && code > 0); 1312 } while (c != '\n' && code > 0);
1313 sprintf(Scratch, "%d 0 obj\n", pdev->ResourceUsage[object].NewObjectNumber); 1313 gs_sprintf(Scratch, "%d 0 obj\n", pdev->ResourceUsage[object].NewObjectNumber);
1314 fwrite(Scratch, strlen(Scratch), 1, linear_params->Lin_File.file); 1314 fwrite(Scratch, strlen(Scratch), 1, linear_params->Lin_File.file);
1315 1315
1316 code = fread(&c, 1, 1, linear_params->sfile); 1316 code = fread(&c, 1, 1, linear_params->sfile);
@@ -1359,7 +1359,7 @@ rewrite_object(gx_device_pdf *const pdev, pdf_linearisation_t *linear_params, in
1359 target++; 1359 target++;
1360 sscanf(target, "%d 0 R", &ID); 1360 sscanf(target, "%d 0 R", &ID);
1361 fwrite(source, target - source, 1, linear_params->Lin_File.file); 1361 fwrite(source, target - source, 1, linear_params->Lin_File.file);
1362 sprintf(Buf, "%d 0 R", pdev->ResourceUsage[ID].NewObjectNumber); 1362 gs_sprintf(Buf, "%d 0 R", pdev->ResourceUsage[ID].NewObjectNumber);
1363 fwrite(Buf, strlen(Buf), 1, linear_params->Lin_File.file); 1363 fwrite(Buf, strlen(Buf), 1, linear_params->Lin_File.file);
1364 source = next; 1364 source = next;
1365 } else { 1365 } else {
@@ -1544,7 +1544,7 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
1544 } 1544 }
1545#endif 1545#endif
1546 /* Linearisation. Part 1, file header */ 1546 /* Linearisation. Part 1, file header */
1547 sprintf(Header, "%%PDF-%d.%d\n", level / 10, level % 10); 1547 gs_sprintf(Header, "%%PDF-%d.%d\n", level / 10, level % 10);
1548 fwrite(Header, strlen(Header), 1, linear_params->Lin_File.file); 1548 fwrite(Header, strlen(Header), 1, linear_params->Lin_File.file);
1549 if (pdev->binary_ok) 1549 if (pdev->binary_ok)
1550 fwrite(Binary, strlen(Binary), 1, linear_params->Lin_File.file); 1550 fwrite(Binary, strlen(Binary), 1, linear_params->Lin_File.file);
@@ -1556,16 +1556,16 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
1556 1556
1557 /* Linearisation. Part 2, the Linearisation dictioanry */ 1557 /* Linearisation. Part 2, the Linearisation dictioanry */
1558 linear_params->LDictOffset = gp_ftell_64(linear_params->Lin_File.file); 1558 linear_params->LDictOffset = gp_ftell_64(linear_params->Lin_File.file);
1559 sprintf(LDict, "%d 0 obj\n<< \n", 1559 gs_sprintf(LDict, "%d 0 obj\n<< \n",
1560 LDictObj); 1560 LDictObj);
1561 fwrite(LDict, strlen(LDict), 1, linear_params->Lin_File.file); 1561 fwrite(LDict, strlen(LDict), 1, linear_params->Lin_File.file);
1562 1562
1563 /* First page cross-reference table here (Part 3) */ 1563 /* First page cross-reference table here (Part 3) */
1564 linear_params->FirstxrefOffset = gp_ftell_64(linear_params->Lin_File.file); 1564 linear_params->FirstxrefOffset = gp_ftell_64(linear_params->Lin_File.file);
1565 sprintf(Header, "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */ 1565 gs_sprintf(Header, "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */
1566 fwrite(Header, strlen(Header), 1, linear_params->Lin_File.file); 1566 fwrite(Header, strlen(Header), 1, linear_params->Lin_File.file);
1567 1567
1568 sprintf(Header, "0000000000 00000 n \n"); 1568 gs_sprintf(Header, "0000000000 00000 n \n");
1569 1569
1570 for (i = LDictObj;i <= linear_params->LastResource + 2; i++) { 1570 for (i = LDictObj;i <= linear_params->LastResource + 2; i++) {
1571 fwrite(Header, 20, 1, linear_params->Lin_File.file); 1571 fwrite(Header, 20, 1, linear_params->Lin_File.file);
@@ -1575,7 +1575,7 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
1575 * +1 for the linearisation dict and +1 for the primary hint stream. 1575 * +1 for the linearisation dict and +1 for the primary hint stream.
1576 */ 1576 */
1577 linear_params->FirsttrailerOffset = gp_ftell_64(linear_params->Lin_File.file); 1577 linear_params->FirsttrailerOffset = gp_ftell_64(linear_params->Lin_File.file);
1578 sprintf(LDict, "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %d>>\nstartxref\r\n0\n%%%%EOF\n \n", 1578 gs_sprintf(LDict, "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %d>>\nstartxref\r\n0\n%%%%EOF\n \n",
1579 linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, fileID, fileID, 0); 1579 linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, fileID, fileID, 0);
1580 fwrite(LDict, strlen(LDict), 1, linear_params->Lin_File.file); 1580 fwrite(LDict, strlen(LDict), 1, linear_params->Lin_File.file);
1581 1581
@@ -1685,7 +1685,7 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
1685 } 1685 }
1686 } 1686 }
1687 /* insert the primary hint stream */ 1687 /* insert the primary hint stream */
1688 sprintf(LDict, "%d 0 obj\n<</Length \n/S >>\nstream\n", HintStreamObj); 1688 gs_sprintf(LDict, "%d 0 obj\n<</Length \n/S >>\nstream\n", HintStreamObj);
1689 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 1689 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
1690 1690
1691 HintStreamStart = gp_ftell_64(linear_params->sfile); 1691 HintStreamStart = gp_ftell_64(linear_params->sfile);
@@ -1999,7 +1999,7 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
1999 flush_hint_stream(linear_params); 1999 flush_hint_stream(linear_params);
2000 HintLength = gp_ftell_64(linear_params->sfile) - HintStreamStart; 2000 HintLength = gp_ftell_64(linear_params->sfile) - HintStreamStart;
2001 2001
2002 sprintf(LDict, "\nendstream\nendobj\n"); 2002 gs_sprintf(LDict, "\nendstream\nendobj\n");
2003 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 2003 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
2004 /* Calculate the length of the primary hint stream */ 2004 /* Calculate the length of the primary hint stream */
2005 HintStreamLen = gp_ftell_64(linear_params->sfile) - pdev->ResourceUsage[HintStreamObj].LinearisedOffset; 2005 HintStreamLen = gp_ftell_64(linear_params->sfile) - pdev->ResourceUsage[HintStreamObj].LinearisedOffset;
@@ -2032,23 +2032,23 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
2032 2032
2033 /* Now the file is long enough, write the xref */ 2033 /* Now the file is long enough, write the xref */
2034 mainxref = gp_ftell_64(linear_params->sfile); 2034 mainxref = gp_ftell_64(linear_params->sfile);
2035 sprintf(Header, "xref\n0 %d\n", LDictObj); 2035 gs_sprintf(Header, "xref\n0 %d\n", LDictObj);
2036 fwrite(Header, strlen(Header), 1, linear_params->sfile); 2036 fwrite(Header, strlen(Header), 1, linear_params->sfile);
2037 2037
2038 linear_params->T = gp_ftell_64(linear_params->sfile) - 1; 2038 linear_params->T = gp_ftell_64(linear_params->sfile) - 1;
2039 sprintf(Header, "0000000000 65535 f \n"); 2039 gs_sprintf(Header, "0000000000 65535 f \n");
2040 fwrite(Header, strlen(Header), 1, linear_params->sfile); 2040 fwrite(Header, strlen(Header), 1, linear_params->sfile);
2041 2041
2042 for (i = 1;i < LDictObj; i++) { 2042 for (i = 1;i < LDictObj; i++) {
2043 for (j = 0; j < pdev->ResourceUsageSize;j++) { 2043 for (j = 0; j < pdev->ResourceUsageSize;j++) {
2044 if (pdev->ResourceUsage[j].NewObjectNumber == i) { 2044 if (pdev->ResourceUsage[j].NewObjectNumber == i) {
2045 sprintf(Header, "%010ld 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset + HintStreamLen); 2045 gs_sprintf(Header, "%010ld 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset + HintStreamLen);
2046 fwrite(Header, 20, 1, linear_params->sfile); 2046 fwrite(Header, 20, 1, linear_params->sfile);
2047 } 2047 }
2048 } 2048 }
2049 } 2049 }
2050 2050
2051 sprintf(LDict, "trailer\n<</Size %d>>\nstartxref\n%ld\n%%%%EOF\n", 2051 gs_sprintf(LDict, "trailer\n<</Size %d>>\nstartxref\n%ld\n%%%%EOF\n",
2052 LDictObj, linear_params->FirstxrefOffset); 2052 LDictObj, linear_params->FirstxrefOffset);
2053 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 2053 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
2054 2054
@@ -2062,32 +2062,32 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
2062 * versions. 2062 * versions.
2063 */ 2063 */
2064 gp_fseek_64(linear_params->sfile, linear_params->LDictOffset, SEEK_SET); 2064 gp_fseek_64(linear_params->sfile, linear_params->LDictOffset, SEEK_SET);
2065 sprintf(LDict, "%d 0 obj\n<</Linearized 1/L %ld/H[ ", LDictObj, linear_params->FileLength); 2065 gs_sprintf(LDict, "%d 0 obj\n<</Linearized 1/L %ld/H[ ", LDictObj, linear_params->FileLength);
2066 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 2066 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
2067 2067
2068 sprintf(LDict, "%ld", pdev->ResourceUsage[HintStreamObj].LinearisedOffset); 2068 gs_sprintf(LDict, "%ld", pdev->ResourceUsage[HintStreamObj].LinearisedOffset);
2069 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 2069 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
2070 sprintf(LDict, " %ld]", HintStreamLen); 2070 gs_sprintf(LDict, " %ld]", HintStreamLen);
2071 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 2071 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
2072 /* Implementation Note 180 in hte PDF Reference 1.7 says that Acrobat 2072 /* Implementation Note 180 in hte PDF Reference 1.7 says that Acrobat
2073 * gets the 'E' value wrong. So its probably not important.... 2073 * gets the 'E' value wrong. So its probably not important....
2074 */ 2074 */
2075 sprintf(LDict, "/O %d/E %ld",pdev->ResourceUsage[pdev->pages[0].Page->id].NewObjectNumber, linear_params->E); 2075 gs_sprintf(LDict, "/O %d/E %ld",pdev->ResourceUsage[pdev->pages[0].Page->id].NewObjectNumber, linear_params->E);
2076 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 2076 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
2077 sprintf(LDict, "/N %d/T %ld>>\nendobj\n", pdev->next_page, linear_params->T); 2077 gs_sprintf(LDict, "/N %d/T %ld>>\nendobj\n", pdev->next_page, linear_params->T);
2078 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 2078 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
2079 2079
2080 /* Return to the secondary xref and write it again filling 2080 /* Return to the secondary xref and write it again filling
2081 * in the missing offsets. 2081 * in the missing offsets.
2082 */ 2082 */
2083 gp_fseek_64(linear_params->sfile, linear_params->FirstxrefOffset, SEEK_SET); 2083 gp_fseek_64(linear_params->sfile, linear_params->FirstxrefOffset, SEEK_SET);
2084 sprintf(Header, "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */ 2084 gs_sprintf(Header, "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */
2085 fwrite(Header, strlen(Header), 1, linear_params->sfile); 2085 fwrite(Header, strlen(Header), 1, linear_params->sfile);
2086 2086
2087 for (i = LDictObj;i <= linear_params->LastResource + 2; i++) { 2087 for (i = LDictObj;i <= linear_params->LastResource + 2; i++) {
2088 for (j = 0; j < pdev->ResourceUsageSize;j++) { 2088 for (j = 0; j < pdev->ResourceUsageSize;j++) {
2089 if (pdev->ResourceUsage[j].NewObjectNumber == i) { 2089 if (pdev->ResourceUsage[j].NewObjectNumber == i) {
2090 sprintf(Header, "%010ld 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset); 2090 gs_sprintf(Header, "%010ld 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset);
2091 fwrite(Header, 20, 1, linear_params->sfile); 2091 fwrite(Header, 20, 1, linear_params->sfile);
2092 } 2092 }
2093 } 2093 }
@@ -2097,14 +2097,14 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
2097 * in the missing values. 2097 * in the missing values.
2098 */ 2098 */
2099 code = gp_fseek_64(linear_params->sfile, linear_params->FirsttrailerOffset, SEEK_SET); 2099 code = gp_fseek_64(linear_params->sfile, linear_params->FirsttrailerOffset, SEEK_SET);
2100 sprintf(LDict, "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %ld>>\nstartxref\r\n0\n%%%%EOF\n", 2100 gs_sprintf(LDict, "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %ld>>\nstartxref\r\n0\n%%%%EOF\n",
2101 linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, fileID, fileID, (unsigned long)mainxref); 2101 linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, fileID, fileID, (unsigned long)mainxref);
2102 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 2102 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
2103 2103
2104 code = gp_fseek_64(linear_params->sfile, pdev->ResourceUsage[HintStreamObj].LinearisedOffset, SEEK_SET); 2104 code = gp_fseek_64(linear_params->sfile, pdev->ResourceUsage[HintStreamObj].LinearisedOffset, SEEK_SET);
2105 sprintf(LDict, "%d 0 obj\n<</Length %10ld", HintStreamObj, HintLength); 2105 gs_sprintf(LDict, "%d 0 obj\n<</Length %10ld", HintStreamObj, HintLength);
2106 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 2106 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
2107 sprintf(LDict, "\n/S %10ld>>\nstream\n", SharedHintOffset); 2107 gs_sprintf(LDict, "\n/S %10ld>>\nstream\n", SharedHintOffset);
2108 fwrite(LDict, strlen(LDict), 1, linear_params->sfile); 2108 fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
2109 2109
2110error: 2110error:
@@ -2605,7 +2605,7 @@ pdf_close(gx_device * dev)
2605 pprintld1(s, "/Encrypt %ld 0 R ", Encrypt_id); 2605 pprintld1(s, "/Encrypt %ld 0 R ", Encrypt_id);
2606 } 2606 }
2607 stream_puts(s, ">>\n"); 2607 stream_puts(s, ">>\n");
2608 sprintf(xref_str, "startxref\n%"PRId64"\n%%%%EOF\n", xref); 2608 gs_sprintf(xref_str, "startxref\n%"PRId64"\n%%%%EOF\n", xref);
2609 stream_puts(s, xref_str); 2609 stream_puts(s, xref_str);
2610 } 2610 }
2611 } 2611 }
diff --git a/gs/devices/vector/gdevpdfb.c b/gs/devices/vector/gdevpdfb.c
index 6774e1c81..4e32ea751 100644
--- a/gs/devices/vector/gdevpdfb.c
+++ b/gs/devices/vector/gdevpdfb.c
@@ -590,7 +590,7 @@ gdev_pdf_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles,
590 if (image_id) { 590 if (image_id) {
591 char buf[MAX_REF_CHARS + 6 + 1]; /* +6 for /R# Do\n */ 591 char buf[MAX_REF_CHARS + 6 + 1]; /* +6 for /R# Do\n */
592 592
593 sprintf(buf, "/R%ld Do\n", image_id); 593 gs_sprintf(buf, "/R%ld Do\n", image_id);
594 pprintd1(s, "%d>>stream\n", strlen(buf)); 594 pprintd1(s, "%d>>stream\n", strlen(buf));
595 if (pdev->PDFA != 0) 595 if (pdev->PDFA != 0)
596 pprints1(s, "%s\nendstream\n", buf); 596 pprints1(s, "%s\nendstream\n", buf);
diff --git a/gs/devices/vector/gdevpdfe.c b/gs/devices/vector/gdevpdfe.c
index 954656e04..87c4bfa96 100644
--- a/gs/devices/vector/gdevpdfe.c
+++ b/gs/devices/vector/gdevpdfe.c
@@ -205,7 +205,7 @@ pdf_xmp_time(char *buf, int buf_length)
205 205
206 time(&t); 206 time(&t);
207 tms = *localtime(&t); 207 tms = *localtime(&t);
208 sprintf(buf1, 208 gs_sprintf(buf1,
209 "%04d-%02d-%02d", 209 "%04d-%02d-%02d",
210 tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday); 210 tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday);
211 strncpy(buf, buf1, buf_length); 211 strncpy(buf, buf1, buf_length);
@@ -860,7 +860,7 @@ pdf_document_metadata(gx_device_pdf *pdev)
860 code = COS_WRITE_OBJECT(pres->object, pdev, resourceNone); 860 code = COS_WRITE_OBJECT(pres->object, pdev, resourceNone);
861 if (code < 0) 861 if (code < 0)
862 return code; 862 return code;
863 sprintf(buf, "%ld 0 R", pres->object->id); 863 gs_sprintf(buf, "%ld 0 R", pres->object->id);
864 pdf_record_usage(pdev, pres->object->id, resource_usage_part9_structure); 864 pdf_record_usage(pdev, pres->object->id, resource_usage_part9_structure);
865 865
866 code = cos_dict_put_c_key_object(pdev->Catalog, "/Metadata", pres->object); 866 code = cos_dict_put_c_key_object(pdev->Catalog, "/Metadata", pres->object);
diff --git a/gs/devices/vector/gdevpdfg.c b/gs/devices/vector/gdevpdfg.c
index 4a13a17e0..d5ca8a2ae 100644
--- a/gs/devices/vector/gdevpdfg.c
+++ b/gs/devices/vector/gdevpdfg.c
@@ -1312,7 +1312,7 @@ pdf_write_transfer_map(gx_device_pdf *pdev, const gx_transfer_map *map,
1312 gs_function_free(pfn, false, mem); 1312 gs_function_free(pfn, false, mem);
1313 if (code < 0) 1313 if (code < 0)
1314 return code; 1314 return code;
1315 sprintf(ids, "%s%s%ld 0 R", key, (key[0] && key[0] != ' ' ? " " : ""), id); 1315 gs_sprintf(ids, "%s%s%ld 0 R", key, (key[0] && key[0] != ' ' ? " " : ""), id);
1316 return 0; 1316 return 0;
1317} 1317}
1318static int 1318static int
@@ -1893,7 +1893,7 @@ pdf_update_halftone(gx_device_pdf *pdev, const gs_imager_state *pis,
1893 } 1893 }
1894 if (code < 0) 1894 if (code < 0)
1895 return code; 1895 return code;
1896 sprintf(hts, "%ld 0 R", id); 1896 gs_sprintf(hts, "%ld 0 R", id);
1897 pdev->halftone_id = pis->dev_ht->id; 1897 pdev->halftone_id = pis->dev_ht->id;
1898 return code; 1898 return code;
1899} 1899}
@@ -2030,7 +2030,7 @@ pdf_update_alpha(gx_device_pdf *pdev, const gs_imager_state *pis,
2030 if (pis->soft_mask_id == 0) 2030 if (pis->soft_mask_id == 0)
2031 strcpy(buf, "/None"); 2031 strcpy(buf, "/None");
2032 else 2032 else
2033 sprintf(buf, "%ld 0 R", pis->soft_mask_id); 2033 gs_sprintf(buf, "%ld 0 R", pis->soft_mask_id);
2034 code = pdf_open_gstate(pdev, ppres); 2034 code = pdf_open_gstate(pdev, ppres);
2035 if (code < 0) 2035 if (code < 0)
2036 return code; 2036 return code;
@@ -2186,7 +2186,7 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_imager_state *pis,
2186 code = pdf_open_gstate(pdev, ppres); 2186 code = pdf_open_gstate(pdev, ppres);
2187 if (code < 0) 2187 if (code < 0)
2188 return code; 2188 return code;
2189 sprintf(buf, "[%d %d]", phase.x, phase.y); 2189 gs_sprintf(buf, "[%d %d]", phase.x, phase.y);
2190 code = cos_dict_put_string_copy(resource_dict(*ppres), "/HTP", buf); 2190 code = cos_dict_put_string_copy(resource_dict(*ppres), "/HTP", buf);
2191 if (code < 0) 2191 if (code < 0)
2192 return code; 2192 return code;
diff --git a/gs/devices/vector/gdevpdfi.c b/gs/devices/vector/gdevpdfi.c
index 3e022c9a5..90dc25150 100644
--- a/gs/devices/vector/gdevpdfi.c
+++ b/gs/devices/vector/gdevpdfi.c
@@ -2116,7 +2116,7 @@ pdf_end_and_do_image(gx_device_pdf *pdev, pdf_image_writer *piw,
2116 if (pdev->image_mask_id != gs_no_id) { 2116 if (pdev->image_mask_id != gs_no_id) {
2117 char buf[20]; 2117 char buf[20];
2118 2118
2119 sprintf(buf, "%ld 0 R", pdev->image_mask_id); 2119 gs_sprintf(buf, "%ld 0 R", pdev->image_mask_id);
2120 code = cos_dict_put_string_copy((cos_dict_t *)pres->object, 2120 code = cos_dict_put_string_copy((cos_dict_t *)pres->object,
2121 pdev->image_mask_is_SMask ? "/SMask" : "/Mask", buf); 2121 pdev->image_mask_is_SMask ? "/SMask" : "/Mask", buf);
2122 if (code < 0) 2122 if (code < 0)
diff --git a/gs/devices/vector/gdevpdfm.c b/gs/devices/vector/gdevpdfm.c
index 0f12db8c7..adffdb84d 100644
--- a/gs/devices/vector/gdevpdfm.c
+++ b/gs/devices/vector/gdevpdfm.c
@@ -153,9 +153,9 @@ pdfmark_make_dest(char dstr[MAX_DEST_STRING], gx_device_pdf * pdev,
153 else if (pdfmark_find_key("/Action", pairs, count, &action) && 153 else if (pdfmark_find_key("/Action", pairs, count, &action) &&
154 pdf_key_eq(&action, "/GoToR") 154 pdf_key_eq(&action, "/GoToR")
155 ) 155 )
156 sprintf(dstr, "[%d ", page - 1); 156 gs_sprintf(dstr, "[%d ", page - 1);
157 else 157 else
158 sprintf(dstr, "[%ld 0 R ", pdf_page_id(pdev, page)); 158 gs_sprintf(dstr, "[%ld 0 R ", pdf_page_id(pdev, page));
159 len = strlen(dstr); 159 len = strlen(dstr);
160 if (len + view_string.size > MAX_DEST_STRING) 160 if (len + view_string.size > MAX_DEST_STRING)
161 return_error(gs_error_limitcheck); 161 return_error(gs_error_limitcheck);
@@ -757,7 +757,7 @@ pdfmark_put_ao_pairs(gx_device_pdf * pdev, cos_dict_t *pcd,
757 char dstr[1 + (sizeof(long) * 8 / 3 + 1) + 25 + 1]; 757 char dstr[1 + (sizeof(long) * 8 / 3 + 1) + 25 + 1];
758 long page_id = pdf_page_id(pdev, pdev->next_page + 1); 758 long page_id = pdf_page_id(pdev, pdev->next_page + 1);
759 759
760 sprintf(dstr, "[%ld 0 R /XYZ null null null]", page_id); 760 gs_sprintf(dstr, "[%ld 0 R /XYZ null null null]", page_id);
761 cos_dict_put_c_key_string(pcd, "/Dest", (const unsigned char*) dstr, 761 cos_dict_put_c_key_string(pcd, "/Dest", (const unsigned char*) dstr,
762 strlen(dstr)); 762 strlen(dstr));
763 } 763 }
@@ -1530,7 +1530,7 @@ pdfmark_PS(gx_device_pdf * pdev, gs_param_string * pairs, uint count,
1530 if (level1_id != gs_no_id) { 1530 if (level1_id != gs_no_id) {
1531 char r[MAX_DEST_STRING]; 1531 char r[MAX_DEST_STRING];
1532 1532
1533 sprintf(r, "%ld 0 R", level1_id); 1533 gs_sprintf(r, "%ld 0 R", level1_id);
1534 code = cos_dict_put_c_key_string(cos_stream_dict(pcs), "/Level1", 1534 code = cos_dict_put_c_key_string(cos_stream_dict(pcs), "/Level1",
1535 (byte *)r, strlen(r)); 1535 (byte *)r, strlen(r));
1536 if (code < 0) 1536 if (code < 0)
diff --git a/gs/devices/vector/gdevpdfo.c b/gs/devices/vector/gdevpdfo.c
index 2ca812693..57b553fc9 100644
--- a/gs/devices/vector/gdevpdfo.c
+++ b/gs/devices/vector/gdevpdfo.c
@@ -701,7 +701,7 @@ cos_array_add_int(cos_array_t *pca, int i)
701 char str[sizeof(int) * 8 / 3 + 3]; /* sign, rounding, 0 terminator */ 701 char str[sizeof(int) * 8 / 3 + 3]; /* sign, rounding, 0 terminator */
702 cos_value_t v; 702 cos_value_t v;
703 703
704 sprintf(str, "%d", i); 704 gs_sprintf(str, "%d", i);
705 return cos_array_add(pca, cos_string_value(&v, (byte *)str, strlen(str))); 705 return cos_array_add(pca, cos_string_value(&v, (byte *)str, strlen(str)));
706} 706}
707int 707int
@@ -1082,7 +1082,7 @@ cos_dict_put_c_key_int(cos_dict_t *pcd, const char *key, int value)
1082{ 1082{
1083 char str[sizeof(int) * 8 / 3 + 3]; /* sign, rounding, 0 terminator */ 1083 char str[sizeof(int) * 8 / 3 + 3]; /* sign, rounding, 0 terminator */
1084 1084
1085 sprintf(str, "%d", value); 1085 gs_sprintf(str, "%d", value);
1086 return cos_dict_put_c_key_string(pcd, key, (byte *)str, strlen(str)); 1086 return cos_dict_put_c_key_string(pcd, key, (byte *)str, strlen(str));
1087} 1087}
1088int 1088int
diff --git a/gs/devices/vector/gdevpdfr.c b/gs/devices/vector/gdevpdfr.c
index 4e7a217f2..ef32eeaf7 100644
--- a/gs/devices/vector/gdevpdfr.c
+++ b/gs/devices/vector/gdevpdfr.c
@@ -140,7 +140,7 @@ pdf_refer_named(gx_device_pdf * pdev, const gs_param_string * pname_orig,
140 } 140 }
141 if (page_number <= 0) 141 if (page_number <= 0)
142 return code; 142 return code;
143 sprintf(page_name_chars, "{Page%d}", page_number); 143 gs_sprintf(page_name_chars, "{Page%d}", page_number);
144 param_string_from_string(pnstr, page_name_chars); 144 param_string_from_string(pnstr, page_name_chars);
145 pname = &pnstr; 145 pname = &pnstr;
146 code = pdf_find_named(pdev, pname, ppco); 146 code = pdf_find_named(pdev, pname, ppco);
@@ -452,7 +452,7 @@ pdf_replace_names(gx_device_pdf * pdev, const gs_param_string * from,
452 452
453 size += sname - scan; 453 size += sname - scan;
454 if (pco) { 454 if (pco) {
455 sprintf(ref, " %ld 0 R ", pco->id); 455 gs_sprintf(ref, " %ld 0 R ", pco->id);
456 size += strlen(ref); 456 size += strlen(ref);
457 } 457 }
458 scan = next; 458 scan = next;
@@ -480,7 +480,7 @@ pdf_replace_names(gx_device_pdf * pdev, const gs_param_string * from,
480 memcpy(sto, scan, copy); 480 memcpy(sto, scan, copy);
481 sto += copy; 481 sto += copy;
482 if (pco) { 482 if (pco) {
483 sprintf(ref, " %ld 0 R ", pco->id); 483 gs_sprintf(ref, " %ld 0 R ", pco->id);
484 rlen = strlen(ref); 484 rlen = strlen(ref);
485 memcpy(sto, ref, rlen); 485 memcpy(sto, ref, rlen);
486 sto += rlen; 486 sto += rlen;
diff --git a/gs/devices/vector/gdevpdft.c b/gs/devices/vector/gdevpdft.c
index 12b30ee9a..eaee1a5ee 100644
--- a/gs/devices/vector/gdevpdft.c
+++ b/gs/devices/vector/gdevpdft.c
@@ -63,7 +63,7 @@ pdf_make_soft_mask_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * ppa
63 code = pdf_write_function(pdev, pparams->transfer_function, &id); 63 code = pdf_write_function(pdev, pparams->transfer_function, &id);
64 if (code < 0) 64 if (code < 0)
65 return code; 65 return code;
66 sprintf(buf, " %ld 0 R", id); 66 gs_sprintf(buf, " %ld 0 R", id);
67 code = cos_dict_put_c_key_string(soft_mask_dict, "/TR", (const byte *)buf, strlen(buf)); 67 code = cos_dict_put_c_key_string(soft_mask_dict, "/TR", (const byte *)buf, strlen(buf));
68 if (code < 0) 68 if (code < 0)
69 return code; 69 return code;
@@ -317,7 +317,7 @@ pdf_end_transparency_mask(gs_imager_state * pis, gx_device_pdf * pdev,
317 return 0; 317 return 0;
318 /* We need to update the 'where_used' field, in case we substituted a resource */ 318 /* We need to update the 'where_used' field, in case we substituted a resource */
319 pres->where_used |= pdev->used_mask; 319 pres->where_used |= pdev->used_mask;
320 sprintf(buf, "%ld 0 R", pdf_resource_id(pres)); 320 gs_sprintf(buf, "%ld 0 R", pdf_resource_id(pres));
321 code = cos_dict_put_c_key_string((cos_dict_t *)pdev->pres_soft_mask_dict->object, 321 code = cos_dict_put_c_key_string((cos_dict_t *)pdev->pres_soft_mask_dict->object,
322 "/G", (const byte *)buf, strlen(buf)); 322 "/G", (const byte *)buf, strlen(buf));
323 if (code < 0) 323 if (code < 0)
diff --git a/gs/devices/vector/gdevpdfu.c b/gs/devices/vector/gdevpdfu.c
index 0e6f7d837..38f2ff50b 100644
--- a/gs/devices/vector/gdevpdfu.c
+++ b/gs/devices/vector/gdevpdfu.c
@@ -341,14 +341,14 @@ static int write_tt_encodings(stream *s, bool HaveTrueTypes)
341 char Buffer[256]; 341 char Buffer[256];
342 single_glyph_list_t *entry = (single_glyph_list_t *)&SingleGlyphList; 342 single_glyph_list_t *entry = (single_glyph_list_t *)&SingleGlyphList;
343 343
344 sprintf(Buffer, "/AdobeGlyphList mark\n"); 344 gs_sprintf(Buffer, "/AdobeGlyphList mark\n");
345 stream_write(s, Buffer, strlen(Buffer)); 345 stream_write(s, Buffer, strlen(Buffer));
346 while (entry->Glyph) { 346 while (entry->Glyph) {
347 sprintf(Buffer, "/%s 16#%04x\n", entry->Glyph, entry->Unicode); 347 gs_sprintf(Buffer, "/%s 16#%04x\n", entry->Glyph, entry->Unicode);
348 stream_write(s, Buffer, strlen(Buffer)); 348 stream_write(s, Buffer, strlen(Buffer));
349 entry++; 349 entry++;
350 }; 350 };
351 sprintf(Buffer, ".dicttomark readonly def\n"); 351 gs_sprintf(Buffer, ".dicttomark readonly def\n");
352 stream_write(s, Buffer, strlen(Buffer)); 352 stream_write(s, Buffer, strlen(Buffer));
353 353
354 index = 0; 354 index = 0;
@@ -425,24 +425,24 @@ int ps2write_dsc_header(gx_device_pdf * pdev, int pages)
425 pagecount++; 425 pagecount++;
426 } 426 }
427 } 427 }
428 sprintf(BBox, "%%%%BoundingBox: 0 0 %d %d\n", (int)urx, (int)ury); 428 gs_sprintf(BBox, "%%%%BoundingBox: 0 0 %d %d\n", (int)urx, (int)ury);
429 stream_write(s, (byte *)BBox, strlen(BBox)); 429 stream_write(s, (byte *)BBox, strlen(BBox));
430 sprintf(BBox, "%%%%HiResBoundingBox: 0 0 %.2f %.2f\n", urx, ury); 430 gs_sprintf(BBox, "%%%%HiResBoundingBox: 0 0 %.2f %.2f\n", urx, ury);
431 stream_write(s, (byte *)BBox, strlen(BBox)); 431 stream_write(s, (byte *)BBox, strlen(BBox));
432 } 432 }
433 cre_date_time_len = pdf_get_docinfo_item(pdev, "/CreationDate", cre_date_time, sizeof(cre_date_time) - 1); 433 cre_date_time_len = pdf_get_docinfo_item(pdev, "/CreationDate", cre_date_time, sizeof(cre_date_time) - 1);
434 cre_date_time[cre_date_time_len] = 0; 434 cre_date_time[cre_date_time_len] = 0;
435 sprintf(BBox, "%%%%Creator: %s %d (%s)\n", gs_product, (int)gs_revision, 435 gs_sprintf(BBox, "%%%%Creator: %s %d (%s)\n", gs_product, (int)gs_revision,
436 pdev->dname); 436 pdev->dname);
437 stream_write(s, (byte *)BBox, strlen(BBox)); 437 stream_write(s, (byte *)BBox, strlen(BBox));
438 stream_puts(s, "%%LanguageLevel: 2\n"); 438 stream_puts(s, "%%LanguageLevel: 2\n");
439 sprintf(BBox, "%%%%CreationDate: %s\n", cre_date_time); 439 gs_sprintf(BBox, "%%%%CreationDate: %s\n", cre_date_time);
440 stream_write(s, (byte *)BBox, strlen(BBox)); 440 stream_write(s, (byte *)BBox, strlen(BBox));
441 sprintf(BBox, "%%%%Pages: %d\n", pages); 441 gs_sprintf(BBox, "%%%%Pages: %d\n", pages);
442 stream_write(s, (byte *)BBox, strlen(BBox)); 442 stream_write(s, (byte *)BBox, strlen(BBox));
443 sprintf(BBox, "%%%%EndComments\n"); 443 gs_sprintf(BBox, "%%%%EndComments\n");
444 stream_write(s, (byte *)BBox, strlen(BBox)); 444 stream_write(s, (byte *)BBox, strlen(BBox));
445 sprintf(BBox, "%%%%BeginProlog\n"); 445 gs_sprintf(BBox, "%%%%BeginProlog\n");
446 stream_write(s, (byte *)BBox, strlen(BBox)); 446 stream_write(s, (byte *)BBox, strlen(BBox));
447 if (pdev->params.CompressPages) { 447 if (pdev->params.CompressPages) {
448 /* When CompressEntireFile is true and ASCII85EncodePages is false, 448 /* When CompressEntireFile is true and ASCII85EncodePages is false,
@@ -493,7 +493,7 @@ pdfwrite_pdf_open_document(gx_device_pdf * pdev)
493 pdev->CompressEntireFile = 0; 493 pdev->CompressEntireFile = 0;
494 else { 494 else {
495 stream_write(s, (byte *)"%!\r", 3); 495 stream_write(s, (byte *)"%!\r", 3);
496 sprintf(BBox, "%%%%BoundingBox: 0 0 %d %d\n", width, height); 496 gs_sprintf(BBox, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
497 stream_write(s, (byte *)BBox, strlen(BBox)); 497 stream_write(s, (byte *)BBox, strlen(BBox));
498 if (pdev->params.CompressPages || pdev->CompressEntireFile) { 498 if (pdev->params.CompressPages || pdev->CompressEntireFile) {
499 /* When CompressEntireFile is true and ASCII85EncodePages is false, 499 /* When CompressEntireFile is true and ASCII85EncodePages is false,
@@ -1340,7 +1340,7 @@ void
1340pdf_reserve_object_id(gx_device_pdf * pdev, pdf_resource_t *pres, long id) 1340pdf_reserve_object_id(gx_device_pdf * pdev, pdf_resource_t *pres, long id)
1341{ 1341{
1342 pres->object->id = (id == 0 ? pdf_obj_ref(pdev) : id); 1342 pres->object->id = (id == 0 ? pdf_obj_ref(pdev) : id);
1343 sprintf(pres->rname, "R%ld", pres->object->id); 1343 gs_sprintf(pres->rname, "R%ld", pres->object->id);
1344} 1344}
1345 1345
1346/* Begin an aside (resource, annotation, ...). */ 1346/* Begin an aside (resource, annotation, ...). */
@@ -1807,9 +1807,9 @@ void
1807pdf_store_default_Producer(char buf[PDF_MAX_PRODUCER]) 1807pdf_store_default_Producer(char buf[PDF_MAX_PRODUCER])
1808{ 1808{
1809 if ((gs_revision % 100) == 0) 1809 if ((gs_revision % 100) == 0)
1810 sprintf(buf, "(%s %1.1f)", gs_product, gs_revision / 100.0); 1810 gs_sprintf(buf, "(%s %1.1f)", gs_product, gs_revision / 100.0);
1811 else 1811 else
1812 sprintf(buf, "(%s %1.2f)", gs_product, gs_revision / 100.0); 1812 gs_sprintf(buf, "(%s %1.2f)", gs_product, gs_revision / 100.0);
1813} 1813}
1814 1814
1815/* Write matrix values. */ 1815/* Write matrix values. */
@@ -1856,7 +1856,7 @@ pdf_put_name_chars_1_2(stream *s, const byte *nstr, uint size)
1856 case '[': case ']': 1856 case '[': case ']':
1857 case '{': case '}': 1857 case '{': case '}':
1858 case '/': 1858 case '/':
1859 sprintf(hex, "#%02x", c); 1859 gs_sprintf(hex, "#%02x", c);
1860 stream_puts(s, hex); 1860 stream_puts(s, hex);
1861 break; 1861 break;
1862 case 0: 1862 case 0:
diff --git a/gs/devices/vector/gdevpdfv.c b/gs/devices/vector/gdevpdfv.c
index a81c5d09f..f0b7cf6bd 100644
--- a/gs/devices/vector/gdevpdfv.c
+++ b/gs/devices/vector/gdevpdfv.c
@@ -157,7 +157,7 @@ pdf_pattern(gx_device_pdf *pdev, const gx_drawing_color *pdc,
157 157
158 if (pcd_XObject == 0) 158 if (pcd_XObject == 0)
159 return_error(gs_error_VMerror); 159 return_error(gs_error_VMerror);
160 sprintf(key, "/R%ld", pcs_image->id); 160 gs_sprintf(key, "/R%ld", pcs_image->id);
161 /* This is non-obvious code. Previously we would put the image object (pcs_image) 161 /* This is non-obvious code. Previously we would put the image object (pcs_image)
162 * into the Resources dit. When we come to write out the Resources dict 162 * into the Resources dit. When we come to write out the Resources dict
163 * that code writes a reference (index 0 R) using the ID from the object. 163 * that code writes a reference (index 0 R) using the ID from the object.
@@ -201,7 +201,7 @@ pdf_pattern(gx_device_pdf *pdev, const gx_drawing_color *pdc,
201 { 201 {
202 char buf[MAX_REF_CHARS + 6 + 1]; /* +6 for /R# Do\n */ 202 char buf[MAX_REF_CHARS + 6 + 1]; /* +6 for /R# Do\n */
203 203
204 sprintf(buf, "/R%ld Do\n", pcs_image->id); 204 gs_sprintf(buf, "/R%ld Do\n", pcs_image->id);
205 cos_stream_add_bytes(pcos, (const byte *)buf, strlen(buf)); 205 cos_stream_add_bytes(pcos, (const byte *)buf, strlen(buf));
206 } 206 }
207 207
@@ -596,7 +596,7 @@ pdf_put_linear_shading(cos_dict_t *pscd, const float *Coords,
596 if (Extend[0] | Extend[1]) { 596 if (Extend[0] | Extend[1]) {
597 char extend_str[1 + 5 + 1 + 5 + 1 + 1]; /* [bool bool] */ 597 char extend_str[1 + 5 + 1 + 5 + 1 + 1]; /* [bool bool] */
598 598
599 sprintf(extend_str, "[%s %s]", 599 gs_sprintf(extend_str, "[%s %s]",
600 (Extend[0] ? "true" : "false"), 600 (Extend[0] ? "true" : "false"),
601 (Extend[1] ? "true" : "false")); 601 (Extend[1] ? "true" : "false"));
602 code = cos_dict_put_c_key_string(pscd, "/Extend", 602 code = cos_dict_put_c_key_string(pscd, "/Extend",
diff --git a/gs/devices/vector/gdevpdtb.c b/gs/devices/vector/gdevpdtb.c
index aa7d6e183..69d2c0b57 100644
--- a/gs/devices/vector/gdevpdtb.c
+++ b/gs/devices/vector/gdevpdtb.c
@@ -350,7 +350,7 @@ pdf_base_font_alloc(gx_device_pdf *pdev, pdf_base_font_t **ppbfont,
350 font_name.size -= SUBSET_PREFIX_SIZE; 350 font_name.size -= SUBSET_PREFIX_SIZE;
351 } 351 }
352 } else { 352 } else {
353 sprintf(fnbuf, ".F%lx", (ulong)copied); 353 gs_sprintf(fnbuf, ".F%lx", (ulong)copied);
354 font_name.data = (byte *)fnbuf; 354 font_name.data = (byte *)fnbuf;
355 font_name.size = strlen(fnbuf); 355 font_name.size = strlen(fnbuf);
356 } 356 }
@@ -535,7 +535,7 @@ pdf_adjust_font_name(gx_device_pdf *pdev, long id, pdf_base_font_t *pbfont)
535 size = i + 1; 535 size = i + 1;
536 } 536 }
537 /* Create a unique name. */ 537 /* Create a unique name. */
538 sprintf(suffix, "%c%lx", SUFFIX_CHAR, id); 538 gs_sprintf(suffix, "%c%lx", SUFFIX_CHAR, id);
539 suffix_size = strlen(suffix); 539 suffix_size = strlen(suffix);
540 data = gs_resize_string(pdev->pdf_memory, chars, size, 540 data = gs_resize_string(pdev->pdf_memory, chars, size,
541 size + suffix_size, 541 size + suffix_size,
diff --git a/gs/devices/vector/gdevpdtc.c b/gs/devices/vector/gdevpdtc.c
index 82f876cb3..abb37a5ba 100644
--- a/gs/devices/vector/gdevpdtc.c
+++ b/gs/devices/vector/gdevpdtc.c
@@ -338,7 +338,7 @@ attach_cmap_resource(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
338 strcpy(pdfont->u.type0.Encoding_name, 338 strcpy(pdfont->u.type0.Encoding_name,
339 (pcmap->WMode ? "/Identity-V" : "/Identity-H")); 339 (pcmap->WMode ? "/Identity-V" : "/Identity-H"));
340 else 340 else
341 sprintf(pdfont->u.type0.Encoding_name, "%ld 0 R", 341 gs_sprintf(pdfont->u.type0.Encoding_name, "%ld 0 R",
342 pdf_resource_id(pcmres)); 342 pdf_resource_id(pcmres));
343 pdfont->u.type0.CMapName.data = chars; 343 pdfont->u.type0.CMapName.data = chars;
344 pdfont->u.type0.CMapName.size = size; 344 pdfont->u.type0.CMapName.size = size;
@@ -349,7 +349,7 @@ attach_cmap_resource(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
349 */ 349 */
350 return_error(gs_error_invalidfont); 350 return_error(gs_error_invalidfont);
351 351
352 sprintf(pdfont->u.type0.Encoding_name, "/%s", *pcmn); 352 gs_sprintf(pdfont->u.type0.Encoding_name, "/%s", *pcmn);
353 pdfont->u.type0.CMapName.data = (const byte *)*pcmn; 353 pdfont->u.type0.CMapName.data = (const byte *)*pcmn;
354 pdfont->u.type0.CMapName.size = strlen(*pcmn); 354 pdfont->u.type0.CMapName.size = strlen(*pcmn);
355 pdfont->u.type0.cmap_is_standard = true; 355 pdfont->u.type0.cmap_is_standard = true;
diff --git a/gs/devices/vector/gdevpdtf.c b/gs/devices/vector/gdevpdtf.c
index 5eea15aad..8a06d8ff6 100644
--- a/gs/devices/vector/gdevpdtf.c
+++ b/gs/devices/vector/gdevpdtf.c
@@ -1160,7 +1160,7 @@ pdf_convert_truetype_font(gx_device_pdf *pdev, pdf_resource_t *pres)
1160 if (code < 0) 1160 if (code < 0)
1161 return 0; 1161 return 0;
1162 pdfont->u.cidfont.CIDSystemInfo_id = pdev->IdentityCIDSystemInfo_id; 1162 pdfont->u.cidfont.CIDSystemInfo_id = pdev->IdentityCIDSystemInfo_id;
1163 sprintf(pdfont0->u.type0.Encoding_name, "%ld 0 R", pdf_resource_id(pdev->OneByteIdentityH)); 1163 gs_sprintf(pdfont0->u.type0.Encoding_name, "%ld 0 R", pdf_resource_id(pdev->OneByteIdentityH));
1164 /* Move ToUnicode : */ 1164 /* Move ToUnicode : */
1165 pdfont0->res_ToUnicode = pdfont->res_ToUnicode; pdfont->res_ToUnicode = 0; 1165 pdfont0->res_ToUnicode = pdfont->res_ToUnicode; pdfont->res_ToUnicode = 0;
1166 pdfont0->cmap_ToUnicode = pdfont->cmap_ToUnicode; pdfont->cmap_ToUnicode = 0; 1166 pdfont0->cmap_ToUnicode = pdfont->cmap_ToUnicode; pdfont->cmap_ToUnicode = 0;
diff --git a/gs/devices/vector/gdevpdti.c b/gs/devices/vector/gdevpdti.c
index 97c5ba19c..18efa0863 100644
--- a/gs/devices/vector/gdevpdti.c
+++ b/gs/devices/vector/gdevpdti.c
@@ -1180,7 +1180,7 @@ pdf_add_resource(gx_device_pdf *pdev, cos_dict_t *pcd, const char *key, pdf_reso
1180 if (code < 0) 1180 if (code < 0)
1181 return code; 1181 return code;
1182 } 1182 }
1183 sprintf(buf, "%ld 0 R\n", pres->object->id); 1183 gs_sprintf(buf, "%ld 0 R\n", pres->object->id);
1184 if (v != NULL) { 1184 if (v != NULL) {
1185 if (v->value_type != COS_VALUE_OBJECT && 1185 if (v->value_type != COS_VALUE_OBJECT &&
1186 v->value_type != COS_VALUE_RESOURCE) 1186 v->value_type != COS_VALUE_RESOURCE)
diff --git a/gs/devices/vector/gdevpdtt.c b/gs/devices/vector/gdevpdtt.c
index 795124134..69f6551dc 100644
--- a/gs/devices/vector/gdevpdtt.c
+++ b/gs/devices/vector/gdevpdtt.c
@@ -2766,7 +2766,7 @@ pdf_choose_output_glyph_hame(gx_device_pdf *pdev, pdf_text_enum_t *penum, gs_con
2766 p = (byte *)gs_alloc_string(pdev->pdf_memory, gnstr->size, "pdf_text_set_cache"); 2766 p = (byte *)gs_alloc_string(pdev->pdf_memory, gnstr->size, "pdf_text_set_cache");
2767 if (p == NULL) 2767 if (p == NULL)
2768 return_error(gs_error_VMerror); 2768 return_error(gs_error_VMerror);
2769 sprintf(buf, "g%04x", (unsigned int)(glyph & 0xFFFF)); 2769 gs_sprintf(buf, "g%04x", (unsigned int)(glyph & 0xFFFF));
2770 memcpy(p, buf, 5); 2770 memcpy(p, buf, 5);
2771 gnstr->data = p; 2771 gnstr->data = p;
2772 } 2772 }
diff --git a/gs/devices/vector/gdevpdtw.c b/gs/devices/vector/gdevpdtw.c
index 2725393ce..4ef1ec627 100644
--- a/gs/devices/vector/gdevpdtw.c
+++ b/gs/devices/vector/gdevpdtw.c
@@ -927,7 +927,7 @@ pdf_write_OneByteIdentityH(gx_device_pdf *pdev)
927 code = cos_dict_put_string_copy(pcd, "/CMapName", "/OneByteIdentityH"); 927 code = cos_dict_put_string_copy(pcd, "/CMapName", "/OneByteIdentityH");
928 if (code < 0) 928 if (code < 0)
929 return code; 929 return code;
930 sprintf(buf, "%ld 0 R", pdev->IdentityCIDSystemInfo_id); 930 gs_sprintf(buf, "%ld 0 R", pdev->IdentityCIDSystemInfo_id);
931 code = cos_dict_put_string_copy(pcd, "/CIDSystemInfo", buf); 931 code = cos_dict_put_string_copy(pcd, "/CIDSystemInfo", buf);
932 if (code < 0) 932 if (code < 0)
933 return code; 933 return code;
diff --git a/gs/devices/vector/gdevps.c b/gs/devices/vector/gdevps.c
index 854cf54a0..4c18fb47b 100644
--- a/gs/devices/vector/gdevps.c
+++ b/gs/devices/vector/gdevps.c
@@ -513,7 +513,7 @@ psw_image_write(gx_device_pswrite * pdev, const char *imagestr,
513 const char *op; 513 const char *op;
514 514
515 if (index >= 0) { 515 if (index >= 0) {
516 sprintf(str, "%d%c", index / 26, index % 26 + 'A'); 516 gs_sprintf(str, "%d%c", index / 26, index % 26 + 'A');
517 pprintd2(s, "%d %d ", x, y); 517 pprintd2(s, "%d %d ", x, y);
518 pprints2(s, "%s %s\n", str, imagestr); 518 pprints2(s, "%s %s\n", str, imagestr);
519 if (s->end_status == ERRC) 519 if (s->end_status == ERRC)
@@ -543,12 +543,12 @@ psw_image_write(gx_device_pswrite * pdev, const char *imagestr,
543 }; 543 };
544 544
545 index = image_cache_lookup(pdev, id, width_bits, height, true); 545 index = image_cache_lookup(pdev, id, width_bits, height, true);
546 sprintf(str, "/%d%c", index / 26, index % 26 + 'A'); 546 gs_sprintf(str, "/%d%c", index / 26, index % 26 + 'A');
547 stream_puts(s, str); 547 stream_puts(s, str);
548 if (depth != 1) 548 if (depth != 1)
549 pprintld1(s, " %ld", ((width_bits + 7) >> 3) * (ulong) height); 549 pprintld1(s, " %ld", ((width_bits + 7) >> 3) * (ulong) height);
550 op = cached[encode]; 550 op = cached[encode];
551 sprintf(endstr, "\n%s\n", imagestr); 551 gs_sprintf(endstr, "\n%s\n", imagestr);
552 } 552 }
553 if (s->end_status == ERRC) 553 if (s->end_status == ERRC)
554 return_error(gs_error_ioerror); 554 return_error(gs_error_ioerror);
@@ -1248,7 +1248,7 @@ psw_copy_color(gx_device * dev,
1248 return (*dev_proc(dev, fill_rectangle)) 1248 return (*dev_proc(dev, fill_rectangle))
1249 (dev, x, y, w, h, (bits[0] << 16) + (bits[1] << 8) + bits[2]); 1249 (dev, x, y, w, h, (bits[0] << 16) + (bits[1] << 8) + bits[2]);
1250 } 1250 }
1251 sprintf(op, "%d Ic", depth / 3); /* RGB */ 1251 gs_sprintf(op, "%d Ic", depth / 3); /* RGB */
1252 code = gdev_vector_update_clip_path(vdev, NULL); 1252 code = gdev_vector_update_clip_path(vdev, NULL);
1253 if (code < 0) 1253 if (code < 0)
1254 return code; 1254 return code;
diff --git a/gs/devices/vector/gdevpsf1.c b/gs/devices/vector/gdevpsf1.c
index 63642020a..e552fb886 100644
--- a/gs/devices/vector/gdevpsf1.c
+++ b/gs/devices/vector/gdevpsf1.c
@@ -646,12 +646,12 @@ write_Private(stream *s, gs_font_type1 *pfont,
646 gs_free_object(pfont->memory, SubrsWithMM, "free Subrs record"); 646 gs_free_object(pfont->memory, SubrsWithMM, "free Subrs record");
647 return code; 647 return code;
648 } 648 }
649 sprintf(buf, "dup %d %u -| ", i, code); 649 gs_sprintf(buf, "dup %d %u -| ", i, code);
650 stream_puts(s, buf); 650 stream_puts(s, buf);
651 write_CharString(s, stripped, code); 651 write_CharString(s, stripped, code);
652 gs_free_object(pfont->memory, stripped, "free Subrs copy for OtherSubrs"); 652 gs_free_object(pfont->memory, stripped, "free Subrs copy for OtherSubrs");
653 } else { 653 } else {
654 sprintf(buf, "dup %d %u -| ", i, gdata.bits.size); 654 gs_sprintf(buf, "dup %d %u -| ", i, gdata.bits.size);
655 stream_puts(s, buf); 655 stream_puts(s, buf);
656 write_CharString(s, gdata.bits.data, gdata.bits.size); 656 write_CharString(s, gdata.bits.data, gdata.bits.size);
657 } 657 }
diff --git a/gs/devices/vector/gdevpsf2.c b/gs/devices/vector/gdevpsf2.c
index fcc24a5be..9019a4cec 100644
--- a/gs/devices/vector/gdevpsf2.c
+++ b/gs/devices/vector/gdevpsf2.c
@@ -274,7 +274,7 @@ cff_put_real(cff_writer_t *pcw, floatp f)
274 byte b = 0xff; 274 byte b = 0xff;
275 const char *p; 275 const char *p;
276 276
277 sprintf(str, "%g", f); 277 gs_sprintf(str, "%g", f);
278 sputc(pcw->strm, CD_REAL); 278 sputc(pcw->strm, CD_REAL);
279 for (p = str; ; ++p) { 279 for (p = str; ; ++p) {
280 int digit; 280 int digit;
diff --git a/gs/devices/vector/gdevsvg.c b/gs/devices/vector/gdevsvg.c
index c1cb1877f..5b7c8ec05 100644
--- a/gs/devices/vector/gdevsvg.c
+++ b/gs/devices/vector/gdevsvg.c
@@ -374,22 +374,22 @@ svg_write_header(gx_device_svg *svg)
374 return 1; 374 return 1;
375 375
376 /* write the initial boilerplate */ 376 /* write the initial boilerplate */
377 sprintf(line, "%s\n", XML_DECL); 377 gs_sprintf(line, "%s\n", XML_DECL);
378 /* svg_write(svg, line); */ 378 /* svg_write(svg, line); */
379 sputs(s, (byte *)line, strlen(line), &used); 379 sputs(s, (byte *)line, strlen(line), &used);
380 sprintf(line, "%s\n", SVG_DOCTYPE); 380 gs_sprintf(line, "%s\n", SVG_DOCTYPE);
381 /* svg_write(svg, line); */ 381 /* svg_write(svg, line); */
382 sputs(s, (byte *)line, strlen(line), &used); 382 sputs(s, (byte *)line, strlen(line), &used);
383 sprintf(line, "<svg xmlns='%s' version='%s'", 383 gs_sprintf(line, "<svg xmlns='%s' version='%s'",
384 SVG_XMLNS, SVG_VERSION); 384 SVG_XMLNS, SVG_VERSION);
385 /* svg_write(svg, line); */ 385 /* svg_write(svg, line); */
386 sputs(s, (byte *)line, strlen(line), &used); 386 sputs(s, (byte *)line, strlen(line), &used);
387 sprintf(line, "\n\twidth='%dpt' height='%dpt'>\n", 387 gs_sprintf(line, "\n\twidth='%dpt' height='%dpt'>\n",
388 (int)svg->MediaSize[0], (int)svg->MediaSize[1]); 388 (int)svg->MediaSize[0], (int)svg->MediaSize[1]);
389 sputs(s, (byte *)line, strlen(line), &used); 389 sputs(s, (byte *)line, strlen(line), &used);
390 390
391 /* Scale drawing so our coordinates are in pixels */ 391 /* Scale drawing so our coordinates are in pixels */
392 sprintf(line, "<g transform='scale(%lf,%lf)'>\n", 392 gs_sprintf(line, "<g transform='scale(%lf,%lf)'>\n",
393 72.0 / svg->HWResolution[0], 393 72.0 / svg->HWResolution[0],
394 72.0 / svg->HWResolution[1]); 394 72.0 / svg->HWResolution[1]);
395 /* svg_write(svg, line); */ 395 /* svg_write(svg, line); */
@@ -430,19 +430,19 @@ svg_write_state(gx_device_svg *svg)
430 /* write out the new current state */ 430 /* write out the new current state */
431 svg_write(svg, "<g "); 431 svg_write(svg, "<g ");
432 if (svg->strokecolor != gx_no_color_index) { 432 if (svg->strokecolor != gx_no_color_index) {
433 sprintf(line, " stroke='#%06x'", svg->strokecolor & 0xffffffL); 433 gs_sprintf(line, " stroke='#%06x'", svg->strokecolor & 0xffffffL);
434 svg_write(svg, line); 434 svg_write(svg, line);
435 } else { 435 } else {
436 svg_write(svg, " stroke='none'"); 436 svg_write(svg, " stroke='none'");
437 } 437 }
438 if (svg->fillcolor != gx_no_color_index) { 438 if (svg->fillcolor != gx_no_color_index) {
439 sprintf(line, " fill='#%06x'", svg->fillcolor & 0xffffffL); 439 gs_sprintf(line, " fill='#%06x'", svg->fillcolor & 0xffffffL);
440 svg_write(svg, line); 440 svg_write(svg, line);
441 } else { 441 } else {
442 svg_write(svg, " fill='none'"); 442 svg_write(svg, " fill='none'");
443 } 443 }
444 if (svg->linewidth != 1.0) { 444 if (svg->linewidth != 1.0) {
445 sprintf(line, " stroke-width='%lf'", svg->linewidth); 445 gs_sprintf(line, " stroke-width='%lf'", svg->linewidth);
446 svg_write(svg, line); 446 svg_write(svg, line);
447 } 447 }
448 if (svg->linecap != SVG_DEFAULT_LINECAP) { 448 if (svg->linecap != SVG_DEFAULT_LINECAP) {
@@ -476,7 +476,7 @@ svg_write_state(gx_device_svg *svg)
476 } 476 }
477 } 477 }
478 if (svg->miterlimit != SVG_DEFAULT_MITERLIMIT) { 478 if (svg->miterlimit != SVG_DEFAULT_MITERLIMIT) {
479 sprintf(line, " stroke-miterlimit='%lf'", svg->miterlimit); 479 gs_sprintf(line, " stroke-miterlimit='%lf'", svg->miterlimit);
480 svg_write(svg, line); 480 svg_write(svg, line);
481 } 481 }
482 svg_write(svg, ">\n"); 482 svg_write(svg, ">\n");
@@ -653,7 +653,7 @@ svg_dorect(gx_device_vector *vdev, fixed x0, fixed y0,
653 svg_write(svg, "<clipPath>\n"); 653 svg_write(svg, "<clipPath>\n");
654 } 654 }
655 655
656 sprintf(line, "<rect x='%lf' y='%lf' width='%lf' height='%lf'", 656 gs_sprintf(line, "<rect x='%lf' y='%lf' width='%lf' height='%lf'",
657 fixed2float(x0), fixed2float(y0), 657 fixed2float(x0), fixed2float(y0),
658 fixed2float(x1 - x0), fixed2float(y1 - y0)); 658 fixed2float(x1 - x0), fixed2float(y1 - y0));
659 svg_write(svg, line); 659 svg_write(svg, line);
@@ -714,7 +714,7 @@ svg_moveto(gx_device_vector *vdev, floatp x0, floatp y0,
714 svg_print_path_type(svg, type); 714 svg_print_path_type(svg, type);
715 if_debug0m('_', svg->memory, "\n"); 715 if_debug0m('_', svg->memory, "\n");
716 716
717 sprintf(line, " M%lf,%lf", x, y); 717 gs_sprintf(line, " M%lf,%lf", x, y);
718 svg_write(svg, line); 718 svg_write(svg, line);
719 719
720 return 0; 720 return 0;
@@ -739,7 +739,7 @@ svg_lineto(gx_device_vector *vdev, floatp x0, floatp y0,
739 svg_print_path_type(svg, type); 739 svg_print_path_type(svg, type);
740 if_debug0m('_', svg->memory, "\n"); 740 if_debug0m('_', svg->memory, "\n");
741 741
742 sprintf(line, " L%lf,%lf", x, y); 742 gs_sprintf(line, " L%lf,%lf", x, y);
743 svg_write(svg, line); 743 svg_write(svg, line);
744 744
745 return 0; 745 return 0;
@@ -766,7 +766,7 @@ svg_curveto(gx_device_vector *vdev, floatp x0, floatp y0,
766 svg_print_path_type(svg, type); 766 svg_print_path_type(svg, type);
767 if_debug0m('_', svg->memory, "\n"); 767 if_debug0m('_', svg->memory, "\n");
768 768
769 sprintf(line, " C%lf,%lf %lf,%lf %lf,%lf", x1,y1, x2,y2, x3,y3); 769 gs_sprintf(line, " C%lf,%lf %lf,%lf %lf,%lf", x1,y1, x2,y2, x3,y3);
770 svg_write(svg, line); 770 svg_write(svg, line);
771 771
772 return 0; 772 return 0;
diff --git a/gs/devices/vector/gdevtxtw.c b/gs/devices/vector/gdevtxtw.c
index ac53c7ca6..1ea03454e 100644
--- a/gs/devices/vector/gdevtxtw.c
+++ b/gs/devices/vector/gdevtxtw.c
@@ -633,16 +633,16 @@ static int escaped_Unicode (unsigned short Unicode, char *Buf)
633{ 633{
634 switch (Unicode) 634 switch (Unicode)
635 { 635 {
636 case 0x3C: sprintf(Buf, "&lt;"); break; 636 case 0x3C: gs_sprintf(Buf, "&lt;"); break;
637 case 0x3E: sprintf(Buf, "&gt;"); break; 637 case 0x3E: gs_sprintf(Buf, "&gt;"); break;
638 case 0x26: sprintf(Buf, "&amp;"); break; 638 case 0x26: gs_sprintf(Buf, "&amp;"); break;
639 case 0x22: sprintf(Buf, "&quot;"); break; 639 case 0x22: gs_sprintf(Buf, "&quot;"); break;
640 case 0x27: sprintf(Buf, "&apos;"); break; 640 case 0x27: gs_sprintf(Buf, "&apos;"); break;
641 default: 641 default:
642 if (Unicode >= 32 && Unicode <= 127) 642 if (Unicode >= 32 && Unicode <= 127)
643 sprintf(Buf, "%c", Unicode); 643 gs_sprintf(Buf, "%c", Unicode);
644 else 644 else
645 sprintf(Buf, "&#x%x;", Unicode); 645 gs_sprintf(Buf, "&#x%x;", Unicode);
646 break; 646 break;
647 } 647 }
648 648
@@ -665,13 +665,13 @@ static int decorated_text_output(gx_device_txtwrite_t *tdev)
665 x_entry = tdev->PageData.unsorted_text_list; 665 x_entry = tdev->PageData.unsorted_text_list;
666 while (x_entry) { 666 while (x_entry) {
667 next_x = x_entry->next; 667 next_x = x_entry->next;
668 sprintf(TextBuffer, "<span bbox=\"%0.0f %0.0f %0.0f %0.0f\" font=\"%s\" size=\"%0.4f\">\n", x_entry->start.x, x_entry->start.y, 668 gs_sprintf(TextBuffer, "<span bbox=\"%0.0f %0.0f %0.0f %0.0f\" font=\"%s\" size=\"%0.4f\">\n", x_entry->start.x, x_entry->start.y,
669 x_entry->end.x, x_entry->end.y, x_entry->FontName,x_entry->size); 669 x_entry->end.x, x_entry->end.y, x_entry->FontName,x_entry->size);
670 fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file); 670 fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file);
671 xpos = x_entry->start.x; 671 xpos = x_entry->start.x;
672 for (i=0;i<x_entry->Unicode_Text_Size;i++) { 672 for (i=0;i<x_entry->Unicode_Text_Size;i++) {
673 escaped_Unicode(x_entry->Unicode_Text[i], (char *)&Escaped); 673 escaped_Unicode(x_entry->Unicode_Text[i], (char *)&Escaped);
674 sprintf(TextBuffer, "<char bbox=\"%0.0f %0.0f %0.0f %0.0f\" c=\"%s\">\n", xpos, 674 gs_sprintf(TextBuffer, "<char bbox=\"%0.0f %0.0f %0.0f %0.0f\" c=\"%s\">\n", xpos,
675 x_entry->start.y, xpos + x_entry->Widths[i], x_entry->end.y, Escaped); 675 x_entry->start.y, xpos + x_entry->Widths[i], x_entry->end.y, Escaped);
676 fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file); 676 fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file);
677 xpos += x_entry->Widths[i]; 677 xpos += x_entry->Widths[i];
@@ -788,13 +788,13 @@ static int decorated_text_output(gx_device_txtwrite_t *tdev)
788 fwrite("<line>\n", sizeof(unsigned char), 7, tdev->file); 788 fwrite("<line>\n", sizeof(unsigned char), 7, tdev->file);
789 x_entry = block_line->x_ordered_list; 789 x_entry = block_line->x_ordered_list;
790 while(x_entry) { 790 while(x_entry) {
791 sprintf(TextBuffer, "<span bbox=\"%0.0f %0.0f %0.0f %0.0f\" font=\"%s\" size=\"%0.4f\">\n", x_entry->start.x, x_entry->start.y, 791 gs_sprintf(TextBuffer, "<span bbox=\"%0.0f %0.0f %0.0f %0.0f\" font=\"%s\" size=\"%0.4f\">\n", x_entry->start.x, x_entry->start.y,
792 x_entry->end.x, x_entry->end.y, x_entry->FontName,x_entry->size); 792 x_entry->end.x, x_entry->end.y, x_entry->FontName,x_entry->size);
793 fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file); 793 fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file);
794 xpos = x_entry->start.x; 794 xpos = x_entry->start.x;
795 for (i=0;i<x_entry->Unicode_Text_Size;i++) { 795 for (i=0;i<x_entry->Unicode_Text_Size;i++) {
796 escaped_Unicode(x_entry->Unicode_Text[i], (char *)&Escaped); 796 escaped_Unicode(x_entry->Unicode_Text[i], (char *)&Escaped);
797 sprintf(TextBuffer, "<char bbox=\"%0.0f %0.0f %0.0f %0.0f\" c=\"%s\">\n", xpos, 797 gs_sprintf(TextBuffer, "<char bbox=\"%0.0f %0.0f %0.0f %0.0f\" c=\"%s\">\n", xpos,
798 x_entry->start.y, xpos + x_entry->Widths[i], x_entry->end.y, Escaped); 798 x_entry->start.y, xpos + x_entry->Widths[i], x_entry->end.y, Escaped);
799 fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file); 799 fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file);
800 xpos += x_entry->Widths[i]; 800 xpos += x_entry->Widths[i];
diff --git a/gs/devices/vector/gdevxps.c b/gs/devices/vector/gdevxps.c
index cf5e310fa..60439effa 100644
--- a/gs/devices/vector/gdevxps.c
+++ b/gs/devices/vector/gdevxps.c
@@ -679,7 +679,7 @@ write_str_to_current_page(gx_device_xps *xps, const char *str)
679 char buf[128]; /* easily enough to accommodate the string and a page number */ 679 char buf[128]; /* easily enough to accommodate the string and a page number */
680 680
681 /* we're one ahead of the page count */ 681 /* we're one ahead of the page count */
682 int code = sprintf(buf, page_template, xps->page_count+1); 682 int code = gs_sprintf(buf, page_template, xps->page_count+1);
683 if (code < 0) 683 if (code < 0)
684 return gs_rethrow_code(code); 684 return gs_rethrow_code(code);
685 685
@@ -829,7 +829,7 @@ xps_beginpage(gx_device_vector *vdev)
829 { 829 {
830 const char *template = "<PageContent Source=\"Pages/%d.fpage\" />"; 830 const char *template = "<PageContent Source=\"Pages/%d.fpage\" />";
831 /* Note page count is 1 less than the current page */ 831 /* Note page count is 1 less than the current page */
832 code = sprintf(buf, template, xps->page_count + 1); 832 code = gs_sprintf(buf, template, xps->page_count + 1);
833 if (code < 0) 833 if (code < 0)
834 return gs_rethrow_code(code); 834 return gs_rethrow_code(code);
835 835
@@ -843,7 +843,7 @@ xps_beginpage(gx_device_vector *vdev)
843 { 843 {
844 const char *page_size_template = "<FixedPage Width=\"%d\" Height=\"%d\" " 844 const char *page_size_template = "<FixedPage Width=\"%d\" Height=\"%d\" "
845 "xmlns=\"http://schemas.microsoft.com/xps/2005/06\" xml:lang=\"en-US\">\n"; 845 "xmlns=\"http://schemas.microsoft.com/xps/2005/06\" xml:lang=\"en-US\">\n";
846 code = sprintf(buf, page_size_template, 846 code = gs_sprintf(buf, page_size_template,
847 (int)(xps->MediaSize[0] * 4.0/3.0), /* pts -> 1/96 inch */ 847 (int)(xps->MediaSize[0] * 4.0/3.0), /* pts -> 1/96 inch */
848 (int)(xps->MediaSize[1] * 4.0/3.0)); 848 (int)(xps->MediaSize[1] * 4.0/3.0));
849 if (code < 0) 849 if (code < 0)
@@ -854,7 +854,7 @@ xps_beginpage(gx_device_vector *vdev)
854 } 854 }
855 { 855 {
856 const char *canvas_template = "<Canvas RenderTransform=\"%g,%g,%g,%g,%g,%g\">\n"; 856 const char *canvas_template = "<Canvas RenderTransform=\"%g,%g,%g,%g,%g,%g\">\n";
857 code = sprintf(buf, canvas_template, 857 code = gs_sprintf(buf, canvas_template,
858 96.0/xps->HWResolution[0], 0.0, 0.0, 858 96.0/xps->HWResolution[0], 0.0, 0.0,
859 96.0/xps->HWResolution[1], 0.0, 0.0); 859 96.0/xps->HWResolution[1], 0.0, 0.0);
860 if (code < 0) 860 if (code < 0)
@@ -991,7 +991,7 @@ xps_dorect(gx_device_vector *vdev, fixed x0, fixed y0,
991 /* NB - F0 should be changed for a different winding type */ 991 /* NB - F0 should be changed for a different winding type */
992 fmt = "Fill=\"#%06X\" Data=\"M %g, %g L %g, %g %g, %g %g, %g Z\" "; 992 fmt = "Fill=\"#%06X\" Data=\"M %g, %g L %g, %g %g, %g %g, %g Z\" ";
993 c = xps->fillcolor & 0xffffffL; 993 c = xps->fillcolor & 0xffffffL;
994 sprintf(line, fmt, c, 994 gs_sprintf(line, fmt, c,
995 fixed2float(x0), fixed2float(y0), 995 fixed2float(x0), fixed2float(y0),
996 fixed2float(x0), fixed2float(y1), 996 fixed2float(x0), fixed2float(y1),
997 fixed2float(x1), fixed2float(y1), 997 fixed2float(x1), fixed2float(y1),
@@ -999,7 +999,7 @@ xps_dorect(gx_device_vector *vdev, fixed x0, fixed y0,
999 } else { 999 } else {
1000 fmt = "Stroke=\"#%06X\" Data=\"M %g, %g L %g, %g %g, %g %g, %g Z\" "; 1000 fmt = "Stroke=\"#%06X\" Data=\"M %g, %g L %g, %g %g, %g %g, %g Z\" ";
1001 c = xps->strokecolor & 0xffffffL; 1001 c = xps->strokecolor & 0xffffffL;
1002 sprintf(line, fmt, c, 1002 gs_sprintf(line, fmt, c,
1003 fixed2float(x0), fixed2float(y0), 1003 fixed2float(x0), fixed2float(y0),
1004 fixed2float(x0), fixed2float(y1), 1004 fixed2float(x0), fixed2float(y1),
1005 fixed2float(x1), fixed2float(y1), 1005 fixed2float(x1), fixed2float(y1),
@@ -1011,7 +1011,7 @@ xps_dorect(gx_device_vector *vdev, fixed x0, fixed y0,
1011 if (type & gx_path_type_stroke) { 1011 if (type & gx_path_type_stroke) {
1012 /* NB format width. */ 1012 /* NB format width. */
1013 fmt = "StrokeThickness=\"%g\" "; 1013 fmt = "StrokeThickness=\"%g\" ";
1014 sprintf(line, fmt, xps->linewidth); 1014 gs_sprintf(line, fmt, xps->linewidth);
1015 write_str_to_current_page(xps, line); 1015 write_str_to_current_page(xps, line);
1016 } 1016 }
1017 /* end and close NB \n not necessary. */ 1017 /* end and close NB \n not necessary. */
@@ -1070,7 +1070,7 @@ xps_beginpath(gx_device_vector *vdev, gx_path_type_t type)
1070 else 1070 else
1071 fmt = "Stroke=\"#%06X\" Data=\""; 1071 fmt = "Stroke=\"#%06X\" Data=\"";
1072 1072
1073 sprintf(line, fmt, c); 1073 gs_sprintf(line, fmt, c);
1074 1074
1075 write_str_to_current_page(xps, line); 1075 write_str_to_current_page(xps, line);
1076 1076
@@ -1094,7 +1094,7 @@ xps_moveto(gx_device_vector *vdev, floatp x0, floatp y0,
1094 return 0; 1094 return 0;
1095 } 1095 }
1096 1096
1097 sprintf(line, " M %g,%g", x, y); 1097 gs_sprintf(line, " M %g,%g", x, y);
1098 write_str_to_current_page(xps, line); 1098 write_str_to_current_page(xps, line);
1099 if_debug1m('_', xps->memory, "xps_moveto %s", line); 1099 if_debug1m('_', xps->memory, "xps_moveto %s", line);
1100 return 0; 1100 return 0;
@@ -1114,7 +1114,7 @@ xps_lineto(gx_device_vector *vdev, floatp x0, floatp y0,
1114 gs_warn1("xps_lineto: type not supported %x\n", type); 1114 gs_warn1("xps_lineto: type not supported %x\n", type);
1115 return 0; 1115 return 0;
1116 } 1116 }
1117 sprintf(line, " L %g,%g", x, y); 1117 gs_sprintf(line, " L %g,%g", x, y);
1118 write_str_to_current_page(xps, line); 1118 write_str_to_current_page(xps, line);
1119 if_debug1m('_', xps->memory, "xps_lineto %s\n", line); 1119 if_debug1m('_', xps->memory, "xps_lineto %s\n", line);
1120 return 0; 1120 return 0;
@@ -1134,7 +1134,7 @@ xps_curveto(gx_device_vector *vdev, floatp x0, floatp y0,
1134 return 0; 1134 return 0;
1135 } 1135 }
1136 1136
1137 sprintf(line, " C %g,%g %g,%g %g,%g", x1, y1, 1137 gs_sprintf(line, " C %g,%g %g,%g %g,%g", x1, y1,
1138 x2,y2,x3,y3); 1138 x2,y2,x3,y3);
1139 write_str_to_current_page(xps,line); 1139 write_str_to_current_page(xps,line);
1140 if_debug1m('_', xps->memory, "xps_curveto %s\n", line); 1140 if_debug1m('_', xps->memory, "xps_curveto %s\n", line);
@@ -1176,7 +1176,7 @@ xps_endpath(gx_device_vector *vdev, gx_path_type_t type)
1176 if (type & gx_path_type_stroke) { 1176 if (type & gx_path_type_stroke) {
1177 /* NB format width. */ 1177 /* NB format width. */
1178 fmt = "\" StrokeThickness=\"%g\" />\n"; 1178 fmt = "\" StrokeThickness=\"%g\" />\n";
1179 sprintf(line, fmt, xps->linewidth); 1179 gs_sprintf(line, fmt, xps->linewidth);
1180 write_str_to_current_page(xps, line); 1180 write_str_to_current_page(xps, line);
1181 } else { /* fill */ 1181 } else { /* fill */
1182 /* close the path data attribute */ 1182 /* close the path data attribute */
diff --git a/gs/psi/dmmain.c b/gs/psi/dmmain.c
index be30abd79..3edad6bce 100644
--- a/gs/psi/dmmain.c
+++ b/gs/psi/dmmain.c
@@ -644,8 +644,8 @@ void main(void)
644 argv[1] = ddevice; 644 argv[1] = ddevice;
645 argv[2] = dformat; 645 argv[2] = dformat;
646 646
647 sprintf(ddevice, "-sDEVICE=display"); 647 gs_sprintf(ddevice, "-sDEVICE=display");
648 sprintf(dformat, "-dDisplayFormat=%d", display_format); 648 gs_sprintf(dformat, "-dDisplayFormat=%d", display_format);
649 649
650 /* Run Ghostscript */ 650 /* Run Ghostscript */
651 if (gsapi_new_instance(&instance, NULL) < 0) 651 if (gsapi_new_instance(&instance, NULL) < 0)
diff --git a/gs/psi/dpmain.c b/gs/psi/dpmain.c
index d607db5f5..2ed49594d 100644
--- a/gs/psi/dpmain.c
+++ b/gs/psi/dpmain.c
@@ -100,9 +100,9 @@ gs_free_dll(void)
100 return TRUE; 100 return TRUE;
101 rc = DosFreeModule(gsdll.hmodule); 101 rc = DosFreeModule(gsdll.hmodule);
102 if (rc) { 102 if (rc) {
103 sprintf(buf, "DosFreeModule returns %d\n", rc); 103 gs_sprintf(buf, "DosFreeModule returns %d\n", rc);
104 gs_addmess(buf); 104 gs_addmess(buf);
105 sprintf(buf, "Unloaded GSDLL\n\n"); 105 gs_sprintf(buf, "Unloaded GSDLL\n\n");
106 gs_addmess(buf); 106 gs_addmess(buf);
107 } 107 }
108 return !rc; 108 return !rc;
@@ -150,7 +150,7 @@ gs_load_dll(void)
150 dllname = szDllName; 150 dllname = szDllName;
151#ifdef DEBUG 151#ifdef DEBUG
152 if (debug) { 152 if (debug) {
153 sprintf(buf, "Trying to load %s\n", dllname); 153 gs_sprintf(buf, "Trying to load %s\n", dllname);
154 gs_addmess(buf); 154 gs_addmess(buf);
155 } 155 }
156#endif 156#endif
@@ -172,7 +172,7 @@ gs_load_dll(void)
172 dllname = fullname; 172 dllname = fullname;
173#ifdef DEBUG 173#ifdef DEBUG
174 if (debug) { 174 if (debug) {
175 sprintf(buf, "Trying to load %s\n", dllname); 175 gs_sprintf(buf, "Trying to load %s\n", dllname);
176 gs_addmess(buf); 176 gs_addmess(buf);
177 } 177 }
178#endif 178#endif
@@ -183,7 +183,7 @@ gs_load_dll(void)
183 dllname = shortname; 183 dllname = shortname;
184#ifdef DEBUG 184#ifdef DEBUG
185 if (debug) { 185 if (debug) {
186 sprintf(buf, "Trying to load %s\n", dllname); 186 gs_sprintf(buf, "Trying to load %s\n", dllname);
187 gs_addmess(buf); 187 gs_addmess(buf);
188 } 188 }
189#endif 189#endif
@@ -197,21 +197,21 @@ gs_load_dll(void)
197#endif 197#endif
198 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_REVISION", 198 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_REVISION",
199 (PFN *) (&gsdll.revision))) != 0) { 199 (PFN *) (&gsdll.revision))) != 0) {
200 sprintf(buf, "Can't find GSAPI_REVISION, rc = %d\n", rc); 200 gs_sprintf(buf, "Can't find GSAPI_REVISION, rc = %d\n", rc);
201 gs_addmess(buf); 201 gs_addmess(buf);
202 gs_load_dll_cleanup(); 202 gs_load_dll_cleanup();
203 return FALSE; 203 return FALSE;
204 } 204 }
205 /* check DLL version */ 205 /* check DLL version */
206 if (gsdll.revision(&rv, sizeof(rv)) != 0) { 206 if (gsdll.revision(&rv, sizeof(rv)) != 0) {
207 sprintf(buf, "Unable to identify Ghostscript DLL revision - it must be newer than needed.\n"); 207 gs_sprintf(buf, "Unable to identify Ghostscript DLL revision - it must be newer than needed.\n");
208 gs_addmess(buf); 208 gs_addmess(buf);
209 gs_load_dll_cleanup(); 209 gs_load_dll_cleanup();
210 return FALSE; 210 return FALSE;
211 } 211 }
212 212
213 if (rv.revision != GS_REVISION) { 213 if (rv.revision != GS_REVISION) {
214 sprintf(buf, "Wrong version of DLL found.\n Found version %ld\n Need version %ld\n", rv.revision, (long)GS_REVISION); 214 gs_sprintf(buf, "Wrong version of DLL found.\n Found version %ld\n Need version %ld\n", rv.revision, (long)GS_REVISION);
215 gs_addmess(buf); 215 gs_addmess(buf);
216 gs_load_dll_cleanup(); 216 gs_load_dll_cleanup();
217 return FALSE; 217 return FALSE;
@@ -219,35 +219,35 @@ gs_load_dll(void)
219 219
220 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_NEW_INSTANCE", 220 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_NEW_INSTANCE",
221 (PFN *) (&gsdll.new_instance))) != 0) { 221 (PFN *) (&gsdll.new_instance))) != 0) {
222 sprintf(buf, "Can't find GSAPI_NEW_INSTANCE, rc = %d\n", rc); 222 gs_sprintf(buf, "Can't find GSAPI_NEW_INSTANCE, rc = %d\n", rc);
223 gs_addmess(buf); 223 gs_addmess(buf);
224 gs_load_dll_cleanup(); 224 gs_load_dll_cleanup();
225 return FALSE; 225 return FALSE;
226 } 226 }
227 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_DELETE_INSTANCE", 227 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_DELETE_INSTANCE",
228 (PFN *) (&gsdll.delete_instance))) != 0) { 228 (PFN *) (&gsdll.delete_instance))) != 0) {
229 sprintf(buf, "Can't find GSAPI_DELETE_INSTANCE, rc = %d\n", rc); 229 gs_sprintf(buf, "Can't find GSAPI_DELETE_INSTANCE, rc = %d\n", rc);
230 gs_addmess(buf); 230 gs_addmess(buf);
231 gs_load_dll_cleanup(); 231 gs_load_dll_cleanup();
232 return FALSE; 232 return FALSE;
233 } 233 }
234 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_SET_STDIO", 234 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_SET_STDIO",
235 (PFN *) (&gsdll.set_stdio))) != 0) { 235 (PFN *) (&gsdll.set_stdio))) != 0) {
236 sprintf(buf, "Can't find GSAPI_SET_STDIO, rc = %d\n", rc); 236 gs_sprintf(buf, "Can't find GSAPI_SET_STDIO, rc = %d\n", rc);
237 gs_addmess(buf); 237 gs_addmess(buf);
238 gs_load_dll_cleanup(); 238 gs_load_dll_cleanup();
239 return FALSE; 239 return FALSE;
240 } 240 }
241 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_SET_DISPLAY_CALLBACK", 241 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_SET_DISPLAY_CALLBACK",
242 (PFN *) (&gsdll.set_display_callback))) != 0) { 242 (PFN *) (&gsdll.set_display_callback))) != 0) {
243 sprintf(buf, "Can't find GSAPI_SET_DISPLAY_CALLBACK, rc = %d\n", rc); 243 gs_sprintf(buf, "Can't find GSAPI_SET_DISPLAY_CALLBACK, rc = %d\n", rc);
244 gs_addmess(buf); 244 gs_addmess(buf);
245 gs_load_dll_cleanup(); 245 gs_load_dll_cleanup();
246 return FALSE; 246 return FALSE;
247 } 247 }
248 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_SET_POLL", 248 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_SET_POLL",
249 (PFN *) (&gsdll.set_poll))) != 0) { 249 (PFN *) (&gsdll.set_poll))) != 0) {
250 sprintf(buf, "Can't find GSAPI_SET_POLL, rc = %d\n", rc); 250 gs_sprintf(buf, "Can't find GSAPI_SET_POLL, rc = %d\n", rc);
251 gs_addmess(buf); 251 gs_addmess(buf);
252 gs_load_dll_cleanup(); 252 gs_load_dll_cleanup();
253 return FALSE; 253 return FALSE;
@@ -255,27 +255,27 @@ gs_load_dll(void)
255 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, 255 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0,
256 "GSAPI_INIT_WITH_ARGS", 256 "GSAPI_INIT_WITH_ARGS",
257 (PFN *) (&gsdll.init_with_args))) != 0) { 257 (PFN *) (&gsdll.init_with_args))) != 0) {
258 sprintf(buf, "Can't find GSAPI_INIT_WITH_ARGS, rc = %d\n", rc); 258 gs_sprintf(buf, "Can't find GSAPI_INIT_WITH_ARGS, rc = %d\n", rc);
259 gs_addmess(buf); 259 gs_addmess(buf);
260 gs_load_dll_cleanup(); 260 gs_load_dll_cleanup();
261 return FALSE; 261 return FALSE;
262 } 262 }
263 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_RUN_STRING", 263 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_RUN_STRING",
264 (PFN *) (&gsdll.run_string))) != 0) { 264 (PFN *) (&gsdll.run_string))) != 0) {
265 sprintf(buf, "Can't find GSAPI_RUN_STRING, rc = %d\n", rc); 265 gs_sprintf(buf, "Can't find GSAPI_RUN_STRING, rc = %d\n", rc);
266 gs_addmess(buf); 266 gs_addmess(buf);
267 gs_load_dll_cleanup(); 267 gs_load_dll_cleanup();
268 return FALSE; 268 return FALSE;
269 } 269 }
270 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_EXIT", 270 if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_EXIT",
271 (PFN *) (&gsdll.exit))) != 0) { 271 (PFN *) (&gsdll.exit))) != 0) {
272 sprintf(buf, "Can't find GSAPI_EXIT, rc = %d\n", rc); 272 gs_sprintf(buf, "Can't find GSAPI_EXIT, rc = %d\n", rc);
273 gs_addmess(buf); 273 gs_addmess(buf);
274 gs_load_dll_cleanup(); 274 gs_load_dll_cleanup();
275 return FALSE; 275 return FALSE;
276 } 276 }
277 } else { 277 } else {
278 sprintf(buf, "Can't load Ghostscript DLL %s \nDosLoadModule rc = %d\n", 278 gs_sprintf(buf, "Can't load Ghostscript DLL %s \nDosLoadModule rc = %d\n",
279 szDllName, rc); 279 szDllName, rc);
280 gs_addmess(buf); 280 gs_addmess(buf);
281 gs_load_dll_cleanup(); 281 gs_load_dll_cleanup();
@@ -373,10 +373,10 @@ static int run_gspmdrv(IMAGE *img)
373 if (debug) 373 if (debug)
374 fprintf(stdout, "run_gspmdrv: starting\n"); 374 fprintf(stdout, "run_gspmdrv: starting\n");
375#endif 375#endif
376 sprintf(id, ID_NAME, img->pid, (ULONG)img->device); 376 gs_sprintf(id, ID_NAME, img->pid, (ULONG)img->device);
377 377
378 /* Create termination queue - used to find out when gspmdrv terminates */ 378 /* Create termination queue - used to find out when gspmdrv terminates */
379 sprintf(term_queue_name, "\\QUEUES\\TERMQ_%s", id); 379 gs_sprintf(term_queue_name, "\\QUEUES\\TERMQ_%s", id);
380 if (DosCreateQueue(&(img->term_queue), QUE_FIFO, term_queue_name)) { 380 if (DosCreateQueue(&(img->term_queue), QUE_FIFO, term_queue_name)) {
381 fprintf(stdout, "run_gspmdrv: failed to create termination queue\n"); 381 fprintf(stdout, "run_gspmdrv: failed to create termination queue\n");
382 return e_limitcheck; 382 return e_limitcheck;
@@ -404,7 +404,7 @@ static int run_gspmdrv(IMAGE *img)
404 /* arguments are: */ 404 /* arguments are: */
405 /* (1) -d (display) option */ 405 /* (1) -d (display) option */
406 /* (2) id string */ 406 /* (2) id string */
407 sprintf(arg, "-d %s", id); 407 gs_sprintf(arg, "-d %s", id);
408 408
409 /* because gspmdrv.exe is a different EXE type to gs.exe, 409 /* because gspmdrv.exe is a different EXE type to gs.exe,
410 * we must use start session not DosExecPgm() */ 410 * we must use start session not DosExecPgm() */
@@ -592,17 +592,17 @@ int display_open(void *handle, void *device)
592 return e_limitcheck; 592 return e_limitcheck;
593 } 593 }
594 img->pid = pppib->pib_ulppid; /* use parent (CMD.EXE) pid */ 594 img->pid = pppib->pib_ulppid; /* use parent (CMD.EXE) pid */
595 sprintf(id, ID_NAME, img->pid, (ULONG) img->device); 595 gs_sprintf(id, ID_NAME, img->pid, (ULONG) img->device);
596 596
597 /* Create update event semaphore */ 597 /* Create update event semaphore */
598 sprintf(name, SYNC_NAME, id); 598 gs_sprintf(name, SYNC_NAME, id);
599 if (DosCreateEventSem(name, &(img->sync_event), 0, FALSE)) { 599 if (DosCreateEventSem(name, &(img->sync_event), 0, FALSE)) {
600 fprintf(stdout, "display_open: failed to create event semaphore %s\n", name); 600 fprintf(stdout, "display_open: failed to create event semaphore %s\n", name);
601 return e_limitcheck; 601 return e_limitcheck;
602 } 602 }
603 /* Create mutex - used for preventing gspmdrv from accessing */ 603 /* Create mutex - used for preventing gspmdrv from accessing */
604 /* bitmap while we are changing the bitmap size. Initially unowned. */ 604 /* bitmap while we are changing the bitmap size. Initially unowned. */
605 sprintf(name, MUTEX_NAME, id); 605 gs_sprintf(name, MUTEX_NAME, id);
606 if (DosCreateMutexSem(name, &(img->bmp_mutex), 0, FALSE)) { 606 if (DosCreateMutexSem(name, &(img->bmp_mutex), 0, FALSE)) {
607 DosCloseEventSem(img->sync_event); 607 DosCloseEventSem(img->sync_event);
608 fprintf(stdout, "display_open: failed to create mutex semaphore %s\n", name); 608 fprintf(stdout, "display_open: failed to create mutex semaphore %s\n", name);
@@ -612,7 +612,7 @@ int display_open(void *handle, void *device)
612 /* Shared memory is common to all processes so we don't want to 612 /* Shared memory is common to all processes so we don't want to
613 * allocate too much. 613 * allocate too much.
614 */ 614 */
615 sprintf(name, SHARED_NAME, id); 615 gs_sprintf(name, SHARED_NAME, id);
616 if (DosAllocSharedMem((PPVOID) & img->bitmap, name, 616 if (DosAllocSharedMem((PPVOID) & img->bitmap, name,
617 13 * 1024 * 1024, PAG_READ | PAG_WRITE)) { 617 13 * 1024 * 1024, PAG_READ | PAG_WRITE)) {
618 fprintf(stdout, "display_open: failed allocating shared BMP memory %s\n", name); 618 fprintf(stdout, "display_open: failed allocating shared BMP memory %s\n", name);
@@ -1020,7 +1020,7 @@ main(int argc, char *argv[])
1020 else if (depth >= 4) 1020 else if (depth >= 4)
1021 format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | 1021 format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE |
1022 DISPLAY_DEPTH_4 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST; 1022 DISPLAY_DEPTH_4 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
1023 sprintf(dformat, "-dDisplayFormat=%d", format); 1023 gs_sprintf(dformat, "-dDisplayFormat=%d", format);
1024 } 1024 }
1025 nargc = argc + 1; 1025 nargc = argc + 1;
1026 1026
diff --git a/gs/psi/dscparse.c b/gs/psi/dscparse.c
index fcc7e628c..46e5d69eb 100644
--- a/gs/psi/dscparse.c
+++ b/gs/psi/dscparse.c
@@ -38,7 +38,7 @@
38 % %%ViewingOrientation: xx xy yx yy 38 % %%ViewingOrientation: xx xy yx yy
39*/ 39*/
40 40
41#include <stdio.h> /* for sprintf(), not file I/O */ 41#include <stdio_.h> /* for sprintf(), not file I/O */
42#include <stdlib.h> 42#include <stdlib.h>
43#include <string.h> 43#include <string.h>
44#include <ctype.h> 44#include <ctype.h>
@@ -584,7 +584,7 @@ dsc_fixup(CDSC *dsc)
584 /* make sure all pages have a label */ 584 /* make sure all pages have a label */
585 for (i=0; i<dsc->page_count; i++) { 585 for (i=0; i<dsc->page_count; i++) {
586 if (strlen(dsc->page[i].label) == 0) { 586 if (strlen(dsc->page[i].label) == 0) {
587 sprintf(buf, "%d", i+1); 587 gs_sprintf(buf, "%d", i+1);
588 if ((dsc->page[i].label = dsc_alloc_string(dsc, buf, (int)strlen(buf))) 588 if ((dsc->page[i].label = dsc_alloc_string(dsc, buf, (int)strlen(buf)))
589 == (char *)NULL) 589 == (char *)NULL)
590 return CDSC_ERROR; /* no memory */ 590 return CDSC_ERROR; /* no memory */
@@ -1178,7 +1178,7 @@ dsc_unknown(CDSC *dsc)
1178 if (dsc->debug_print_fn) { 1178 if (dsc->debug_print_fn) {
1179 char line[DSC_LINE_LENGTH]; 1179 char line[DSC_LINE_LENGTH];
1180 unsigned int length = min(DSC_LINE_LENGTH-1, dsc->line_length); 1180 unsigned int length = min(DSC_LINE_LENGTH-1, dsc->line_length);
1181 sprintf(line, "Unknown in %s section at line %d:\n ", 1181 gs_sprintf(line, "Unknown in %s section at line %d:\n ",
1182 dsc_scan_section_name[dsc->scan_section], dsc->line_count); 1182 dsc_scan_section_name[dsc->scan_section], dsc->line_count);
1183 dsc_debug_print(dsc, line); 1183 dsc_debug_print(dsc, line);
1184 strncpy(line, dsc->line, length); 1184 strncpy(line, dsc->line, length);
@@ -2673,7 +2673,7 @@ dsc_check_match_prompt(CDSC *dsc, const char *str, int count)
2673 strncpy(buf, dsc->line, dsc->line_length); 2673 strncpy(buf, dsc->line, dsc->line_length);
2674 buf[dsc->line_length] = '\0'; 2674 buf[dsc->line_length] = '\0';
2675 } 2675 }
2676 sprintf(buf+strlen(buf), "\n%%%%Begin%.40s: / %%%%End%.40s\n", str, str); 2676 gs_sprintf(buf+strlen(buf), "\n%%%%Begin%.40s: / %%%%End%.40s\n", str, str);
2677 return dsc_error(dsc, CDSC_MESSAGE_BEGIN_END, buf, (int)strlen(buf)); 2677 return dsc_error(dsc, CDSC_MESSAGE_BEGIN_END, buf, (int)strlen(buf));
2678 } 2678 }
2679 return CDSC_RESPONSE_CANCEL; 2679 return CDSC_RESPONSE_CANCEL;
diff --git a/gs/psi/dwimg.c b/gs/psi/dwimg.c
index 5e0833e08..d71bf23ca 100644
--- a/gs/psi/dwimg.c
+++ b/gs/psi/dwimg.c
@@ -36,6 +36,11 @@
36 36
37#define STRICT 37#define STRICT
38#include <windows.h> 38#include <windows.h>
39
40
41/* prevent gp.h redefining sprintf */
42#define sprintf sprintf
43
39#include "stdio_.h" 44#include "stdio_.h"
40 45
41#include "dwres.h" 46#include "dwres.h"
diff --git a/gs/psi/dwmainc.c b/gs/psi/dwmainc.c
index 317bd40b9..679185cd7 100644
--- a/gs/psi/dwmainc.c
+++ b/gs/psi/dwmainc.c
@@ -13,6 +13,8 @@
13 CA 94903, U.S.A., +1(415)492-9861, for further information. 13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14*/ 14*/
15 15
16/* prevent gp.h redefining sprintf */
17#define sprintf sprintf
16 18
17/* dwmainc.c */ 19/* dwmainc.c */
18 20
diff --git a/gs/psi/dxmain.c b/gs/psi/dxmain.c
index 6d650a7e4..9dc4dca8a 100644
--- a/gs/psi/dxmain.c
+++ b/gs/psi/dxmain.c
@@ -1160,7 +1160,7 @@ int main(int argc, char *argv[])
1160 use_gui = gtk_init_check(&argc, &argv); 1160 use_gui = gtk_init_check(&argc, &argv);
1161 1161
1162 /* insert display device parameters as first arguments */ 1162 /* insert display device parameters as first arguments */
1163 sprintf(dformat, "-dDisplayFormat=%d", 1163 gs_sprintf(dformat, "-dDisplayFormat=%d",
1164 DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 1164 DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
1165 DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST); 1165 DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST);
1166 nargc = argc + 1; 1166 nargc = argc + 1;
diff --git a/gs/psi/int.mak b/gs/psi/int.mak
index ef378bc70..35830bae4 100644
--- a/gs/psi/int.mak
+++ b/gs/psi/int.mak
@@ -651,7 +651,7 @@ $(PSOBJ)zdscpars.$(OBJ) : $(PSSRC)zdscpars.c $(GH) $(memory__h) $(string__h)\
651 $(gsstruct_h) 651 $(gsstruct_h)
652 $(PSCC) $(PSO_)zdscpars.$(OBJ) $(C_) $(PSSRC)zdscpars.c 652 $(PSCC) $(PSO_)zdscpars.$(OBJ) $(C_) $(PSSRC)zdscpars.c
653 653
654$(PSOBJ)dscparse.$(OBJ) : $(PSSRC)dscparse.c $(dscparse_h) 654$(PSOBJ)dscparse.$(OBJ) : $(PSSRC)dscparse.c $(dscparse_h) $(stdio__h)
655 $(PSCC) $(PSO_)dscparse.$(OBJ) $(C_) $(PSSRC)dscparse.c 655 $(PSCC) $(PSO_)dscparse.$(OBJ) $(C_) $(PSSRC)dscparse.c
656 656
657dscparse_=$(PSOBJ)zdscpars.$(OBJ) $(PSOBJ)dscparse.$(OBJ) 657dscparse_=$(PSOBJ)zdscpars.$(OBJ) $(PSOBJ)dscparse.$(OBJ)
diff --git a/gs/psi/iparam.c b/gs/psi/iparam.c
index 8e1b402ab..559b9b84b 100644
--- a/gs/psi/iparam.c
+++ b/gs/psi/iparam.c
@@ -65,7 +65,7 @@ ref_to_key(const ref * pref, gs_param_key_t * key, iparam_list *plist)
65 int len; 65 int len;
66 byte *buf; 66 byte *buf;
67 67
68 sprintf(istr, "%"PRIpsint, pref->value.intval); 68 gs_sprintf(istr, "%"PRIpsint, pref->value.intval);
69 len = strlen(istr); 69 len = strlen(istr);
70 /* GC will take care of freeing this: */ 70 /* GC will take care of freeing this: */
71 buf = gs_alloc_string(plist->memory, len, "ref_to_key"); 71 buf = gs_alloc_string(plist->memory, len, "ref_to_key");
diff --git a/gs/psi/iutil.c b/gs/psi/iutil.c
index aa6abf56c..a982e730f 100644
--- a/gs/psi/iutil.c
+++ b/gs/psi/iutil.c
@@ -340,10 +340,10 @@ obj_cvp(const ref * op, byte * str, uint len, uint * prlen,
340 float value = op->value.realval; 340 float value = op->value.realval;
341 float scanned; 341 float scanned;
342 342
343 sprintf(buf, "%g", value); 343 gs_sprintf(buf, "%g", value);
344 sscanf(buf, "%f", &scanned); 344 sscanf(buf, "%f", &scanned);
345 if (scanned != value) 345 if (scanned != value)
346 sprintf(buf, "%.9g", value); 346 gs_sprintf(buf, "%.9g", value);
347 ensure_dot(buf); 347 ensure_dot(buf);
348 goto rs; 348 goto rs;
349 } 349 }
@@ -494,7 +494,7 @@ other:
494 data = (const byte *)(op->value.boolval ? "true" : "false"); 494 data = (const byte *)(op->value.boolval ? "true" : "false");
495 break; 495 break;
496 case t_integer: 496 case t_integer:
497 sprintf(buf, "%"PRIpsint, op->value.intval); 497 gs_sprintf(buf, "%"PRIpsint, op->value.intval);
498 break; 498 break;
499 case t_string: 499 case t_string:
500 check_read(*op); 500 check_read(*op);
@@ -529,7 +529,7 @@ other:
529 break; 529 break;
530 } 530 }
531 /* Internal operator, no name. */ 531 /* Internal operator, no name. */
532 sprintf(buf, "@0x%lx", (ulong) op->value.opproc); 532 gs_sprintf(buf, "@0x%lx", (ulong) op->value.opproc);
533 break; 533 break;
534 } 534 }
535 case t_real: 535 case t_real:
@@ -542,7 +542,7 @@ other:
542 if (op->value.realval == (float)0.0001) { 542 if (op->value.realval == (float)0.0001) {
543 strcpy(buf, "0.0001"); 543 strcpy(buf, "0.0001");
544 } else { 544 } else {
545 sprintf(buf, "%g", op->value.realval); 545 gs_sprintf(buf, "%g", op->value.realval);
546 } 546 }
547 ensure_dot(buf); 547 ensure_dot(buf);
548 break; 548 break;
@@ -573,9 +573,9 @@ ensure_dot(char *buf)
573 sscanf(pe + 1, "%d", &i); 573 sscanf(pe + 1, "%d", &i);
574 /* MSVC .net 2005 express doesn't support "%+02d" */ 574 /* MSVC .net 2005 express doesn't support "%+02d" */
575 if (i >= 0) 575 if (i >= 0)
576 sprintf(pe + 1, "+%02d", i); 576 gs_sprintf(pe + 1, "+%02d", i);
577 else 577 else
578 sprintf(pe + 1, "-%02d", -i); 578 gs_sprintf(pe + 1, "-%02d", -i);
579 } else if (strchr(buf, '.') == NULL) { 579 } else if (strchr(buf, '.') == NULL) {
580 strcat(buf, ".0"); 580 strcat(buf, ".0");
581 } 581 }
diff --git a/gs/psi/iutil2.c b/gs/psi/iutil2.c
index 5361744ea..df63c703b 100644
--- a/gs/psi/iutil2.c
+++ b/gs/psi/iutil2.c
@@ -56,7 +56,7 @@ param_read_password(gs_param_list * plist, const char *kstr, password * ppass)
56 code = param_read_long(plist, kstr, &ipass); 56 code = param_read_long(plist, kstr, &ipass);
57 if (code != 0) /* error or missing */ 57 if (code != 0) /* error or missing */
58 return code; 58 return code;
59 sprintf((char *)ppass->data, "%ld", ipass); 59 gs_sprintf((char *)ppass->data, "%ld", ipass);
60 ppass->size = strlen((char *)ppass->data); 60 ppass->size = strlen((char *)ppass->data);
61 return 0; 61 return 0;
62} 62}
diff --git a/gs/psi/msvc.mak b/gs/psi/msvc.mak
index e6d4b0277..c971bd5c0 100644
--- a/gs/psi/msvc.mak
+++ b/gs/psi/msvc.mak
@@ -343,6 +343,10 @@ TIFFCONFIG_SUFFIX=.vc
343TIFFPLATFORM=win32 343TIFFPLATFORM=win32
344!endif 344!endif
345 345
346!ifndef TRIOSRCDIR
347TRIOSRCDIR=trio
348!endif
349
346# Define the directory where the zlib sources are stored. 350# Define the directory where the zlib sources are stored.
347# See zlib.mak for more information. 351# See zlib.mak for more information.
348 352
diff --git a/gs/psi/zbfont.c b/gs/psi/zbfont.c
index 84031c09a..fced10fed 100644
--- a/gs/psi/zbfont.c
+++ b/gs/psi/zbfont.c
@@ -109,7 +109,7 @@ zfont_encode_char(gs_font *pfont, gs_char chr, gs_glyph_space_t gspace)
109 109
110 if (gspace == GLYPH_SPACE_NOGEN) 110 if (gspace == GLYPH_SPACE_NOGEN)
111 return gs_no_glyph; 111 return gs_no_glyph;
112 sprintf(buf, "j%ld", chr); /* 'j' is arbutrary. */ 112 gs_sprintf(buf, "j%ld", chr); /* 'j' is arbutrary. */
113 code = name_ref(pfont->memory, (const byte *)buf, strlen(buf), &tname, 1); 113 code = name_ref(pfont->memory, (const byte *)buf, strlen(buf), &tname, 1);
114 if (code < 0) { 114 if (code < 0) {
115 /* Can't propagate the error due to interface limitation, 115 /* Can't propagate the error due to interface limitation,
@@ -131,7 +131,7 @@ zfont_glyph_name(gs_font *font, gs_glyph index, gs_const_string *pstr)
131 char cid_name[sizeof(gs_glyph) * 3 + 1]; 131 char cid_name[sizeof(gs_glyph) * 3 + 1];
132 int code; 132 int code;
133 133
134 sprintf(cid_name, "%lu", (ulong) index); 134 gs_sprintf(cid_name, "%lu", (ulong) index);
135 code = name_ref(font->memory, (const byte *)cid_name, strlen(cid_name), 135 code = name_ref(font->memory, (const byte *)cid_name, strlen(cid_name),
136 &nref, 1); 136 &nref, 1);
137 if (code < 0) 137 if (code < 0)
diff --git a/gs/psi/zdouble.c b/gs/psi/zdouble.c
index a68487461..303af1cd5 100644
--- a/gs/psi/zdouble.c
+++ b/gs/psi/zdouble.c
@@ -323,7 +323,7 @@ zcvsd(i_ctx_t *i_ctx_p)
323 len = r_size(op - 1); 323 len = r_size(op - 1);
324 if (len > MAX_CHARS) 324 if (len > MAX_CHARS)
325 return_error(e_limitcheck); 325 return_error(e_limitcheck);
326 sprintf(buf, "%f", 1.5); 326 gs_sprintf(buf, "%f", 1.5);
327 dot = buf[1]; /* locale-dependent */ 327 dot = buf[1]; /* locale-dependent */
328 memcpy(str, op[-1].value.bytes, len); 328 memcpy(str, op[-1].value.bytes, len);
329 /* 329 /*
@@ -406,7 +406,7 @@ zdcvs(i_ctx_t *i_ctx_p)
406 if (code < 0) 406 if (code < 0)
407 return code; 407 return code;
408 check_write_type(*op, t_string); 408 check_write_type(*op, t_string);
409 sprintf(str, "%f", 1.5); 409 gs_sprintf(str, "%f", 1.5);
410 dot = str[1]; /* locale-dependent */ 410 dot = str[1]; /* locale-dependent */
411 /* 411 /*
412 * To get fully accurate output results for IEEE double- 412 * To get fully accurate output results for IEEE double-
@@ -420,10 +420,10 @@ zdcvs(i_ctx_t *i_ctx_p)
420 { 420 {
421 double scanned; 421 double scanned;
422 422
423 sprintf(str, "%g", num); 423 gs_sprintf(str, "%g", num);
424 sscanf(str, "%lf", &scanned); 424 sscanf(str, "%lf", &scanned);
425 if (scanned != num) 425 if (scanned != num)
426 sprintf(str, "%.16g", num); 426 gs_sprintf(str, "%.16g", num);
427 } 427 }
428 len = strlen(str); 428 len = strlen(str);
429 if (len > r_size(op)) 429 if (len > r_size(op))
diff --git a/gs/psi/zfapi.c b/gs/psi/zfapi.c
index 23268061a..46b3ca249 100644
--- a/gs/psi/zfapi.c
+++ b/gs/psi/zfapi.c
@@ -585,11 +585,11 @@ FAPI_FF_get_word(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index)
585 length += r_size(&string) + 1; 585 length += r_size(&string) + 1;
586 break; 586 break;
587 case t_real: 587 case t_real:
588 sprintf(Buffer, "%f", Element.value.realval); 588 gs_sprintf(Buffer, "%f", Element.value.realval);
589 length += strlen(Buffer) + 1; 589 length += strlen(Buffer) + 1;
590 break; 590 break;
591 case t_integer: 591 case t_integer:
592 sprintf(Buffer, "%"PRIpsint, Element.value.intval); 592 gs_sprintf(Buffer, "%"PRIpsint, Element.value.intval);
593 length += strlen(Buffer) + 1; 593 length += strlen(Buffer) + 1;
594 break; 594 break;
595 case t_operator: 595 case t_operator:
@@ -825,12 +825,12 @@ FAPI_FF_get_proc(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index,
825 ptr += r_size(&string); 825 ptr += r_size(&string);
826 break; 826 break;
827 case t_real: 827 case t_real:
828 sprintf(Buf, "%f", Element.value.realval); 828 gs_sprintf(Buf, "%f", Element.value.realval);
829 strcpy(ptr, Buf); 829 strcpy(ptr, Buf);
830 ptr += strlen(Buf); 830 ptr += strlen(Buf);
831 break; 831 break;
832 case t_integer: 832 case t_integer:
833 sprintf(Buf, "%"PRIpsint, Element.value.intval); 833 gs_sprintf(Buf, "%"PRIpsint, Element.value.intval);
834 strcpy(ptr, Buf); 834 strcpy(ptr, Buf);
835 ptr += strlen(Buf); 835 ptr += strlen(Buf);
836 break; 836 break;
diff --git a/gs/psi/zfont2.c b/gs/psi/zfont2.c
index 45e048e03..547a034f1 100644
--- a/gs/psi/zfont2.c
+++ b/gs/psi/zfont2.c
@@ -2666,7 +2666,7 @@ parse_font(i_ctx_t *i_ctx_p, ref *topdict,
2666 return sid; 2666 return sid;
2667 if ((code = make_name_from_sid(i_ctx_p, &name, strings, data, sid)) < 0) { 2667 if ((code = make_name_from_sid(i_ctx_p, &name, strings, data, sid)) < 0) {
2668 char buf[40]; 2668 char buf[40];
2669 int len = sprintf(buf, "sid-%d", sid); 2669 int len = gs_sprintf(buf, "sid-%d", sid);
2670 2670
2671 if ((code = name_ref(imemory, (unsigned char *)buf, len, &name, 1)) < 0) 2671 if ((code = name_ref(imemory, (unsigned char *)buf, len, &name, 1)) < 0)
2672 return code; 2672 return code;
diff --git a/gs/trio/CHANGES b/gs/trio/CHANGES
new file mode 100644
index 000000000..fec2926f8
--- /dev/null
+++ b/gs/trio/CHANGES
@@ -0,0 +1,785 @@
1CHANGES -- trio
2
3
4The changes listed without a name attributed to them were most likely done by
5Bjorn Reese and/or Daniel Stenberg.
6
7Version 1.14 - 2010/01/26
8-------------------------
9* David Byron
10 Added trio_xstring_append_max.
11
12* Fixed compilation problem on Cygwin due to lack of long double math
13 (reported by Matthias Andree).
14
15* David Boyce
16 Added #undef of standard stdio function names before assigning trio functions
17 to them.
18
19* Matthias Andree
20 Upgraded configure.in to use new macros instead of obsoleted macros.
21
22* Matthias Andree
23 Added VPATH to Makefile.in
24
25* Tom Honermann
26 Fixed problem with subnormal numbers which caused an infinite loop outputting
27 leading spaces.
28
29* Adam McLaurin
30 Improved parsing performance by avoiding memset() and memcpy() on character
31 arrays.
32
33* Gideon Smeding
34 Fixed %u scanning of signed numbers.
35
36* Gideon Smeding
37 Fixed group scanning for non-matching input.
38
39* Fixed missing undo of look-ahead reading for scanf functions. This does only
40 work for the scanf* and fscanf* functions, not dscanf* and cscanf* functions
41 (reported by Gideon Smeding).
42
43* If the format string is empty, scanf does not attempt to read any input.
44
45* Ralf Junker
46 Fixed Borland compilation for user-defined specifiers.
47
48
49Version 1.13 - 2008/11/09
50-------------------------
51* Ives Aerts
52 Added the $<format|skip> format for user-defined specifiers, which is
53 compatible with compiler warnings about mismatches between specifiers and
54 arguments.
55
56* Added TRIO_DEPRECATED flag (reported by David Boyce)
57
58* Fixed rounding adjustment for long double (reported as bug item #2136686).
59
60* Added Makefile dependency for test target (reported as bug item #2136636).
61
62* David Boyce
63 Fixed long long support for MSVC.
64
65* Fixed potential problem with read after buffer end for non-zero terminated
66 strings (reported as bug item #1828465).
67
68* Andreas Stricker
69 Added WinCE support.
70
71* Fixed number of significant digits for %g.
72
73
74Version 1.12 - 2006/10/22
75-------------------------
76* Fixed scanning of floats (reported by Bernd Ahlers).
77
78* Fixed configure.in for GCC on Tru64 and MIPSpro on IRIX (reported by Andreas
79 Maus).
80
81* Olli Savia
82 Added support for LynxOS.
83
84
85Version 1.11 - 2006/04/08
86-------------------------
87* Mark Pickelmann
88 Fixed trio_unregister. If the first element was removed, the remaining
89 list would be removed as well.
90
91* Fixed unintended formatting of %e that would result in non-zero numbers
92 starting with zero (reported by Mark Pickelmann and Gisli Ottarsson).
93
94* Fixed compilation with Sun Workshop 6 (reported by Matthias Andree).
95
96* Fixed accuracy for denormalized numbers (bug item #758327).
97
98* Glen Davidson
99 Fixed scanning of floating-point numbers without a decimal-point (bug item
100 #1370427).
101
102* David Byron
103 Fixed more compiler warnings.
104
105* Fixed compilation of trio_to_long_double and TRIO_FEATURE_FLOAT (reported by
106 David Byron).
107
108* Fixed precision of large floating-point numbers (bug item #1314524).
109
110* Karl Bochert
111 Fixed trio_fpclassify_and_signbit to only restore the floating-point
112 precision.
113
114* Fixed detection of need for ieee option on FreeBSD/Alpha.
115
116* Added TRIO_SNPRINTF_ONLY compilation.
117
118* Fixed trio_to_double by not using strtod() on Tru64/DECC because it does not
119 support hex-floats.
120
121* Fixed crash on 64 bits machines related to a previous workaround in version
122 1.9 for uninitialized va_list (reported by Nicolai Tufar, suggestion by
123 Douglas Gwyn).
124
125* Patrick Jessee
126 Fixed width calculation for %g.
127
128* Added macros for internal features.
129
130* Jon Foster
131 Added macros for conditional compilation of many features. Documented all
132 the features.
133
134* Karl Bochert
135 Fixed problem with Borland C++, which changes the floating-point precision
136 for certain math functions (log10() and _fpclass()).
137
138* Karl Bochert
139 Fixed compilation warnings on Borland C++.
140
141* Removed any occurrence of #elif because Borland C++ reports wrong line
142 numbers when they are present (reported by Karl Bochert).
143
144* David Byron
145 Added trio_asprintfv.
146
147* Brian Chapman
148 Fixed Mac OS X compilation.
149
150* David Byron
151 Fixed several compiler warnings.
152
153* Fixed printing of out-of-range arguments for %hhd and %hd. These arguments
154 can be out of range because of default integer promotion.
155
156* Bob Friesenhahn
157 Fixed installation of header files.
158
159* Joe Orton
160 Added SHELL to Makefile.in to avoid problems with CShells.
161
162* Shaun Tancheff
163 Fixed regresion tests for MSVC.
164
165* Craig Berry
166 Fixed the VMS C99 workaround.
167
168
169Version 1.10 - 2003/03/06
170-------------------------
171* Rearranged some include files to accommodate large file support (reported by
172 Albert Chin-A-Young).
173
174* Added support for SunOS 4.1.x lack of strerror, tolower, and toupper
175 (reported by Peter McCluskey).
176
177* Fixed pedantic compilation with TRIO_MINIMAL.
178
179* Jose Kahan
180 Moved <limits.h> to avoid redefinition problems.
181
182* Fixed hex-float exponents (reported by Matthias Clasen).
183
184* Fixed handling of negative width and precision via paramters (reported by
185 Jacob Navia).
186
187* Nigel Hall
188 Fixed TRIO_VA_START for VMS.
189
190* Rune Enggaard Lausen
191 Fixed compilation for Borland C++ Builder.
192
193* Fixed precision of hex-float numbers (reported by James Antill).
194
195* Fixed plus sign only to be added for signed numbers.
196
197* Fixed printing of integers with value and precision of zero (reported by
198 James Antill).
199
200* Fixed %#.o to only print one zero if the value is zero (reported by James
201 Antill).
202
203* Rewrote check for IEEE compilation option to remove dependency on additional
204 scripts.
205
206* Mehdi Lavasani
207 Makefile install target fixed to work with older install programs.
208
209* Collapsed the DECC, MSVC, HP-UX, and AIX code for trio_fpclassify_and_sign()
210 with further preprocessing.
211
212
213Version 1.9 - 2002/10/13
214------------------------
215* Fixed trio_fpclassify_and_signbit on AIX 3.2
216
217* Added configure check for -ieee/-mieee compilation option for Alpha machines.
218
219* Craig Berry
220 Fixed compilation on VMS.
221
222* Albert Chin-A-Young
223 Fixed incorrect conditional expression in trio_isinf.
224
225* Fixed the warnings about uninitialized va_list in the printfv and scanfv
226 family without the use of compiler specific pragmas (suggested by Ian
227 Pilcher).
228
229* Fixed space flag for floating-point numbers (reported by Ian Main).
230
231
232Version 1.8 - 2002/07/10
233------------------------
234* Fixed infinite loop in multibyte handling (reported by Gisli Ottarsson).
235
236* Added the customizable cprintf/cscanf family which enables to user to specify
237 input and output stream functions (suggested by Florian Schulze).
238
239* Fixed trio_isinf by removing the HP-UX workaround, and instead making sure
240 that the C99 macro will adhere to the trio return values (reported by Luke
241 Dunstan).
242
243* Alexander Lukyanov
244 Fixed boundary case for scanning and EOF.
245
246* Jacob Navia
247 Enabled the L modifier for formatting.
248
249* Added TRIO_MINIMAL to build trio without the string functions.
250
251* Added the R modifier to print rounded floating-point numbers.
252
253* Added trio_to_long_double and long double scanning (the L modifier).
254
255* Added trio_locale_decimal_point, trio_locale_thousand_separator,
256 trio_locale_grouping to overwrite locale settings.
257
258* Rewrote TrioWriteDouble to avoid temporary buffers and thus the danger of
259 buffer overflows (for instance %.5000f).
260
261* Improved floating-point formatting accuracy.
262
263* Fixed formatting of non-decimal exponents.
264
265* Fixed thousand separator checking.
266
267* Fixed %f scanning to get a float and %lf to get a double.
268
269* Fixed WIN32 compilation (reported by Emmanuel Mogenet)
270
271* Fixed regression test cases to exclude disabled features.
272
273
274Version 1.7 - 2002/05/07
275------------------------
276* Fixed trio_to_double to handle hex-floats properly.
277
278* Fixed printing of %a-format to be like %e, not like %g.
279
280* Fixed floating-point printing of values beyond the machine accuracy.
281
282* Fixed %f for printing with large precision.
283
284* Fixed the usage of C99 nan(), which caused a crash on OSF/1 (reported by
285 Georg Bolz)
286
287* Joe Orton
288 Fixed %p on 64-bit platforms.
289
290* Made trio compile with K&R compilers.
291
292* Emmanuel Mogenet
293 Fixed bug in trio_asprintf.
294
295* Emmanuel Mogenet
296 Various WIN32 fixes.
297
298* Joe Orton
299 Fixed trio_isinf() on HP-UX, and added test cases.
300
301* Joe Orton
302 Fixed non-portable use of $^ in Makefile.
303
304* Joe Orton
305 Added autoconf.
306
307* Alexander Lukyanov
308 Fixed a number of bugs in the scanning of EOF and the count specifier.
309
310* Richard Jinks
311 Added trio_nzero
312
313* Fixed incorrect handling of return code from TrioReadChar (reported by
314 Henrik Löf)
315
316* Fixed parsing of character class expressions.
317
318* Fixed trio_to_double which did not work with long fractions.
319
320* Fixed %f for printing of large numbers.
321
322* Fixed %#s to handle whitespaces as non-printable characters.
323
324* Added trio_isfinite, trio_signbit, and trio_fpclassify.
325
326* Added new test cases.
327
328
329Version 1.6 - 2002/01/13
330------------------------
331* Added dynamic string functions.
332
333* Rewrote and extended documentation in JavaDoc (using Doxygen).
334
335* Moved and renamed strio functions to triostr.
336
337* Robert Collins
338 Added definition for Cygwin.
339
340* Markus Henke
341 Added long double workaround for the HP C/iX compiler.
342
343* Marc Verwerft
344 Improved error handling for dynamically allocated strings.
345
346* John Fotheringham
347 Made trionan compile on OpenVMS.
348
349* Added 'd' and 'D' as exponent letters when using TRIO_MICROSOFT.
350
351* Fixed uninitial memory read for the parameter modifiers.
352
353
354Version 1.5 - 2001/09/08
355------------------------
356* Merged with libxml changes.
357
358* Moved NaN and Inf handling to separate file to enable reuse in other
359 projects.
360
361* Igor Zlatkovic
362 Fixed TrioGenerateNan for MSVC.
363
364* Fixed lots of preprocessor macros and internal data structure names.
365
366
367Version 1.4 - 2001/06/03
368------------------------
369* Added hex-float (%a and %A) for scanning.
370
371* Added wide character arguments (%ls, %ws, %S, %lc, %wc, and %C) for both
372 printf and scanf.
373
374* Added mutex callbacks for user-specified specifiers to enable applications to
375 add thread-safety. These are registered with trio_register, where the
376 namespace is set to either ":enter" to lock a mutex, or ":leave" to unlock a
377 mutex.
378
379* Added equivalence class expressions for scanning. For example, %[[=a=]] scans
380 for all letters in the same equivalence class as the letter 'a' as defined
381 by the locale.
382
383* Changed character class expressions for scanning. The expressions must now
384 be embedded withing an extra set of brackets, e.g. %[[:alpha:]]. This was
385 done to adhere to the syntax of UNIX98 regular expressions.
386
387* Added the possibility to specify standard support (TRIO_C99 etc.) as compiler
388 options.
389
390* Fixed conversion of hex-float in StrToDouble.
391
392* Fixed formatting of hex-float numbers.
393
394* Stan Boehm
395 Fixed crash on QNX, which happend because some buffers on the stack were too
396 big.
397
398* Fixed default precision for %f and %g (reported by Jose Ortiz)
399
400* Howard Kapustein
401 Added the I8, I16, I32, and I64 modifiers.
402
403* Jose Ortiz
404 Fixed rounding problem for %e.
405
406* Jose Ortiz
407 Fixed various problems with the xlC and Sun C++ compilers.
408
409
410Version 1.3 - 2001/05/16
411------------------------
412* trio's treatment of the field width when the %e code was used was not
413 correct (reported by Gisli Ottarsson). It turns out the fraction part should
414 be zero-padded by default and the exponent part should be zero-prefixed if
415 it is only one digit. At least that's how the GNU and Sun libc's work. The
416 trio floating point output looks identical to them now.
417
418* Fixed group scanning with modifiers.
419
420* Fixed compilation for 64-bit Digital Unix.
421
422* Igor Zlatkovic
423 Fixed compilation of dprintf, which uses read/write, for MSVC.
424
425* Fixed various compilation problems on Digital Unix (mainly associated with
426 va_list).
427
428
429Version 1.2 - 2001/04/11
430------------------------
431* Added autoconf integration. If compiled with HAVE_CONFIG_H the following
432 happens. Firstly, <config.h> is included. Secondly, trio will only be
433 compiled if WITH_TRIO is defined herein. Thirdly, if TRIO_REPLACE_STDIO is
434 defined, only stdio functions that have not been detected by autoconf, i.e.
435 those not defined by HAVE_PRINTF or similar, will be replaced by trio
436 functions (suggested by Daniel Veillard).
437
438* Fixed '%m.nf' output. Previously trio did not treat the width properly
439 in all cases (reported by Gisli Ottarsson).
440
441* Added explicit promotion for the scanfv family.
442
443* Fixed more C++ compilation warnings.
444
445
446Version 1.1 - 2001/02/25
447------------------------
448* Added explicit promotion for the printfv familiy. A float must be specified
449 by %hf.
450
451* Fixed positionals for printfv (reported by Gisli Ottarsson).
452
453* Fixed an integer to pointer conversion problem on the SGI MIPS C compiler
454 (reported by Gisli Ottarsson).
455
456* Fixed ANSI C++ warnings (type casting, and namespace is a reserved keyword).
457
458* Added \n to all examples in the documentation to prevent confusion.
459
460* Fixed StrSubstringMax
461
462
463Version 1.0 - 2000/12/10
464------------------------
465* Bumped Version number.
466
467
468Version 0.25 - 2000/12/09
469-------------------------
470* Wrote more documentation.
471
472* Improved NaN support and added NaN to regression test.
473
474* Fixed C99 support.
475
476* Added missing getter/setter functions.
477
478
479Version 0.24 - 2000/12/02
480-------------------------
481* Added callback functionality for the user-defined specifier (<>). All
482 the necessary functions are defined in triop.h header file. See the
483 documentation for trio_register for further detail.
484
485* Wrote initial documentation on the callback functionality.
486
487* Added the printfv and scanfv family of functions, which takes a pointer
488 array rather than variadic arguments. Each pointer in the array must point
489 to the associated data (requested by Bruce Korb).
490
491* As indicated in version 0.21 the extension modifiers (<>) have now been
492 completely removed.
493
494* Added skipping of thousand-separators in floating-point number scanning.
495
496
497Version 0.23 - 2000/10/21
498-------------------------
499* Added width to scanning of floating-point numbers.
500
501* Wrote more documentation on trio_printf.
502
503* Fixed problem with trailing zeroes after decimal-point.
504
505
506Version 0.22 - 2000/08/06
507-------------------------
508* Added LC_CTYPE locale dependent character class expressions to scan lists.
509 Included are [:alnum:], [:alpha:], [:cntrl:], [:digit:], [:graph:],
510 [:lower:], [:print:], [:punct:], [:space:], [:upper:], [:xdigit:]
511
512* Added C escapes to alternative string formatting and scanning.
513
514* Added StrSubstringMax.
515
516* Wrote a little more documentation.
517
518* Fixed scanf return values.
519
520* Fixed a sign error for non-ascii characters.
521
522
523Version 0.21 - 2000/07/19
524-------------------------
525* Converted the documentation to TeX. With latex2man the documentation can
526 automatically be converted into man pages.
527
528* Added trio_scanf, trio_vscanf, trio_fscanf, and trio_vfscanf.
529
530* Added trio_dprintf, trio_vdprintf, trio_dscanf, and trio_vdscanf. These
531 functions can be used to write and read directly to pipes and sockets (the
532 assume blocking sockets). Stdio buffering is surpassed, so the functions are
533 async-safe. However, reading from stdin (STDIN_FILENO) or writing to stdout
534 (STDOUT_FILENO) reintroduces the buffering.
535
536* Paul Janzen
537 Added trio_asprintf and trio_vasprintf, which are compatible with the GNU
538 and BSD interfaces.
539
540* Added scanlist ranges for group scanning (%[]).
541
542* Added width for scanning (missing for floating-point numbers though).
543
544* Added variable size modifier (&) to handle system defined types of unknown
545 size. This modifier makes certain assumptions about the integer sizes, which
546 may not be valid on any machine. Consequently, the modifier will remain
547 undocumented, as it may be removed later.
548
549* Added \777 and \xFF to alternative string scanning (%#s)
550
551* Added the TRIO_REPLACE_STDIO check in the header.
552
553* Improved performance of the multibyte character parsing.
554
555* Fixed positionals (%n$) which had stopped working.
556
557* Fixed hh and ll modifiers to allow exactly two letters and no more.
558
559* Fixed ANSI C++ warnings. Also fixed the compiler warning about casting
560 between integer and pointer (this has been annoying me for ages).
561
562* Fixed snprintf and vsnprintf with zero buffer size.
563
564* Fixed NAN problems (reported by Keith Briggs).
565
566* Fixed parsing of multibyte characters. The format string was not correctly
567 advanced in case of a multibyte character.
568
569* Renamed many of the internal functions to have more consistant names.
570
571* Removed the <quote=c> and <fill=c> modifiers. They are not really worth
572 including. The other <> modifiers may disappear as well.
573
574
575Version 0.20 - 2000/06/05
576-------------------------
577* Added intmax_t and ptrdiff_t support.
578
579* Added support for LC_NUMERIC grouping.
580
581* Added double-dot notation for the conversion base. The style is now
582 %width.precision.base, where any argument can be a number, an asterix
583 indicating a parameter, or be omitted entirely. For example, %*..2i is
584 to specify binary numbers without precision, and with width as a parameter
585 on the va_list.
586
587* Added sticky modifier (!), which makes subsequent specifiers of the same
588 type reuse the current modifiers. Inspired by a suggestion from Gary Porter.
589
590* Added group scanning (%[]). Scanlist ranges and multibyte sequences are not
591 supported yet.
592
593* Added count scanning (%n).
594
595* Changed the number scanning to accept thousand separators and any base.
596
597* Fixed positional for parameters. It is possible to write something like
598 %3$*1$.*2$d (which happens to be the same as %*.*d).
599
600* Fixed precision of integers.
601
602* Fixed parameter flags. Before trio could only handle one parameter flag per
603 specifier, although two (three with double-dot base) were possible.
604
605* Fixed isinf() for those platforms where it is unimplemented.
606
607
608Version 0.18 - 2000/05/27
609-------------------------
610* Rewrote the entire floating-point formatting function (Danny Dulai had
611 reported several errors and even supplied some patches, which unfortunately
612 were lost due to the refactoring).
613
614* Removed the use of strlen() in the declaration of a stack array. This
615 caused problems on some compilers (besides it isn't really ANSI C compliant
616 anyways). Using some arbitrarily chosen maximum value; should examine if
617 some standard defines an upper limit on the length of decimal-point and
618 thousands-separator (sizeof(wchar_t) perhaps?)
619
620* Changed the parsing of the format string to be multibyte aware.
621
622
623Version 0.17 - 2000/05/19
624-------------------------
625* Added INF, -INF, and NAN for floating-point numbers.
626
627* Fixed %#.9g -- alternative with precision.
628
629* Ken Gibson
630 Fixed printing of negative hex numbers
631
632* Joerg (last name unknown)
633 Fixed convertion of non-ASCII characters
634
635
636Version 0.16 - 1999/08/06
637-------------------------
638* Changed the constness of the second argument of StrFloat and StrDouble. The
639 lack of parameter overloading in C is the reason for the strange use of
640 constness in strtof and strtod.
641
642* Cleaned up constness.
643
644
645Version 0.15 - 1999/07/23
646-------------------------
647* Fixed the internal representation of numbers from signed to unsigned. Signed
648 numbers posed a problem for large unsigned numbers (reported by Tero)
649
650* Fixed a tiny bug in trio_vsprintfcat
651
652* Changed the meaning of the max argument of StrAppendMax to be consistant
653 with StrFormatAppendMax. Now it is the maximal size of the entire target
654 buffer, not just the appended size. This makes it easier to avoid buffer
655 overflows (requested by Tero)
656
657
658Version 0.14 - 1999/05/16
659-------------------------
660* Added size_t support (just waiting for a C99 compliant compiler to add
661 ptrdiff_t and intmax_t)
662
663* Rewrote TrioOutStreamDouble so it does not use the libc sprintf to emulate
664 floating-point anylonger.
665
666* Fixed width, precision, and adjustment for numbers and doubles.
667
668
669Version 0.13 - 1999/05/06
670-------------------------
671* Fixed zero padding for %d. Now %d will only zero pad if explicitly requested
672 to do so with the 0 flag (reported by Tero).
673
674* Fixed an incorrect while() condition in TrioGetString (reported by Tero).
675
676
677Version 0.12 - 1999/04/19
678-------------------------
679* Fixed incorrect zero padding of pointers
680
681* Added StrHash with STRIO_HASH_PLAIN
682
683* Added StrFormatDateMax
684
685
686Version 0.11 - 1999/03/25
687-------------------------
688* Made it compile under cygwin
689
690* Fixed a bug were TrioPreprocess would return an error if no formatting chars
691 were found (reported by Tero).
692
693
694Version - 1999/03/19
695--------------------
696* Added trio_strerror and TRIO_ERROR_NAME.
697
698* Changed the error codes to be positive (as errno)
699
700* Fixed two reads of uninitialized memory reported by Purify
701
702* Added binary specifiers 'b' and 'B' (like SCO.) ThousandSeparator can be
703 used to separate nibbles (4 bit)
704
705* Renamed all Internal* functions to Trio*, which seems like a better
706 namespace (even though it is of no practical interest because these
707 functions are not visible beyond the scope of this file.)
708
709
710Version - 1999/03/12
711--------------------
712* Added hex-float format for StrToDouble
713
714* Double references and gaps in the arguments are not allowed (for the %n$
715 format) and in both cases an error code is returned.
716
717* Added StrToDouble (and StrToFloat)
718
719
720Version - 1999/03/08
721--------------------
722* Added InStream and OutStream to the trio_T structure.
723
724* Started work on TrioScan.
725
726* Return values for errors changed. Two macros to unpack the error code has
727 been added to the header.
728
729* Shortshort (hh) flag added.
730
731* %#s also quotes the quote-char now.
732
733* Removed the 'errorInFormat' boolean, which isn't used anymore after the
734 functions bail out with an error instead.
735
736
737Version - 1999/03/04
738--------------------
739* More than MAX_PARAMETERS parametes will now cause the TrioPreprocess()
740 function to return error.
741
742* Unknown flags and/or specifiers cause errors too.
743
744* Added trio_snprintfcat and trio_vsnprintfcat and the defined name
745 StrFormatAppendMax. They append a formatted string to the end of a string.
746
747* Define MAX_PARAMETERS to 128 at all times instead of using NL_ARGMAX when
748 that exists.
749
750* Added platform fixes for Amiga as suggested by Tero Jänkä <tesaja@utu.fi>
751
752
753Version - 1999/01/31
754--------------------
755* vaprintf did add a zero byte even when it had failed.
756
757* Cleaned up the code for locale handling and thousand separator
758
759* Added trio_aprintf() and trio_vaprintf(). They return an allocated string.
760
761* Added thousands separator for numbers
762
763* Added floating point support for *printf
764
765
766Version - 1998/10/20
767--------------------
768* StrMatchCase() called StrMatch() instead of itself recursively
769
770* Rewrote the implementation of *printf and *scanf and put all the code in
771 this file. Extended qualifiers and qualifiers from other standards were
772 added.
773
774* Added StrSpanFunction, StrToLong, and StrToUnsignedLong
775
776
777Version - 1998/05/23
778--------------------
779* Made the StrEqual* functions resistant to NULL pointers
780
781* Turns out strdup() is no standard at all, and some platforms (I seem to
782 recall HP-UX) has problems with it. Made our own StrDuplicate() instead.
783
784* Added StrFormat() and StrFormatMax() to serve as sprintf() and snprintf()
785 respectively.
diff --git a/gs/trio/FILES b/gs/trio/FILES
new file mode 100644
index 000000000..22a5ea121
--- /dev/null
+++ b/gs/trio/FILES
@@ -0,0 +1,33 @@
1FILES
2README
3CHANGES
4Makefile.in
5maketgz
6strio.h
7trio.c
8trio.h
9triodef.h
10trionan.c
11trionan.h
12triop.h
13triostr.c
14triostr.h
15compare.c
16example.c
17regression.c
18configure
19configure.in
20install-sh
21autogen.sh
22doc/doc.h
23doc/doc_dynamic.h
24doc/doc_printf.h
25doc/doc_register.h
26doc/doc_scanf.h
27doc/doc_static.h
28doc/footer.html
29doc/header.html
30doc/trio.cfg
31doc/trio.css
32html/trio.css
33html/*.html
diff --git a/gs/trio/Makefile.in b/gs/trio/Makefile.in
new file mode 100644
index 000000000..4f3b9692b
--- /dev/null
+++ b/gs/trio/Makefile.in
@@ -0,0 +1,73 @@
1SHELL = @SHELL@
2CC = @CC@
3CFLAGS = @CFLAGS@ -I. -DDEBUG
4OBJS = triostr.o trio.o trionan.o
5TARGETLIB = libtrio.a
6TARGETINCS = trio.h triop.h triodef.h trionan.h triostr.h
7LDFLAGS = -L. -ltrio -lm
8AR = ar
9RANLIB = @RANLIB@
10ERASE = rm -f
11MKDIR = mkdir -p
12GENDOC = doxygen
13srcdir = @srcdir@
14# VPATH doesn't seem to work with /usr/xpg4/bin/make on Solaris
15# (use /usr/ccs/bin/make), and doesn't work on older Solaris make
16# such as Solaris 2.6.
17VPATH = @srcdir@
18
19# Installation settings
20INSTALL = @INSTALL@
21INSTALL_DATA = @INSTALL_DATA@
22prefix = @prefix@
23exec_prefix = @exec_prefix@
24includedir = @includedir@
25libdir = @libdir@
26
27all: $(TARGETLIB) $(TARGET)
28
29.PHONY: all check test install doc clean
30
31$(srcdir)/configure: configure.in
32 cd $(srcdir) && autoconf
33
34Makefile: Makefile.in config.status
35 CONFIG_COMMANDS= CONFIG_LINKS= CONFIG_HEADERS= \
36 CONFIG_FILES=Makefile ./config.status
37
38config.status: configure
39 ./config.status --recheck
40
41check: test
42test: regression
43 ./regression
44
45install: $(TARGETLIB)
46 $(MKDIR) $(libdir)
47 $(MKDIR) $(includedir)
48 $(INSTALL_DATA) $(TARGETLIB) $(libdir)/$(TARGETLIB)
49 for i in $(TARGETINCS);do \
50 (set -x;$(INSTALL_DATA) $(srcdir)/$$i $(includedir)); \
51 done
52
53regression: regression.o $(TARGETLIB)
54 $(CC) $(CFLAGS) regression.o $(LDFLAGS) -o $@
55
56example: example.o $(TARGETLIB)
57 $(CC) $(CFLAGS) example.o $(LDFLAGS) -o $@
58
59compare: compare.o $(TARGETLIB)
60 $(CC) $(CFLAGS) compare.o $(LDFLAGS) -o $@
61
62userdef: userdef.o $(TARGETLIB)
63 $(CC) $(CFLAGS) userdef.o $(LDFLAGS) -o $@
64
65$(TARGETLIB): $(OBJS)
66 $(AR) ruv $(TARGETLIB) $(OBJS)
67 $(RANLIB) $(TARGETLIB)
68
69doc::
70 (cd $(srcdir) && $(GENDOC) doc/trio.cfg)
71
72clean:
73 $(ERASE) *~ core core.* regression example $(TOBJS) $(OBJS) $(TARGET) $(TARGETLIB) example.o regression.o
diff --git a/gs/trio/README b/gs/trio/README
new file mode 100644
index 000000000..55ad1b07d
--- /dev/null
+++ b/gs/trio/README
@@ -0,0 +1,38 @@
1README -- trio
2
3Trio is a package with portable string functions. Including printf() clones
4and others.
5
6 Copyright (C) 1998-2001 by Bjorn Reese and Daniel Stenberg.
7
8 Permission to use, copy, modify, and distribute this software for any
9 purpose with or without fee is hereby granted, provided that the above
10 copyright notice and this permission notice appear in all copies.
11
12 THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
13 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
14 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
15 CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
16
17Trio is intended to be an integral part of another application, so we
18have not done anything to create a proper installation.
19
20Compile with 'make' (edit the Makefile if you want a release build)
21
22Test the package with 'make test'
23
24Install by copying trio.h, triop.h, and libtrio.a (and man/man?/* if
25you want documentation) to the appropriate directories.
26
27Catch some usage examples in example.c
28
29Send feedback and patches to the mailing list, subscription and other
30information is found here:
31
32 http://lists.sourceforge.net/lists/listinfo/ctrio-talk
33
34Enjoy!
35
36Trio web page
37
38 http://daniel.haxx.se/trio/
diff --git a/gs/trio/autogen.sh b/gs/trio/autogen.sh
new file mode 100755
index 000000000..9299034ef
--- /dev/null
+++ b/gs/trio/autogen.sh
@@ -0,0 +1,3 @@
1#!/bin/sh
2autoconf
3rm -rf autom4te.cache
diff --git a/gs/trio/compare.c b/gs/trio/compare.c
new file mode 100644
index 000000000..3823aa2de
--- /dev/null
+++ b/gs/trio/compare.c
@@ -0,0 +1,53 @@
1#include "trio.h"
2
3#define compare(format, value) printf("FORMAT: %s\n", format); printf("TRIO: "); trio_printf(format,value); printf("\nLIBC: "); \
4printf(format,value); printf("\n\n");
5
6int main()
7{
8 compare("\"%e\"",2.342E+02);
9 compare("\"%10.4e\"",-2.342E-02);
10 compare("\"%11.4e\"",-2.342E-02);
11 compare("\"%12.4e\"",-2.342E-02);
12 compare("\"%13.4e\"",-2.342E-02);
13 compare("\"%14.4e\"",-2.342E-02);
14 compare("\"%15.4e\"",-2.342E-02);
15 compare("\"%16.4e\"",-2.342E-02);
16 compare("\"%16.4e\"",-2.342E-22);
17 compare("\"%G\"",-2.342E-02);
18 compare("\"%G\"",3.1415e-6);
19 compare("%016e", 3141.5);
20 compare("%16e", 3141.5);
21 compare("%-16e", 3141.5);
22 compare("%010.3e", 3141.5);
23
24 compare("*%5f*", 3.3);
25 compare("*%5f*", 3.0);
26 compare("*%5f*", .999999E-4);
27 compare("*%5f*", .99E-3);
28 compare("*%5f*", 3333.0);
29
30 compare("*%5g*", 3.3);
31 compare("*%5g*", 3.0);
32 compare("*%5g*", .999999E-4);
33 compare("*%5g*", .99E-3);
34 compare("*%5g*", 3333.0);
35 compare("*%5g*", 0.01);
36
37 compare("*%5.g*", 3.3);
38 compare("*%5.g*", 3.0);
39 compare("*%5.g*", .999999E-4);
40 compare("*%5.g*", 1.0E-4);
41 compare("*%5.g*", .99E-3);
42 compare("*%5.g*", 3333.0);
43 compare("*%5.g*", 0.01);
44
45 compare("*%5.2g*", 3.3);
46 compare("*%5.2g*", 3.0);
47 compare("*%5.2g*", .999999E-4);
48 compare("*%5.2g*", .99E-3);
49 compare("*%5.2g*", 3333.0);
50 compare("*%5.2g*", 0.01);
51
52 return 0;
53}
diff --git a/gs/trio/configure.in b/gs/trio/configure.in
new file mode 100644
index 000000000..f1ed7659c
--- /dev/null
+++ b/gs/trio/configure.in
@@ -0,0 +1,54 @@
1dnl
2dnl Configuration for trio
3dnl
4
5AC_INIT
6AC_CONFIG_SRCDIR([triodef.h])
7AC_PREREQ(2.55) dnl autoconf 2.55 was released in 2002
8
9AC_PROG_CC
10ifdef([AC_PROG_CC_STDC], [AC_PROG_CC_STDC])
11AC_LANG([C])
12
13AC_PROG_INSTALL
14AC_PROG_RANLIB
15
16dnl
17dnl Alpha floating-point compiler option.
18dnl
19
20AC_MSG_CHECKING(for IEEE compilation options)
21AC_CACHE_VAL(ac_cv_ieee_option, [
22 AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[
23 #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__))) && (defined(VMS) || defined(__VMS)))
24 # error "Option needed"
25 typedef int option_needed[-1];
26 #endif
27 ]]]),
28 ac_cv_ieee_option="/IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE",
29 AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[
30 #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__))) && !(defined(VMS) || defined(__VMS)) && !defined(_CFE))
31 # error "Option needed"
32 typedef int option_needed[-1];
33 #endif
34 ]]]),
35 ac_cv_ieee_option="-ieee",
36 AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[
37 #if !(defined(__alpha) && (defined(__GNUC__) && (defined(__osf__) || defined(__linux__))))
38 # error "Option needed"
39 typedef int option_needed[-1];
40 #endif
41 ]]]),
42 ac_cv_ieee_option="-mieee",
43 ac_cv_ieee_option="none"
44 )
45 )
46 )
47])
48AC_MSG_RESULT($ac_cv_ieee_option)
49if test $ac_cv_ieee_option != none; then
50 CFLAGS="${CFLAGS} ${ac_cv_ieee_option}"
51fi
52
53AC_CONFIG_FILES([Makefile])
54AC_OUTPUT
diff --git a/gs/trio/doc/doc.h b/gs/trio/doc/doc.h
new file mode 100644
index 000000000..49de1466a
--- /dev/null
+++ b/gs/trio/doc/doc.h
@@ -0,0 +1,172 @@
1/*************************************************************************
2 *
3 * $Id: doc.h,v 1.20 2006/08/18 11:32:08 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
18/**
19@mainpage
20
21@author Bjørn Reese
22@author Daniel Stenberg
23
24@section intro Introduction
25
26Trio is a fully matured and stable set of printf and string functions
27designed be used by applications with focus on portability or with the
28need for additional features that are not supported by standard stdio
29implementation.
30
31There are several cases where you may want to consider using trio:
32
33@li Portability across heterogeneous platforms.
34@li Embedded systems without stdio support.
35@li Extendability of unsupported features.
36@li Your native version does not do everything you need.
37
38When you write applications that must be portable to a wide range of
39platforms you often have to deal with inadequate implementations of the
40stdio library functions. Most notably is the lack of secure formatting
41functions, such as snprintf, or the lack of parameter reordering commonly
42used for the internationalization of applications, such as the <num>$
43modifier. Sometimes the feature you need is simply not present in stdio.
44So you end up spending much effort on determining which platforms supports
45what, and to write your own versions of various features. This is where
46trio can help you. Trio is a platform-independent implementation of the
47stdio printf and scanf functions and the string library functions.
48
49The functionality described in the stdio standards is a compromise, and
50does unfortunately not include a mechanism to extend the functionality for
51an individual application. Oftentimes an application has the need for an
52extra feature, and the application code can become much more clear and
53readable by using an extension mechanism. Trio supports a range of useful
54extensions such as user-defined specifiers, passing of arguments in arrays,
55localized string scanning, thousand-separators, and arbitrary integer bases.
56
57Trio fully implements the C99 (ISO/IEC 9899:1999) and UNIX98 (the Single
58Unix Specification, Version 2) standards, as well as many features from
59other implemenations, e.g. the GNU libc and BSD4.
60
61@section examples Examples
62
63@subsection ex1 Binary Numbers
64Output an integer as a binary number using a trio extension.
65@verbatim
66 trio_printf("%..2i\n", number);
67@endverbatim
68
69@subsection ex2 Thousand-separator
70Output a number with thousand-separator using a trio extension.
71@verbatim
72 trio_printf("%'f\n", 12345.6);
73@endverbatim
74The thousand-separator described by the locale is used.
75
76@subsection ex3 Fixed Length Array and Sticky Modifier
77Output an fixed length array of floating-point numbers.
78@verbatim
79 double array[] = {1.0, 2.0, 3.0};
80 printf("%.2f %.2f %.2f\n", array[0], array[1], array[2]);
81@endverbatim
82The same with two trio extensions (arguments are passed in an array, and
83the first formatting specifier sets the sticky option so we do not have
84to type all the formatting modifiers for the remaining formatting specifiers)
85@verbatim
86 trio_printfv("%!.2f %f %f\n", array);
87@endverbatim
88Another, and more powerful, application of being able to pass arguments in
89an array is the creation of the printf/scanf statement at run-time, where
90the formatting string, and thus the argument list, is based on an external
91configuration file.
92
93@subsection ex4 Localized scanning
94Parse a string consisting of one or more upper-case alphabetic characters
95followed by one or more numeric characters.
96@verbatim
97 sscanf(buffer, "%[A-Z]%[0-9]", alphabetic, numeric);
98@endverbatim
99The same but with locale using a trio extension.
100@verbatim
101 trio_sscanf(buffer, "%[[:upper:]]%[[:digit:]]", alphabetic, numeric);
102@endverbatim
103
104@section legal Legal Issues
105Trio is distributed under the following license, which allows practically
106anybody to use it in almost any kind of software, including proprietary
107software, without difficulty.
108
109"Copyright (C) 1998-2001 Bjorn Reese and Daniel Stenberg.
110
111Permission to use, copy, modify, and distribute this software for any
112purpose with or without fee is hereby granted, provided that the above
113copyright notice and this permission notice appear in all copies.
114
115THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
116WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
117MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
118CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER."
119
120@section contribution Contribution
121
122@subsection contribute Contribute
123We appreciate any type of contribution, from ideas over improvements to
124error corrections.
125
126The project space contains references to bug and feature tracking,
127mailing-list, and the CVS repository. We prefer communication via the
128mailing-list, but do not require you to be subscribed, because trio is a
129small project.
130
131The project space is located at http://sourceforge.net/projects/ctrio/
132
133@subsection contributors Contributors
134We have received contributions from the following persons (in alphabetic
135order sorted by surname)
136
137@li Craig Berry
138@li Karl Bochert
139@li Stan Boehm
140@li David Byron
141@li Brian Chapman
142@li Robert Collins
143@li Danny Dulai
144@li Bob Friesenhahn
145@li Jon Foster
146@li John Fotheringham
147@li Markus Henke
148@li Ken Gibson
149@li Paul Janzen
150@li Patrick Jessee
151@li Richard Jinks
152@li Tero Jänkä
153@li Howard Kapustein
154@li Rune Enggaard Lausen
155@li Mehdi Lavasani
156@li Alexander Lukyanov
157@li Andreas Maus
158@li Mikey Menezes
159@li Emmanuel Mogenet
160@li Jacob Navia
161@li Jose Ortiz
162@li Joe Orton
163@li Gisli Ottarsson
164@li Mark Pickelmann
165@li Olli Savia
166@li Shaun Tancheff
167@li Marc Werwerft
168@li Igor Zlatkovic
169
170Please let us know, and accept our apology, if we have omitted anybody.
171
172*/
diff --git a/gs/trio/doc/doc_dynamic.h b/gs/trio/doc/doc_dynamic.h
new file mode 100644
index 000000000..92482676e
--- /dev/null
+++ b/gs/trio/doc/doc_dynamic.h
@@ -0,0 +1,31 @@
1/*************************************************************************
2 *
3 * $Id: doc_dynamic.h,v 1.1 2001/12/27 17:29:20 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
18/** @addtogroup DynamicStrings Dynamic String Functions.
19Dynamic string functions.
20
21@b SYNOPSIS
22
23@verbatim
24cc ... -ltrio -lm
25
26#include <triostr.h>
27@endverbatim
28
29@b DESCRIPTION
30
31*/
diff --git a/gs/trio/doc/doc_printf.h b/gs/trio/doc/doc_printf.h
new file mode 100644
index 000000000..32439e26c
--- /dev/null
+++ b/gs/trio/doc/doc_printf.h
@@ -0,0 +1,532 @@
1/*************************************************************************
2 *
3 * $Id: doc_printf.h,v 1.5 2008/10/12 12:09:51 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
18/** @addtogroup Printf Formatted Printing Functions.
19Variations of formatted printing functions.
20
21@b SYNOPSIS
22
23@verbatim
24cc ... -ltrio -lm
25
26#include <trio.h>
27@endverbatim
28
29@b DESCRIPTION
30
31This documentation is incomplete.
32The documentation of the printf family in [C99] and [UNIX98] also applies
33to the trio counterparts.
34
35All these functions outputs a string which is formatted according to the
36@p format string and the consecutive arguments. The @p format string is
37described in the Formatting section below.
38
39@ref trio_printf, @ref trio_vprintf, and @ref trio_printfv writes the
40output to the standard output stream (stdout).
41
42@ref trio_fprintf, @ref trio_vfprintf, and @ref trio_fprintfv writes the
43output to a given output stream.
44
45@ref trio_dprintf, @ref trio_vdprintf, and @ref trio_dprintfv writes the
46output to a file descriptor (this includes, for example, sockets).
47
48@ref trio_sprintf, @ref trio_vsprintf, and @ref trio_sprintfv writes the
49output into @p buffer.
50
51@ref trio_snprintf, @ref trio_vsnprintf, and @ref trio_snprintfv writes @p
52max - 1 characters into @p buffer followed by a terminating zero character.
53If @p max is 1, then @p buffer will be an empty string. If @p max is 0,
54then @p buffer is left untouched, and can consequently be NULL. The number
55of characters that would have been written to @p buffer, had there been
56sufficient space, is returned.
57
58@ref trio_snprintfcat appends the formatted text at the end of @p buffer.
59
60@ref trio_asprintf, @ref trio_vasprintf, and @ref trio_asprintfv allocates
61and returns an allocated string in @p buffer containing the formatted text.
62
63@b FORMATTING
64
65The @p format string can contain normal text and conversion indicators.
66The normal text can be any character except the nil character (\000 =
67'\0') and the percent character (\045 = '%'). Conversion indicators
68consists of an indication character (%), followed by zero or more conversion
69modifiers, and exactly one conversion specifier.
70
71@b Modifiers
72
73Some modifiers exhibit the same behaviour for all specifiers, other modifiers
74indicate different behaviours for different specifiers, and other modifiers
75are only applicable to certain specifiers. The relationship is described for
76each modifier. The number 9 is used to denotes an arbitrary integer.
77
78@em Positional ( @c 9$ ) [UNIX98]
79
80Normally the arguments supplied to these functions are interpreted
81incrementially from left to right. Arguments can be referenced specifically in
82the format string. The modifier n$ selects the nth argument. The first
83argument is referred as 1$. If this modifier is used, it must be the first
84modifier after the indication character. n$ can also be used for argument
85width, precision, and base.
86
87The performance penalty of using positionals is almost neglible (contrary to
88most other printf implementations).
89
90@li @em Reference @em Mix.
91Mixing normal and positional specifiers is allowed [TRIO]. For example,
92@verbatim
93 trio_printf("%d %3$d %2$d\n", 1, 2, 3);
94@endverbatim
95results in
96@verbatim
97 1 3 2
98@endverbatim
99Arguments for the printf family are passed on the stack. On most platforms it
100is not possible to determine the size of individual stack elements, so it is
101essential that the format string corresponds exactly to the passed arguments.
102If this is not the case, incorrect values may be put into the result.
103
104@li @em Reference @em Gap.
105For the same reason it is also essential that the format string does not
106contain any &quot;gaps&quot; in the positional arguments. For example,
107@verbatim
108 trio_printf("%1$d %3$d\n", 1, 2, 3);
109@endverbatim
110is NOT allowed. The format string parser has no knowledge about whether the
111second argument is, say, an integer or a long double (which have different
112sizes).
113@verbatim
114@endverbatim
115[UNIX98] describes this as unspecified behaviour. [TRIO] will detect reference
116gaps and return an error.
117
118@li @em Double @em Reference.
119It is also not allowed to reference an argument twice or more. For example,
120@verbatim
121 trio_printf("%1$d %1$lf\n", 1);
122@endverbatim
123is NOT allowed, because it references the first argument as two differently
124sized objects.
125@verbatim
126@endverbatim
127[UNIX98] describes this as unspecified behaviour. [TRIO] will detect double
128references and return an error.
129
130The following two statements are equivalent
131@verbatim
132 trio_printf("|%d %s\n|", 42, "meanings");
133 |42 meanings|
134
135 trio_printf("|%1$d %2$s|\n", 42, "meanings");
136 |42 meanings|
137@endverbatim
138
139@em Width ( @c 9 )
140
141Specifies the minimum width of a field. If the fields has less characters than
142specified by the width, the field will be left adjusted and padded by spaces.
143The adjustment and padding can be changed by the Alignment ( @c - ) and
144Padding ( @c 0 ) modifiers.
145
146The width is specified as a number. If an asterix ( @c * ) is used instead, the
147width will be read from the argument list.
148
149Prefixes, such as 0x for hexadecimal integers, are part of width.
150@verbatim
151 trio_printf("|%10i|\n", 42);
152 | 42|
153@endverbatim
154
155@em Precision ( @c .9 )
156
157The precision has different semantics for the various data types.
158The precision specifies the maximum number of printed characters for strings,
159the number of digits after the decimal-point for floating-point numbers,
160the number of significant digits for the @c g (and @c G) representation of
161floating-point numbers, the minimum number of printed digits for integers.
162@verbatim
163 trio_printf("|%10.8i|%.8i|\n", 42, 42);
164 | 00000042|00000042|
165@endverbatim
166
167@em Base ( @c ..9 ) [TRIO]
168
169Sets the base that the associated integer must be converted to. The base can
170be between 2 and 36 (both included).
171@verbatim
172 trio_printf("|%10.8.2i|%10..2i|%..2i|\n", 42, 42, 42);
173 | 00101010| 101010|101010|
174
175 trio_printf("|%*.8.*i|\n", 10, 2, 42);
176 | 00101010|
177@endverbatim
178
179@em Padding ( @c 0 )
180
181Integer and floating point numbers are prepended by zeros. The number of
182leading zeros are determined by the precision. If precision is not present,
183width is used instead.
184
185@em Short ( @c h )
186
187Integer arguments are read as an ( @c unsigned ) @c short @c int. String
188and character arguments are read as @c char @c * and @c char respectively.
189
190@em Short @em short ( @c hh ) [C99, GNU]
191
192The argument is read as an ( @c unsigned ) @c char.
193
194@em Fixed @em Size ( @c I ) [MSVC]
195
196The argument is read as a fixed sized integer. The modifier is followed by
197a number, which specifies the number of bits in the integer, and can be one
198of the following
199
200@li @c I8
201@li @c I16
202@li @c I32
203@li @c I64 (if 64-bits integers are supported)
204
205Works only for integers (i, u, d, o, x, X)
206
207@em Largest ( @c j ) [C99]
208
209The argument is read as an @c intmax_t / @c uintmax_t, which is defined to
210be the largest signed/unsigned integer.
211
212@em Long ( @c l )
213
214An integral argument is read as an ( @c unsigned ) @c long @c int. A string
215argument is read as a @c wchar_t @c *, and output as a multi-byte character
216sequence.
217
218@em Long @em long ( @c ll ) [C99, UNIX98, GNU]
219
220The argument is read as an ( @c unsigned ) @c long @c long @c int.
221
222@em Long @em double ( @c L ) [C99, UNIX98, GNU]
223
224The argument is read as a @c long @c double.
225
226@em ptrdiff_t ( @c t ) [C99]
227
228The argument is read as a @c ptrdiff_t, which is defined to be the signed
229integer type of the result of subtracting two pointers.
230
231@em Quad ( @c q ) [BSD, GNU]
232
233Corresponds to the long long modifier ( @c ll ).
234
235@em Wide ( @c w ) [MISC]
236
237For a string argument this is equivalent to using the long modifier ( @c l ).
238
239@em size_t ( @c z ) [C99]
240
241The argument is read as a @c size_t, which is defined to be the type
242returned by the @c sizeof operator.
243
244@em size_t ( @c Z ) [GNU]
245
246Corresponds to the size_t modifier ( @c z ).
247
248@em Alternative ( @c # )
249
250Prepend radix indicator for hexadecimal, octal, and binary integer numbers
251and for pointers.
252Always add a decimal-point for floating-point numbers.
253Escape non-printable characters for strings.
254
255@em Spacing ( )
256
257Prepend leading spaces when necessary.
258
259@em Sign ( @c + )
260
261Always prepend a sign to numbers. Normally only the negative sign is prepended
262to a number. With this modifier the positive sign may also be prepended.
263
264@em Alignment ( @c - )
265
266The output will be left-justified in the field specified by the width.
267
268@em Argument ( @c * )
269
270Width, precision, or base is read from the argument list, rather than from
271the formatting string.
272
273@em Quote / @em Grouping ( @c ' ) [MISC]
274
275Groups integers and the integer-part of floating-point numbers according to
276the locale. Quote strings and characters.
277
278@em Sticky ( @c ! ) [TRIO]
279
280The modifiers listed for the current specifier will be reused by subsequent
281specifiers of the same group.
282The following specifier groups exists
283@li Integer ( @c i, @c u, @c d, @c o, @c x, @c X )
284@li Floating-point ( @c f, @c F, @c e, @c E, @c g, @c G, @c a, @c A )
285@li Character ( @c c )
286@li String ( @c s )
287@li Pointer ( @c p )
288@li Count ( @c n )
289@li Errno ( @c m )
290@li Group ( @c [] )
291
292The sticky modifiers are active until superseeded by other sticky modifiers,
293or the end of the format string is reached.
294Local modifiers overrides sticky modifiers for the given specifier only.
295@verbatim
296 trio_printf("|%!08#x|%04x|%x|\n", 42, 42, 42);
297 |0x00002a|0x2a|0x00002a|
298@endverbatim
299
300@b Specifiers
301
302@em Percent ( @c % )
303
304Produce a percent ( @c % ) character. This is used to quote the indication
305character. No modifiers are allowed.
306The full syntax is @c %%.
307@verbatim
308 trio_printf("Percent is %%\n");
309 Percent is %
310@endverbatim
311
312@em Hex @em floats ( @c a, @c A ) [C99]
313
314Output a hexadecimal (base 16) representation of a floating point number. The
315number is automatically preceeded by @c 0x ( or @c 0X ). The exponent is
316@c p ( or @c P ).
317@verbatim
318 trio_printf("|%a|%A|\n", 3.1415, 3.1415e20);
319 |0x3.228bc|0X3.228BCP+14|
320@endverbatim
321
322@em Binary @em numbers ( @c b, @c B ) [MISC - SCO UnixWare 7]
323
324DEPRECATED: Use Base modifier @c %..2i instead.
325
326@em Character ( @c c )
327
328Output a single character.
329
330@li Quote ( @c ' ) [TRIO].
331Quote the character.
332
333@em Decimal ( @c d )
334
335Output a decimal (base 10) representation of a number.
336
337@li Grouping ( @c ' ) [TRIO].
338The number is separated by the locale thousand separator.
339@verbatim
340 trio_printf("|%'ld|\n", 1234567);
341 |1,234,567|
342@endverbatim
343
344@em Floating-point ( @c e, @c E)
345
346Output a decimal floating-point number.
347The style is @c [-]9.99e[-]9, where
348@li @c [-]9.99 is the mantissa (as described for the @c f, @c F specifier), and
349@li @c e[-]9 is the exponent indicator (either @c e or @c E, depending on the
350floating-point specifier), followed by an optional sign and the exponent
351
352If the precision is wider than the maximum number of digits that can be
353represented by the floating-point unit, then the number will be adequately
354rounded. For example, assuming DBL_DIG is 15
355@verbatim
356 trio_printf("|%.18e|\n", (1.0 / 3.0));
357 |3.333333333333333000e-01|
358@endverbatim
359
360@em Floating-point ( @c f, @c F )
361
362Output a decimal floating-point number.
363The style is @c [-]9.99, where
364@li @c [-] is an optional sign (either @c + or @c -),
365@li @c 9 is the integer-part (possibly interspersed with thousand-separators),
366@li @c . is the decimal-point (depending on the locale), and
367@li @c 99 is the fractional-part.
368
369If more digits are needed to output the number, than can be represented with
370the accuracy of the floating-point unit, then the number will be adequately
371rounded. For example, assuming that DBL_DIG is 15
372@verbatim
373 trio_printf("|%f|\n", (2.0 / 3.0) * 1E18);
374 |666666666666666700.000000|
375@endverbatim
376
377The following modifiers holds a special meaning for this specifier
378@li Alternative ( @c # ) [C99].
379Add decimal point.
380@li Grouping ( @c ' ) [TRIO].
381Group integer part of number into thousands (according to locale).
382
383@em Floating-point ( @c g, @c G)
384
385Output a decimal floating-point representation of a number. The format of
386either the @c f, @c F specifier or the @c e, @c E specifier is used, whatever
387produces the shortest result.
388
389@em Integer ( @c i )
390
391Output a signed integer. Default base is 10.
392
393@em Errno ( @c m ) [GNU]
394
395@em Count ( @c n )
396
397Insert into the location pointed to by the argument, the number of octets
398written to the output so far.
399
400@em Octal ( @c o )
401
402Output an octal (base 8) representation of a number.
403
404@em Pointer ( @c p )
405
406Ouput the address of the argument. The address is printed as a hexadecimal
407number. If the argument is the NULL pointer the text @c (nil) will be used
408instead.
409@li Alternative ( @c # ) [TRIO].
410Prepend 0x
411
412@em String ( @c s, @c S )
413
414Output a string. The argument must point to a zero terminated string. If the
415argument is the NULL pointer the text @c (nil) will be used instead.
416@c S is equivalent to @c ls.
417@li Alternative ( @c # ) [TRIO].
418Escape non-printable characters.
419
420Non-printable characters are converted into C escapes, or hexadecimal numbers
421where no C escapes exists for the character. The C escapes, the hexadecimal
422number, and all backslashes are prepended by a backslash ( @c \ ).
423The supported C escapes are
424@li @c \a (\007) = alert
425@li @c \b (\010) = backspace
426@li @c \f (\014) = formfeed
427@li @c \n (\012) = newline
428@li @c \r (\015) = carriage return
429@li @c \t (\011) = horizontal tab
430@li @c \v (\013) = vertical tab
431
432@verbatim
433 trio_printf("|One %s Three|One %'s Three|\n", "Two", "Two");
434 |One Two Three|One "Two" Three|
435
436 trio_printf("|Argument missing %s|\n", NULL);
437 |Argument missing (nil)|
438
439 trio_printf("|%#s|\n", "\007 \a.");
440 |\a \a.|
441@endverbatim
442
443@em Unsigned ( @c u )
444
445Output an unsigned integer. Default base is 10.
446
447@em Hex ( @c x, @c X )
448
449Output a hexadecimal (base 16) representation of a number.
450
451@li Alternative ( @c # ).
452Preceed the number by @c 0x ( or @c 0X ). The two characters are counted
453as part of the width.
454
455@em User-defined ( @c <> )
456
457Invoke user-defined formatting.
458See @ref trio_register for further information.
459
460@b RETURN @b VALUES
461
462All functions returns the number of outputted characters. If an error occured
463then a negative error code is returned [TRIO]. Note that this is a deviation
464from the standard, which simply returns -1 (or EOF) and errno set
465appropriately.
466The error condition can be detected by checking whether the function returns
467a negative number or not, and the number can be parsed with the following
468macros. The error codes are primarily intended as debugging aide for the
469developer.
470
471@li TRIO_EINVAL: Invalid argument.
472@li TRIO_ETOOMANY: Too many arguments.
473@li TRIO_EDBLREF: Double argument reference.
474@li TRIO_EGAP: Argument reference gap.
475@li TRIO_ENOMEM: Out of memory.
476@li TRIO_ERANGE: Invalid range.
477@li TRIO_ERRNO: The error is specified by the errno variable.
478
479Example:
480@verbatim
481 int rc;
482
483 rc = trio_printf("%r\n", 42);
484 if (rc < 0) {
485 if (TRIO_ERROR_CODE(rc) != TRIO_EOF) {
486 trio_printf("Error: %s at position %d\n",
487 TRIO_ERROR_NAME(rc),
488 TRIO_ERROR_POSITION(rc));
489 }
490 }
491@endverbatim
492
493@b SEE @b ALSO
494
495@e trio_scanf, @e trio_register.
496
497@b NOTES
498
499The printfv family uses an array rather than the stack to pass arguments.
500This means that @c short @c int and @c float values will not be handled by
501the default argument promotion in C. Instead, these values must be explicitly
502converted with the Short (h) modifier in both cases.
503
504Example:
505@verbatim
506 void *array[2];
507 float float_number = 42.0;
508 short short_number = 42;
509
510 array[0] = &float_number;
511 array[1] = &short_number;
512
513 trio_printfv("%hf %hd\n", array); /* CORRECT */
514 trio_printfv("%f %d\n", array); /* WRONG */
515@endverbatim
516
517@b CONFORMING @b TO
518
519Throughout this document the following abbreviations have been used to
520indicate what standard a feature conforms to. If nothing else is indicated
521ANSI C (C89) is assumed.
522
523@li [C89] ANSI X3.159-1989
524@li [C99] ISO/IEC 9899:1999
525@li [UNIX98] The Single UNIX Specification, Version 2
526@li [BSD] 4.4BSD
527@li [GNU] GNU libc
528@li [MSVC] Microsoft Visual C
529@li [MISC] Other non-standard sources
530@li [TRIO] Extensions specific for this package
531
532*/
diff --git a/gs/trio/doc/doc_register.h b/gs/trio/doc/doc_register.h
new file mode 100644
index 000000000..3ce86c570
--- /dev/null
+++ b/gs/trio/doc/doc_register.h
@@ -0,0 +1,384 @@
1/*************************************************************************
2 *
3 * $Id: doc_register.h,v 1.3 2008/10/12 12:09:51 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
18/** @addtogroup UserDefined User-defined Formatted Printing Functions.
19Functions for using customized formatting specifiers.
20
21@b SYNOPSIS
22
23@verbatim
24cc ... -ltrio -lm
25
26#include <trio.h>
27#include <triop.h>
28@endverbatim
29
30@b DESCRIPTION
31
32This documentation is incomplete.
33
34@b User-defined @b Specifier
35
36The user-defined specifier consists of a start character (\074 = '<'), an
37optional namespace string followed by a namespace separator (\072 = ':'),
38a format string, an optional skipping separator (\174 = '|'), and an end
39character (\076 = '>').
40
41The namespace string can consist of alphanumeric characters, and is used to
42define a named reference (see below). The namespace is case-sensitive. If no
43namespace is specified, then we use an unnamed reference (see below).
44
45The format can consist of any character except the end character ('>'), the
46namespace separator (':'), the skipping separator ('|'), and the nil character
47(\000).
48
49Any modifier can be used together with the user-defined specifier.
50
51There are two formats for invoking a user-defined specifier. The first format
52is an extension of the normal printf/scanf formatting. It uses the percent
53character (\045 = '%') followed by optional qualifiers and a specifier. For
54example:
55
56@verbatim
57 trio_printf("%<format>\n", my_handle, my_data);
58@endverbatim
59
60Some C compilers can issue a warning if there is a mismatch between specifiers
61and arguments. Unfortunately, these warnings does not work with the first
62format for user-defined specifiers. Therefore the second format has been
63introduced. The second format can only be applied to user-defined specifiers.
64
65The second format starts with a dollar character (\044 = '$') instead of the
66percent character, and is followed by optional qualifiers and the user-defined
67specifier. If the specifier contains a pipe character (\174 = '|'), then
68everything between the pipe character and the end character ('>') is ignored.
69The ignored part can be used to list the normal specifiers that the C compiler
70uses to determine mismatches. For example:
71
72@verbatim
73 trio_printf("$<format|%p%p>\n", my_handle, my_data);
74@endverbatim
75
76@b Registering
77
78A user-defined specifier must be registered before it can be used.
79Unregistered user-defined specifiers are ignored. The @ref trio_register
80function is used to register a user-defined specifier. It takes two argument,
81a callback function and a namespace, and it returns a handle. The handle must
82be used to unregister the specifier later.
83
84The following example registers a user-define specifier with the "my_namespace"
85namespace:
86
87@verbatim
88 my_handle = trio_register(my_callback, "my_namespace");
89@endverbatim
90
91There can only be one user-defined specifier with a given namespace. There
92can be an unlimited number (subject to maximum length of the namespace) of
93different user-defined specifiers.
94
95Passing NULL as the namespace argument results in an anonymous reference.
96There can be an unlimited number of anonymous references.
97
98@b REFERENCES
99
100There are two ways that a registered callback can be called. Either the
101user-defined specifier must contain the registered namespace in the format
102string, or the handle is passed as an argument to the formatted printing
103function.
104
105If the namespace is used, then a user-defined pointer must be passed as an
106argument:
107
108@verbatim
109 trio_printf("%<my_namespace:format>\n", my_data);
110@endverbatim
111
112If the handle is used, then the user-defined specifier must not contain a
113namespace. Instead the handle must be passed as an argument, followed by a
114user-defined pointer:
115
116@verbatim
117 trio_printf("%<format>\n", my_handle, my_data);
118@endverbatim
119
120The two examples above are equivalent.
121
122There must be exactly one user-defined pointer per user-defined specifier.
123This pointer can be used within the callback function with the
124@ref trio_get_argument getter function (see below).
125
126The format string is optional. It can be used within the callback function
127with the @ref trio_get_format getter function.
128
129@b Anonymous @b References
130Anonymous references are specified by passing NULL as the namespace.
131
132The handle must be passed as an argument followed by a user-defined pointer.
133No namespace can be specified.
134
135@verbatim
136 anon_handle = trio_register(callback, NULL);
137 trio_printf("%<format>\n", anon_handle, my_data);
138@endverbatim
139
140@b Restrictions
141
142@li The length of the namespace string cannot exceed 63 characters.
143@li The length of the user-defined format string cannot exceed 255 characters.
144@li User-defined formatting cannot re-define existing specifiers.
145This restriction was imposed because the existing formatting specifiers have
146a well-defined behaviour, and any re-definition would apply globally to an
147application (imagine a third-party library changing the behaviour of a
148specifier that is crusial to your application).
149
150@b CALLBACK @b FUNCTION
151
152The callback function will be called if a matching user-defined specifier
153is found within the formatting string. The callback function takes one input
154parameter, an opaque reference which is needed by the private functions. It
155returns an @c int, which is currently ignored. The prototype is
156
157@verbatim
158 int (*trio_callback_t)(void *ref);
159@endverbatim
160
161See the Example section for full examples.
162
163@b PRINTING @b FUNCTIONS
164
165The following printing functions must only be used inside a callback function.
166These functions will print to the same output medium as the printf function
167which invoked the callback function. For example, if the user-defined
168specifier is used in an sprintf function, then these print functions will
169output their result to the same string.
170
171@b Elementary @b Printing
172
173There are a number of function to print elementary data types.
174
175@li @ref trio_print_int Print a signed integer. For example:
176@verbatim
177 trio_print_int(42);
178@endverbatim
179@li @ref trio_print_uint Print an unsigned integer.
180@li @ref trio_print_double Print a floating-point number.
181@li @ref trio_print_string Print a string. For example:
182@verbatim
183 trio_print_string("Hello World");
184 trio_print_string(trio_get_format());
185@endverbatim
186@li @ref trio_print_pointer Print a pointer.
187
188@b Formatted @b Printing
189
190The functions @ref trio_print_ref, @ref trio_vprint_ref, and
191@ref trio_printv_ref outputs a formatted string just like its printf
192equivalents.
193
194@verbatim
195 trio_print_ref(ref, "There are %d towels\n", 42);
196 trio_print_ref(ref, "%<recursive>\n", recursive_writer, trio_get_argument(ref));
197@endverbatim
198
199@b GETTER @b AND @b SETTER @b FUNCTIONS
200
201The following getter and setter functions must only be used inside a callback
202function. They can either operate on the modifiers or on special data.
203
204@b Modifiers
205
206The value of a modifier, or a boolean indication of its presence or absence,
207can be found or set with the getter and setter functions.
208The generic prototypes of the these getter and setter functions are
209
210@verbatim
211 int trio_get_???(void *ref);
212 void trio_set_???(void *ref, int);
213@endverbatim
214
215where @c ??? refers to a modifier. For example, to get the width of the
216user-defined specifier use
217
218@verbatim
219 int width = trio_get_width(ref);
220@endverbatim
221
222@b Special @b Data
223
224Consider the following user-defined specifier, in its two possible referencing
225presentations.
226
227@verbatim
228 trio_printf("%<format>\n", namespace_writer, argument);
229 trio_printf("%<namespace:format>\n", argument);
230@endverbatim
231
232@ref trio_get_format will get the @p format string, and
233@ref trio_get_argument} will get the @p argument parameter.
234There are no associated setter functions.
235
236@b EXAMPLES
237
238The following examples show various types of user-defined specifiers. Although
239each specifier is demonstrated in isolation, they can all co-exist within the
240same application.
241
242@b Time @b Example
243
244Print the time in the format "HOUR:MINUTE:SECOND" if "time" is specified inside
245the user-defined specifier.
246
247@verbatim
248 static int time_print(void *ref)
249 {
250 const char *format;
251 time_t *data;
252 char buffer[256];
253
254 format = trio_get_format(ref);
255 if ((format) && (strcmp(format, "time") == 0)) {
256 data = trio_get_argument(ref);
257 if (data == NULL)
258 return -1;
259 strftime(buffer, sizeof(buffer), "%H:%M:%S", localtime(data));
260 trio_print_string(ref, buffer);
261 }
262 return 0;
263 }
264@endverbatim
265
266@verbatim
267 int main(void)
268 {
269 void *handle;
270 time_t now = time(NULL);
271
272 handle = trio_register(time_print, "my_time");
273
274 trio_printf("%<time>\n", handle, &now);
275 trio_printf("%<my_time:time>\n", &now);
276
277 trio_unregister(handle);
278 return 0;
279 }
280@endverbatim
281
282@b Complex @b Numbers @b Example
283
284Consider a complex number consisting of a real part, re, and an imaginary part,
285im.
286
287@verbatim
288 struct Complex {
289 double re;
290 double im;
291 };
292@endverbatim
293
294This example can print such a complex number in one of two formats.
295The default format is "re + i im". If the alternative modifier is used, then
296the format is "r exp(i theta)", where r is the length of the complex vector
297(re, im) and theta is its angle.
298
299@verbatim
300 static int complex_print(void *ref)
301 {
302 struct Complex *data;
303 const char *format;
304
305 data = (struct Complex *)trio_get_argument(ref);
306 if (data) {
307 format = trio_get_format(ref);
308
309 if (trio_get_alternative(ref)) {
310 double r, theta;
311
312 r = sqrt(pow(data->re, 2) + pow(data->im, 2));
313 theta = acos(data->re / r);
314 trio_print_ref(ref, "%#f exp(i %#f)", r, theta);
315
316 } else {
317 trio_print_ref(ref, "%#f + i %#f", data->re, data->im);
318 }
319 }
320 return 0;
321 }
322@endverbatim
323
324@verbatim
325 int main(void)
326 {
327 void *handle;
328
329 handle = trio_register(complex_print, "complex");
330
331 /* Normal format. With handle and the with namespace */
332 trio_printf("%<>\n", handle, &complex);
333 trio_printf("%<complex:>\n", &complex);
334 /* In exponential notation */
335 trio_printf("%#<>\n", handle, &complex);
336 trio_printf("%#<complex:unused data>\n", &complex);
337
338 trio_unregister(handle);
339 return 0;
340 }
341@endverbatim
342
343@b RETURN @b VALUES
344
345@ref trio_register returns a handle, or NULL if an error occured.
346
347@b SEE @b ALSO
348
349@ref trio_printf
350
351@b NOTES
352
353User-defined specifiers, @ref trio_register, and @ref trio_unregister are
354not thread-safe. In multi-threaded applications they must be guarded by
355mutexes. Trio provides two special callback functions, called ":enter" and
356":leave", which are invoked every time a thread-unsafe operation is attempted.
357As the thread model is determined by the application, these callback functions
358must be implemented by the application.
359
360The following callback functions are for demonstration-purposes only.
361Replace their bodies with locking and unlocking of a mutex to achieve
362thread-safety.
363@verbatim
364 static int enter_region(void *ref)
365 {
366 fprintf(stderr, "Enter Region\n");
367 return 1;
368 }
369
370 static int leave_region(void *ref)
371 {
372 fprintf(stderr, "Leave Region\n");
373 return 1;
374 }
375@endverbatim
376These two callbacks must be registered before other callbacks are registered.
377@verbatim
378 trio_register(enter_region, ":enter");
379 trio_register(leave_region, ":leave");
380
381 another_handle = trio_register(another_callback, NULL);
382@endverbatim
383
384*/
diff --git a/gs/trio/doc/doc_scanf.h b/gs/trio/doc/doc_scanf.h
new file mode 100644
index 000000000..4d997d401
--- /dev/null
+++ b/gs/trio/doc/doc_scanf.h
@@ -0,0 +1,120 @@
1/*************************************************************************
2 *
3 * $Id: doc_scanf.h,v 1.1 2001/12/27 17:29:20 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
18/** @addtogroup Scanf Formatted Scanning Functions.
19Variations of formatted scanning functions.
20
21@b SYNOPSIS
22
23@verbatim
24cc ... -ltrio -lm
25
26#include <trio.h>
27@endverbatim
28
29@b DESCRIPTION
30
31This documentation is incomplete.
32The documentation of the scanf family in [C99] and [UNIX98] also applies
33to the trio counterparts.
34
35@b SCANNING
36
37The scanning is controlled by the format string.
38The format string can contain normal text and conversion indicators.
39The normal text can be any character except the nil character
40(\000) and the percent character (\045 = '\%').
41Conversion indicators consists of an indication character (%), followed by
42zero or more conversion modifiers, and exactly one conversion specifier.
43
44@b Modifiers
45
46@em Positional ( @c 9$ ) [UNIX98]
47
48See @ref trio_printf.
49
50@b Specifiers
51
52@em Percent ( @c % )
53
54@em Character ( @c c )
55
56@em Decimal ( @c d )
57
58@em Floating-point ( @c a, @c A, @c e, @c E, @c f, @c F, @c g, @c G )
59
60@em Integer ( @c i )
61
62@em Count ( @c n )
63
64@em Octal ( @c o )
65
66@em Pointer ( @c p )
67
68@em String ( @c s )
69
70@em Unsigned ( @c u )
71
72@em Hex ( @c x, @c X )
73
74@em Scanlist ( @c [] )
75
76Scanlist Exclusion (@c ^ )
77
78Scanlist Range ( @c - ) [TRIO]
79
80@li Only increasing ranges, i.e. @c [a-b], but not @c [b-a].
81@li Transitive ranges, ie. @c [a-b-c] equals @c [a-c].
82@li Trailing minus, ie. @c [a-] is interpreted as an @c a and a @c -.
83@li Duplicates are ignored.
84
85Scanlist Equivalence Class Expression ( @c [= @c =] ) [TRIO]
86
87Locale dependent (LC_COLLATE).
88Only one expression can appear inside the delimiters.
89@li @c [=a=] All letters in the same equivalence class as the letter @c a.
90@verbatim
91 trio_scanf("%[[=a=]b]\n", buffer);
92 trio_scanf("%[[=a=][=b=]]\n", buffer);
93@endverbatim
94
95Scanlist Character Class Expression ( @c [: @c :]) [TRIO]
96Locale dependent (LC_CTYPE).
97Only one expression can appear inside the delimiters.
98@li @c [:alnum:] Same as @c [:alpha:] and @c [:digit:]
99@li @c [:alpha:] Same as @c [:lower:] and @c [:upper:]
100@li @c [:cntrl:] Control characters
101@li @c [:digit:] Decimal digits
102@li @c [:graph:] Printable characters except space
103@li @c [:lower:] Lower case alphabetic letters
104@li @c [:print:] Printable characters
105@li @c [:punct:] Punctuation
106@li @c [:space:] Whitespace characters
107@li @c [:upper:] Upper case alphabetic letters
108@li @c [:xdigit:] Hexadecimal digits
109@verbatim
110 trio_scanf("%[[:alnum:]]\n", buffer);
111 trio_scanf("%[[:alpha:][:digit:]]\n", buffer);
112@endverbatim
113
114@b RETURN @b VALUES
115
116@b SEE @b ALSO
117
118@ref trio_printf
119
120*/
diff --git a/gs/trio/doc/doc_static.h b/gs/trio/doc/doc_static.h
new file mode 100644
index 000000000..6816196d9
--- /dev/null
+++ b/gs/trio/doc/doc_static.h
@@ -0,0 +1,61 @@
1/*************************************************************************
2 *
3 * $Id: doc_static.h,v 1.1 2001/12/27 17:29:20 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
18/** @addtogroup StaticStrings Static String Functions.
19Replacements for the standard C string functions.
20
21@b SYNOPSIS
22
23@verbatim
24cc ... -ltrio -lm
25
26#include <triostr.h>
27@endverbatim
28
29@b DESCRIPTION
30
31This package renames, fixes, and extends the standard C string handling
32functions.
33
34@b Naming
35
36Renaming is done to provide more clear names, to provide a consistant naming
37and argument policy, and to hide portability issues.
38
39@li All functions starts with "trio_".
40@li Target is always the first argument, if present, except where the target
41is optional, such as @ref trio_to_double.
42@li Functions requiring a size for target includes "_max" in its name, and
43the size is always the second argument.
44@li Functions performing case-sensitive operations includes "_case" in its
45name.
46
47@b Fixing
48
49Fixing is done to avoid subtle error conditions.
50For example, @c strncpy does not terminate the result with a zero if the
51source string is bigger than the maximal length, so technically the result
52is not a C string anymore. @ref trio_copy_max makes sure that the result
53is zero terminated.
54
55@b Extending
56
57Extending is done to provide a richer set of fundamental functions.
58This includes functionality such as wildcard matching ( @c trio_match )
59and calculation of hash values ( @c trio_hash ).
60
61*/
diff --git a/gs/trio/doc/footer.html b/gs/trio/doc/footer.html
new file mode 100644
index 000000000..f149fa2a1
--- /dev/null
+++ b/gs/trio/doc/footer.html
@@ -0,0 +1,4 @@
1<HR>
2<center class="copyright">Copyright (C) 2001 - 2006 Bj&oslash;rn Reese and Daniel Stenberg.</center>
3</body>
4</html>
diff --git a/gs/trio/doc/header.html b/gs/trio/doc/header.html
new file mode 100644
index 000000000..fd2edd1b9
--- /dev/null
+++ b/gs/trio/doc/header.html
@@ -0,0 +1,8 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
5 <title>TRIO</title>
6 <link href="trio.css" rel="stylesheet" type="text/css">
7</head>
8<body>
diff --git a/gs/trio/doc/trio.cfg b/gs/trio/doc/trio.cfg
new file mode 100644
index 000000000..4bc1ee679
--- /dev/null
+++ b/gs/trio/doc/trio.cfg
@@ -0,0 +1,873 @@
1# Doxyfile 1.2.12
2
3# This file describes the settings to be used by the documentation system
4# doxygen (www.doxygen.org) for a project
5#
6# All text after a hash (#) is considered a comment and will be ignored
7# The format is:
8# TAG = value [value, ...]
9# For lists items can also be appended using:
10# TAG += value [value, ...]
11# Values that contain spaces should be placed between quotes (" ")
12
13#---------------------------------------------------------------------------
14# General configuration options
15#---------------------------------------------------------------------------
16
17# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
18# by quotes) that should identify the project.
19
20PROJECT_NAME = TRIO
21
22# The PROJECT_NUMBER tag can be used to enter a project or revision number.
23# This could be handy for archiving the generated documentation or
24# if some version control system is used.
25
26PROJECT_NUMBER =
27
28# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
29# base path where the generated documentation will be put.
30# If a relative path is entered, it will be relative to the location
31# where doxygen was started. If left blank the current directory will be used.
32
33OUTPUT_DIRECTORY =
34
35# The OUTPUT_LANGUAGE tag is used to specify the language in which all
36# documentation generated by doxygen is written. Doxygen will use this
37# information to generate all constant output in the proper language.
38# The default language is English, other supported languages are:
39# Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French,
40# German, Hungarian, Italian, Japanese, Korean, Norwegian, Polish,
41# Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish.
42
43OUTPUT_LANGUAGE = English
44
45# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
46# documentation are documented, even if no documentation was available.
47# Private class members and static file members will be hidden unless
48# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
49
50EXTRACT_ALL = NO
51
52# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
53# will be included in the documentation.
54
55EXTRACT_PRIVATE = NO
56
57# If the EXTRACT_STATIC tag is set to YES all static members of a file
58# will be included in the documentation.
59
60EXTRACT_STATIC = NO
61
62# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
63# undocumented members of documented classes, files or namespaces.
64# If set to NO (the default) these members will be included in the
65# various overviews, but no documentation section is generated.
66# This option has no effect if EXTRACT_ALL is enabled.
67
68HIDE_UNDOC_MEMBERS = YES
69
70# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
71# undocumented classes that are normally visible in the class hierarchy.
72# If set to NO (the default) these class will be included in the various
73# overviews. This option has no effect if EXTRACT_ALL is enabled.
74
75HIDE_UNDOC_CLASSES = YES
76
77# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
78# include brief member descriptions after the members that are listed in
79# the file and class documentation (similar to JavaDoc).
80# Set to NO to disable this.
81
82BRIEF_MEMBER_DESC = YES
83
84# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
85# the brief description of a member or function before the detailed description.
86# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
87# brief descriptions will be completely suppressed.
88
89REPEAT_BRIEF = YES
90
91# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
92# Doxygen will generate a detailed section even if there is only a brief
93# description.
94
95ALWAYS_DETAILED_SEC = NO
96
97# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
98# path before files name in the file list and in the header files. If set
99# to NO the shortest path that makes the file name unique will be used.
100
101FULL_PATH_NAMES = NO
102
103# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
104# can be used to strip a user defined part of the path. Stripping is
105# only done if one of the specified strings matches the left-hand part of
106# the path. It is allowed to use relative paths in the argument list.
107
108STRIP_FROM_PATH =
109
110# The INTERNAL_DOCS tag determines if documentation
111# that is typed after a \internal command is included. If the tag is set
112# to NO (the default) then the documentation will be excluded.
113# Set it to YES to include the internal documentation.
114
115INTERNAL_DOCS = NO
116
117# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
118# doxygen to hide any special comment blocks from generated source code
119# fragments. Normal C and C++ comments will always remain visible.
120
121STRIP_CODE_COMMENTS = YES
122
123# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
124# file names in lower case letters. If set to YES upper case letters are also
125# allowed. This is useful if you have classes or files whose names only differ
126# in case and if your file system supports case sensitive file names. Windows
127# users are adviced to set this option to NO.
128
129CASE_SENSE_NAMES = NO
130
131# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
132# (but less readable) file names. This can be useful is your file systems
133# doesn't support long names like on DOS, Mac, or CD-ROM.
134
135SHORT_NAMES = NO
136
137# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
138# will show members with their full class and namespace scopes in the
139# documentation. If set to YES the scope will be hidden.
140
141HIDE_SCOPE_NAMES = NO
142
143# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
144# will generate a verbatim copy of the header file for each class for
145# which an include is specified. Set to NO to disable this.
146
147VERBATIM_HEADERS = NO
148
149# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
150# will put list of the files that are included by a file in the documentation
151# of that file.
152
153SHOW_INCLUDE_FILES = NO
154
155# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
156# will interpret the first line (until the first dot) of a JavaDoc-style
157# comment as the brief description. If set to NO, the JavaDoc
158# comments will behave just like the Qt-style comments (thus requiring an
159# explict @brief command for a brief description.
160
161JAVADOC_AUTOBRIEF = YES
162
163# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
164# member inherits the documentation from any documented member that it
165# reimplements.
166
167INHERIT_DOCS = YES
168
169# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
170# is inserted in the documentation for inline members.
171
172INLINE_INFO = YES
173
174# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
175# will sort the (detailed) documentation of file and class members
176# alphabetically by member name. If set to NO the members will appear in
177# declaration order.
178
179SORT_MEMBER_DOCS = YES
180
181# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
182# tag is set to YES, then doxygen will reuse the documentation of the first
183# member in the group (if any) for the other members of the group. By default
184# all members of a group must be documented explicitly.
185
186DISTRIBUTE_GROUP_DOC = NO
187
188# The TAB_SIZE tag can be used to set the number of spaces in a tab.
189# Doxygen uses this value to replace tabs by spaces in code fragments.
190
191TAB_SIZE = 8
192
193# The GENERATE_TODOLIST tag can be used to enable (YES) or
194# disable (NO) the todo list. This list is created by putting \todo
195# commands in the documentation.
196
197GENERATE_TODOLIST = YES
198
199# The GENERATE_TESTLIST tag can be used to enable (YES) or
200# disable (NO) the test list. This list is created by putting \test
201# commands in the documentation.
202
203GENERATE_TESTLIST = YES
204
205# The GENERATE_BUGLIST tag can be used to enable (YES) or
206# disable (NO) the bug list. This list is created by putting \bug
207# commands in the documentation.
208
209GENERATE_BUGLIST = YES
210
211# This tag can be used to specify a number of aliases that acts
212# as commands in the documentation. An alias has the form "name=value".
213# For example adding "sideeffect=\par Side Effects:\n" will allow you to
214# put the command \sideeffect (or @sideeffect) in the documentation, which
215# will result in a user defined paragraph with heading "Side Effects:".
216# You can put \n's in the value part of an alias to insert newlines.
217
218ALIASES =
219
220# The ENABLED_SECTIONS tag can be used to enable conditional
221# documentation sections, marked by \if sectionname ... \endif.
222
223ENABLED_SECTIONS =
224
225# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
226# the initial value of a variable or define consist of for it to appear in
227# the documentation. If the initializer consists of more lines than specified
228# here it will be hidden. Use a value of 0 to hide initializers completely.
229# The appearance of the initializer of individual variables and defines in the
230# documentation can be controlled using \showinitializer or \hideinitializer
231# command in the documentation regardless of this setting.
232
233MAX_INITIALIZER_LINES = 30
234
235# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
236# only. Doxygen will then generate output that is more tailored for C.
237# For instance some of the names that are used will be different. The list
238# of all members will be omitted, etc.
239
240OPTIMIZE_OUTPUT_FOR_C = YES
241
242# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
243# at the bottom of the documentation of classes and structs. If set to YES the
244# list will mention the files that were used to generate the documentation.
245
246SHOW_USED_FILES = YES
247
248#---------------------------------------------------------------------------
249# configuration options related to warning and progress messages
250#---------------------------------------------------------------------------
251
252# The QUIET tag can be used to turn on/off the messages that are generated
253# by doxygen. Possible values are YES and NO. If left blank NO is used.
254
255QUIET = NO
256
257# The WARNINGS tag can be used to turn on/off the warning messages that are
258# generated by doxygen. Possible values are YES and NO. If left blank
259# NO is used.
260
261WARNINGS = YES
262
263# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
264# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
265# automatically be disabled.
266
267WARN_IF_UNDOCUMENTED = YES
268
269# The WARN_FORMAT tag determines the format of the warning messages that
270# doxygen can produce. The string should contain the $file, $line, and $text
271# tags, which will be replaced by the file and line number from which the
272# warning originated and the warning text.
273
274WARN_FORMAT =
275
276# The WARN_LOGFILE tag can be used to specify a file to which warning
277# and error messages should be written. If left blank the output is written
278# to stderr.
279
280WARN_LOGFILE =
281
282#---------------------------------------------------------------------------
283# configuration options related to the input files
284#---------------------------------------------------------------------------
285
286# The INPUT tag can be used to specify the files and/or directories that contain
287# documented source files. You may enter file names like "myfile.cpp" or
288# directories like "/usr/src/myproject". Separate the files or directories
289# with spaces.
290
291INPUT = . doc
292
293# If the value of the INPUT tag contains directories, you can use the
294# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
295# and *.h) to filter out the source-files in the directories. If left
296# blank file matching one of the following patterns are included:
297# *.c *.cc *.cxx *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
298# *.h++ *.idl
299
300FILE_PATTERNS = *.h *.c
301
302# The RECURSIVE tag can be used to turn specify whether or not subdirectories
303# should be searched for input files as well. Possible values are YES and NO.
304# If left blank NO is used.
305
306RECURSIVE = NO
307
308# The EXCLUDE tag can be used to specify files and/or directories that should
309# excluded from the INPUT source files. This way you can easily exclude a
310# subdirectory from a directory tree whose root is specified with the INPUT tag.
311
312EXCLUDE =
313
314# If the value of the INPUT tag contains directories, you can use the
315# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
316# certain files from those directories.
317
318EXCLUDE_PATTERNS =
319
320# The EXAMPLE_PATH tag can be used to specify one or more files or
321# directories that contain example code fragments that are included (see
322# the \include command).
323
324EXAMPLE_PATH = doc
325
326# If the value of the EXAMPLE_PATH tag contains directories, you can use the
327# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
328# and *.h) to filter out the source-files in the directories. If left
329# blank all files are included.
330
331EXAMPLE_PATTERNS =
332
333# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
334# searched for input files to be used with the \include or \dontinclude
335# commands irrespective of the value of the RECURSIVE tag.
336# Possible values are YES and NO. If left blank NO is used.
337
338EXAMPLE_RECURSIVE = NO
339
340# The IMAGE_PATH tag can be used to specify one or more files or
341# directories that contain image that are included in the documentation (see
342# the \image command).
343
344IMAGE_PATH =
345
346# The INPUT_FILTER tag can be used to specify a program that doxygen should
347# invoke to filter for each input file. Doxygen will invoke the filter program
348# by executing (via popen()) the command <filter> <input-file>, where <filter>
349# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
350# input file. Doxygen will then use the output that the filter program writes
351# to standard output.
352
353INPUT_FILTER =
354
355# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
356# INPUT_FILTER) will be used to filter the input files when producing source
357# files to browse.
358
359FILTER_SOURCE_FILES = NO
360
361#---------------------------------------------------------------------------
362# configuration options related to source browsing
363#---------------------------------------------------------------------------
364
365# If the SOURCE_BROWSER tag is set to YES then a list of source files will
366# be generated. Documented entities will be cross-referenced with these sources.
367
368SOURCE_BROWSER = NO
369
370# Setting the INLINE_SOURCES tag to YES will include the body
371# of functions and classes directly in the documentation.
372
373INLINE_SOURCES = NO
374
375# If the REFERENCED_BY_RELATION tag is set to YES (the default)
376# then for each documented function all documented
377# functions referencing it will be listed.
378
379REFERENCED_BY_RELATION = YES
380
381# If the REFERENCES_RELATION tag is set to YES (the default)
382# then for each documented function all documented entities
383# called/used by that function will be listed.
384
385REFERENCES_RELATION = YES
386
387#---------------------------------------------------------------------------
388# configuration options related to the alphabetical class index
389#---------------------------------------------------------------------------
390
391# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
392# of all compounds will be generated. Enable this if the project
393# contains a lot of classes, structs, unions or interfaces.
394
395ALPHABETICAL_INDEX = NO
396
397# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
398# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
399# in which this list will be split (can be a number in the range [1..20])
400
401COLS_IN_ALPHA_INDEX = 5
402
403# In case all classes in a project start with a common prefix, all
404# classes will be put under the same header in the alphabetical index.
405# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
406# should be ignored while generating the index headers.
407
408IGNORE_PREFIX =
409
410#---------------------------------------------------------------------------
411# configuration options related to the HTML output
412#---------------------------------------------------------------------------
413
414# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
415# generate HTML output.
416
417GENERATE_HTML = YES
418
419# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
420# If a relative path is entered the value of OUTPUT_DIRECTORY will be
421# put in front of it. If left blank `html' will be used as the default path.
422
423HTML_OUTPUT =
424
425# The HTML_HEADER tag can be used to specify a personal HTML header for
426# each generated HTML page. If it is left blank doxygen will generate a
427# standard header.
428
429HTML_HEADER = doc/header.html
430
431# The HTML_FOOTER tag can be used to specify a personal HTML footer for
432# each generated HTML page. If it is left blank doxygen will generate a
433# standard footer.
434
435HTML_FOOTER = doc/footer.html
436
437# The HTML_STYLESHEET tag can be used to specify a user defined cascading
438# style sheet that is used by each HTML page. It can be used to
439# fine-tune the look of the HTML output. If the tag is left blank doxygen
440# will generate a default style sheet
441
442HTML_STYLESHEET = doc/trio.css
443
444# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
445# files or namespaces will be aligned in HTML using tables. If set to
446# NO a bullet list will be used.
447
448HTML_ALIGN_MEMBERS = YES
449
450# If the GENERATE_HTMLHELP tag is set to YES, additional index files
451# will be generated that can be used as input for tools like the
452# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
453# of the generated HTML documentation.
454
455GENERATE_HTMLHELP = NO
456
457# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
458# controls if a separate .chi index file is generated (YES) or that
459# it should be included in the master .chm file (NO).
460
461GENERATE_CHI = NO
462
463# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
464# controls whether a binary table of contents is generated (YES) or a
465# normal table of contents (NO) in the .chm file.
466
467BINARY_TOC = NO
468
469# The TOC_EXPAND flag can be set to YES to add extra items for group members
470# to the contents of the Html help documentation and to the tree view.
471
472TOC_EXPAND = NO
473
474# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
475# top of each HTML page. The value NO (the default) enables the index and
476# the value YES disables it.
477
478DISABLE_INDEX = NO
479
480# This tag can be used to set the number of enum values (range [1..20])
481# that doxygen will group on one line in the generated HTML documentation.
482
483ENUM_VALUES_PER_LINE = 4
484
485# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
486# generated containing a tree-like index structure (just like the one that
487# is generated for HTML Help). For this to work a browser that supports
488# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+,
489# or Internet explorer 4.0+). Note that for large projects the tree generation
490# can take a very long time. In such cases it is better to disable this feature.
491# Windows users are probably better off using the HTML help feature.
492
493GENERATE_TREEVIEW = NO
494
495# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
496# used to set the initial width (in pixels) of the frame in which the tree
497# is shown.
498
499TREEVIEW_WIDTH = 250
500
501#---------------------------------------------------------------------------
502# configuration options related to the LaTeX output
503#---------------------------------------------------------------------------
504
505# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
506# generate Latex output.
507
508GENERATE_LATEX = NO
509
510# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
511# If a relative path is entered the value of OUTPUT_DIRECTORY will be
512# put in front of it. If left blank `latex' will be used as the default path.
513
514LATEX_OUTPUT =
515
516# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
517# LaTeX documents. This may be useful for small projects and may help to
518# save some trees in general.
519
520COMPACT_LATEX = NO
521
522# The PAPER_TYPE tag can be used to set the paper type that is used
523# by the printer. Possible values are: a4, a4wide, letter, legal and
524# executive. If left blank a4wide will be used.
525
526PAPER_TYPE = a4wide
527
528# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
529# packages that should be included in the LaTeX output.
530
531EXTRA_PACKAGES =
532
533# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
534# the generated latex document. The header should contain everything until
535# the first chapter. If it is left blank doxygen will generate a
536# standard header. Notice: only use this tag if you know what you are doing!
537
538LATEX_HEADER =
539
540# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
541# is prepared for conversion to pdf (using ps2pdf). The pdf file will
542# contain links (just like the HTML output) instead of page references
543# This makes the output suitable for online browsing using a pdf viewer.
544
545PDF_HYPERLINKS = NO
546
547# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
548# plain latex in the generated Makefile. Set this option to YES to get a
549# higher quality PDF documentation.
550
551USE_PDFLATEX = NO
552
553# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
554# command to the generated LaTeX files. This will instruct LaTeX to keep
555# running if errors occur, instead of asking the user for help.
556# This option is also used when generating formulas in HTML.
557
558LATEX_BATCHMODE = NO
559
560#---------------------------------------------------------------------------
561# configuration options related to the RTF output
562#---------------------------------------------------------------------------
563
564# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
565# The RTF output is optimised for Word 97 and may not look very pretty with
566# other RTF readers or editors.
567
568GENERATE_RTF = NO
569
570# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
571# If a relative path is entered the value of OUTPUT_DIRECTORY will be
572# put in front of it. If left blank `rtf' will be used as the default path.
573
574RTF_OUTPUT =
575
576# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
577# RTF documents. This may be useful for small projects and may help to
578# save some trees in general.
579
580COMPACT_RTF = NO
581
582# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
583# will contain hyperlink fields. The RTF file will
584# contain links (just like the HTML output) instead of page references.
585# This makes the output suitable for online browsing using WORD or other
586# programs which support those fields.
587# Note: wordpad (write) and others do not support links.
588
589RTF_HYPERLINKS = NO
590
591# Load stylesheet definitions from file. Syntax is similar to doxygen's
592# config file, i.e. a series of assigments. You only have to provide
593# replacements, missing definitions are set to their default value.
594
595RTF_STYLESHEET_FILE =
596
597# Set optional variables used in the generation of an rtf document.
598# Syntax is similar to doxygen's config file.
599
600RTF_EXTENSIONS_FILE =
601
602#---------------------------------------------------------------------------
603# configuration options related to the man page output
604#---------------------------------------------------------------------------
605
606# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
607# generate man pages
608
609GENERATE_MAN = NO
610
611# The MAN_OUTPUT tag is used to specify where the man pages will be put.
612# If a relative path is entered the value of OUTPUT_DIRECTORY will be
613# put in front of it. If left blank `man' will be used as the default path.
614
615MAN_OUTPUT =
616
617# The MAN_EXTENSION tag determines the extension that is added to
618# the generated man pages (default is the subroutine's section .3)
619
620MAN_EXTENSION =
621
622# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
623# then it will generate one additional man file for each entity
624# documented in the real man page(s). These additional files
625# only source the real man page, but without them the man command
626# would be unable to find the correct page. The default is NO.
627
628MAN_LINKS = NO
629
630#---------------------------------------------------------------------------
631# configuration options related to the XML output
632#---------------------------------------------------------------------------
633
634# If the GENERATE_XML tag is set to YES Doxygen will
635# generate an XML file that captures the structure of
636# the code including all documentation. Note that this
637# feature is still experimental and incomplete at the
638# moment.
639
640GENERATE_XML = NO
641
642#---------------------------------------------------------------------------
643# Configuration options related to the preprocessor
644#---------------------------------------------------------------------------
645
646# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
647# evaluate all C-preprocessor directives found in the sources and include
648# files.
649
650ENABLE_PREPROCESSING = YES
651
652# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
653# names in the source code. If set to NO (the default) only conditional
654# compilation will be performed. Macro expansion can be done in a controlled
655# way by setting EXPAND_ONLY_PREDEF to YES.
656
657MACRO_EXPANSION = YES
658
659# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
660# then the macro expansion is limited to the macros specified with the
661# PREDEFINED and EXPAND_AS_PREDEFINED tags.
662
663EXPAND_ONLY_PREDEF = YES
664
665# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
666# in the INCLUDE_PATH (see below) will be search if a #include is found.
667
668SEARCH_INCLUDES = YES
669
670# The INCLUDE_PATH tag can be used to specify one or more directories that
671# contain include files that are not input files but should be processed by
672# the preprocessor.
673
674INCLUDE_PATH =
675
676# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
677# patterns (like *.h and *.hpp) to filter out the header-files in the
678# directories. If left blank, the patterns specified with FILE_PATTERNS will
679# be used.
680
681INCLUDE_FILE_PATTERNS =
682
683# The PREDEFINED tag can be used to specify one or more macro names that
684# are defined before the preprocessor is started (similar to the -D option of
685# gcc). The argument of the tag is a list of macros of the form: name
686# or name=definition (no spaces). If the definition and the = are
687# omitted =1 is assumed.
688
689PREDEFINED = __STDC__=1 TRIO_DOCUMENTATION= TRIO_PUBLIC= TRIO_PRIVATE=static TRIO_CONST=const TRIO_VOLATILE=volatile TRIO_SIGNED=signed TRIO_INLINE=inline TRIO_NOARGS=void TRIO_ARGS1(z,a)=(a) TRIO_ARGS2(z,a,b)=(a,b) TRIO_ARGS3(z,a,b,c)=(a,b,c) TRIO_ARGS4(z,a,b,c,d)=(a,b,c,d) TRIO_ARGS5(z,a,b,c,d,e)=(a,b,c,d,e) TRIO_ARGS6(z,a,b,c,d,e,f)=(a,b,c,d,e,f) TRIO_VARGS2(z,a,b)=(a,b) TRIO_VARGS3(z,a,b,c)=(a,b,c) TRIO_VARGS4(z,a,b,c,d)=(a,b,c,d) TRIO_VARGS5(z,a,b,c,d,e)=(a,b,c,d,e)
690
691# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
692# this tag can be used to specify a list of macro names that should be expanded.
693# The macro definition that is found in the sources will be used.
694# Use the PREDEFINED tag if you want to use a different macro definition.
695
696EXPAND_AS_DEFINED =
697
698# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
699# doxygen's preprocessor will remove all function-like macros that are alone
700# on a line and do not end with a semicolon. Such function macros are typically
701# used for boiler-plate code, and will confuse the parser if not removed.
702
703SKIP_FUNCTION_MACROS = YES
704
705#---------------------------------------------------------------------------
706# Configuration::addtions related to external references
707#---------------------------------------------------------------------------
708
709# The TAGFILES tag can be used to specify one or more tagfiles.
710
711TAGFILES =
712
713# When a file name is specified after GENERATE_TAGFILE, doxygen will create
714# a tag file that is based on the input files it reads.
715
716GENERATE_TAGFILE =
717
718# If the ALLEXTERNALS tag is set to YES all external classes will be listed
719# in the class index. If set to NO only the inherited external classes
720# will be listed.
721
722ALLEXTERNALS = NO
723
724# The PERL_PATH should be the absolute path and name of the perl script
725# interpreter (i.e. the result of `which perl').
726
727PERL_PATH =
728
729#---------------------------------------------------------------------------
730# Configuration options related to the dot tool
731#---------------------------------------------------------------------------
732
733# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
734# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or
735# super classes. Setting the tag to NO turns the diagrams off. Note that this
736# option is superceded by the HAVE_DOT option below. This is only a fallback. It is
737# recommended to install and use dot, since it yield more powerful graphs.
738
739CLASS_DIAGRAMS = YES
740
741# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
742# available from the path. This tool is part of Graphviz, a graph visualization
743# toolkit from AT&T and Lucent Bell Labs. The other options in this section
744# have no effect if this option is set to NO (the default)
745
746HAVE_DOT = NO
747
748# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
749# will generate a graph for each documented class showing the direct and
750# indirect inheritance relations. Setting this tag to YES will force the
751# the CLASS_DIAGRAMS tag to NO.
752
753CLASS_GRAPH = YES
754
755# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
756# will generate a graph for each documented class showing the direct and
757# indirect implementation dependencies (inheritance, containment, and
758# class references variables) of the class with other documented classes.
759
760COLLABORATION_GRAPH = YES
761
762# If set to YES, the inheritance and collaboration graphs will show the
763# relations between templates and their instances.
764
765TEMPLATE_RELATIONS = YES
766
767# If set to YES, the inheritance and collaboration graphs will hide
768# inheritance and usage relations if the target is undocumented
769# or is not a class.
770
771HIDE_UNDOC_RELATIONS = YES
772
773# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
774# tags are set to YES then doxygen will generate a graph for each documented
775# file showing the direct and indirect include dependencies of the file with
776# other documented files.
777
778INCLUDE_GRAPH = YES
779
780# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
781# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
782# documented header file showing the documented files that directly or
783# indirectly include this file.
784
785INCLUDED_BY_GRAPH = YES
786
787# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
788# will graphical hierarchy of all classes instead of a textual one.
789
790GRAPHICAL_HIERARCHY = YES
791
792# The tag DOT_PATH can be used to specify the path where the dot tool can be
793# found. If left blank, it is assumed the dot tool can be found on the path.
794
795DOT_PATH =
796
797# The DOTFILE_DIRS tag can be used to specify one or more directories that
798# contain dot files that are included in the documentation (see the
799# \dotfile command).
800
801DOTFILE_DIRS =
802
803# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
804# (in pixels) of the graphs generated by dot. If a graph becomes larger than
805# this value, doxygen will try to truncate the graph, so that it fits within
806# the specified constraint. Beware that most browsers cannot cope with very
807# large images.
808
809MAX_DOT_GRAPH_WIDTH = 1024
810
811# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
812# (in pixels) of the graphs generated by dot. If a graph becomes larger than
813# this value, doxygen will try to truncate the graph, so that it fits within
814# the specified constraint. Beware that most browsers cannot cope with very
815# large images.
816
817MAX_DOT_GRAPH_HEIGHT = 1024
818
819# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
820# generate a legend page explaining the meaning of the various boxes and
821# arrows in the dot generated graphs.
822
823GENERATE_LEGEND = YES
824
825# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
826# remove the intermedate dot files that are used to generate
827# the various graphs.
828
829DOT_CLEANUP = YES
830
831#---------------------------------------------------------------------------
832# Configuration::addtions related to the search engine
833#---------------------------------------------------------------------------
834
835# The SEARCHENGINE tag specifies whether or not a search engine should be
836# used. If set to NO the values of all tags below this one will be ignored.
837
838SEARCHENGINE = NO
839
840# The CGI_NAME tag should be the name of the CGI script that
841# starts the search engine (doxysearch) with the correct parameters.
842# A script with this name will be generated by doxygen.
843
844CGI_NAME =
845
846# The CGI_URL tag should be the absolute URL to the directory where the
847# cgi binaries are located. See the documentation of your http daemon for
848# details.
849
850CGI_URL =
851
852# The DOC_URL tag should be the absolute URL to the directory where the
853# documentation is located. If left blank the absolute path to the
854# documentation, with file:// prepended to it, will be used.
855
856DOC_URL =
857
858# The DOC_ABSPATH tag should be the absolute path to the directory where the
859# documentation is located. If left blank the directory on the local machine
860# will be used.
861
862DOC_ABSPATH =
863
864# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
865# is installed.
866
867BIN_ABSPATH =
868
869# The EXT_DOC_PATHS tag can be used to specify one or more paths to
870# documentation generated for other projects. This allows doxysearch to search
871# the documentation for these projects as well.
872
873EXT_DOC_PATHS =
diff --git a/gs/trio/doc/trio.css b/gs/trio/doc/trio.css
new file mode 100644
index 000000000..1b3a99261
--- /dev/null
+++ b/gs/trio/doc/trio.css
@@ -0,0 +1,35 @@
1/* HTML tags */
2
3BODY {
4 background-color: white;
5 color: darkblue;
6}
7
8TD { color: darkblue; }
9
10H1 { text-align: center; }
11
12H3 { font-style: italic; }
13
14HR {
15 width: 85%;
16 align: center;
17}
18
19.copyright { color: darkblue; }
20
21/* Links */
22
23:link { color: blue; }
24
25:visited { color: purple; }
26
27:active { color: red; }
28
29.el:link { font-style: italic; }
30
31/* Examples */
32
33DIV.fragment {
34 color: maroon;
35}
diff --git a/gs/trio/example.c b/gs/trio/example.c
new file mode 100644
index 000000000..924d1a1b4
--- /dev/null
+++ b/gs/trio/example.c
@@ -0,0 +1,543 @@
1/*************************************************************************
2 * For testing purposes
3 */
4
5#include <stdarg.h>
6#include <limits.h>
7#include <math.h>
8#include <unistd.h>
9/* #include <nan.h> */
10#include <wchar.h>
11#include "strio.h"
12#include "trio.h"
13#undef printf
14
15#if !defined(USE_LONGLONG)
16# if defined(__GNUC__) && !defined(__STRICT_ANSI__)
17# define USE_LONGLONG
18# elif defined(__SUNPRO_C)
19# define USE_LONGLONG
20# endif
21#endif
22
23#if defined(USE_LONGLONG)
24# define LONGLONG long long
25#else
26# define LONGLONG long
27#endif
28
29#if defined(TRIO_C99)
30# define LONGEST intmax_t
31#else
32# define LONGEST LONGLONG
33#endif
34
35static const char rcsid[] = "@(#)$Id: example.c,v 1.9 2001/11/25 13:47:38 breese Exp $";
36
37/*************************************************************************
38 *
39 */
40void Dump(char *buffer, int rc)
41{
42 if (rc < 0)
43 {
44 printf("Err = %d (%s), Pos = %d\n",
45 TRIO_ERROR_CODE(rc),
46 TRIO_ERROR_NAME(rc),
47 TRIO_ERROR_POSITION(rc));
48 }
49 else
50 printf("buffer[% 3d] = \"%s\"\n", rc, buffer);
51}
52
53/*************************************************************************
54 *
55 */
56int main(void)
57{
58 char buffer[512];
59 int rc;
60 LONGLONG int dummy;
61 char *fool;
62 int num;
63 int num2;
64 int count;
65 double dnum;
66 char *end;
67 char text[256];
68 char ch;
69 int nerrors = 0;
70 void *p1;
71 char *p2;
72
73 printf("%s\n", rcsid);
74
75/* printf("%d %u %d %u\n", */
76/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
77/* trio_printf("%d %u %d %u\n", */
78/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
79/* printf("%d %u\n", INT_MIN, INT_MIN); */
80/* trio_printf("%d %u\n", INT_MIN, INT_MIN); */
81
82/* printf("%ld %lu %ld %lu\n", */
83/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
84/* trio_printf("%ld %lu %ld %lu\n", */
85/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
86/* printf("%ld %lu\n", INT_MIN, INT_MIN); */
87/* trio_printf("%ld %lu\n", INT_MIN, INT_MIN); */
88
89/* printf("%lld %llu %lld %llu\n", */
90/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
91/* trio_printf("%lld %llu %lld %llu\n", */
92/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
93/* printf("%lld %llu\n", INT_MIN, INT_MIN); */
94/* trio_printf("%lld %llu\n", INT_MIN, INT_MIN); */
95
96/* return 0; */
97
98
99/* dnum = StrToDouble("3.14e+44", (const char **)&end); */
100/* printf("double = %e (%s)\n", dnum, end); */
101/* dnum = StrToDouble("0xA3.14p44", (const char **)&end); */
102/* printf("double = %e (%s)\n", dnum, end); */
103
104 /* trio_printf("%.*stext\n", 0, "-----"); */ /* fails */
105
106/* trio_printf("%Zd\n", (size_t)sizeof(char)); */
107
108/* rc = StrFormat(buffer, "%a", 3.14e+44); */
109/* Dump(buffer, rc); */
110
111 /* rc = StrFormat(buffer, "Filled string: %-16<fill=_>s", "test"); */
112
113/* errno = EINTR; */
114/* rc = StrFormat(buffer, "Error: %m"); */
115
116/* rc = StrFormat(buffer, "Count %lln", &dummy); */
117/* printf("dummy = %lld\n", dummy); */
118
119/* rc = StrFormat(buffer, "Char %<quote='>c", 'X'); */
120
121/* rc = StrFormatMax(buffer, 20, "Here goes %-20<adjust=_>s", "test"); */
122
123/* rc = StrFormat(buffer, "Hex-float %a", 3.1415); */
124/* Dump(buffer, rc); */
125/* rc = StrFormat(buffer, "Hex-float %A", 3.1415e20); */
126/* Dump(buffer, rc); */
127/* rc = StrFormat(buffer, "Double %#g", 3.1415e20); */
128/* Dump(buffer, rc); */
129/* rc = StrFormat(buffer, "Double %.3f", 3.1415); */
130/* Dump(buffer, rc); */
131/* rc = StrFormat(buffer, "Double %+e", 3.1415); */
132/* Dump(buffer, rc); */
133
134/* printf("'%.2f'\n", 99.99999); */
135/* trio_printf("'%.2f'\n", 99.99999); */
136/* printf("'%f'\n", 0.0); */
137/* trio_printf("'%f'\n", 0.0); */
138/* printf("'%f'\n", 3141.0); */
139/* trio_printf("'%f'\n", 3141.0); */
140/* printf("'%#f'\n", 3141.0); */
141/* trio_printf("'%#f'\n", 3141.0); */
142/* printf("'%'f'\n", 31415.2); */
143/* trio_printf("'%'f'\n", 31415.2); */
144/* printf("'%-16e'\n", 3141.5); */
145/* trio_printf("'%-16e'\n", 3141.5); */
146/* printf("'%#f'\n", 3141.0); */
147/* trio_printf("'%#f'\n", 3141.0); */
148/* printf("'%f'\n", 3141.5); */
149/* trio_printf("'%f'\n", 3141.5); */
150/* printf("'%#.6g'\n", 3141.5); */
151/* trio_printf("'%#.6g'\n", 3141.5); */
152
153/* printf("'%20e'\n", 314.5); */
154/* trio_printf("'%20e'\n", 314.5); */
155
156/* printf("'%-16e'\n", 3141.5); */
157/* trio_printf("'%-16e'\n", 3141.5); */
158
159/* printf("'%#.4g'\n", 314151.5); */
160/* trio_printf("'%#.4g'\n", 314151.5); */
161
162/* printf("'%#.4g'\n", 0.0); */
163/* trio_printf("'%#.4g'\n", 0.0); */
164
165/* printf("'%#.4g'\n", 11.0); */
166/* trio_printf("'%#.4g'\n", 11.0); */
167
168/* printf("%f\n", HUGE_VAL); */
169/* trio_printf("%f\n", HUGE_VAL); */
170/* printf("%f\n", -HUGE_VAL); */
171/* trio_printf("%f\n", -HUGE_VAL); */
172/* #define NAN (cos(HUGE_VAL)) */
173/* printf("%f\n", NAN); */
174/* trio_printf("%f\n", NAN); */
175
176/* printf("'%+06d'\n", 1234); */
177/* trio_printf("'%+06d'\n", 1234); */
178/* printf("'%-#6.3x'\n", 12); */
179/* trio_printf("'%-#06.3x'\n", 12); */
180/* printf("'%+6d'\n", 1234); */
181/* trio_printf("'%+6d'\n", 1234); */
182/* printf("'%-08d'\n", 12); */
183/* trio_printf("'%-08d'\n", 12); */
184/* printf("'%08.6d'\n", 12); */
185/* trio_printf("'%08.6d'\n", 12); */
186/* printf("'%4d'\n", 123456); */
187/* trio_printf("'%4d'\n", 123456); */
188/* printf("'%.4d'\n", 12); */
189/* trio_printf("'%.4d'\n", 12); */
190
191/* trio_printf("%!#08x %04x %..10x\n", 42, 42, 42); */
192/* trio_printf("%*.*.*i\n", 8, 4, 2, 23); */
193/* trio_printf("%8.4.2i %<base=2>08i %.8.2i %..2i\n", 23, 23, 23, 23); */
194
195/* trio_printf("%8i\n", 42); */
196/* trio_printf("%.7i\n", 42); */
197/* trio_printf("%..2i\n", 42); */
198/* trio_printf("%8.7i\n", 42); */
199/* trio_printf("%8..2i\n", 42); */
200/* trio_printf("%8.7.2i\n", 42); */
201/* trio_printf("%*.*.*i\n", 8, 7, 2, 42); */
202
203/* { */
204/* LONGLONG ll = 1234567890; */
205/* rc = trio_printf("%&i %d\n", sizeof(ll), ll, 42); */
206/* Dump(buffer, rc); */
207/* } */
208/* { */
209/* char ch = 12; */
210/* rc = trio_printf("%&i %d\n", sizeof(ch), ch, 42); */
211/* Dump(buffer, rc); */
212/* } */
213/* { */
214/* pid_t pid = 99; */
215/* rc = trio_printf("%&i %d\n", sizeof(pid), pid, 42); */
216/* Dump(buffer, rc); */
217/* } */
218
219/* rc = trio_printf("%*.*.*i\n", 6, 4, 10, 12); */
220/* Dump(buffer, rc); */
221/* rc = trio_printf("%1$0*3$.*2$d\n", 3141, 6, 10); */
222/* Dump(buffer, rc); */
223
224/* rc = trio_asprintf(&end, "%s%n", "0123456789", &num); */
225/* printf("%d %d '%s'\n", rc, num, end); */
226/* if (end) */
227/* free(end); */
228
229/* trio_printf("%016e\n", 3141.5); */
230/* trio_printf("%'f\n", 424242.42); */
231/* trio_printf("%#.4f\n", 0.0); */
232/* trio_printf("%'d\n", 424242); */
233
234/* rc = trio_sprintf(buffer, "%4$d %3$*8$d %2$.*7$d %1$*6$.*5$d\n", */
235/* 123, */
236/* 1234, */
237/* 12345, */
238/* 123456, */
239/* 5, 6, 7, 8 */
240/* ); */
241/* Dump(buffer, rc); */
242/* rc = trio_sprintf(buffer, "%2$s %1$#s", "111", "222"); */
243/* Dump(buffer, rc); */
244
245/* trio_printf(" %x %!#x %g %09x %x\n", 123456, 123456, 123456.0, 123456, 123456); */
246/* trio_printf("%!'i %f %i\n", 12345, 12345.0, 12345); */
247/* trio_printf("%!<base=2>i %i\n", 23, 23); */
248
249/* rc = trio_sprintf(buffer, "%I32d", 12345); */
250/* Dump(buffer, rc); */
251/* rc = trio_sprintf(buffer, "%I32I8d", 12345); */
252/* Dump(buffer, rc); */
253
254/* rc = trio_sprintf(buffer, "*%5f*", 3.3); */
255/* Dump(buffer, rc); */
256
257/* { */
258/* wchar_t *wstring = L"some data"; */
259/* wchar_t wbuffer[512]; */
260
261/* rc = trio_sprintf(buffer, "%ls", wstring); */
262/* Dump(buffer, rc); */
263
264/* rc = trio_sscanf(buffer, "%ls", wbuffer); */
265/* Dump(buffer, rc); */
266/* rc = trio_sprintf(buffer, "%ls", wbuffer); */
267/* Dump(buffer, rc); */
268/* } */
269
270 /* rc = StrFormat(buffer, "\040-\040\040-\n"); */
271
272/* rc = StrFormat(buffer, "%.*s@%s", 3, "Daniel", "Fool"); */
273/* rc = StrFormatAppendMax(buffer, 512, " %s is a doh", "Simpson"); */
274
275/* rc = StrFormat(buffer, "hello %1$d %1$d", 31, 32); */
276/* Dump(buffer, rc); */
277/* rc = StrFormat(buffer, "%2$d %3$d", 31, 32, 33); */
278/* Dump(buffer, rc); */
279
280/* rc = trio_sprintf(buffer, "%d say %g hey %s", 42, 3.14, "text"); */
281/* Dump(buffer, rc); */
282/* trio_sscanf(buffer, "%d %*s %e hey %s", &num, &dnum, text); */
283/* printf("num = %d, dnum = %e, text = \"%s\"\n", num, dnum, text); */
284
285/* rc = trio_sprintf(buffer, "%g", HUGE_VAL); */
286/* Dump(buffer, rc); */
287/* trio_sscanf(buffer, "%f", &dnum); */
288/* printf("dnum = %e\n", dnum); */
289
290/* rc = trio_sprintf(buffer, "%g", -HUGE_VAL); */
291/* Dump(buffer, rc); */
292/* trio_sscanf(buffer, "%f", &dnum); */
293/* printf("dnum = %e\n", dnum); */
294
295/* #if defined(NAN) */
296/* rc = trio_sprintf(buffer, "%g", NAN); */
297/* Dump(buffer, rc); */
298/* if ((rc = trio_sscanf(buffer, "%f", &dnum)) < 0) */
299/* Dump(buffer, rc); */
300/* else */
301/* printf("dnum = %e\n", dnum); */
302/* #endif */
303
304/* rc = trio_sprintf(buffer, "%*d", 6, 1234); */
305/* Dump(buffer, rc); */
306
307/* rc = trio_sprintf(buffer, "'%!08.6d' '%!d' '%d'", 4, 6, 8); */
308/* Dump(buffer, rc); */
309
310/* rc = trio_sprintf(buffer, "%0g", 0.123); */
311/* Dump(buffer, rc); */
312
313/* { */
314/* void *argarray[4]; */
315/* int value = 42; */
316/* double number = 123.456; */
317/* float small_number = 123.456; */
318
319/* argarray[0] = &value; */
320/* argarray[1] = "my string"; */
321/* rc = trio_sprintfv(buffer, "%d %s", argarray); */
322/* Dump(buffer, rc); */
323/* rc = trio_snprintfv(buffer, 8, "%d %s", argarray); */
324/* Dump(buffer, rc); */
325
326/* argarray[0] = &num; */
327/* argarray[1] = text; */
328/* rc = trio_sscanfv(buffer, "%d %s", argarray); */
329/* Dump(buffer, rc); */
330/* printf("num = %d text = \"%s\"\n", num, text); */
331
332/* argarray[0] = &number; */
333/* argarray[1] = &small_number; */
334/* rc = trio_sprintfv(buffer, "%f %hf", argarray); */
335/* Dump(buffer, rc); */
336/* printf("number = %f small_number = \"%f\"\n", number, small_number); */
337/* } */
338
339#if 0
340 rc = trio_sprintf(buffer, "abcba");
341 Dump(buffer, rc);
342 trio_sscanf(buffer, "%[ab]", text);
343 printf("text = \"%s\"\n", text);
344 trio_sscanf(buffer, "%*[ab]c%[^\n]", text);
345 printf("text = \"%s\"\n", text);
346
347 trio_sprintf(buffer, "aabcdba aaa");
348 rc = trio_sscanf(buffer, "%s", text);
349 Dump(buffer, rc);
350 printf("text = \"%s\"\n", text);
351 rc = trio_sscanf(buffer, "%*1[aA]%[a-c]", text);
352 Dump(buffer, rc);
353 printf("text = \"%s\"\n", text);
354
355 rc = trio_sprintf(buffer, "10021");
356 rc = trio_sscanf(buffer, "%b%n%d", &num, &count, &num2);
357 Dump(buffer, rc);
358 printf("num = %d %d %d\n", num, num2, count);
359#endif
360
361/* rc = trio_sprintf(buffer, "%'d", 10000); */
362/* rc = trio_sscanf(buffer, "%'d", &num); */
363/* Dump(buffer, rc); */
364/* printf("num = %d\n", num); */
365
366/* rc = trio_dprintf(STDOUT_FILENO, "%s\n", "hello there"); */
367/* Dump(buffer, rc); */
368/* rc = trio_dscanf(STDIN_FILENO, "%s", buffer); */
369/* Dump(buffer, rc); */
370
371/* rc = trio_scanf("%s", buffer); */
372/* Dump(buffer, rc); */
373
374/* rc = trio_sprintf(buffer, "Ttext"); */
375/* Dump(buffer, rc); */
376/* trio_sscanf(buffer, "%*[Tt]e%c", &ch); */
377/* printf("ch = %c\n", ch); */
378
379/* printf("%p\n", &main); */
380/* rc = trio_sprintf(buffer, "%p %p", &main, NULL); */
381/* Dump(buffer, rc); */
382/* trio_sscanf(buffer, "%p %p", &p1, &p2); */
383/* printf("pointer = %p %p\n", p1, p2); */
384
385/* rc = trio_sprintf(buffer, "%@.@.@i", 8, 7, 2, 42); */
386/* Dump(buffer, rc); */
387/* trio_sprintf(buffer, "abcdefghijklmnopqrstuvwxyz"); */
388/* rc = trio_sscanf(buffer, "%100s", text); */
389/* Dump(text, rc); */
390/* rc = trio_sscanf(buffer, "%@s", 100, text); */
391/* Dump(text, rc); */
392
393/* rc = trio_sprintf(buffer, "%..2i", 42); */
394/* Dump(buffer, rc); */
395/* rc = trio_sscanf(buffer, "%..2i", &num); */
396/* printf("%d\n", num); */
397/* rc = trio_sscanf(buffer, "%..@i", 2, &num); */
398/* printf("%d\n", num); */
399
400/* { */
401/* int num1, num2, num3, num4; */
402
403/* rc = trio_sprintf(buffer, "123_456 [12%%-34%%]"); */
404/* Dump(buffer, rc); */
405/* rc = trio_sscanf(buffer, "%5i%*1s%5i%*1s%5i%*2s%5i", */
406/* &num1, &num2, &num3, &num4); */
407/* Dump(buffer, rc); */
408/* printf("%d %d %d %d %d\n", rc, num1, num2, num3, num4); */
409/* rc = trio_sscanf(buffer, "%d_%d [%d%%-%d%%]", */
410/* &num1, &num2, &num3, &num4); */
411/* Dump(buffer, rc); */
412/* printf("%d %d %d %d %d\n", rc, num1, num2, num3, num4); */
413/* } */
414
415/* rc = trio_sprintf(buffer, "01 3456789"); */
416/* Dump(buffer, rc); */
417/* memset(&text, 0, sizeof(text)); */
418/* rc = trio_sscanf(buffer, "%4c", &text); */
419/* Dump(text, rc); */
420/* memset(&text, 0, sizeof(text)); */
421/* rc = sscanf(buffer, "%4c", &text); */
422/* Dump(text, rc); */
423
424/* rc = trio_sprintf(buffer, "12345 6"); */
425/* Dump(buffer, rc); */
426/* rc = trio_sscanf(buffer, "%2d", &num); */
427/* Dump(buffer, rc); */
428/* printf("%d\n", num); */
429/* rc = sscanf(buffer, "%2d", &num); */
430/* Dump(buffer, rc); */
431/* printf("%d\n", num); */
432
433/* rc = trio_sprintf(buffer, "aa\\x0abb"); */
434/* Dump(buffer, rc); */
435/* rc = trio_sscanf(buffer, "aa%#sbb", &text); */
436/* Dump(text, rc); */
437
438/* rc = trio_sscanf("0 ", "%f", &dnum, text); */
439/* printf("%d %f\n", rc, dnum); */
440/* rc = sscanf("0 ", "%f %s", &dnum, text); */
441/* printf("%d %f\n", rc, dnum); */
442
443/* rc = trio_sscanf("lære", "%[:alpha:]", text); */
444/* Dump(text, rc); */
445
446/* rc = trio_sscanf("-0.123e3", "%8e", &dnum); */
447/* printf("%d %f\n", rc, dnum); */
448
449/* rc = trio_sscanf("123,456.78", "%'f", &dnum); */
450/* printf("%d %f\n", rc, dnum); */
451
452/* rc = trio_sscanf("1.e-6","%g", &dnum); */
453/* printf("%d %g\n", rc, dnum); */
454/* rc = trio_sscanf("1e-6","%g", &dnum); */
455/* printf("%d %g\n", rc, dnum); */
456
457/* rc = trio_sprintf(buffer, "%0.40e\n", 14.0); */
458/* Dump(buffer, rc); */
459
460/* rc = trio_sprintf(buffer, "%010.3e\n", 3141.5); */
461/* Dump(buffer, rc); */
462
463/* rc = trio_sprintf(buffer, "%e", 0.6); */
464/* Dump(buffer, rc); */
465/* rc = trio_sprintf(buffer, "%e", 0.5); */
466/* Dump(buffer, rc); */
467
468/* rc = trio_sprintf(buffer, "%#11.5g", 1e5); */
469/* Dump(buffer, rc); */
470
471/* rc = trio_sprintf(buffer, "%010.3e", 3141.5); */
472/* Dump(buffer, rc); */
473
474/* rc = trio_sprintf(buffer, "%11.5g", 1e-5); */
475/* Dump(buffer, rc); */
476
477/* rc = trio_sprintf(buffer, "%g", 1.79769e+308); */
478/* printf("%d \"%s\"\n", rc, buffer); */
479/* trio_sscanf(buffer, "%g", &dnum); */
480/* printf("%d %g\n", rc, dnum); */
481
482/* rc = trio_snprintf(0, 0, "text"); */
483/* Dump(buffer, rc); */
484
485/* rc = trio_sprintf(buffer, "%.16.2f", (float)41.8713); */
486/* Dump(buffer, rc); */
487/* rc = trio_sprintf(buffer, "%.16.2f", (float)41.8687); */
488/* Dump(buffer, rc); */
489/* rc = trio_sprintf(buffer, "%.16.2f", (float)41.8684); */
490/* Dump(buffer, rc); */
491
492/* rc = trio_sprintf(buffer, "%#.4g", 1e-3); */
493/* Dump(buffer, rc); */
494
495/* rc = trio_sprintf(buffer, "%#.2g", (double)0.01); */
496/* Dump(buffer, rc); */
497
498/* rc = trio_sprintf(buffer, "%#11.5g", (double)1.0); */
499/* Dump(buffer, rc); */
500/* rc = trio_sprintf(buffer, "%#11.5g", (double)0.9999999999999999); */
501/* Dump(buffer, rc); */
502
503/* rc = trio_sprintf(buffer, "%#11.5g", (double)0.1); */
504/* Dump(buffer, rc); */
505/* rc = trio_sprintf(buffer, "%#11.5g", (double)0.0999999999999999); */
506/* Dump(buffer, rc); */
507
508/* rc = trio_sprintf(buffer, "%#11.5g", (double)0.01); */
509/* Dump(buffer, rc); */
510/* rc = trio_sprintf(buffer, "%#11.5g", (double)0.0099999999999999); */
511/* Dump(buffer, rc); */
512
513/* char * buf = "aaaaaaaaaaaaaaaaaaaaaaaaa"; */
514/* int buf_len = 4; */
515/* rc = trio_sprintf(buffer, ">%.*s\n", buf_len, buf); */
516
517/* rc = trio_sprintf(buffer, "$d", 1); */
518/* Dump(buffer, rc); */
519
520/* trio_sprintf(buffer, "%lld.%ld%s", 0LL, 0L, ","); */
521/* Dump(buffer, rc); */
522
523/* trio_sprintf(buffer, "%+.14e", (double)1.27299014704543e-313); */
524/* Dump(buffer, rc); */
525
526/* rc = scanf(""); */
527/* rc = trio_scanf(""); */
528
529/* trio_sprintf(buffer, "abcd"); */
530/* rc = trio_sscanf(buffer, "%c", &ch); */
531/* printf("%d %c\n", rc, ch); */
532
533/* for(unsigned int i = 0U ; i < 100000U ; ++i) */
534/* { */
535/* trio_sprintf(buffer, "The next value of '%s' is %d (ln: %d) ('%s')\n", */
536/* "i", i+1, __LINE__, "foo bar"); */
537/* } */
538
539 rc = trio_snprintf(NULL, 0, "%s", "not used");
540 Dump(buffer, rc);
541
542 return 0;
543}
diff --git a/gs/trio/html/group___dynamic_strings.html b/gs/trio/html/group___dynamic_strings.html
new file mode 100644
index 000000000..5593a5f42
--- /dev/null
+++ b/gs/trio/html/group___dynamic_strings.html
@@ -0,0 +1,300 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
5 <title>TRIO</title>
6 <link href="trio.css" rel="stylesheet" type="text/css">
7</head>
8<body>
9<!-- Generated by Doxygen 1.2.18 -->
10<center>
11<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; </center>
12<hr><h1>Dynamic String Functions.</h1>Dynamic string functions.
13<a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0>
14<tr><td></td></tr>
15<tr><td colspan=2><br><h2>Functions</h2></td></tr>
16<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING trio_string_t *&nbsp;</td><td valign=bottom><a class="el" href="group___dynamic_strings.html#a0">trio_string_create</a> (int initial_size)</td></tr>
17<tr><td>&nbsp;</td><td><font size=-1><em>Create a new dynamic string.</em> <a href="#a0"></a><em></em></font><br><br></td></tr>
18<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING void&nbsp;</td><td valign=bottom><a class="el" href="group___dynamic_strings.html#a1">trio_string_destroy</a> (trio_string_t *self)</td></tr>
19<tr><td>&nbsp;</td><td><font size=-1><em>Deallocate the dynamic string and its contents.</em> <a href="#a1"></a><em></em></font><br><br></td></tr>
20<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING char *&nbsp;</td><td valign=bottom><a class="el" href="group___dynamic_strings.html#a2">trio_string_extract</a> (trio_string_t *self)</td></tr>
21<tr><td>&nbsp;</td><td><font size=-1><em>Extract the content.</em> <a href="#a2"></a><em></em></font><br><br></td></tr>
22<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING void&nbsp;</td><td valign=bottom><a class="el" href="group___dynamic_strings.html#a3">trio_xstring_set</a> (trio_string_t *self, char *buffer)</td></tr>
23<tr><td>&nbsp;</td><td><font size=-1><em>Set the content of the dynamic string.</em> <a href="#a3"></a><em></em></font><br><br></td></tr>
24<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___dynamic_strings.html#a6">trio_string_append</a> (trio_string_t *self, trio_string_t *other)</td></tr>
25<tr><td>&nbsp;</td><td><font size=-1><em>Append the second string to the first.</em> <a href="#a6"></a><em></em></font><br><br></td></tr>
26<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___dynamic_strings.html#a9">trio_string_contains</a> (trio_string_t *self, trio_string_t *other)</td></tr>
27<tr><td>&nbsp;</td><td><font size=-1><em>Search for the first occurrence of second parameter in the first.</em> <a href="#a9"></a><em></em></font><br><br></td></tr>
28</table>
29<hr><a name="_details"></a><h2>Detailed Description</h2>
30Dynamic string functions.
31<p>
32<b>SYNOPSIS</b>
33<p>
34<div class="fragment"><pre>
35cc ... -ltrio -lm
36
37#include &lt;triostr.h&gt;
38</pre></div>
39<p>
40<b>DESCRIPTION</b> <hr><h2>Function Documentation</h2>
41<a name="a6" doxytag="triostr-macro.c::trio_string_append"></a><p>
42<table width="100%" cellpadding="2" cellspacing="0" border="0">
43 <tr>
44 <td class="md">
45 <table cellpadding="0" cellspacing="0" border="0">
46 <tr>
47 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_string_append </td>
48 <td class="md" valign="top">(&nbsp;</td>
49 <td class="md" nowrap valign="top">trio_string_t *&nbsp;</td>
50 <td class="mdname" nowrap>&nbsp; <em>self</em>, </td>
51 </tr>
52 <tr>
53 <td></td>
54 <td></td>
55 <td class="md" nowrap>trio_string_t *&nbsp;</td>
56 <td class="mdname" nowrap>&nbsp; <em>other</em></td>
57 </tr>
58 <tr>
59 <td></td>
60 <td class="md">)&nbsp;</td>
61 <td class="md" colspan="2"></td>
62 </tr>
63
64 </table>
65 </td>
66 </tr>
67</table>
68<table cellspacing=5 cellpadding=0 border=0>
69 <tr>
70 <td>
71 &nbsp;
72 </td>
73 <td>
74
75<p>
76Append the second string to the first.
77<p>
78<dl compact><dt><b>Parameters: </b></dt><dd>
79<table border=0 cellspacing=2 cellpadding=0>
80<tr><td valign=top><em>self</em>&nbsp;</td><td>
81Dynamic string to be modified. </td></tr>
82<tr><td valign=top><em>other</em>&nbsp;</td><td>
83Dynamic string to copy from. </td></tr>
84</table>
85</dl><dl compact><dt><b>Returns: </b></dt><dd>
86Boolean value indicating success or failure. </dl> </td>
87 </tr>
88</table>
89<a name="a9" doxytag="triostr-macro.c::trio_string_contains"></a><p>
90<table width="100%" cellpadding="2" cellspacing="0" border="0">
91 <tr>
92 <td class="md">
93 <table cellpadding="0" cellspacing="0" border="0">
94 <tr>
95 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_string_contains </td>
96 <td class="md" valign="top">(&nbsp;</td>
97 <td class="md" nowrap valign="top">trio_string_t *&nbsp;</td>
98 <td class="mdname" nowrap>&nbsp; <em>self</em>, </td>
99 </tr>
100 <tr>
101 <td></td>
102 <td></td>
103 <td class="md" nowrap>trio_string_t *&nbsp;</td>
104 <td class="mdname" nowrap>&nbsp; <em>other</em></td>
105 </tr>
106 <tr>
107 <td></td>
108 <td class="md">)&nbsp;</td>
109 <td class="md" colspan="2"></td>
110 </tr>
111
112 </table>
113 </td>
114 </tr>
115</table>
116<table cellspacing=5 cellpadding=0 border=0>
117 <tr>
118 <td>
119 &nbsp;
120 </td>
121 <td>
122
123<p>
124Search for the first occurrence of second parameter in the first.
125<p>
126<dl compact><dt><b>Parameters: </b></dt><dd>
127<table border=0 cellspacing=2 cellpadding=0>
128<tr><td valign=top><em>self</em>&nbsp;</td><td>
129Dynamic string to be modified. </td></tr>
130<tr><td valign=top><em>other</em>&nbsp;</td><td>
131Dynamic string to copy from. </td></tr>
132</table>
133</dl><dl compact><dt><b>Returns: </b></dt><dd>
134Boolean value indicating success or failure. </dl> </td>
135 </tr>
136</table>
137<a name="a0" doxytag="triostr-macro.c::trio_string_create"></a><p>
138<table width="100%" cellpadding="2" cellspacing="0" border="0">
139 <tr>
140 <td class="md">
141 <table cellpadding="0" cellspacing="0" border="0">
142 <tr>
143 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING trio_string_t* trio_string_create </td>
144 <td class="md" valign="top">(&nbsp;</td>
145 <td class="md" nowrap valign="top">int&nbsp;</td>
146 <td class="mdname1" valign="top" nowrap>&nbsp; <em>initial_size</em> </td>
147 <td class="md" valign="top">)&nbsp;</td>
148 <td class="md" nowrap></td>
149 </tr>
150
151 </table>
152 </td>
153 </tr>
154</table>
155<table cellspacing=5 cellpadding=0 border=0>
156 <tr>
157 <td>
158 &nbsp;
159 </td>
160 <td>
161
162<p>
163Create a new dynamic string.
164<p>
165<dl compact><dt><b>Parameters: </b></dt><dd>
166<table border=0 cellspacing=2 cellpadding=0>
167<tr><td valign=top><em>initial_size</em>&nbsp;</td><td>
168Initial size of the buffer. </td></tr>
169</table>
170</dl><dl compact><dt><b>Returns: </b></dt><dd>
171Newly allocated dynamic string, or NULL if memory allocation failed. </dl> </td>
172 </tr>
173</table>
174<a name="a1" doxytag="triostr-macro.c::trio_string_destroy"></a><p>
175<table width="100%" cellpadding="2" cellspacing="0" border="0">
176 <tr>
177 <td class="md">
178 <table cellpadding="0" cellspacing="0" border="0">
179 <tr>
180 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING void trio_string_destroy </td>
181 <td class="md" valign="top">(&nbsp;</td>
182 <td class="md" nowrap valign="top">trio_string_t *&nbsp;</td>
183 <td class="mdname1" valign="top" nowrap>&nbsp; <em>self</em> </td>
184 <td class="md" valign="top">)&nbsp;</td>
185 <td class="md" nowrap></td>
186 </tr>
187
188 </table>
189 </td>
190 </tr>
191</table>
192<table cellspacing=5 cellpadding=0 border=0>
193 <tr>
194 <td>
195 &nbsp;
196 </td>
197 <td>
198
199<p>
200Deallocate the dynamic string and its contents.
201<p>
202<dl compact><dt><b>Parameters: </b></dt><dd>
203<table border=0 cellspacing=2 cellpadding=0>
204<tr><td valign=top><em>self</em>&nbsp;</td><td>
205Dynamic string </td></tr>
206</table>
207</dl> </td>
208 </tr>
209</table>
210<a name="a2" doxytag="triostr-macro.c::trio_string_extract"></a><p>
211<table width="100%" cellpadding="2" cellspacing="0" border="0">
212 <tr>
213 <td class="md">
214 <table cellpadding="0" cellspacing="0" border="0">
215 <tr>
216 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING char* trio_string_extract </td>
217 <td class="md" valign="top">(&nbsp;</td>
218 <td class="md" nowrap valign="top">trio_string_t *&nbsp;</td>
219 <td class="mdname1" valign="top" nowrap>&nbsp; <em>self</em> </td>
220 <td class="md" valign="top">)&nbsp;</td>
221 <td class="md" nowrap></td>
222 </tr>
223
224 </table>
225 </td>
226 </tr>
227</table>
228<table cellspacing=5 cellpadding=0 border=0>
229 <tr>
230 <td>
231 &nbsp;
232 </td>
233 <td>
234
235<p>
236Extract the content.
237<p>
238<dl compact><dt><b>Parameters: </b></dt><dd>
239<table border=0 cellspacing=2 cellpadding=0>
240<tr><td valign=top><em>self</em>&nbsp;</td><td>
241Dynamic String </td></tr>
242</table>
243</dl><dl compact><dt><b>Returns: </b></dt><dd>
244Content of dynamic string.</dl>The content is removed from the dynamic string. This enables destruction of the dynamic string without deallocation of the content. </td>
245 </tr>
246</table>
247<a name="a3" doxytag="triostr-macro.c::trio_xstring_set"></a><p>
248<table width="100%" cellpadding="2" cellspacing="0" border="0">
249 <tr>
250 <td class="md">
251 <table cellpadding="0" cellspacing="0" border="0">
252 <tr>
253 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING void trio_xstring_set </td>
254 <td class="md" valign="top">(&nbsp;</td>
255 <td class="md" nowrap valign="top">trio_string_t *&nbsp;</td>
256 <td class="mdname" nowrap>&nbsp; <em>self</em>, </td>
257 </tr>
258 <tr>
259 <td></td>
260 <td></td>
261 <td class="md" nowrap>char *&nbsp;</td>
262 <td class="mdname" nowrap>&nbsp; <em>buffer</em></td>
263 </tr>
264 <tr>
265 <td></td>
266 <td class="md">)&nbsp;</td>
267 <td class="md" colspan="2"></td>
268 </tr>
269
270 </table>
271 </td>
272 </tr>
273</table>
274<table cellspacing=5 cellpadding=0 border=0>
275 <tr>
276 <td>
277 &nbsp;
278 </td>
279 <td>
280
281<p>
282Set the content of the dynamic string.
283<p>
284<dl compact><dt><b>Parameters: </b></dt><dd>
285<table border=0 cellspacing=2 cellpadding=0>
286<tr><td valign=top><em>self</em>&nbsp;</td><td>
287Dynamic String </td></tr>
288<tr><td valign=top><em>buffer</em>&nbsp;</td><td>
289The new content.</td></tr>
290</table>
291</dl>Sets the content of the dynamic string to a copy <code>buffer</code>. An existing content will be deallocated first, if necessary.
292<p>
293<dl compact><dt><b>Remarks: </b></dt><dd>
294 This function will make a copy of <code>buffer</code>. You are responsible for deallocating <code>buffer</code> yourself. </dl> </td>
295 </tr>
296</table>
297<HR>
298<center class="copyright">Copyright (C) 2001 - 2006 Bj&oslash;rn Reese and Daniel Stenberg.</center>
299</body>
300</html>
diff --git a/gs/trio/html/group___printf.html b/gs/trio/html/group___printf.html
new file mode 100644
index 000000000..e7d56868b
--- /dev/null
+++ b/gs/trio/html/group___printf.html
@@ -0,0 +1,1404 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
5 <title>TRIO</title>
6 <link href="trio.css" rel="stylesheet" type="text/css">
7</head>
8<body>
9<!-- Generated by Doxygen 1.2.18 -->
10<center>
11<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; </center>
12<hr><h1>Formatted Printing Functions.</h1>Variations of formatted printing functions.
13<a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0>
14<tr><td></td></tr>
15<tr><td colspan=2><br><h2>Functions</h2></td></tr>
16<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a0">trio_printf</a> (const char *format,...)</td></tr>
17<tr><td>&nbsp;</td><td><font size=-1><em>Print to standard output stream.</em> <a href="#a0"></a><em></em></font><br><br></td></tr>
18<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a1">trio_vprintf</a> (const char *format, va_list args)</td></tr>
19<tr><td>&nbsp;</td><td><font size=-1><em>Print to standard output stream.</em> <a href="#a1"></a><em></em></font><br><br></td></tr>
20<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a2">trio_printfv</a> (const char *format, trio_pointer_t *args)</td></tr>
21<tr><td>&nbsp;</td><td><font size=-1><em>Print to standard output stream.</em> <a href="#a2"></a><em></em></font><br><br></td></tr>
22<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a3">trio_fprintf</a> (FILE *file, const char *format,...)</td></tr>
23<tr><td>&nbsp;</td><td><font size=-1><em>Print to file.</em> <a href="#a3"></a><em></em></font><br><br></td></tr>
24<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a4">trio_vfprintf</a> (FILE *file, const char *format, va_list args)</td></tr>
25<tr><td>&nbsp;</td><td><font size=-1><em>Print to file.</em> <a href="#a4"></a><em></em></font><br><br></td></tr>
26<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a5">trio_fprintfv</a> (FILE *file, const char *format, trio_pointer_t *args)</td></tr>
27<tr><td>&nbsp;</td><td><font size=-1><em>Print to file.</em> <a href="#a5"></a><em></em></font><br><br></td></tr>
28<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a6">trio_dprintf</a> (int fd, const char *format,...)</td></tr>
29<tr><td>&nbsp;</td><td><font size=-1><em>Print to file descriptor.</em> <a href="#a6"></a><em></em></font><br><br></td></tr>
30<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a7">trio_vdprintf</a> (int fd, const char *format, va_list args)</td></tr>
31<tr><td>&nbsp;</td><td><font size=-1><em>Print to file descriptor.</em> <a href="#a7"></a><em></em></font><br><br></td></tr>
32<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a8">trio_dprintfv</a> (int fd, const char *format, trio_pointer_t *args)</td></tr>
33<tr><td>&nbsp;</td><td><font size=-1><em>Print to file descriptor.</em> <a href="#a8"></a><em></em></font><br><br></td></tr>
34<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a12">trio_sprintf</a> (char *buffer, const char *format,...)</td></tr>
35<tr><td>&nbsp;</td><td><font size=-1><em>Print to string.</em> <a href="#a12"></a><em></em></font><br><br></td></tr>
36<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a13">trio_vsprintf</a> (char *buffer, const char *format, va_list args)</td></tr>
37<tr><td>&nbsp;</td><td><font size=-1><em>Print to string.</em> <a href="#a13"></a><em></em></font><br><br></td></tr>
38<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a14">trio_sprintfv</a> (char *buffer, const char *format, trio_pointer_t *args)</td></tr>
39<tr><td>&nbsp;</td><td><font size=-1><em>Print to string.</em> <a href="#a14"></a><em></em></font><br><br></td></tr>
40<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a15">trio_snprintf</a> (char *buffer, size_t max, const char *format,...)</td></tr>
41<tr><td>&nbsp;</td><td><font size=-1><em>Print at most <code>max</code> characters to string.</em> <a href="#a15"></a><em></em></font><br><br></td></tr>
42<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a16">trio_vsnprintf</a> (char *buffer, size_t max, const char *format, va_list args)</td></tr>
43<tr><td>&nbsp;</td><td><font size=-1><em>Print at most <code>max</code> characters to string.</em> <a href="#a16"></a><em></em></font><br><br></td></tr>
44<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a17">trio_snprintfv</a> (char *buffer, size_t max, const char *format, trio_pointer_t *args)</td></tr>
45<tr><td>&nbsp;</td><td><font size=-1><em>Print at most <code>max</code> characters to string.</em> <a href="#a17"></a><em></em></font><br><br></td></tr>
46<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a22">trio_asprintf</a> (char **result, const char *format,...)</td></tr>
47<tr><td>&nbsp;</td><td><font size=-1><em>Allocate and print to string.</em> <a href="#a22"></a><em></em></font><br><br></td></tr>
48<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a23">trio_vasprintf</a> (char **result, const char *format, va_list args)</td></tr>
49<tr><td>&nbsp;</td><td><font size=-1><em>Allocate and print to string.</em> <a href="#a23"></a><em></em></font><br><br></td></tr>
50<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___printf.html#a24">trio_asprintfv</a> (char **result, const char *format, trio_pointer_t *args)</td></tr>
51<tr><td>&nbsp;</td><td><font size=-1><em>Allocate and print to string.</em> <a href="#a24"></a><em></em></font><br><br></td></tr>
52</table>
53<hr><a name="_details"></a><h2>Detailed Description</h2>
54Variations of formatted printing functions.
55<p>
56<b>SYNOPSIS</b>
57<p>
58<div class="fragment"><pre>
59cc ... -ltrio -lm
60
61#include &lt;trio.h&gt;
62</pre></div>
63<p>
64<b>DESCRIPTION</b>
65<p>
66This documentation is incomplete. The documentation of the printf family in [C99] and [UNIX98] also applies to the trio counterparts.
67<p>
68All these functions outputs a string which is formatted according to the <code>format</code> string and the consecutive arguments. The <code>format</code> string is described in the Formatting section below.
69<p>
70<a class="el" href="group___printf.html#a218">Formatted Printing Functions.</a>, <a class="el" href="group___printf.html#a219">Formatted Printing Functions.</a>, and <a class="el" href="group___printf.html#a220">Formatted Printing Functions.</a> writes the output to the standard output stream (stdout).
71<p>
72<a class="el" href="group___printf.html#a221">Formatted Printing Functions.</a>, <a class="el" href="group___printf.html#a222">Formatted Printing Functions.</a>, and <a class="el" href="group___printf.html#a223">Formatted Printing Functions.</a> writes the output to a given output stream.
73<p>
74<a class="el" href="group___printf.html#a224">Formatted Printing Functions.</a>, <a class="el" href="group___printf.html#a225">Formatted Printing Functions.</a>, and <a class="el" href="group___printf.html#a226">Formatted Printing Functions.</a> writes the output to a file descriptor (this includes, for example, sockets).
75<p>
76<a class="el" href="group___printf.html#a230">Formatted Printing Functions.</a>, <a class="el" href="group___printf.html#a231">Formatted Printing Functions.</a>, and <a class="el" href="group___printf.html#a232">Formatted Printing Functions.</a> writes the output into <code>buffer</code>.
77<p>
78<a class="el" href="group___printf.html#a233">Formatted Printing Functions.</a>, <a class="el" href="group___printf.html#a234">Formatted Printing Functions.</a>, and <a class="el" href="group___printf.html#a235">Formatted Printing Functions.</a> writes <code>max</code> - 1 characters into <code>buffer</code> followed by a terminating zero character. If <code>max</code> is 1, then <code>buffer</code> will be an empty string. If <code>max</code> is 0, then <code>buffer</code> is left untouched, and can consequently be NULL. The number of characters that would have been written to <code>buffer</code>, had there been sufficient space, is returned.
79<p>
80trio_snprintfcat appends the formatted text at the end of <code>buffer</code>.
81<p>
82<a class="el" href="group___printf.html#a240">Formatted Printing Functions.</a>, <a class="el" href="group___printf.html#a241">Formatted Printing Functions.</a>, and <a class="el" href="group___printf.html#a242">Formatted Printing Functions.</a> allocates and returns an allocated string in <code>buffer</code> containing the formatted text.
83<p>
84<b>FORMATTING</b>
85<p>
86The <code>format</code> string can contain normal text and conversion indicators. The normal text can be any character except the nil character (\000 = '\0') and the percent character (\045 = '%'). Conversion indicators consists of an indication character (%), followed by zero or more conversion modifiers, and exactly one conversion specifier.
87<p>
88<b>Modifiers</b>
89<p>
90Some modifiers exhibit the same behaviour for all specifiers, other modifiers indicate different behaviours for different specifiers, and other modifiers are only applicable to certain specifiers. The relationship is described for each modifier. The number 9 is used to denotes an arbitrary integer.
91<p>
92<em>Positional</em> ( <code>9$</code> ) [UNIX98]
93<p>
94Normally the arguments supplied to these functions are interpreted incrementially from left to right. Arguments can be referenced specifically in the format string. The modifier n$ selects the nth argument. The first argument is referred as 1$. If this modifier is used, it must be the first modifier after the indication character. n$ can also be used for argument width, precision, and base.
95<p>
96The performance penalty of using positionals is almost neglible (contrary to most other printf implementations).
97<p>
98<ul>
99<li> <em>Reference</em> <em>Mix</em>. Mixing normal and positional specifiers is allowed [TRIO]. For example, <div class="fragment"><pre>
100 trio_printf("%d %3$d %2$d\n", 1, 2, 3);
101</pre></div> results in <div class="fragment"><pre>
102 1 3 2
103</pre></div> Arguments for the printf family are passed on the stack. On most platforms it is not possible to determine the size of individual stack elements, so it is essential that the format string corresponds exactly to the passed arguments. If this is not the case, incorrect values may be put into the result.</ul>
104<ul>
105<li> <em>Reference</em> <em>Gap</em>. For the same reason it is also essential that the format string does not contain any "gaps" in the positional arguments. For example, <div class="fragment"><pre>
106 trio_printf("%1$d %3$d\n", 1, 2, 3);
107</pre></div> is NOT allowed. The format string parser has no knowledge about whether the second argument is, say, an integer or a long double (which have different sizes). <div class="fragment"><pre>
108</pre></div> [UNIX98] describes this as unspecified behaviour. [TRIO] will detect reference gaps and return an error.</ul>
109<ul>
110<li> <em>Double</em> <em>Reference</em>. It is also not allowed to reference an argument twice or more. For example, <div class="fragment"><pre>
111 trio_printf("%1$d %1$lf\n", 1);
112</pre></div> is NOT allowed, because it references the first argument as two differently sized objects. <div class="fragment"><pre>
113</pre></div> [UNIX98] describes this as unspecified behaviour. [TRIO] will detect double references and return an error.</ul>
114The following two statements are equivalent <div class="fragment"><pre>
115 trio_printf("|%d %s\n|", 42, "meanings");
116 |42 meanings|
117
118 trio_printf("|%1$d %2$s|\n", 42, "meanings");
119 |42 meanings|
120</pre></div>
121<p>
122<em>Width</em> ( <code>9</code> )
123<p>
124Specifies the minimum width of a field. If the fields has less characters than specified by the width, the field will be left adjusted and padded by spaces. The adjustment and padding can be changed by the Alignment ( <code>-</code> ) and Padding ( <code>0</code> ) modifiers.
125<p>
126The width is specified as a number. If an asterix ( <code>*</code> ) is used instead, the width will be read from the argument list.
127<p>
128Prefixes, such as 0x for hexadecimal integers, are part of width. <div class="fragment"><pre>
129 trio_printf("|%10i|\n", 42);
130 | 42|
131</pre></div>
132<p>
133<em>Precision</em> ( .<code>9</code> )
134<p>
135The precision has different semantics for the various data types. The precision specifies the maximum number of printed characters for strings, the number of digits after the decimal-point for floating-point numbers, the number of significant digits for the <code>g</code> (and <code>G)</code> representation of floating-point numbers, the minimum number of printed digits for integers. <div class="fragment"><pre>
136 trio_printf("|%10.8i|%.8i|\n", 42, 42);
137 | 00000042|00000042|
138</pre></div>
139<p>
140<em>Base</em> ( ..<code>9</code> ) [TRIO]
141<p>
142Sets the base that the associated integer must be converted to. The base can be between 2 and 36 (both included). <div class="fragment"><pre>
143 trio_printf("|%10.8.2i|%10..2i|%..2i|\n", 42, 42, 42);
144 | 00101010| 101010|101010|
145
146 trio_printf("|%*.8.*i|\n", 10, 2, 42);
147 | 00101010|
148</pre></div>
149<p>
150<em>Padding</em> ( <code>0</code> )
151<p>
152Integer and floating point numbers are prepended by zeros. The number of leading zeros are determined by the precision. If precision is not present, width is used instead.
153<p>
154<em>Short</em> ( <code>h</code> )
155<p>
156Integer arguments are read as an ( <code>unsigned</code> ) <code>short</code> <code>int</code>. String and character arguments are read as <code>char</code> <code>*</code> and <code>char</code> respectively.
157<p>
158<em>Short</em> <em>short</em> ( <code>hh</code> ) [C99, GNU]
159<p>
160The argument is read as an ( <code>unsigned</code> ) <code>char</code>.
161<p>
162<em>Fixed</em> <em>Size</em> ( <code>I</code> ) [MSVC]
163<p>
164The argument is read as a fixed sized integer. The modifier is followed by a number, which specifies the number of bits in the integer, and can be one of the following
165<p>
166<ul>
167<li> <code>I8</code> <li> <code>I16</code> <li> <code>I32</code> <li> <code>I64</code> (if 64-bits integers are supported)</ul>
168Works only for integers (i, u, d, o, x, X)
169<p>
170<em>Largest</em> ( <code>j</code> ) [C99]
171<p>
172The argument is read as an <code>intmax_t</code> / <code>uintmax_t</code>, which is defined to be the largest signed/unsigned integer.
173<p>
174<em>Long</em> ( <code>l</code> )
175<p>
176An integral argument is read as an ( <code>unsigned</code> ) <code>long</code> <code>int</code>. A string argument is read as a <code>wchar_t</code> <code>*</code>, and output as a multi-byte character sequence.
177<p>
178<em>Long</em> <em>long</em> ( <code>ll</code> ) [C99, UNIX98, GNU]
179<p>
180The argument is read as an ( <code>unsigned</code> ) <code>long</code> <code>long</code> <code>int</code>.
181<p>
182<em>Long</em> <em>double</em> ( <code>L</code> ) [C99, UNIX98, GNU]
183<p>
184The argument is read as a <code>long</code> <code>double</code>.
185<p>
186<em>ptrdiff_t</em> ( <code>t</code> ) [C99]
187<p>
188The argument is read as a <code>ptrdiff_t</code>, which is defined to be the signed integer type of the result of subtracting two pointers.
189<p>
190<em>Quad</em> ( <code>q</code> ) [BSD, GNU]
191<p>
192Corresponds to the long long modifier ( <code>ll</code> ).
193<p>
194<em>Wide</em> ( <code>w</code> ) [MISC]
195<p>
196For a string argument this is equivalent to using the long modifier ( <code>l</code> ).
197<p>
198<em>size_t</em> ( <code>z</code> ) [C99]
199<p>
200The argument is read as a <code>size_t</code>, which is defined to be the type returned by the <code>sizeof</code> operator.
201<p>
202<em>size_t</em> ( <code>Z</code> ) [GNU]
203<p>
204Corresponds to the size_t modifier ( <code>z</code> ).
205<p>
206<em>Alternative</em> ( <code>#</code> )
207<p>
208Prepend radix indicator for hexadecimal, octal, and binary integer numbers and for pointers. Always add a decimal-point for floating-point numbers. Escape non-printable characters for strings.
209<p>
210<em>Spacing</em> ( )
211<p>
212Prepend leading spaces when necessary.
213<p>
214<em>Sign</em> ( <code>+</code> )
215<p>
216Always prepend a sign to numbers. Normally only the negative sign is prepended to a number. With this modifier the positive sign may also be prepended.
217<p>
218<em>Alignment</em> ( <code>-</code> )
219<p>
220The output will be left-justified in the field specified by the width.
221<p>
222<em>Argument</em> ( <code>*</code> )
223<p>
224Width, precision, or base is read from the argument list, rather than from the formatting string.
225<p>
226<em>Quote</em> / <em>Grouping</em> ( ' <code>)</code> [MISC]
227<p>
228Groups integers and the integer-part of floating-point numbers according to the locale. Quote strings and characters.
229<p>
230<em>Sticky</em> ( <code>!</code> ) [TRIO]
231<p>
232The modifiers listed for the current specifier will be reused by subsequent specifiers of the same group. The following specifier groups exists <ul>
233<li> Integer ( <code>i</code>, <code>u</code>, <code>d</code>, <code>o</code>, <code>x</code>, <code>X</code> ) <li> Floating-point ( <code>f</code>, <code>F</code>, <code>e</code>, <code>E</code>, <code>g</code>, <code>G</code>, <code>a</code>, <code>A</code> ) <li> Character ( <code>c</code> ) <li> String ( <code>s</code> ) <li> Pointer ( <code>p</code> ) <li> Count ( <code>n</code> ) <li> Errno ( <code>m</code> ) <li> Group ( <code>[]</code> )</ul>
234The sticky modifiers are active until superseeded by other sticky modifiers, or the end of the format string is reached. Local modifiers overrides sticky modifiers for the given specifier only. <div class="fragment"><pre>
235 trio_printf("|%!08#x|%04x|%x|\n", 42, 42, 42);
236 |0x00002a|0x2a|0x00002a|
237</pre></div>
238<p>
239<b>Specifiers</b>
240<p>
241<em>Percent</em> ( <code>%</code> )
242<p>
243Produce a percent ( <code>%</code> ) character. This is used to quote the indication character. No modifiers are allowed. The full syntax is <code>%%</code>. <div class="fragment"><pre>
244 trio_printf("Percent is %%\n");
245 Percent is %
246</pre></div>
247<p>
248<em>Hex</em> <em>floats</em> ( <code>a</code>, <code>A</code> ) [C99]
249<p>
250Output a hexadecimal (base 16) representation of a floating point number. The number is automatically preceeded by <code>0x</code> ( or <code>0X</code> ). The exponent is <code>p</code> ( or <code>P</code> ). <div class="fragment"><pre>
251 trio_printf("|%a|%A|\n", 3.1415, 3.1415e20);
252 |0x3.228bc|0X3.228BCP+14|
253</pre></div>
254<p>
255<em>Binary</em> <em>numbers</em> ( <code>b</code>, <code>B</code> ) [MISC - SCO UnixWare 7]
256<p>
257DEPRECATED: Use Base modifier <code>%..2i</code> instead.
258<p>
259<em>Character</em> ( <code>c</code> )
260<p>
261Output a single character.
262<p>
263<ul>
264<li> Quote ( ' <code>)</code> [TRIO]. Quote the character.</ul>
265<em>Decimal</em> ( <code>d</code> )
266<p>
267Output a decimal (base 10) representation of a number.
268<p>
269<ul>
270<li> Grouping ( ' <code>)</code> [TRIO]. The number is separated by the locale thousand separator. <div class="fragment"><pre>
271 trio_printf("|%'ld|\n", 1234567);
272 |1,234,567|
273</pre></div></ul>
274<em>Floating-point</em> ( <code>e</code>, <code>E)</code>
275<p>
276Output a decimal floating-point number. The style is <code>[-]9.99e[-]9</code>, where <ul>
277<li> <code>[-]9.99</code> is the mantissa (as described for the <code>f</code>, <code>F</code> specifier), and <li> <code>e[-]9</code> is the exponent indicator (either <code>e</code> or <code>E</code>, depending on the floating-point specifier), followed by an optional sign and the exponent</ul>
278If the precision is wider than the maximum number of digits that can be represented by the floating-point unit, then the number will be adequately rounded. For example, assuming DBL_DIG is 15 <div class="fragment"><pre>
279 trio_printf("|%.18e|\n", (1.0 / 3.0));
280 |3.333333333333333000e-01|
281</pre></div>
282<p>
283<em>Floating-point</em> ( <code>f</code>, <code>F</code> )
284<p>
285Output a decimal floating-point number. The style is <code>[-]9.99</code>, where <ul>
286<li> <code>[-]</code> is an optional sign (either <code>+</code> or <code>-)</code>, <li> <code>9</code> is the integer-part (possibly interspersed with thousand-separators), <li> . <code>is</code> the decimal-point (depending on the locale), and <li> <code>99</code> is the fractional-part.</ul>
287If more digits are needed to output the number, than can be represented with the accuracy of the floating-point unit, then the number will be adequately rounded. For example, assuming that DBL_DIG is 15 <div class="fragment"><pre>
288 trio_printf("|%f|\n", (2.0 / 3.0) * 1E18);
289 |666666666666666700.000000|
290</pre></div>
291<p>
292The following modifiers holds a special meaning for this specifier <ul>
293<li> Alternative ( <code>#</code> ) [C99]. Add decimal point. <li> Grouping ( ' <code>)</code> [TRIO]. Group integer part of number into thousands (according to locale).</ul>
294<em>Floating-point</em> ( <code>g</code>, <code>G)</code>
295<p>
296Output a decimal floating-point representation of a number. The format of either the <code>f</code>, <code>F</code> specifier or the <code>e</code>, <code>E</code> specifier is used, whatever produces the shortest result.
297<p>
298<em>Integer</em> ( <code>i</code> )
299<p>
300Output a signed integer. Default base is 10.
301<p>
302<em>Errno</em> ( <code>m</code> ) [GNU]
303<p>
304<em>Count</em> ( <code>n</code> )
305<p>
306Insert into the location pointed to by the argument, the number of octets written to the output so far.
307<p>
308<em>Octal</em> ( <code>o</code> )
309<p>
310Output an octal (base 8) representation of a number.
311<p>
312<em>Pointer</em> ( <code>p</code> )
313<p>
314Ouput the address of the argument. The address is printed as a hexadecimal number. If the argument is the NULL pointer the text <code>(nil)</code> will be used instead. <ul>
315<li> Alternative ( <code>#</code> ) [TRIO]. Prepend 0x</ul>
316<em>String</em> ( <code>s</code>, <code>S</code> )
317<p>
318Output a string. The argument must point to a zero terminated string. If the argument is the NULL pointer the text <code>(nil)</code> will be used instead. <code>S</code> is equivalent to <code>ls</code>. <ul>
319<li> Alternative ( <code>#</code> ) [TRIO]. Escape non-printable characters.</ul>
320Non-printable characters are converted into C escapes, or hexadecimal numbers where no C escapes exists for the character. The C escapes, the hexadecimal number, and all backslashes are prepended by a backslash ( <code>\</code> ). The supported C escapes are <ul>
321<li> <code>\a</code> (\007) = alert <li> <code>\b</code> (\010) = backspace <li> <code>\f</code> (\014) = formfeed <li> <code>\n</code> (\012) = newline <li> <code>\r</code> (\015) = carriage return <li> <code>\t</code> (\011) = horizontal tab <li> <code>\v</code> (\013) = vertical tab</ul>
322<div class="fragment"><pre>
323 trio_printf("|One %s Three|One %'s Three|\n", "Two", "Two");
324 |One Two Three|One "Two" Three|
325
326 trio_printf("|Argument missing %s|\n", NULL);
327 |Argument missing (nil)|
328
329 trio_printf("|%#s|\n", "\007 \a.");
330 |\a \a.|
331</pre></div>
332<p>
333<em>Unsigned</em> ( <code>u</code> )
334<p>
335Output an unsigned integer. Default base is 10.
336<p>
337<em>Hex</em> ( <code>x</code>, <code>X</code> )
338<p>
339Output a hexadecimal (base 16) representation of a number.
340<p>
341<ul>
342<li> Alternative ( <code>#</code> ). Preceed the number by <code>0x</code> ( or <code>0X</code> ). The two characters are counted as part of the width.</ul>
343<em>User-defined</em> ( <code>&lt;&gt;</code> )
344<p>
345Invoke user-defined formatting. See <a class="el" href="group___user_defined.html#a243">User-defined Formatted Printing Functions.</a> for further information.
346<p>
347<b>RETURN</b> <b>VALUES</b>
348<p>
349All functions returns the number of outputted characters. If an error occured then a negative error code is returned [TRIO]. Note that this is a deviation from the standard, which simply returns -1 (or EOF) and errno set appropriately. The error condition can be detected by checking whether the function returns a negative number or not, and the number can be parsed with the following macros. The error codes are primarily intended as debugging aide for the developer.
350<p>
351<ul>
352<li> TRIO_EINVAL: Invalid argument. <li> TRIO_ETOOMANY: Too many arguments. <li> TRIO_EDBLREF: Double argument reference. <li> TRIO_EGAP: Argument reference gap. <li> TRIO_ENOMEM: Out of memory. <li> TRIO_ERANGE: Invalid range. <li> TRIO_ERRNO: The error is specified by the errno variable.</ul>
353Example: <div class="fragment"><pre>
354 int rc;
355
356 rc = trio_printf("%r\n", 42);
357 if (rc &lt; 0) {
358 if (TRIO_ERROR_CODE(rc) != TRIO_EOF) {
359 trio_printf("Error: %s at position %d\n",
360 TRIO_ERROR_NAME(rc),
361 TRIO_ERROR_POSITION(rc));
362 }
363 }
364</pre></div>
365<p>
366<b>SEE</b> <b>ALSO</b>
367<p>
368<em>trio_scanf</em>, <em>trio_register</em>.
369<p>
370<b>NOTES</b>
371<p>
372The printfv family uses an array rather than the stack to pass arguments. This means that <code>short</code> <code>int</code> and <code>float</code> values will not be handled by the default argument promotion in C. Instead, these values must be explicitly converted with the Short (h) modifier in both cases.
373<p>
374Example: <div class="fragment"><pre>
375 void *array[2];
376 float float_number = 42.0;
377 short short_number = 42;
378
379 array[0] = &amp;float_number;
380 array[1] = &amp;short_number;
381
382 trio_printfv("%hf %hd\n", array); /* CORRECT
383 trio_printfv("%f %d\n", array); /* WRONG
384</pre></div>
385<p>
386<b>CONFORMING</b> <b>TO</b>
387<p>
388Throughout this document the following abbreviations have been used to indicate what standard a feature conforms to. If nothing else is indicated ANSI C (C89) is assumed.
389<p>
390<ul>
391<li> [C89] ANSI X3.159-1989 <li> [C99] ISO/IEC 9899:1999 <li> [UNIX98] The Single UNIX Specification, Version 2 <li> [BSD] 4.4BSD <li> [GNU] GNU libc <li> [MSVC] Microsoft Visual C <li> [MISC] Other non-standard sources <li> [TRIO] Extensions specific for this package </ul>
392<hr><h2>Function Documentation</h2>
393<a name="a22" doxytag="trio-cdetect.c::trio_asprintf"></a><p>
394<table width="100%" cellpadding="2" cellspacing="0" border="0">
395 <tr>
396 <td class="md">
397 <table cellpadding="0" cellspacing="0" border="0">
398 <tr>
399 <td class="md" nowrap valign="top"> int trio_asprintf </td>
400 <td class="md" valign="top">(&nbsp;</td>
401 <td class="md" nowrap valign="top">char **&nbsp;</td>
402 <td class="mdname" nowrap>&nbsp; <em>result</em>, </td>
403 </tr>
404 <tr>
405 <td></td>
406 <td></td>
407 <td class="md" nowrap>const char *&nbsp;</td>
408 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
409 </tr>
410 <tr>
411 <td></td>
412 <td></td>
413 <td class="md" nowrap>...&nbsp;</td>
414 <td class="mdname" nowrap>&nbsp;</td>
415 </tr>
416 <tr>
417 <td></td>
418 <td class="md">)&nbsp;</td>
419 <td class="md" colspan="2"></td>
420 </tr>
421
422 </table>
423 </td>
424 </tr>
425</table>
426<table cellspacing=5 cellpadding=0 border=0>
427 <tr>
428 <td>
429 &nbsp;
430 </td>
431 <td>
432
433<p>
434Allocate and print to string.
435<p>
436The memory allocated and returned by <code>result</code> must be freed by the calling application.<dl compact><dt><b>Parameters: </b></dt><dd>
437<table border=0 cellspacing=2 cellpadding=0>
438<tr><td valign=top><em>result</em>&nbsp;</td><td>
439Output string. </td></tr>
440<tr><td valign=top><em>format</em>&nbsp;</td><td>
441Formatting string. </td></tr>
442<tr><td valign=top><em>...</em>&nbsp;</td><td>
443Arguments. </td></tr>
444</table>
445</dl><dl compact><dt><b>Returns: </b></dt><dd>
446Number of printed characters. </dl> </td>
447 </tr>
448</table>
449<a name="a24" doxytag="trio-cdetect.c::trio_asprintfv"></a><p>
450<table width="100%" cellpadding="2" cellspacing="0" border="0">
451 <tr>
452 <td class="md">
453 <table cellpadding="0" cellspacing="0" border="0">
454 <tr>
455 <td class="md" nowrap valign="top"> int trio_asprintfv </td>
456 <td class="md" valign="top">(&nbsp;</td>
457 <td class="md" nowrap valign="top">char **&nbsp;</td>
458 <td class="mdname" nowrap>&nbsp; <em>result</em>, </td>
459 </tr>
460 <tr>
461 <td></td>
462 <td></td>
463 <td class="md" nowrap>const char *&nbsp;</td>
464 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
465 </tr>
466 <tr>
467 <td></td>
468 <td></td>
469 <td class="md" nowrap>trio_pointer_t *&nbsp;</td>
470 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
471 </tr>
472 <tr>
473 <td></td>
474 <td class="md">)&nbsp;</td>
475 <td class="md" colspan="2"></td>
476 </tr>
477
478 </table>
479 </td>
480 </tr>
481</table>
482<table cellspacing=5 cellpadding=0 border=0>
483 <tr>
484 <td>
485 &nbsp;
486 </td>
487 <td>
488
489<p>
490Allocate and print to string.
491<p>
492The memory allocated and returned by <code>result</code> must be freed by the calling application.<dl compact><dt><b>Parameters: </b></dt><dd>
493<table border=0 cellspacing=2 cellpadding=0>
494<tr><td valign=top><em>result</em>&nbsp;</td><td>
495Output string. </td></tr>
496<tr><td valign=top><em>format</em>&nbsp;</td><td>
497Formatting string. </td></tr>
498<tr><td valign=top><em>args</em>&nbsp;</td><td>
499Arguments. </td></tr>
500</table>
501</dl><dl compact><dt><b>Returns: </b></dt><dd>
502Number of printed characters. </dl> </td>
503 </tr>
504</table>
505<a name="a6" doxytag="trio-cdetect.c::trio_dprintf"></a><p>
506<table width="100%" cellpadding="2" cellspacing="0" border="0">
507 <tr>
508 <td class="md">
509 <table cellpadding="0" cellspacing="0" border="0">
510 <tr>
511 <td class="md" nowrap valign="top"> int trio_dprintf </td>
512 <td class="md" valign="top">(&nbsp;</td>
513 <td class="md" nowrap valign="top">int&nbsp;</td>
514 <td class="mdname" nowrap>&nbsp; <em>fd</em>, </td>
515 </tr>
516 <tr>
517 <td></td>
518 <td></td>
519 <td class="md" nowrap>const char *&nbsp;</td>
520 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
521 </tr>
522 <tr>
523 <td></td>
524 <td></td>
525 <td class="md" nowrap>...&nbsp;</td>
526 <td class="mdname" nowrap>&nbsp;</td>
527 </tr>
528 <tr>
529 <td></td>
530 <td class="md">)&nbsp;</td>
531 <td class="md" colspan="2"></td>
532 </tr>
533
534 </table>
535 </td>
536 </tr>
537</table>
538<table cellspacing=5 cellpadding=0 border=0>
539 <tr>
540 <td>
541 &nbsp;
542 </td>
543 <td>
544
545<p>
546Print to file descriptor.
547<p>
548<dl compact><dt><b>Parameters: </b></dt><dd>
549<table border=0 cellspacing=2 cellpadding=0>
550<tr><td valign=top><em>fd</em>&nbsp;</td><td>
551File descriptor. </td></tr>
552<tr><td valign=top><em>format</em>&nbsp;</td><td>
553Formatting string. </td></tr>
554<tr><td valign=top><em>...</em>&nbsp;</td><td>
555Arguments. </td></tr>
556</table>
557</dl><dl compact><dt><b>Returns: </b></dt><dd>
558Number of printed characters. </dl> </td>
559 </tr>
560</table>
561<a name="a8" doxytag="trio-cdetect.c::trio_dprintfv"></a><p>
562<table width="100%" cellpadding="2" cellspacing="0" border="0">
563 <tr>
564 <td class="md">
565 <table cellpadding="0" cellspacing="0" border="0">
566 <tr>
567 <td class="md" nowrap valign="top"> int trio_dprintfv </td>
568 <td class="md" valign="top">(&nbsp;</td>
569 <td class="md" nowrap valign="top">int&nbsp;</td>
570 <td class="mdname" nowrap>&nbsp; <em>fd</em>, </td>
571 </tr>
572 <tr>
573 <td></td>
574 <td></td>
575 <td class="md" nowrap>const char *&nbsp;</td>
576 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
577 </tr>
578 <tr>
579 <td></td>
580 <td></td>
581 <td class="md" nowrap>trio_pointer_t *&nbsp;</td>
582 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
583 </tr>
584 <tr>
585 <td></td>
586 <td class="md">)&nbsp;</td>
587 <td class="md" colspan="2"></td>
588 </tr>
589
590 </table>
591 </td>
592 </tr>
593</table>
594<table cellspacing=5 cellpadding=0 border=0>
595 <tr>
596 <td>
597 &nbsp;
598 </td>
599 <td>
600
601<p>
602Print to file descriptor.
603<p>
604<dl compact><dt><b>Parameters: </b></dt><dd>
605<table border=0 cellspacing=2 cellpadding=0>
606<tr><td valign=top><em>fd</em>&nbsp;</td><td>
607File descriptor. </td></tr>
608<tr><td valign=top><em>format</em>&nbsp;</td><td>
609Formatting string. </td></tr>
610<tr><td valign=top><em>args</em>&nbsp;</td><td>
611Arguments. </td></tr>
612</table>
613</dl><dl compact><dt><b>Returns: </b></dt><dd>
614Number of printed characters. </dl> </td>
615 </tr>
616</table>
617<a name="a3" doxytag="trio-cdetect.c::trio_fprintf"></a><p>
618<table width="100%" cellpadding="2" cellspacing="0" border="0">
619 <tr>
620 <td class="md">
621 <table cellpadding="0" cellspacing="0" border="0">
622 <tr>
623 <td class="md" nowrap valign="top"> int trio_fprintf </td>
624 <td class="md" valign="top">(&nbsp;</td>
625 <td class="md" nowrap valign="top">FILE *&nbsp;</td>
626 <td class="mdname" nowrap>&nbsp; <em>file</em>, </td>
627 </tr>
628 <tr>
629 <td></td>
630 <td></td>
631 <td class="md" nowrap>const char *&nbsp;</td>
632 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
633 </tr>
634 <tr>
635 <td></td>
636 <td></td>
637 <td class="md" nowrap>...&nbsp;</td>
638 <td class="mdname" nowrap>&nbsp;</td>
639 </tr>
640 <tr>
641 <td></td>
642 <td class="md">)&nbsp;</td>
643 <td class="md" colspan="2"></td>
644 </tr>
645
646 </table>
647 </td>
648 </tr>
649</table>
650<table cellspacing=5 cellpadding=0 border=0>
651 <tr>
652 <td>
653 &nbsp;
654 </td>
655 <td>
656
657<p>
658Print to file.
659<p>
660<dl compact><dt><b>Parameters: </b></dt><dd>
661<table border=0 cellspacing=2 cellpadding=0>
662<tr><td valign=top><em>file</em>&nbsp;</td><td>
663File pointer. </td></tr>
664<tr><td valign=top><em>format</em>&nbsp;</td><td>
665Formatting string. </td></tr>
666<tr><td valign=top><em>...</em>&nbsp;</td><td>
667Arguments. </td></tr>
668</table>
669</dl><dl compact><dt><b>Returns: </b></dt><dd>
670Number of printed characters. </dl> </td>
671 </tr>
672</table>
673<a name="a5" doxytag="trio-cdetect.c::trio_fprintfv"></a><p>
674<table width="100%" cellpadding="2" cellspacing="0" border="0">
675 <tr>
676 <td class="md">
677 <table cellpadding="0" cellspacing="0" border="0">
678 <tr>
679 <td class="md" nowrap valign="top"> int trio_fprintfv </td>
680 <td class="md" valign="top">(&nbsp;</td>
681 <td class="md" nowrap valign="top">FILE *&nbsp;</td>
682 <td class="mdname" nowrap>&nbsp; <em>file</em>, </td>
683 </tr>
684 <tr>
685 <td></td>
686 <td></td>
687 <td class="md" nowrap>const char *&nbsp;</td>
688 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
689 </tr>
690 <tr>
691 <td></td>
692 <td></td>
693 <td class="md" nowrap>trio_pointer_t *&nbsp;</td>
694 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
695 </tr>
696 <tr>
697 <td></td>
698 <td class="md">)&nbsp;</td>
699 <td class="md" colspan="2"></td>
700 </tr>
701
702 </table>
703 </td>
704 </tr>
705</table>
706<table cellspacing=5 cellpadding=0 border=0>
707 <tr>
708 <td>
709 &nbsp;
710 </td>
711 <td>
712
713<p>
714Print to file.
715<p>
716<dl compact><dt><b>Parameters: </b></dt><dd>
717<table border=0 cellspacing=2 cellpadding=0>
718<tr><td valign=top><em>file</em>&nbsp;</td><td>
719File pointer. </td></tr>
720<tr><td valign=top><em>format</em>&nbsp;</td><td>
721Formatting string. </td></tr>
722<tr><td valign=top><em>args</em>&nbsp;</td><td>
723Arguments. </td></tr>
724</table>
725</dl><dl compact><dt><b>Returns: </b></dt><dd>
726Number of printed characters. </dl> </td>
727 </tr>
728</table>
729<a name="a0" doxytag="trio-cdetect.c::trio_printf"></a><p>
730<table width="100%" cellpadding="2" cellspacing="0" border="0">
731 <tr>
732 <td class="md">
733 <table cellpadding="0" cellspacing="0" border="0">
734 <tr>
735 <td class="md" nowrap valign="top"> int trio_printf </td>
736 <td class="md" valign="top">(&nbsp;</td>
737 <td class="md" nowrap valign="top">const char *&nbsp;</td>
738 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
739 </tr>
740 <tr>
741 <td></td>
742 <td></td>
743 <td class="md" nowrap>...&nbsp;</td>
744 <td class="mdname" nowrap>&nbsp;</td>
745 </tr>
746 <tr>
747 <td></td>
748 <td class="md">)&nbsp;</td>
749 <td class="md" colspan="2"></td>
750 </tr>
751
752 </table>
753 </td>
754 </tr>
755</table>
756<table cellspacing=5 cellpadding=0 border=0>
757 <tr>
758 <td>
759 &nbsp;
760 </td>
761 <td>
762
763<p>
764Print to standard output stream.
765<p>
766<dl compact><dt><b>Parameters: </b></dt><dd>
767<table border=0 cellspacing=2 cellpadding=0>
768<tr><td valign=top><em>format</em>&nbsp;</td><td>
769Formatting string. </td></tr>
770<tr><td valign=top><em>...</em>&nbsp;</td><td>
771Arguments. </td></tr>
772</table>
773</dl><dl compact><dt><b>Returns: </b></dt><dd>
774Number of printed characters. </dl> </td>
775 </tr>
776</table>
777<a name="a2" doxytag="trio-cdetect.c::trio_printfv"></a><p>
778<table width="100%" cellpadding="2" cellspacing="0" border="0">
779 <tr>
780 <td class="md">
781 <table cellpadding="0" cellspacing="0" border="0">
782 <tr>
783 <td class="md" nowrap valign="top"> int trio_printfv </td>
784 <td class="md" valign="top">(&nbsp;</td>
785 <td class="md" nowrap valign="top">const char *&nbsp;</td>
786 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
787 </tr>
788 <tr>
789 <td></td>
790 <td></td>
791 <td class="md" nowrap>trio_pointer_t *&nbsp;</td>
792 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
793 </tr>
794 <tr>
795 <td></td>
796 <td class="md">)&nbsp;</td>
797 <td class="md" colspan="2"></td>
798 </tr>
799
800 </table>
801 </td>
802 </tr>
803</table>
804<table cellspacing=5 cellpadding=0 border=0>
805 <tr>
806 <td>
807 &nbsp;
808 </td>
809 <td>
810
811<p>
812Print to standard output stream.
813<p>
814<dl compact><dt><b>Parameters: </b></dt><dd>
815<table border=0 cellspacing=2 cellpadding=0>
816<tr><td valign=top><em>format</em>&nbsp;</td><td>
817Formatting string. </td></tr>
818<tr><td valign=top><em>args</em>&nbsp;</td><td>
819Arguments. </td></tr>
820</table>
821</dl><dl compact><dt><b>Returns: </b></dt><dd>
822Number of printed characters. </dl> </td>
823 </tr>
824</table>
825<a name="a15" doxytag="trio-cdetect.c::trio_snprintf"></a><p>
826<table width="100%" cellpadding="2" cellspacing="0" border="0">
827 <tr>
828 <td class="md">
829 <table cellpadding="0" cellspacing="0" border="0">
830 <tr>
831 <td class="md" nowrap valign="top"> int trio_snprintf </td>
832 <td class="md" valign="top">(&nbsp;</td>
833 <td class="md" nowrap valign="top">char *&nbsp;</td>
834 <td class="mdname" nowrap>&nbsp; <em>buffer</em>, </td>
835 </tr>
836 <tr>
837 <td></td>
838 <td></td>
839 <td class="md" nowrap>size_t&nbsp;</td>
840 <td class="mdname" nowrap>&nbsp; <em>max</em>, </td>
841 </tr>
842 <tr>
843 <td></td>
844 <td></td>
845 <td class="md" nowrap>const char *&nbsp;</td>
846 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
847 </tr>
848 <tr>
849 <td></td>
850 <td></td>
851 <td class="md" nowrap>...&nbsp;</td>
852 <td class="mdname" nowrap>&nbsp;</td>
853 </tr>
854 <tr>
855 <td></td>
856 <td class="md">)&nbsp;</td>
857 <td class="md" colspan="2"></td>
858 </tr>
859
860 </table>
861 </td>
862 </tr>
863</table>
864<table cellspacing=5 cellpadding=0 border=0>
865 <tr>
866 <td>
867 &nbsp;
868 </td>
869 <td>
870
871<p>
872Print at most <code>max</code> characters to string.
873<p>
874<dl compact><dt><b>Parameters: </b></dt><dd>
875<table border=0 cellspacing=2 cellpadding=0>
876<tr><td valign=top><em>buffer</em>&nbsp;</td><td>
877Output string. </td></tr>
878<tr><td valign=top><em>max</em>&nbsp;</td><td>
879Maximum number of characters to print. </td></tr>
880<tr><td valign=top><em>format</em>&nbsp;</td><td>
881Formatting string. </td></tr>
882<tr><td valign=top><em>...</em>&nbsp;</td><td>
883Arguments. </td></tr>
884</table>
885</dl><dl compact><dt><b>Returns: </b></dt><dd>
886Number of printed characters. </dl> </td>
887 </tr>
888</table>
889<a name="a17" doxytag="trio-cdetect.c::trio_snprintfv"></a><p>
890<table width="100%" cellpadding="2" cellspacing="0" border="0">
891 <tr>
892 <td class="md">
893 <table cellpadding="0" cellspacing="0" border="0">
894 <tr>
895 <td class="md" nowrap valign="top"> int trio_snprintfv </td>
896 <td class="md" valign="top">(&nbsp;</td>
897 <td class="md" nowrap valign="top">char *&nbsp;</td>
898 <td class="mdname" nowrap>&nbsp; <em>buffer</em>, </td>
899 </tr>
900 <tr>
901 <td></td>
902 <td></td>
903 <td class="md" nowrap>size_t&nbsp;</td>
904 <td class="mdname" nowrap>&nbsp; <em>max</em>, </td>
905 </tr>
906 <tr>
907 <td></td>
908 <td></td>
909 <td class="md" nowrap>const char *&nbsp;</td>
910 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
911 </tr>
912 <tr>
913 <td></td>
914 <td></td>
915 <td class="md" nowrap>trio_pointer_t *&nbsp;</td>
916 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
917 </tr>
918 <tr>
919 <td></td>
920 <td class="md">)&nbsp;</td>
921 <td class="md" colspan="2"></td>
922 </tr>
923
924 </table>
925 </td>
926 </tr>
927</table>
928<table cellspacing=5 cellpadding=0 border=0>
929 <tr>
930 <td>
931 &nbsp;
932 </td>
933 <td>
934
935<p>
936Print at most <code>max</code> characters to string.
937<p>
938<dl compact><dt><b>Parameters: </b></dt><dd>
939<table border=0 cellspacing=2 cellpadding=0>
940<tr><td valign=top><em>buffer</em>&nbsp;</td><td>
941Output string. </td></tr>
942<tr><td valign=top><em>max</em>&nbsp;</td><td>
943Maximum number of characters to print. </td></tr>
944<tr><td valign=top><em>format</em>&nbsp;</td><td>
945Formatting string. </td></tr>
946<tr><td valign=top><em>args</em>&nbsp;</td><td>
947Arguments. </td></tr>
948</table>
949</dl><dl compact><dt><b>Returns: </b></dt><dd>
950Number of printed characters. </dl> </td>
951 </tr>
952</table>
953<a name="a12" doxytag="trio-cdetect.c::trio_sprintf"></a><p>
954<table width="100%" cellpadding="2" cellspacing="0" border="0">
955 <tr>
956 <td class="md">
957 <table cellpadding="0" cellspacing="0" border="0">
958 <tr>
959 <td class="md" nowrap valign="top"> int trio_sprintf </td>
960 <td class="md" valign="top">(&nbsp;</td>
961 <td class="md" nowrap valign="top">char *&nbsp;</td>
962 <td class="mdname" nowrap>&nbsp; <em>buffer</em>, </td>
963 </tr>
964 <tr>
965 <td></td>
966 <td></td>
967 <td class="md" nowrap>const char *&nbsp;</td>
968 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
969 </tr>
970 <tr>
971 <td></td>
972 <td></td>
973 <td class="md" nowrap>...&nbsp;</td>
974 <td class="mdname" nowrap>&nbsp;</td>
975 </tr>
976 <tr>
977 <td></td>
978 <td class="md">)&nbsp;</td>
979 <td class="md" colspan="2"></td>
980 </tr>
981
982 </table>
983 </td>
984 </tr>
985</table>
986<table cellspacing=5 cellpadding=0 border=0>
987 <tr>
988 <td>
989 &nbsp;
990 </td>
991 <td>
992
993<p>
994Print to string.
995<p>
996<dl compact><dt><b>Parameters: </b></dt><dd>
997<table border=0 cellspacing=2 cellpadding=0>
998<tr><td valign=top><em>buffer</em>&nbsp;</td><td>
999Output string. </td></tr>
1000<tr><td valign=top><em>format</em>&nbsp;</td><td>
1001Formatting string. </td></tr>
1002<tr><td valign=top><em>...</em>&nbsp;</td><td>
1003Arguments. </td></tr>
1004</table>
1005</dl><dl compact><dt><b>Returns: </b></dt><dd>
1006Number of printed characters. </dl> </td>
1007 </tr>
1008</table>
1009<a name="a14" doxytag="trio-cdetect.c::trio_sprintfv"></a><p>
1010<table width="100%" cellpadding="2" cellspacing="0" border="0">
1011 <tr>
1012 <td class="md">
1013 <table cellpadding="0" cellspacing="0" border="0">
1014 <tr>
1015 <td class="md" nowrap valign="top"> int trio_sprintfv </td>
1016 <td class="md" valign="top">(&nbsp;</td>
1017 <td class="md" nowrap valign="top">char *&nbsp;</td>
1018 <td class="mdname" nowrap>&nbsp; <em>buffer</em>, </td>
1019 </tr>
1020 <tr>
1021 <td></td>
1022 <td></td>
1023 <td class="md" nowrap>const char *&nbsp;</td>
1024 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
1025 </tr>
1026 <tr>
1027 <td></td>
1028 <td></td>
1029 <td class="md" nowrap>trio_pointer_t *&nbsp;</td>
1030 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
1031 </tr>
1032 <tr>
1033 <td></td>
1034 <td class="md">)&nbsp;</td>
1035 <td class="md" colspan="2"></td>
1036 </tr>
1037
1038 </table>
1039 </td>
1040 </tr>
1041</table>
1042<table cellspacing=5 cellpadding=0 border=0>
1043 <tr>
1044 <td>
1045 &nbsp;
1046 </td>
1047 <td>
1048
1049<p>
1050Print to string.
1051<p>
1052<dl compact><dt><b>Parameters: </b></dt><dd>
1053<table border=0 cellspacing=2 cellpadding=0>
1054<tr><td valign=top><em>buffer</em>&nbsp;</td><td>
1055Output string. </td></tr>
1056<tr><td valign=top><em>format</em>&nbsp;</td><td>
1057Formatting string. </td></tr>
1058<tr><td valign=top><em>args</em>&nbsp;</td><td>
1059Arguments. </td></tr>
1060</table>
1061</dl><dl compact><dt><b>Returns: </b></dt><dd>
1062Number of printed characters. </dl> </td>
1063 </tr>
1064</table>
1065<a name="a23" doxytag="trio-cdetect.c::trio_vasprintf"></a><p>
1066<table width="100%" cellpadding="2" cellspacing="0" border="0">
1067 <tr>
1068 <td class="md">
1069 <table cellpadding="0" cellspacing="0" border="0">
1070 <tr>
1071 <td class="md" nowrap valign="top"> int trio_vasprintf </td>
1072 <td class="md" valign="top">(&nbsp;</td>
1073 <td class="md" nowrap valign="top">char **&nbsp;</td>
1074 <td class="mdname" nowrap>&nbsp; <em>result</em>, </td>
1075 </tr>
1076 <tr>
1077 <td></td>
1078 <td></td>
1079 <td class="md" nowrap>const char *&nbsp;</td>
1080 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
1081 </tr>
1082 <tr>
1083 <td></td>
1084 <td></td>
1085 <td class="md" nowrap>va_list&nbsp;</td>
1086 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
1087 </tr>
1088 <tr>
1089 <td></td>
1090 <td class="md">)&nbsp;</td>
1091 <td class="md" colspan="2"></td>
1092 </tr>
1093
1094 </table>
1095 </td>
1096 </tr>
1097</table>
1098<table cellspacing=5 cellpadding=0 border=0>
1099 <tr>
1100 <td>
1101 &nbsp;
1102 </td>
1103 <td>
1104
1105<p>
1106Allocate and print to string.
1107<p>
1108The memory allocated and returned by <code>result</code> must be freed by the calling application.<dl compact><dt><b>Parameters: </b></dt><dd>
1109<table border=0 cellspacing=2 cellpadding=0>
1110<tr><td valign=top><em>result</em>&nbsp;</td><td>
1111Output string. </td></tr>
1112<tr><td valign=top><em>format</em>&nbsp;</td><td>
1113Formatting string. </td></tr>
1114<tr><td valign=top><em>args</em>&nbsp;</td><td>
1115Arguments. </td></tr>
1116</table>
1117</dl><dl compact><dt><b>Returns: </b></dt><dd>
1118Number of printed characters. </dl> </td>
1119 </tr>
1120</table>
1121<a name="a7" doxytag="trio-cdetect.c::trio_vdprintf"></a><p>
1122<table width="100%" cellpadding="2" cellspacing="0" border="0">
1123 <tr>
1124 <td class="md">
1125 <table cellpadding="0" cellspacing="0" border="0">
1126 <tr>
1127 <td class="md" nowrap valign="top"> int trio_vdprintf </td>
1128 <td class="md" valign="top">(&nbsp;</td>
1129 <td class="md" nowrap valign="top">int&nbsp;</td>
1130 <td class="mdname" nowrap>&nbsp; <em>fd</em>, </td>
1131 </tr>
1132 <tr>
1133 <td></td>
1134 <td></td>
1135 <td class="md" nowrap>const char *&nbsp;</td>
1136 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
1137 </tr>
1138 <tr>
1139 <td></td>
1140 <td></td>
1141 <td class="md" nowrap>va_list&nbsp;</td>
1142 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
1143 </tr>
1144 <tr>
1145 <td></td>
1146 <td class="md">)&nbsp;</td>
1147 <td class="md" colspan="2"></td>
1148 </tr>
1149
1150 </table>
1151 </td>
1152 </tr>
1153</table>
1154<table cellspacing=5 cellpadding=0 border=0>
1155 <tr>
1156 <td>
1157 &nbsp;
1158 </td>
1159 <td>
1160
1161<p>
1162Print to file descriptor.
1163<p>
1164<dl compact><dt><b>Parameters: </b></dt><dd>
1165<table border=0 cellspacing=2 cellpadding=0>
1166<tr><td valign=top><em>fd</em>&nbsp;</td><td>
1167File descriptor. </td></tr>
1168<tr><td valign=top><em>format</em>&nbsp;</td><td>
1169Formatting string. </td></tr>
1170<tr><td valign=top><em>args</em>&nbsp;</td><td>
1171Arguments. </td></tr>
1172</table>
1173</dl><dl compact><dt><b>Returns: </b></dt><dd>
1174Number of printed characters. </dl> </td>
1175 </tr>
1176</table>
1177<a name="a4" doxytag="trio-cdetect.c::trio_vfprintf"></a><p>
1178<table width="100%" cellpadding="2" cellspacing="0" border="0">
1179 <tr>
1180 <td class="md">
1181 <table cellpadding="0" cellspacing="0" border="0">
1182 <tr>
1183 <td class="md" nowrap valign="top"> int trio_vfprintf </td>
1184 <td class="md" valign="top">(&nbsp;</td>
1185 <td class="md" nowrap valign="top">FILE *&nbsp;</td>
1186 <td class="mdname" nowrap>&nbsp; <em>file</em>, </td>
1187 </tr>
1188 <tr>
1189 <td></td>
1190 <td></td>
1191 <td class="md" nowrap>const char *&nbsp;</td>
1192 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
1193 </tr>
1194 <tr>
1195 <td></td>
1196 <td></td>
1197 <td class="md" nowrap>va_list&nbsp;</td>
1198 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
1199 </tr>
1200 <tr>
1201 <td></td>
1202 <td class="md">)&nbsp;</td>
1203 <td class="md" colspan="2"></td>
1204 </tr>
1205
1206 </table>
1207 </td>
1208 </tr>
1209</table>
1210<table cellspacing=5 cellpadding=0 border=0>
1211 <tr>
1212 <td>
1213 &nbsp;
1214 </td>
1215 <td>
1216
1217<p>
1218Print to file.
1219<p>
1220<dl compact><dt><b>Parameters: </b></dt><dd>
1221<table border=0 cellspacing=2 cellpadding=0>
1222<tr><td valign=top><em>file</em>&nbsp;</td><td>
1223File pointer. </td></tr>
1224<tr><td valign=top><em>format</em>&nbsp;</td><td>
1225Formatting string. </td></tr>
1226<tr><td valign=top><em>args</em>&nbsp;</td><td>
1227Arguments. </td></tr>
1228</table>
1229</dl><dl compact><dt><b>Returns: </b></dt><dd>
1230Number of printed characters. </dl> </td>
1231 </tr>
1232</table>
1233<a name="a1" doxytag="trio-cdetect.c::trio_vprintf"></a><p>
1234<table width="100%" cellpadding="2" cellspacing="0" border="0">
1235 <tr>
1236 <td class="md">
1237 <table cellpadding="0" cellspacing="0" border="0">
1238 <tr>
1239 <td class="md" nowrap valign="top"> int trio_vprintf </td>
1240 <td class="md" valign="top">(&nbsp;</td>
1241 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1242 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
1243 </tr>
1244 <tr>
1245 <td></td>
1246 <td></td>
1247 <td class="md" nowrap>va_list&nbsp;</td>
1248 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
1249 </tr>
1250 <tr>
1251 <td></td>
1252 <td class="md">)&nbsp;</td>
1253 <td class="md" colspan="2"></td>
1254 </tr>
1255
1256 </table>
1257 </td>
1258 </tr>
1259</table>
1260<table cellspacing=5 cellpadding=0 border=0>
1261 <tr>
1262 <td>
1263 &nbsp;
1264 </td>
1265 <td>
1266
1267<p>
1268Print to standard output stream.
1269<p>
1270<dl compact><dt><b>Parameters: </b></dt><dd>
1271<table border=0 cellspacing=2 cellpadding=0>
1272<tr><td valign=top><em>format</em>&nbsp;</td><td>
1273Formatting string. </td></tr>
1274<tr><td valign=top><em>args</em>&nbsp;</td><td>
1275Arguments. </td></tr>
1276</table>
1277</dl><dl compact><dt><b>Returns: </b></dt><dd>
1278Number of printed characters. </dl> </td>
1279 </tr>
1280</table>
1281<a name="a16" doxytag="trio-cdetect.c::trio_vsnprintf"></a><p>
1282<table width="100%" cellpadding="2" cellspacing="0" border="0">
1283 <tr>
1284 <td class="md">
1285 <table cellpadding="0" cellspacing="0" border="0">
1286 <tr>
1287 <td class="md" nowrap valign="top"> int trio_vsnprintf </td>
1288 <td class="md" valign="top">(&nbsp;</td>
1289 <td class="md" nowrap valign="top">char *&nbsp;</td>
1290 <td class="mdname" nowrap>&nbsp; <em>buffer</em>, </td>
1291 </tr>
1292 <tr>
1293 <td></td>
1294 <td></td>
1295 <td class="md" nowrap>size_t&nbsp;</td>
1296 <td class="mdname" nowrap>&nbsp; <em>max</em>, </td>
1297 </tr>
1298 <tr>
1299 <td></td>
1300 <td></td>
1301 <td class="md" nowrap>const char *&nbsp;</td>
1302 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
1303 </tr>
1304 <tr>
1305 <td></td>
1306 <td></td>
1307 <td class="md" nowrap>va_list&nbsp;</td>
1308 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
1309 </tr>
1310 <tr>
1311 <td></td>
1312 <td class="md">)&nbsp;</td>
1313 <td class="md" colspan="2"></td>
1314 </tr>
1315
1316 </table>
1317 </td>
1318 </tr>
1319</table>
1320<table cellspacing=5 cellpadding=0 border=0>
1321 <tr>
1322 <td>
1323 &nbsp;
1324 </td>
1325 <td>
1326
1327<p>
1328Print at most <code>max</code> characters to string.
1329<p>
1330<dl compact><dt><b>Parameters: </b></dt><dd>
1331<table border=0 cellspacing=2 cellpadding=0>
1332<tr><td valign=top><em>buffer</em>&nbsp;</td><td>
1333Output string. </td></tr>
1334<tr><td valign=top><em>max</em>&nbsp;</td><td>
1335Maximum number of characters to print. </td></tr>
1336<tr><td valign=top><em>format</em>&nbsp;</td><td>
1337Formatting string. </td></tr>
1338<tr><td valign=top><em>args</em>&nbsp;</td><td>
1339Arguments. </td></tr>
1340</table>
1341</dl><dl compact><dt><b>Returns: </b></dt><dd>
1342Number of printed characters. </dl> </td>
1343 </tr>
1344</table>
1345<a name="a13" doxytag="trio-cdetect.c::trio_vsprintf"></a><p>
1346<table width="100%" cellpadding="2" cellspacing="0" border="0">
1347 <tr>
1348 <td class="md">
1349 <table cellpadding="0" cellspacing="0" border="0">
1350 <tr>
1351 <td class="md" nowrap valign="top"> int trio_vsprintf </td>
1352 <td class="md" valign="top">(&nbsp;</td>
1353 <td class="md" nowrap valign="top">char *&nbsp;</td>
1354 <td class="mdname" nowrap>&nbsp; <em>buffer</em>, </td>
1355 </tr>
1356 <tr>
1357 <td></td>
1358 <td></td>
1359 <td class="md" nowrap>const char *&nbsp;</td>
1360 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
1361 </tr>
1362 <tr>
1363 <td></td>
1364 <td></td>
1365 <td class="md" nowrap>va_list&nbsp;</td>
1366 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
1367 </tr>
1368 <tr>
1369 <td></td>
1370 <td class="md">)&nbsp;</td>
1371 <td class="md" colspan="2"></td>
1372 </tr>
1373
1374 </table>
1375 </td>
1376 </tr>
1377</table>
1378<table cellspacing=5 cellpadding=0 border=0>
1379 <tr>
1380 <td>
1381 &nbsp;
1382 </td>
1383 <td>
1384
1385<p>
1386Print to string.
1387<p>
1388<dl compact><dt><b>Parameters: </b></dt><dd>
1389<table border=0 cellspacing=2 cellpadding=0>
1390<tr><td valign=top><em>buffer</em>&nbsp;</td><td>
1391Output string. </td></tr>
1392<tr><td valign=top><em>format</em>&nbsp;</td><td>
1393Formatting string. </td></tr>
1394<tr><td valign=top><em>args</em>&nbsp;</td><td>
1395Arguments. </td></tr>
1396</table>
1397</dl><dl compact><dt><b>Returns: </b></dt><dd>
1398Number of printed characters. </dl> </td>
1399 </tr>
1400</table>
1401<HR>
1402<center class="copyright">Copyright (C) 2001 - 2006 Bj&oslash;rn Reese and Daniel Stenberg.</center>
1403</body>
1404</html>
diff --git a/gs/trio/html/group___scanf.html b/gs/trio/html/group___scanf.html
new file mode 100644
index 000000000..23659cc2c
--- /dev/null
+++ b/gs/trio/html/group___scanf.html
@@ -0,0 +1,766 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
5 <title>TRIO</title>
6 <link href="trio.css" rel="stylesheet" type="text/css">
7</head>
8<body>
9<!-- Generated by Doxygen 1.2.18 -->
10<center>
11<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; </center>
12<hr><h1>Formatted Scanning Functions.</h1>Variations of formatted scanning functions.
13<a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0>
14<tr><td></td></tr>
15<tr><td colspan=2><br><h2>Functions</h2></td></tr>
16<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a0">trio_scanf</a> (const char *format,...)</td></tr>
17<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from standard input stream.</em> <a href="#a0"></a><em></em></font><br><br></td></tr>
18<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a1">trio_vscanf</a> (const char *format, va_list args)</td></tr>
19<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from standard input stream.</em> <a href="#a1"></a><em></em></font><br><br></td></tr>
20<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a2">trio_scanfv</a> (const char *format, trio_pointer_t *args)</td></tr>
21<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from standard input stream.</em> <a href="#a2"></a><em></em></font><br><br></td></tr>
22<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a3">trio_fscanf</a> (FILE *file, const char *format,...)</td></tr>
23<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from file.</em> <a href="#a3"></a><em></em></font><br><br></td></tr>
24<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a4">trio_vfscanf</a> (FILE *file, const char *format, va_list args)</td></tr>
25<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from file.</em> <a href="#a4"></a><em></em></font><br><br></td></tr>
26<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a5">trio_fscanfv</a> (FILE *file, const char *format, trio_pointer_t *args)</td></tr>
27<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from file.</em> <a href="#a5"></a><em></em></font><br><br></td></tr>
28<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a6">trio_dscanf</a> (int fd, const char *format,...)</td></tr>
29<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from file descriptor.</em> <a href="#a6"></a><em></em></font><br><br></td></tr>
30<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a7">trio_vdscanf</a> (int fd, const char *format, va_list args)</td></tr>
31<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from file descriptor.</em> <a href="#a7"></a><em></em></font><br><br></td></tr>
32<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a8">trio_dscanfv</a> (int fd, const char *format, trio_pointer_t *args)</td></tr>
33<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from file descriptor.</em> <a href="#a8"></a><em></em></font><br><br></td></tr>
34<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a12">trio_sscanf</a> (const char *buffer, const char *format,...)</td></tr>
35<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from string.</em> <a href="#a12"></a><em></em></font><br><br></td></tr>
36<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a13">trio_vsscanf</a> (const char *buffer, const char *format, va_list args)</td></tr>
37<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from string.</em> <a href="#a13"></a><em></em></font><br><br></td></tr>
38<tr><td nowrap align=right valign=top>int&nbsp;</td><td valign=bottom><a class="el" href="group___scanf.html#a14">trio_sscanfv</a> (const char *buffer, const char *format, trio_pointer_t *args)</td></tr>
39<tr><td>&nbsp;</td><td><font size=-1><em>Scan characters from string.</em> <a href="#a14"></a><em></em></font><br><br></td></tr>
40</table>
41<hr><a name="_details"></a><h2>Detailed Description</h2>
42Variations of formatted scanning functions.
43<p>
44<b>SYNOPSIS</b>
45<p>
46<div class="fragment"><pre>
47cc ... -ltrio -lm
48
49#include &lt;trio.h&gt;
50</pre></div>
51<p>
52<b>DESCRIPTION</b>
53<p>
54This documentation is incomplete. The documentation of the scanf family in [C99] and [UNIX98] also applies to the trio counterparts.
55<p>
56<b>SCANNING</b>
57<p>
58The scanning is controlled by the format string. The format string can contain normal text and conversion indicators. The normal text can be any character except the nil character (\000) and the percent character (\045 = '%'). Conversion indicators consists of an indication character (%), followed by zero or more conversion modifiers, and exactly one conversion specifier.
59<p>
60<b>Modifiers</b>
61<p>
62<em>Positional</em> ( <code>9$</code> ) [UNIX98]
63<p>
64See <a class="el" href="group___printf.html#a218">Formatted Printing Functions.</a>.
65<p>
66<b>Specifiers</b>
67<p>
68<em>Percent</em> ( <code>%</code> )
69<p>
70<em>Character</em> ( <code>c</code> )
71<p>
72<em>Decimal</em> ( <code>d</code> )
73<p>
74<em>Floating-point</em> ( <code>a</code>, <code>A</code>, <code>e</code>, <code>E</code>, <code>f</code>, <code>F</code>, <code>g</code>, <code>G</code> )
75<p>
76<em>Integer</em> ( <code>i</code> )
77<p>
78<em>Count</em> ( <code>n</code> )
79<p>
80<em>Octal</em> ( <code>o</code> )
81<p>
82<em>Pointer</em> ( <code>p</code> )
83<p>
84<em>String</em> ( <code>s</code> )
85<p>
86<em>Unsigned</em> ( <code>u</code> )
87<p>
88<em>Hex</em> ( <code>x</code>, <code>X</code> )
89<p>
90<em>Scanlist</em> ( <code>[]</code> )
91<p>
92Scanlist Exclusion (<code>^</code> )
93<p>
94Scanlist Range ( <code>-</code> ) [TRIO]
95<p>
96<ul>
97<li> Only increasing ranges, i.e. <code>[a-b]</code>, but not <code>[b-a]</code>. <li> Transitive ranges, ie. <code>[a-b-c]</code> equals <code>[a-c]</code>. <li> Trailing minus, ie. <code>[a-]</code> is interpreted as an <code>a</code> and a <code>-</code>. <li> Duplicates are ignored.</ul>
98Scanlist Equivalence Class Expression ( <code>[</code>= =<code>]</code> ) [TRIO]
99<p>
100Locale dependent (LC_COLLATE). Only one expression can appear inside the delimiters. <ul>
101<li> <code>[=a=]</code> All letters in the same equivalence class as the letter <code>a</code>. <div class="fragment"><pre>
102 trio_scanf("%[[=a=]b]\n", buffer);
103 trio_scanf("%[[=a=][=b=]]\n", buffer);
104</pre></div></ul>
105Scanlist Character Class Expression ( <code>[</code>: :<code>])</code> [TRIO] Locale dependent (LC_CTYPE). Only one expression can appear inside the delimiters. <ul>
106<li> <code>[:alnum:]</code> Same as <code>[:alpha:]</code> and <code>[:digit:]</code> <li> <code>[:alpha:]</code> Same as <code>[:lower:]</code> and <code>[:upper:]</code> <li> <code>[:cntrl:]</code> Control characters <li> <code>[:digit:]</code> Decimal digits <li> <code>[:graph:]</code> Printable characters except space <li> <code>[:lower:]</code> Lower case alphabetic letters <li> <code>[:print:]</code> Printable characters <li> <code>[:punct:]</code> Punctuation <li> <code>[:space:]</code> Whitespace characters <li> <code>[:upper:]</code> Upper case alphabetic letters <li> <code>[:xdigit:]</code> Hexadecimal digits <div class="fragment"><pre>
107 trio_scanf("%[[:alnum:]]\n", buffer);
108 trio_scanf("%[[:alpha:][:digit:]]\n", buffer);
109</pre></div></ul>
110<b>RETURN</b> <b>VALUES</b>
111<p>
112<b>SEE</b> <b>ALSO</b>
113<p>
114<a class="el" href="group___printf.html#a218">Formatted Printing Functions.</a> <hr><h2>Function Documentation</h2>
115<a name="a6" doxytag="trio-cdetect.c::trio_dscanf"></a><p>
116<table width="100%" cellpadding="2" cellspacing="0" border="0">
117 <tr>
118 <td class="md">
119 <table cellpadding="0" cellspacing="0" border="0">
120 <tr>
121 <td class="md" nowrap valign="top"> int trio_dscanf </td>
122 <td class="md" valign="top">(&nbsp;</td>
123 <td class="md" nowrap valign="top">int&nbsp;</td>
124 <td class="mdname" nowrap>&nbsp; <em>fd</em>, </td>
125 </tr>
126 <tr>
127 <td></td>
128 <td></td>
129 <td class="md" nowrap>const char *&nbsp;</td>
130 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
131 </tr>
132 <tr>
133 <td></td>
134 <td></td>
135 <td class="md" nowrap>...&nbsp;</td>
136 <td class="mdname" nowrap>&nbsp;</td>
137 </tr>
138 <tr>
139 <td></td>
140 <td class="md">)&nbsp;</td>
141 <td class="md" colspan="2"></td>
142 </tr>
143
144 </table>
145 </td>
146 </tr>
147</table>
148<table cellspacing=5 cellpadding=0 border=0>
149 <tr>
150 <td>
151 &nbsp;
152 </td>
153 <td>
154
155<p>
156Scan characters from file descriptor.
157<p>
158<dl compact><dt><b>Parameters: </b></dt><dd>
159<table border=0 cellspacing=2 cellpadding=0>
160<tr><td valign=top><em>fd</em>&nbsp;</td><td>
161File descriptor. </td></tr>
162<tr><td valign=top><em>format</em>&nbsp;</td><td>
163Formatting string. </td></tr>
164<tr><td valign=top><em>...</em>&nbsp;</td><td>
165Arguments. </td></tr>
166</table>
167</dl><dl compact><dt><b>Returns: </b></dt><dd>
168Number of scanned characters. </dl> </td>
169 </tr>
170</table>
171<a name="a8" doxytag="trio-cdetect.c::trio_dscanfv"></a><p>
172<table width="100%" cellpadding="2" cellspacing="0" border="0">
173 <tr>
174 <td class="md">
175 <table cellpadding="0" cellspacing="0" border="0">
176 <tr>
177 <td class="md" nowrap valign="top"> int trio_dscanfv </td>
178 <td class="md" valign="top">(&nbsp;</td>
179 <td class="md" nowrap valign="top">int&nbsp;</td>
180 <td class="mdname" nowrap>&nbsp; <em>fd</em>, </td>
181 </tr>
182 <tr>
183 <td></td>
184 <td></td>
185 <td class="md" nowrap>const char *&nbsp;</td>
186 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
187 </tr>
188 <tr>
189 <td></td>
190 <td></td>
191 <td class="md" nowrap>trio_pointer_t *&nbsp;</td>
192 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
193 </tr>
194 <tr>
195 <td></td>
196 <td class="md">)&nbsp;</td>
197 <td class="md" colspan="2"></td>
198 </tr>
199
200 </table>
201 </td>
202 </tr>
203</table>
204<table cellspacing=5 cellpadding=0 border=0>
205 <tr>
206 <td>
207 &nbsp;
208 </td>
209 <td>
210
211<p>
212Scan characters from file descriptor.
213<p>
214<dl compact><dt><b>Parameters: </b></dt><dd>
215<table border=0 cellspacing=2 cellpadding=0>
216<tr><td valign=top><em>fd</em>&nbsp;</td><td>
217File descriptor. </td></tr>
218<tr><td valign=top><em>format</em>&nbsp;</td><td>
219Formatting string. </td></tr>
220<tr><td valign=top><em>args</em>&nbsp;</td><td>
221Arguments. </td></tr>
222</table>
223</dl><dl compact><dt><b>Returns: </b></dt><dd>
224Number of scanned characters. </dl> </td>
225 </tr>
226</table>
227<a name="a3" doxytag="trio-cdetect.c::trio_fscanf"></a><p>
228<table width="100%" cellpadding="2" cellspacing="0" border="0">
229 <tr>
230 <td class="md">
231 <table cellpadding="0" cellspacing="0" border="0">
232 <tr>
233 <td class="md" nowrap valign="top"> int trio_fscanf </td>
234 <td class="md" valign="top">(&nbsp;</td>
235 <td class="md" nowrap valign="top">FILE *&nbsp;</td>
236 <td class="mdname" nowrap>&nbsp; <em>file</em>, </td>
237 </tr>
238 <tr>
239 <td></td>
240 <td></td>
241 <td class="md" nowrap>const char *&nbsp;</td>
242 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
243 </tr>
244 <tr>
245 <td></td>
246 <td></td>
247 <td class="md" nowrap>...&nbsp;</td>
248 <td class="mdname" nowrap>&nbsp;</td>
249 </tr>
250 <tr>
251 <td></td>
252 <td class="md">)&nbsp;</td>
253 <td class="md" colspan="2"></td>
254 </tr>
255
256 </table>
257 </td>
258 </tr>
259</table>
260<table cellspacing=5 cellpadding=0 border=0>
261 <tr>
262 <td>
263 &nbsp;
264 </td>
265 <td>
266
267<p>
268Scan characters from file.
269<p>
270<dl compact><dt><b>Parameters: </b></dt><dd>
271<table border=0 cellspacing=2 cellpadding=0>
272<tr><td valign=top><em>file</em>&nbsp;</td><td>
273File pointer. </td></tr>
274<tr><td valign=top><em>format</em>&nbsp;</td><td>
275Formatting string. </td></tr>
276<tr><td valign=top><em>...</em>&nbsp;</td><td>
277Arguments. </td></tr>
278</table>
279</dl><dl compact><dt><b>Returns: </b></dt><dd>
280Number of scanned characters. </dl> </td>
281 </tr>
282</table>
283<a name="a5" doxytag="trio-cdetect.c::trio_fscanfv"></a><p>
284<table width="100%" cellpadding="2" cellspacing="0" border="0">
285 <tr>
286 <td class="md">
287 <table cellpadding="0" cellspacing="0" border="0">
288 <tr>
289 <td class="md" nowrap valign="top"> int trio_fscanfv </td>
290 <td class="md" valign="top">(&nbsp;</td>
291 <td class="md" nowrap valign="top">FILE *&nbsp;</td>
292 <td class="mdname" nowrap>&nbsp; <em>file</em>, </td>
293 </tr>
294 <tr>
295 <td></td>
296 <td></td>
297 <td class="md" nowrap>const char *&nbsp;</td>
298 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
299 </tr>
300 <tr>
301 <td></td>
302 <td></td>
303 <td class="md" nowrap>trio_pointer_t *&nbsp;</td>
304 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
305 </tr>
306 <tr>
307 <td></td>
308 <td class="md">)&nbsp;</td>
309 <td class="md" colspan="2"></td>
310 </tr>
311
312 </table>
313 </td>
314 </tr>
315</table>
316<table cellspacing=5 cellpadding=0 border=0>
317 <tr>
318 <td>
319 &nbsp;
320 </td>
321 <td>
322
323<p>
324Scan characters from file.
325<p>
326<dl compact><dt><b>Parameters: </b></dt><dd>
327<table border=0 cellspacing=2 cellpadding=0>
328<tr><td valign=top><em>file</em>&nbsp;</td><td>
329File pointer. </td></tr>
330<tr><td valign=top><em>format</em>&nbsp;</td><td>
331Formatting string. </td></tr>
332<tr><td valign=top><em>args</em>&nbsp;</td><td>
333Arguments. </td></tr>
334</table>
335</dl><dl compact><dt><b>Returns: </b></dt><dd>
336Number of scanned characters. </dl> </td>
337 </tr>
338</table>
339<a name="a0" doxytag="trio-cdetect.c::trio_scanf"></a><p>
340<table width="100%" cellpadding="2" cellspacing="0" border="0">
341 <tr>
342 <td class="md">
343 <table cellpadding="0" cellspacing="0" border="0">
344 <tr>
345 <td class="md" nowrap valign="top"> int trio_scanf </td>
346 <td class="md" valign="top">(&nbsp;</td>
347 <td class="md" nowrap valign="top">const char *&nbsp;</td>
348 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
349 </tr>
350 <tr>
351 <td></td>
352 <td></td>
353 <td class="md" nowrap>...&nbsp;</td>
354 <td class="mdname" nowrap>&nbsp;</td>
355 </tr>
356 <tr>
357 <td></td>
358 <td class="md">)&nbsp;</td>
359 <td class="md" colspan="2"></td>
360 </tr>
361
362 </table>
363 </td>
364 </tr>
365</table>
366<table cellspacing=5 cellpadding=0 border=0>
367 <tr>
368 <td>
369 &nbsp;
370 </td>
371 <td>
372
373<p>
374Scan characters from standard input stream.
375<p>
376<dl compact><dt><b>Parameters: </b></dt><dd>
377<table border=0 cellspacing=2 cellpadding=0>
378<tr><td valign=top><em>format</em>&nbsp;</td><td>
379Formatting string. </td></tr>
380<tr><td valign=top><em>...</em>&nbsp;</td><td>
381Arguments. </td></tr>
382</table>
383</dl><dl compact><dt><b>Returns: </b></dt><dd>
384Number of scanned characters. </dl> </td>
385 </tr>
386</table>
387<a name="a2" doxytag="trio-cdetect.c::trio_scanfv"></a><p>
388<table width="100%" cellpadding="2" cellspacing="0" border="0">
389 <tr>
390 <td class="md">
391 <table cellpadding="0" cellspacing="0" border="0">
392 <tr>
393 <td class="md" nowrap valign="top"> int trio_scanfv </td>
394 <td class="md" valign="top">(&nbsp;</td>
395 <td class="md" nowrap valign="top">const char *&nbsp;</td>
396 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
397 </tr>
398 <tr>
399 <td></td>
400 <td></td>
401 <td class="md" nowrap>trio_pointer_t *&nbsp;</td>
402 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
403 </tr>
404 <tr>
405 <td></td>
406 <td class="md">)&nbsp;</td>
407 <td class="md" colspan="2"></td>
408 </tr>
409
410 </table>
411 </td>
412 </tr>
413</table>
414<table cellspacing=5 cellpadding=0 border=0>
415 <tr>
416 <td>
417 &nbsp;
418 </td>
419 <td>
420
421<p>
422Scan characters from standard input stream.
423<p>
424<dl compact><dt><b>Parameters: </b></dt><dd>
425<table border=0 cellspacing=2 cellpadding=0>
426<tr><td valign=top><em>format</em>&nbsp;</td><td>
427Formatting string. </td></tr>
428<tr><td valign=top><em>args</em>&nbsp;</td><td>
429Arguments. </td></tr>
430</table>
431</dl><dl compact><dt><b>Returns: </b></dt><dd>
432Number of scanned characters. </dl> </td>
433 </tr>
434</table>
435<a name="a12" doxytag="trio-cdetect.c::trio_sscanf"></a><p>
436<table width="100%" cellpadding="2" cellspacing="0" border="0">
437 <tr>
438 <td class="md">
439 <table cellpadding="0" cellspacing="0" border="0">
440 <tr>
441 <td class="md" nowrap valign="top"> int trio_sscanf </td>
442 <td class="md" valign="top">(&nbsp;</td>
443 <td class="md" nowrap valign="top">const char *&nbsp;</td>
444 <td class="mdname" nowrap>&nbsp; <em>buffer</em>, </td>
445 </tr>
446 <tr>
447 <td></td>
448 <td></td>
449 <td class="md" nowrap>const char *&nbsp;</td>
450 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
451 </tr>
452 <tr>
453 <td></td>
454 <td></td>
455 <td class="md" nowrap>...&nbsp;</td>
456 <td class="mdname" nowrap>&nbsp;</td>
457 </tr>
458 <tr>
459 <td></td>
460 <td class="md">)&nbsp;</td>
461 <td class="md" colspan="2"></td>
462 </tr>
463
464 </table>
465 </td>
466 </tr>
467</table>
468<table cellspacing=5 cellpadding=0 border=0>
469 <tr>
470 <td>
471 &nbsp;
472 </td>
473 <td>
474
475<p>
476Scan characters from string.
477<p>
478<dl compact><dt><b>Parameters: </b></dt><dd>
479<table border=0 cellspacing=2 cellpadding=0>
480<tr><td valign=top><em>buffer</em>&nbsp;</td><td>
481Input string. </td></tr>
482<tr><td valign=top><em>format</em>&nbsp;</td><td>
483Formatting string. </td></tr>
484<tr><td valign=top><em>...</em>&nbsp;</td><td>
485Arguments. </td></tr>
486</table>
487</dl><dl compact><dt><b>Returns: </b></dt><dd>
488Number of scanned characters. </dl> </td>
489 </tr>
490</table>
491<a name="a14" doxytag="trio-cdetect.c::trio_sscanfv"></a><p>
492<table width="100%" cellpadding="2" cellspacing="0" border="0">
493 <tr>
494 <td class="md">
495 <table cellpadding="0" cellspacing="0" border="0">
496 <tr>
497 <td class="md" nowrap valign="top"> int trio_sscanfv </td>
498 <td class="md" valign="top">(&nbsp;</td>
499 <td class="md" nowrap valign="top">const char *&nbsp;</td>
500 <td class="mdname" nowrap>&nbsp; <em>buffer</em>, </td>
501 </tr>
502 <tr>
503 <td></td>
504 <td></td>
505 <td class="md" nowrap>const char *&nbsp;</td>
506 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
507 </tr>
508 <tr>
509 <td></td>
510 <td></td>
511 <td class="md" nowrap>trio_pointer_t *&nbsp;</td>
512 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
513 </tr>
514 <tr>
515 <td></td>
516 <td class="md">)&nbsp;</td>
517 <td class="md" colspan="2"></td>
518 </tr>
519
520 </table>
521 </td>
522 </tr>
523</table>
524<table cellspacing=5 cellpadding=0 border=0>
525 <tr>
526 <td>
527 &nbsp;
528 </td>
529 <td>
530
531<p>
532Scan characters from string.
533<p>
534<dl compact><dt><b>Parameters: </b></dt><dd>
535<table border=0 cellspacing=2 cellpadding=0>
536<tr><td valign=top><em>buffer</em>&nbsp;</td><td>
537Input string. </td></tr>
538<tr><td valign=top><em>format</em>&nbsp;</td><td>
539Formatting string. </td></tr>
540<tr><td valign=top><em>args</em>&nbsp;</td><td>
541Arguments. </td></tr>
542</table>
543</dl><dl compact><dt><b>Returns: </b></dt><dd>
544Number of scanned characters. </dl> </td>
545 </tr>
546</table>
547<a name="a7" doxytag="trio-cdetect.c::trio_vdscanf"></a><p>
548<table width="100%" cellpadding="2" cellspacing="0" border="0">
549 <tr>
550 <td class="md">
551 <table cellpadding="0" cellspacing="0" border="0">
552 <tr>
553 <td class="md" nowrap valign="top"> int trio_vdscanf </td>
554 <td class="md" valign="top">(&nbsp;</td>
555 <td class="md" nowrap valign="top">int&nbsp;</td>
556 <td class="mdname" nowrap>&nbsp; <em>fd</em>, </td>
557 </tr>
558 <tr>
559 <td></td>
560 <td></td>
561 <td class="md" nowrap>const char *&nbsp;</td>
562 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
563 </tr>
564 <tr>
565 <td></td>
566 <td></td>
567 <td class="md" nowrap>va_list&nbsp;</td>
568 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
569 </tr>
570 <tr>
571 <td></td>
572 <td class="md">)&nbsp;</td>
573 <td class="md" colspan="2"></td>
574 </tr>
575
576 </table>
577 </td>
578 </tr>
579</table>
580<table cellspacing=5 cellpadding=0 border=0>
581 <tr>
582 <td>
583 &nbsp;
584 </td>
585 <td>
586
587<p>
588Scan characters from file descriptor.
589<p>
590<dl compact><dt><b>Parameters: </b></dt><dd>
591<table border=0 cellspacing=2 cellpadding=0>
592<tr><td valign=top><em>fd</em>&nbsp;</td><td>
593File descriptor. </td></tr>
594<tr><td valign=top><em>format</em>&nbsp;</td><td>
595Formatting string. </td></tr>
596<tr><td valign=top><em>args</em>&nbsp;</td><td>
597Arguments. </td></tr>
598</table>
599</dl><dl compact><dt><b>Returns: </b></dt><dd>
600Number of scanned characters. </dl> </td>
601 </tr>
602</table>
603<a name="a4" doxytag="trio-cdetect.c::trio_vfscanf"></a><p>
604<table width="100%" cellpadding="2" cellspacing="0" border="0">
605 <tr>
606 <td class="md">
607 <table cellpadding="0" cellspacing="0" border="0">
608 <tr>
609 <td class="md" nowrap valign="top"> int trio_vfscanf </td>
610 <td class="md" valign="top">(&nbsp;</td>
611 <td class="md" nowrap valign="top">FILE *&nbsp;</td>
612 <td class="mdname" nowrap>&nbsp; <em>file</em>, </td>
613 </tr>
614 <tr>
615 <td></td>
616 <td></td>
617 <td class="md" nowrap>const char *&nbsp;</td>
618 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
619 </tr>
620 <tr>
621 <td></td>
622 <td></td>
623 <td class="md" nowrap>va_list&nbsp;</td>
624 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
625 </tr>
626 <tr>
627 <td></td>
628 <td class="md">)&nbsp;</td>
629 <td class="md" colspan="2"></td>
630 </tr>
631
632 </table>
633 </td>
634 </tr>
635</table>
636<table cellspacing=5 cellpadding=0 border=0>
637 <tr>
638 <td>
639 &nbsp;
640 </td>
641 <td>
642
643<p>
644Scan characters from file.
645<p>
646<dl compact><dt><b>Parameters: </b></dt><dd>
647<table border=0 cellspacing=2 cellpadding=0>
648<tr><td valign=top><em>file</em>&nbsp;</td><td>
649File pointer. </td></tr>
650<tr><td valign=top><em>format</em>&nbsp;</td><td>
651Formatting string. </td></tr>
652<tr><td valign=top><em>args</em>&nbsp;</td><td>
653Arguments. </td></tr>
654</table>
655</dl><dl compact><dt><b>Returns: </b></dt><dd>
656Number of scanned characters. </dl> </td>
657 </tr>
658</table>
659<a name="a1" doxytag="trio-cdetect.c::trio_vscanf"></a><p>
660<table width="100%" cellpadding="2" cellspacing="0" border="0">
661 <tr>
662 <td class="md">
663 <table cellpadding="0" cellspacing="0" border="0">
664 <tr>
665 <td class="md" nowrap valign="top"> int trio_vscanf </td>
666 <td class="md" valign="top">(&nbsp;</td>
667 <td class="md" nowrap valign="top">const char *&nbsp;</td>
668 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
669 </tr>
670 <tr>
671 <td></td>
672 <td></td>
673 <td class="md" nowrap>va_list&nbsp;</td>
674 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
675 </tr>
676 <tr>
677 <td></td>
678 <td class="md">)&nbsp;</td>
679 <td class="md" colspan="2"></td>
680 </tr>
681
682 </table>
683 </td>
684 </tr>
685</table>
686<table cellspacing=5 cellpadding=0 border=0>
687 <tr>
688 <td>
689 &nbsp;
690 </td>
691 <td>
692
693<p>
694Scan characters from standard input stream.
695<p>
696<dl compact><dt><b>Parameters: </b></dt><dd>
697<table border=0 cellspacing=2 cellpadding=0>
698<tr><td valign=top><em>format</em>&nbsp;</td><td>
699Formatting string. </td></tr>
700<tr><td valign=top><em>args</em>&nbsp;</td><td>
701Arguments. </td></tr>
702</table>
703</dl><dl compact><dt><b>Returns: </b></dt><dd>
704Number of scanned characters. </dl> </td>
705 </tr>
706</table>
707<a name="a13" doxytag="trio-cdetect.c::trio_vsscanf"></a><p>
708<table width="100%" cellpadding="2" cellspacing="0" border="0">
709 <tr>
710 <td class="md">
711 <table cellpadding="0" cellspacing="0" border="0">
712 <tr>
713 <td class="md" nowrap valign="top"> int trio_vsscanf </td>
714 <td class="md" valign="top">(&nbsp;</td>
715 <td class="md" nowrap valign="top">const char *&nbsp;</td>
716 <td class="mdname" nowrap>&nbsp; <em>buffer</em>, </td>
717 </tr>
718 <tr>
719 <td></td>
720 <td></td>
721 <td class="md" nowrap>const char *&nbsp;</td>
722 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
723 </tr>
724 <tr>
725 <td></td>
726 <td></td>
727 <td class="md" nowrap>va_list&nbsp;</td>
728 <td class="mdname" nowrap>&nbsp; <em>args</em></td>
729 </tr>
730 <tr>
731 <td></td>
732 <td class="md">)&nbsp;</td>
733 <td class="md" colspan="2"></td>
734 </tr>
735
736 </table>
737 </td>
738 </tr>
739</table>
740<table cellspacing=5 cellpadding=0 border=0>
741 <tr>
742 <td>
743 &nbsp;
744 </td>
745 <td>
746
747<p>
748Scan characters from string.
749<p>
750<dl compact><dt><b>Parameters: </b></dt><dd>
751<table border=0 cellspacing=2 cellpadding=0>
752<tr><td valign=top><em>buffer</em>&nbsp;</td><td>
753Input string. </td></tr>
754<tr><td valign=top><em>format</em>&nbsp;</td><td>
755Formatting string. </td></tr>
756<tr><td valign=top><em>args</em>&nbsp;</td><td>
757Arguments. </td></tr>
758</table>
759</dl><dl compact><dt><b>Returns: </b></dt><dd>
760Number of scanned characters. </dl> </td>
761 </tr>
762</table>
763<HR>
764<center class="copyright">Copyright (C) 2001 - 2006 Bj&oslash;rn Reese and Daniel Stenberg.</center>
765</body>
766</html>
diff --git a/gs/trio/html/group___special_quantities.html b/gs/trio/html/group___special_quantities.html
new file mode 100644
index 000000000..8bcdee421
--- /dev/null
+++ b/gs/trio/html/group___special_quantities.html
@@ -0,0 +1,377 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
5 <title>TRIO</title>
6 <link href="trio.css" rel="stylesheet" type="text/css">
7</head>
8<body>
9<!-- Generated by Doxygen 1.2.18 -->
10<center>
11<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; </center>
12<hr><h1>Special Quantifies.</h1>Functions to detect and fabricate special quantities in floating-point numbers.
13<a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0>
14<tr><td></td></tr>
15<tr><td colspan=2><br><h2>Functions</h2></td></tr>
16<tr><td nowrap align=right valign=top>TRIO_PUBLIC_NAN int&nbsp;</td><td valign=bottom><a class="el" href="group___special_quantities.html#a4">trio_isnan</a> (double number)</td></tr>
17<tr><td>&nbsp;</td><td><font size=-1><em>Check for NaN.</em> <a href="#a4"></a><em></em></font><br><br></td></tr>
18<tr><td nowrap align=right valign=top>TRIO_PUBLIC_NAN int&nbsp;</td><td valign=bottom><a class="el" href="group___special_quantities.html#a5">trio_isinf</a> (double number)</td></tr>
19<tr><td>&nbsp;</td><td><font size=-1><em>Check for infinity.</em> <a href="#a5"></a><em></em></font><br><br></td></tr>
20<tr><td nowrap align=right valign=top>TRIO_PUBLIC_NAN int&nbsp;</td><td valign=bottom><a class="el" href="group___special_quantities.html#a6">trio_isfinite</a> (double number)</td></tr>
21<tr><td>&nbsp;</td><td><font size=-1><em>Check for finity.</em> <a href="#a6"></a><em></em></font><br><br></td></tr>
22<tr><td nowrap align=right valign=top>TRIO_PUBLIC_NAN int&nbsp;</td><td valign=bottom><a class="el" href="group___special_quantities.html#a7">trio_signbit</a> (double number)</td></tr>
23<tr><td>&nbsp;</td><td><font size=-1><em>Examine the sign of a number.</em> <a href="#a7"></a><em></em></font><br><br></td></tr>
24<tr><td nowrap align=right valign=top>TRIO_PUBLIC_NAN int&nbsp;</td><td valign=bottom><a class="el" href="group___special_quantities.html#a8">trio_fpclassify</a> (double number)</td></tr>
25<tr><td>&nbsp;</td><td><font size=-1><em>Examine the class of a number.</em> <a href="#a8"></a><em></em></font><br><br></td></tr>
26<tr><td nowrap align=right valign=top>TRIO_PUBLIC_NAN double&nbsp;</td><td valign=bottom><a class="el" href="group___special_quantities.html#a9">trio_nzero</a> (void)</td></tr>
27<tr><td>&nbsp;</td><td><font size=-1><em>Generate negative zero.</em> <a href="#a9"></a><em></em></font><br><br></td></tr>
28<tr><td nowrap align=right valign=top>TRIO_PUBLIC_NAN double&nbsp;</td><td valign=bottom><a class="el" href="group___special_quantities.html#a10">trio_pinf</a> (void)</td></tr>
29<tr><td>&nbsp;</td><td><font size=-1><em>Generate positive infinity.</em> <a href="#a10"></a><em></em></font><br><br></td></tr>
30<tr><td nowrap align=right valign=top>TRIO_PUBLIC_NAN double&nbsp;</td><td valign=bottom><a class="el" href="group___special_quantities.html#a11">trio_ninf</a> (void)</td></tr>
31<tr><td>&nbsp;</td><td><font size=-1><em>Generate negative infinity.</em> <a href="#a11"></a><em></em></font><br><br></td></tr>
32<tr><td nowrap align=right valign=top>TRIO_PUBLIC_NAN double&nbsp;</td><td valign=bottom><a class="el" href="group___special_quantities.html#a12">trio_nan</a> (void)</td></tr>
33<tr><td>&nbsp;</td><td><font size=-1><em>Generate NaN.</em> <a href="#a12"></a><em></em></font><br><br></td></tr>
34</table>
35<hr><a name="_details"></a><h2>Detailed Description</h2>
36Functions to detect and fabricate special quantities in floating-point numbers.
37<p>
38<b>SYNOPSIS</b>
39<p>
40<div class="fragment"><pre>
41cc ... -ltrio -lm
42
43#include &lt;trionan.h&gt;
44</pre></div>
45<p>
46<b>DESCRIPTION</b>
47<p>
48Certain arithmetical operations does not result in normal numbers. Instead they result in special quantities that must be handled differently by the floating-point hardware. These includes Infinity and Not-A-Number (NaN).
49<p>
50For example, 0/0 (zero divided by zero) yields NaN. Any operation which involves a NaN will result in NaN. Any comparison involving NaN will be unsuccessful, even if NaN is compared to NaN.
51<p>
52These special quantities are represented with special bit patterns by the floating-point hardware, and this bit patterns depend on the hardware. There may even be hardware that does not support special quantities, so the functions in this module are not guaranteed to work on all platforms.
53<p>
54The approach used in this module is to (in decreasing order of importance) <ul>
55<li> Use C99 functionality when available. <li> Use IEEE 754-1985 bit patterns if possible. <li> Use platform-specific techniques.</ul>
56<b>NOTES</b>
57<p>
58This module does not depend on the rest of trio, and can thus be reused separately. The following files are necessary: <ul>
59<li> <code>triodef.h</code> <li> <code>trionan.h</code> <li> <code>trionan.c</code> </ul>
60<hr><h2>Function Documentation</h2>
61<a name="a8" doxytag="trionan-macro.c::trio_fpclassify"></a><p>
62<table width="100%" cellpadding="2" cellspacing="0" border="0">
63 <tr>
64 <td class="md">
65 <table cellpadding="0" cellspacing="0" border="0">
66 <tr>
67 <td class="md" nowrap valign="top"> TRIO_PUBLIC_NAN int trio_fpclassify </td>
68 <td class="md" valign="top">(&nbsp;</td>
69 <td class="md" nowrap valign="top">double&nbsp;</td>
70 <td class="mdname1" valign="top" nowrap>&nbsp; <em>number</em> </td>
71 <td class="md" valign="top">)&nbsp;</td>
72 <td class="md" nowrap></td>
73 </tr>
74
75 </table>
76 </td>
77 </tr>
78</table>
79<table cellspacing=5 cellpadding=0 border=0>
80 <tr>
81 <td>
82 &nbsp;
83 </td>
84 <td>
85
86<p>
87Examine the class of a number.
88<p>
89<dl compact><dt><b>Parameters: </b></dt><dd>
90<table border=0 cellspacing=2 cellpadding=0>
91<tr><td valign=top><em>number</em>&nbsp;</td><td>
92An arbitrary floating-point number. </td></tr>
93</table>
94</dl><dl compact><dt><b>Returns: </b></dt><dd>
95Enumerable value indicating the class of <code>number</code> </dl> </td>
96 </tr>
97</table>
98<a name="a6" doxytag="trionan-macro.c::trio_isfinite"></a><p>
99<table width="100%" cellpadding="2" cellspacing="0" border="0">
100 <tr>
101 <td class="md">
102 <table cellpadding="0" cellspacing="0" border="0">
103 <tr>
104 <td class="md" nowrap valign="top"> TRIO_PUBLIC_NAN int trio_isfinite </td>
105 <td class="md" valign="top">(&nbsp;</td>
106 <td class="md" nowrap valign="top">double&nbsp;</td>
107 <td class="mdname1" valign="top" nowrap>&nbsp; <em>number</em> </td>
108 <td class="md" valign="top">)&nbsp;</td>
109 <td class="md" nowrap></td>
110 </tr>
111
112 </table>
113 </td>
114 </tr>
115</table>
116<table cellspacing=5 cellpadding=0 border=0>
117 <tr>
118 <td>
119 &nbsp;
120 </td>
121 <td>
122
123<p>
124Check for finity.
125<p>
126<dl compact><dt><b>Parameters: </b></dt><dd>
127<table border=0 cellspacing=2 cellpadding=0>
128<tr><td valign=top><em>number</em>&nbsp;</td><td>
129An arbitrary floating-point number. </td></tr>
130</table>
131</dl><dl compact><dt><b>Returns: </b></dt><dd>
132Boolean value indicating whether or not the number is a finite. </dl> </td>
133 </tr>
134</table>
135<a name="a5" doxytag="trionan-macro.c::trio_isinf"></a><p>
136<table width="100%" cellpadding="2" cellspacing="0" border="0">
137 <tr>
138 <td class="md">
139 <table cellpadding="0" cellspacing="0" border="0">
140 <tr>
141 <td class="md" nowrap valign="top"> TRIO_PUBLIC_NAN int trio_isinf </td>
142 <td class="md" valign="top">(&nbsp;</td>
143 <td class="md" nowrap valign="top">double&nbsp;</td>
144 <td class="mdname1" valign="top" nowrap>&nbsp; <em>number</em> </td>
145 <td class="md" valign="top">)&nbsp;</td>
146 <td class="md" nowrap></td>
147 </tr>
148
149 </table>
150 </td>
151 </tr>
152</table>
153<table cellspacing=5 cellpadding=0 border=0>
154 <tr>
155 <td>
156 &nbsp;
157 </td>
158 <td>
159
160<p>
161Check for infinity.
162<p>
163<dl compact><dt><b>Parameters: </b></dt><dd>
164<table border=0 cellspacing=2 cellpadding=0>
165<tr><td valign=top><em>number</em>&nbsp;</td><td>
166An arbitrary floating-point number. </td></tr>
167</table>
168</dl><dl compact><dt><b>Returns: </b></dt><dd>
1691 if positive infinity, -1 if negative infinity, 0 otherwise. </dl> </td>
170 </tr>
171</table>
172<a name="a4" doxytag="trionan-macro.c::trio_isnan"></a><p>
173<table width="100%" cellpadding="2" cellspacing="0" border="0">
174 <tr>
175 <td class="md">
176 <table cellpadding="0" cellspacing="0" border="0">
177 <tr>
178 <td class="md" nowrap valign="top"> TRIO_PUBLIC_NAN int trio_isnan </td>
179 <td class="md" valign="top">(&nbsp;</td>
180 <td class="md" nowrap valign="top">double&nbsp;</td>
181 <td class="mdname1" valign="top" nowrap>&nbsp; <em>number</em> </td>
182 <td class="md" valign="top">)&nbsp;</td>
183 <td class="md" nowrap></td>
184 </tr>
185
186 </table>
187 </td>
188 </tr>
189</table>
190<table cellspacing=5 cellpadding=0 border=0>
191 <tr>
192 <td>
193 &nbsp;
194 </td>
195 <td>
196
197<p>
198Check for NaN.
199<p>
200<dl compact><dt><b>Parameters: </b></dt><dd>
201<table border=0 cellspacing=2 cellpadding=0>
202<tr><td valign=top><em>number</em>&nbsp;</td><td>
203An arbitrary floating-point number. </td></tr>
204</table>
205</dl><dl compact><dt><b>Returns: </b></dt><dd>
206Boolean value indicating whether or not the number is a NaN. </dl> </td>
207 </tr>
208</table>
209<a name="a12" doxytag="trionan-macro.c::trio_nan"></a><p>
210<table width="100%" cellpadding="2" cellspacing="0" border="0">
211 <tr>
212 <td class="md">
213 <table cellpadding="0" cellspacing="0" border="0">
214 <tr>
215 <td class="md" nowrap valign="top"> TRIO_PUBLIC_NAN double trio_nan </td>
216 <td class="md" valign="top">(&nbsp;</td>
217 <td class="md" nowrap valign="top">void&nbsp;</td>
218 <td class="mdname1" valign="top" nowrap>&nbsp; </td>
219 <td class="md" valign="top">)&nbsp;</td>
220 <td class="md" nowrap></td>
221 </tr>
222
223 </table>
224 </td>
225 </tr>
226</table>
227<table cellspacing=5 cellpadding=0 border=0>
228 <tr>
229 <td>
230 &nbsp;
231 </td>
232 <td>
233
234<p>
235Generate NaN.
236<p>
237<dl compact><dt><b>Returns: </b></dt><dd>
238Floating-point representation of NaN. </dl> </td>
239 </tr>
240</table>
241<a name="a11" doxytag="trionan-macro.c::trio_ninf"></a><p>
242<table width="100%" cellpadding="2" cellspacing="0" border="0">
243 <tr>
244 <td class="md">
245 <table cellpadding="0" cellspacing="0" border="0">
246 <tr>
247 <td class="md" nowrap valign="top"> TRIO_PUBLIC_NAN double trio_ninf </td>
248 <td class="md" valign="top">(&nbsp;</td>
249 <td class="md" nowrap valign="top">void&nbsp;</td>
250 <td class="mdname1" valign="top" nowrap>&nbsp; </td>
251 <td class="md" valign="top">)&nbsp;</td>
252 <td class="md" nowrap></td>
253 </tr>
254
255 </table>
256 </td>
257 </tr>
258</table>
259<table cellspacing=5 cellpadding=0 border=0>
260 <tr>
261 <td>
262 &nbsp;
263 </td>
264 <td>
265
266<p>
267Generate negative infinity.
268<p>
269<dl compact><dt><b>Returns: </b></dt><dd>
270Floating-point value of negative infinity. </dl> </td>
271 </tr>
272</table>
273<a name="a9" doxytag="trionan-macro.c::trio_nzero"></a><p>
274<table width="100%" cellpadding="2" cellspacing="0" border="0">
275 <tr>
276 <td class="md">
277 <table cellpadding="0" cellspacing="0" border="0">
278 <tr>
279 <td class="md" nowrap valign="top"> TRIO_PUBLIC_NAN double trio_nzero </td>
280 <td class="md" valign="top">(&nbsp;</td>
281 <td class="md" nowrap valign="top">void&nbsp;</td>
282 <td class="mdname1" valign="top" nowrap>&nbsp; </td>
283 <td class="md" valign="top">)&nbsp;</td>
284 <td class="md" nowrap></td>
285 </tr>
286
287 </table>
288 </td>
289 </tr>
290</table>
291<table cellspacing=5 cellpadding=0 border=0>
292 <tr>
293 <td>
294 &nbsp;
295 </td>
296 <td>
297
298<p>
299Generate negative zero.
300<p>
301<dl compact><dt><b>Returns: </b></dt><dd>
302Floating-point representation of negative zero. </dl> </td>
303 </tr>
304</table>
305<a name="a10" doxytag="trionan-macro.c::trio_pinf"></a><p>
306<table width="100%" cellpadding="2" cellspacing="0" border="0">
307 <tr>
308 <td class="md">
309 <table cellpadding="0" cellspacing="0" border="0">
310 <tr>
311 <td class="md" nowrap valign="top"> TRIO_PUBLIC_NAN double trio_pinf </td>
312 <td class="md" valign="top">(&nbsp;</td>
313 <td class="md" nowrap valign="top">void&nbsp;</td>
314 <td class="mdname1" valign="top" nowrap>&nbsp; </td>
315 <td class="md" valign="top">)&nbsp;</td>
316 <td class="md" nowrap></td>
317 </tr>
318
319 </table>
320 </td>
321 </tr>
322</table>
323<table cellspacing=5 cellpadding=0 border=0>
324 <tr>
325 <td>
326 &nbsp;
327 </td>
328 <td>
329
330<p>
331Generate positive infinity.
332<p>
333<dl compact><dt><b>Returns: </b></dt><dd>
334Floating-point representation of positive infinity. </dl> </td>
335 </tr>
336</table>
337<a name="a7" doxytag="trionan-macro.c::trio_signbit"></a><p>
338<table width="100%" cellpadding="2" cellspacing="0" border="0">
339 <tr>
340 <td class="md">
341 <table cellpadding="0" cellspacing="0" border="0">
342 <tr>
343 <td class="md" nowrap valign="top"> TRIO_PUBLIC_NAN int trio_signbit </td>
344 <td class="md" valign="top">(&nbsp;</td>
345 <td class="md" nowrap valign="top">double&nbsp;</td>
346 <td class="mdname1" valign="top" nowrap>&nbsp; <em>number</em> </td>
347 <td class="md" valign="top">)&nbsp;</td>
348 <td class="md" nowrap></td>
349 </tr>
350
351 </table>
352 </td>
353 </tr>
354</table>
355<table cellspacing=5 cellpadding=0 border=0>
356 <tr>
357 <td>
358 &nbsp;
359 </td>
360 <td>
361
362<p>
363Examine the sign of a number.
364<p>
365<dl compact><dt><b>Parameters: </b></dt><dd>
366<table border=0 cellspacing=2 cellpadding=0>
367<tr><td valign=top><em>number</em>&nbsp;</td><td>
368An arbitrary floating-point number. </td></tr>
369</table>
370</dl><dl compact><dt><b>Returns: </b></dt><dd>
371Boolean value indicating whether or not the number has the sign bit set (i.e. is negative). </dl> </td>
372 </tr>
373</table>
374<HR>
375<center class="copyright">Copyright (C) 2001 - 2006 Bj&oslash;rn Reese and Daniel Stenberg.</center>
376</body>
377</html>
diff --git a/gs/trio/html/group___static_strings.html b/gs/trio/html/group___static_strings.html
new file mode 100644
index 000000000..835cee8e3
--- /dev/null
+++ b/gs/trio/html/group___static_strings.html
@@ -0,0 +1,1864 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
5 <title>TRIO</title>
6 <link href="trio.css" rel="stylesheet" type="text/css">
7</head>
8<body>
9<!-- Generated by Doxygen 1.2.18 -->
10<center>
11<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; </center>
12<hr><h1>Static String Functions.</h1>Replacements for the standard C string functions.
13<a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0>
14<tr><td></td></tr>
15<tr><td colspan=2><br><h2>Functions</h2></td></tr>
16<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING char *&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a5">trio_create</a> (size_t size)</td></tr>
17<tr><td>&nbsp;</td><td><font size=-1><em>Create new string.</em> <a href="#a5"></a><em></em></font><br><br></td></tr>
18<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING void&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a6">trio_destroy</a> (char *string)</td></tr>
19<tr><td>&nbsp;</td><td><font size=-1><em>Destroy string.</em> <a href="#a6"></a><em></em></font><br><br></td></tr>
20<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING size_t&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a7">trio_length</a> (const char *string)</td></tr>
21<tr><td>&nbsp;</td><td><font size=-1><em>Count the number of characters in a string.</em> <a href="#a7"></a><em></em></font><br><br></td></tr>
22<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a8">trio_append</a> (char *target, const char *source)</td></tr>
23<tr><td>&nbsp;</td><td><font size=-1><em>Append <code>source</code> at the end of <code>target</code>.</em> <a href="#a8"></a><em></em></font><br><br></td></tr>
24<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a9">trio_append_max</a> (char *target, size_t max, const char *source)</td></tr>
25<tr><td>&nbsp;</td><td><font size=-1><em>Append at most <code>max</code> characters from <code>source</code> to <code>target</code>.</em> <a href="#a9"></a><em></em></font><br><br></td></tr>
26<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a10">trio_contains</a> (const char *string, const char *substring)</td></tr>
27<tr><td>&nbsp;</td><td><font size=-1><em>Determine if a string contains a substring.</em> <a href="#a10"></a><em></em></font><br><br></td></tr>
28<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a11">trio_copy</a> (char *target, const char *source)</td></tr>
29<tr><td>&nbsp;</td><td><font size=-1><em>Copy <code>source</code> to <code>target</code>.</em> <a href="#a11"></a><em></em></font><br><br></td></tr>
30<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a12">trio_copy_max</a> (char *target, size_t max, const char *source)</td></tr>
31<tr><td>&nbsp;</td><td><font size=-1><em>Copy at most <code>max</code> characters from <code>source</code> to <code>target</code>.</em> <a href="#a12"></a><em></em></font><br><br></td></tr>
32<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING char *&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a13">trio_duplicate</a> (const char *source)</td></tr>
33<tr><td>&nbsp;</td><td><font size=-1><em>Duplicate <code>source</code>.</em> <a href="#a13"></a><em></em></font><br><br></td></tr>
34<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING char *&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a14">trio_duplicate_max</a> (const char *source, size_t max)</td></tr>
35<tr><td>&nbsp;</td><td><font size=-1><em>Duplicate at most <code>max</code> characters of <code>source</code>.</em> <a href="#a14"></a><em></em></font><br><br></td></tr>
36<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a15">trio_equal</a> (const char *first, const char *second)</td></tr>
37<tr><td>&nbsp;</td><td><font size=-1><em>Compare if two strings are equal.</em> <a href="#a15"></a><em></em></font><br><br></td></tr>
38<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a16">trio_equal_case</a> (const char *first, const char *second)</td></tr>
39<tr><td>&nbsp;</td><td><font size=-1><em>Compare if two strings are equal.</em> <a href="#a16"></a><em></em></font><br><br></td></tr>
40<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a17">trio_equal_case_max</a> (const char *first, size_t max, const char *second)</td></tr>
41<tr><td>&nbsp;</td><td><font size=-1><em>Compare if two strings up until the first <code>max</code> characters are equal.</em> <a href="#a17"></a><em></em></font><br><br></td></tr>
42<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a18">trio_equal_locale</a> (const char *first, const char *second)</td></tr>
43<tr><td>&nbsp;</td><td><font size=-1><em>Compare if two strings are equal.</em> <a href="#a18"></a><em></em></font><br><br></td></tr>
44<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a19">trio_equal_max</a> (const char *first, size_t max, const char *second)</td></tr>
45<tr><td>&nbsp;</td><td><font size=-1><em>Compare if two strings up until the first <code>max</code> characters are equal.</em> <a href="#a19"></a><em></em></font><br><br></td></tr>
46<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING const char *&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a20">trio_error</a> (int error_number)</td></tr>
47<tr><td>&nbsp;</td><td><font size=-1><em>Provide a textual description of an error code (errno).</em> <a href="#a20"></a><em></em></font><br><br></td></tr>
48<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING size_t&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a21">trio_format_date_max</a> (char *target, size_t max, const char *format, const struct tm *datetime)</td></tr>
49<tr><td>&nbsp;</td><td><font size=-1><em>Format the date/time according to <code>format</code>.</em> <a href="#a21"></a><em></em></font><br><br></td></tr>
50<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING unsigned <br>
51long&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a22">trio_hash</a> (const char *string, int type)</td></tr>
52<tr><td>&nbsp;</td><td><font size=-1><em>Calculate a hash value for a string.</em> <a href="#a22"></a><em></em></font><br><br></td></tr>
53<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING char *&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a23">trio_index</a> (const char *string, int character)</td></tr>
54<tr><td>&nbsp;</td><td><font size=-1><em>Find first occurrence of a character in a string.</em> <a href="#a23"></a><em></em></font><br><br></td></tr>
55<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING char *&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a24">trio_index_last</a> (const char *string, int character)</td></tr>
56<tr><td>&nbsp;</td><td><font size=-1><em>Find last occurrence of a character in a string.</em> <a href="#a24"></a><em></em></font><br><br></td></tr>
57<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a25">trio_lower</a> (char *target)</td></tr>
58<tr><td>&nbsp;</td><td><font size=-1><em>Convert the alphabetic letters in the string to lower-case.</em> <a href="#a25"></a><em></em></font><br><br></td></tr>
59<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a26">trio_match</a> (const char *string, const char *pattern)</td></tr>
60<tr><td>&nbsp;</td><td><font size=-1><em>Compare two strings using wildcards.</em> <a href="#a26"></a><em></em></font><br><br></td></tr>
61<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a27">trio_match_case</a> (const char *string, const char *pattern)</td></tr>
62<tr><td>&nbsp;</td><td><font size=-1><em>Compare two strings using wildcards.</em> <a href="#a27"></a><em></em></font><br><br></td></tr>
63<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING size_t&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a28">trio_span_function</a> (char *target, const char *source, int(*Function)(int))</td></tr>
64<tr><td>&nbsp;</td><td><font size=-1><em>Execute a function on each character in string.</em> <a href="#a28"></a><em></em></font><br><br></td></tr>
65<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING char *&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a29">trio_substring</a> (const char *string, const char *substring)</td></tr>
66<tr><td>&nbsp;</td><td><font size=-1><em>Search for a substring in a string.</em> <a href="#a29"></a><em></em></font><br><br></td></tr>
67<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING char *&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a30">trio_substring_max</a> (const char *string, size_t max, const char *substring)</td></tr>
68<tr><td>&nbsp;</td><td><font size=-1><em>Search for a substring in the first <code>max</code> characters of a string.</em> <a href="#a30"></a><em></em></font><br><br></td></tr>
69<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING char *&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a31">trio_tokenize</a> (char *string, const char *delimiters)</td></tr>
70<tr><td>&nbsp;</td><td><font size=-1><em>Tokenize string.</em> <a href="#a31"></a><em></em></font><br><br></td></tr>
71<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING trio_long_double_t&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a32">trio_to_long_double</a> (const char *source, char **endp)</td></tr>
72<tr><td>&nbsp;</td><td><font size=-1><em>Convert string to floating-point number.</em> <a href="#a32"></a><em></em></font><br><br></td></tr>
73<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING double&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a33">trio_to_double</a> (const char *source, char **endp)</td></tr>
74<tr><td>&nbsp;</td><td><font size=-1><em>Convert string to floating-point number.</em> <a href="#a33"></a><em></em></font><br><br></td></tr>
75<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING float&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a34">trio_to_float</a> (const char *source, char **endp)</td></tr>
76<tr><td>&nbsp;</td><td><font size=-1><em>Convert string to floating-point number.</em> <a href="#a34"></a><em></em></font><br><br></td></tr>
77<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING long&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a35">trio_to_long</a> (const char *string, char **endp, int base)</td></tr>
78<tr><td>&nbsp;</td><td><font size=-1><em>Convert string to signed integer.</em> <a href="#a35"></a><em></em></font><br><br></td></tr>
79<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a36">trio_to_lower</a> (int source)</td></tr>
80<tr><td>&nbsp;</td><td><font size=-1><em>Convert one alphabetic letter to lower-case.</em> <a href="#a36"></a><em></em></font><br><br></td></tr>
81<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING unsigned <br>
82long&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a37">trio_to_unsigned_long</a> (const char *string, char **endp, int base)</td></tr>
83<tr><td>&nbsp;</td><td><font size=-1><em>Convert string to unsigned integer.</em> <a href="#a37"></a><em></em></font><br><br></td></tr>
84<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a38">trio_to_upper</a> (int source)</td></tr>
85<tr><td>&nbsp;</td><td><font size=-1><em>Convert one alphabetic letter to upper-case.</em> <a href="#a38"></a><em></em></font><br><br></td></tr>
86<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING int&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a39">trio_upper</a> (char *target)</td></tr>
87<tr><td>&nbsp;</td><td><font size=-1><em>Convert the alphabetic letters in the string to upper-case.</em> <a href="#a39"></a><em></em></font><br><br></td></tr>
88<tr><td nowrap align=right valign=top>TRIO_PUBLIC_STRING size_t&nbsp;</td><td valign=bottom><a class="el" href="group___static_strings.html#a40">trio_length_max</a> (const char *string, size_t max)</td></tr>
89<tr><td>&nbsp;</td><td><font size=-1><em>Count at most <code>max</code> characters in a string.</em> <a href="#a40"></a><em></em></font><br><br></td></tr>
90</table>
91<hr><a name="_details"></a><h2>Detailed Description</h2>
92Replacements for the standard C string functions.
93<p>
94<b>SYNOPSIS</b>
95<p>
96<div class="fragment"><pre>
97cc ... -ltrio -lm
98
99#include &lt;triostr.h&gt;
100</pre></div>
101<p>
102<b>DESCRIPTION</b>
103<p>
104This package renames, fixes, and extends the standard C string handling functions.
105<p>
106<b>Naming</b>
107<p>
108Renaming is done to provide more clear names, to provide a consistant naming and argument policy, and to hide portability issues.
109<p>
110<ul>
111<li> All functions starts with "trio_". <li> Target is always the first argument, if present, except where the target is optional, such as <a class="el" href="group___static_strings.html#a33">Static String Functions.</a>. <li> Functions requiring a size for target includes "_max" in its name, and the size is always the second argument. <li> Functions performing case-sensitive operations includes "_case" in its name.</ul>
112<b>Fixing</b>
113<p>
114Fixing is done to avoid subtle error conditions. For example, <code>strncpy</code> does not terminate the result with a zero if the source string is bigger than the maximal length, so technically the result is not a C string anymore. <a class="el" href="group___static_strings.html#a12">Static String Functions.</a> makes sure that the result is zero terminated.
115<p>
116<b>Extending</b>
117<p>
118Extending is done to provide a richer set of fundamental functions. This includes functionality such as wildcard matching ( <code>trio_match</code> ) and calculation of hash values ( <code>trio_hash</code> ). <hr><h2>Function Documentation</h2>
119<a name="a8" doxytag="triostr-macro.c::trio_append"></a><p>
120<table width="100%" cellpadding="2" cellspacing="0" border="0">
121 <tr>
122 <td class="md">
123 <table cellpadding="0" cellspacing="0" border="0">
124 <tr>
125 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_append </td>
126 <td class="md" valign="top">(&nbsp;</td>
127 <td class="md" nowrap valign="top">char *&nbsp;</td>
128 <td class="mdname" nowrap>&nbsp; <em>target</em>, </td>
129 </tr>
130 <tr>
131 <td></td>
132 <td></td>
133 <td class="md" nowrap>const char *&nbsp;</td>
134 <td class="mdname" nowrap>&nbsp; <em>source</em></td>
135 </tr>
136 <tr>
137 <td></td>
138 <td class="md">)&nbsp;</td>
139 <td class="md" colspan="2"></td>
140 </tr>
141
142 </table>
143 </td>
144 </tr>
145</table>
146<table cellspacing=5 cellpadding=0 border=0>
147 <tr>
148 <td>
149 &nbsp;
150 </td>
151 <td>
152
153<p>
154Append <code>source</code> at the end of <code>target</code>.
155<p>
156<dl compact><dt><b>Parameters: </b></dt><dd>
157<table border=0 cellspacing=2 cellpadding=0>
158<tr><td valign=top><em>target</em>&nbsp;</td><td>
159Target string. </td></tr>
160<tr><td valign=top><em>source</em>&nbsp;</td><td>
161Source string. </td></tr>
162</table>
163</dl><dl compact><dt><b>Returns: </b></dt><dd>
164Boolean value indicating success or failure.</dl><dl compact><dt><b>Precondition: </b></dt><dd>
165<code>target</code> must point to a memory chunk with sufficient room to contain the <code>target</code> string and <code>source</code> string. <dd>
166No boundary checking is performed, so insufficient memory will result in a buffer overrun. </dl><dl compact><dt><b>Postcondition: </b></dt><dd>
167<code>target</code> will be zero terminated. </dl> </td>
168 </tr>
169</table>
170<a name="a9" doxytag="triostr-macro.c::trio_append_max"></a><p>
171<table width="100%" cellpadding="2" cellspacing="0" border="0">
172 <tr>
173 <td class="md">
174 <table cellpadding="0" cellspacing="0" border="0">
175 <tr>
176 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_append_max </td>
177 <td class="md" valign="top">(&nbsp;</td>
178 <td class="md" nowrap valign="top">char *&nbsp;</td>
179 <td class="mdname" nowrap>&nbsp; <em>target</em>, </td>
180 </tr>
181 <tr>
182 <td></td>
183 <td></td>
184 <td class="md" nowrap>size_t&nbsp;</td>
185 <td class="mdname" nowrap>&nbsp; <em>max</em>, </td>
186 </tr>
187 <tr>
188 <td></td>
189 <td></td>
190 <td class="md" nowrap>const char *&nbsp;</td>
191 <td class="mdname" nowrap>&nbsp; <em>source</em></td>
192 </tr>
193 <tr>
194 <td></td>
195 <td class="md">)&nbsp;</td>
196 <td class="md" colspan="2"></td>
197 </tr>
198
199 </table>
200 </td>
201 </tr>
202</table>
203<table cellspacing=5 cellpadding=0 border=0>
204 <tr>
205 <td>
206 &nbsp;
207 </td>
208 <td>
209
210<p>
211Append at most <code>max</code> characters from <code>source</code> to <code>target</code>.
212<p>
213<dl compact><dt><b>Parameters: </b></dt><dd>
214<table border=0 cellspacing=2 cellpadding=0>
215<tr><td valign=top><em>target</em>&nbsp;</td><td>
216Target string. </td></tr>
217<tr><td valign=top><em>max</em>&nbsp;</td><td>
218Maximum number of characters to append. </td></tr>
219<tr><td valign=top><em>source</em>&nbsp;</td><td>
220Source string. </td></tr>
221</table>
222</dl><dl compact><dt><b>Returns: </b></dt><dd>
223Boolean value indicating success or failure.</dl><dl compact><dt><b>Precondition: </b></dt><dd>
224<code>target</code> must point to a memory chuck with sufficient room to contain the <code>target</code> string and the <code>source</code> string (at most <code>max</code> characters). <dd>
225No boundary checking is performed, so insufficient memory will result in a buffer overrun. </dl><dl compact><dt><b>Postcondition: </b></dt><dd>
226<code>target</code> will be zero terminated. </dl> </td>
227 </tr>
228</table>
229<a name="a10" doxytag="triostr-macro.c::trio_contains"></a><p>
230<table width="100%" cellpadding="2" cellspacing="0" border="0">
231 <tr>
232 <td class="md">
233 <table cellpadding="0" cellspacing="0" border="0">
234 <tr>
235 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_contains </td>
236 <td class="md" valign="top">(&nbsp;</td>
237 <td class="md" nowrap valign="top">const char *&nbsp;</td>
238 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
239 </tr>
240 <tr>
241 <td></td>
242 <td></td>
243 <td class="md" nowrap>const char *&nbsp;</td>
244 <td class="mdname" nowrap>&nbsp; <em>substring</em></td>
245 </tr>
246 <tr>
247 <td></td>
248 <td class="md">)&nbsp;</td>
249 <td class="md" colspan="2"></td>
250 </tr>
251
252 </table>
253 </td>
254 </tr>
255</table>
256<table cellspacing=5 cellpadding=0 border=0>
257 <tr>
258 <td>
259 &nbsp;
260 </td>
261 <td>
262
263<p>
264Determine if a string contains a substring.
265<p>
266<dl compact><dt><b>Parameters: </b></dt><dd>
267<table border=0 cellspacing=2 cellpadding=0>
268<tr><td valign=top><em>string</em>&nbsp;</td><td>
269String to be searched. </td></tr>
270<tr><td valign=top><em>substring</em>&nbsp;</td><td>
271String to be found. </td></tr>
272</table>
273</dl><dl compact><dt><b>Returns: </b></dt><dd>
274Boolean value indicating success or failure. </dl> </td>
275 </tr>
276</table>
277<a name="a11" doxytag="triostr-macro.c::trio_copy"></a><p>
278<table width="100%" cellpadding="2" cellspacing="0" border="0">
279 <tr>
280 <td class="md">
281 <table cellpadding="0" cellspacing="0" border="0">
282 <tr>
283 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_copy </td>
284 <td class="md" valign="top">(&nbsp;</td>
285 <td class="md" nowrap valign="top">char *&nbsp;</td>
286 <td class="mdname" nowrap>&nbsp; <em>target</em>, </td>
287 </tr>
288 <tr>
289 <td></td>
290 <td></td>
291 <td class="md" nowrap>const char *&nbsp;</td>
292 <td class="mdname" nowrap>&nbsp; <em>source</em></td>
293 </tr>
294 <tr>
295 <td></td>
296 <td class="md">)&nbsp;</td>
297 <td class="md" colspan="2"></td>
298 </tr>
299
300 </table>
301 </td>
302 </tr>
303</table>
304<table cellspacing=5 cellpadding=0 border=0>
305 <tr>
306 <td>
307 &nbsp;
308 </td>
309 <td>
310
311<p>
312Copy <code>source</code> to <code>target</code>.
313<p>
314<dl compact><dt><b>Parameters: </b></dt><dd>
315<table border=0 cellspacing=2 cellpadding=0>
316<tr><td valign=top><em>target</em>&nbsp;</td><td>
317Target string. </td></tr>
318<tr><td valign=top><em>source</em>&nbsp;</td><td>
319Source string. </td></tr>
320</table>
321</dl><dl compact><dt><b>Returns: </b></dt><dd>
322Boolean value indicating success or failure.</dl><dl compact><dt><b>Precondition: </b></dt><dd>
323<code>target</code> must point to a memory chunk with sufficient room to contain the <code>source</code> string. <dd>
324No boundary checking is performed, so insufficient memory will result in a buffer overrun. </dl><dl compact><dt><b>Postcondition: </b></dt><dd>
325<code>target</code> will be zero terminated. </dl> </td>
326 </tr>
327</table>
328<a name="a12" doxytag="triostr-macro.c::trio_copy_max"></a><p>
329<table width="100%" cellpadding="2" cellspacing="0" border="0">
330 <tr>
331 <td class="md">
332 <table cellpadding="0" cellspacing="0" border="0">
333 <tr>
334 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_copy_max </td>
335 <td class="md" valign="top">(&nbsp;</td>
336 <td class="md" nowrap valign="top">char *&nbsp;</td>
337 <td class="mdname" nowrap>&nbsp; <em>target</em>, </td>
338 </tr>
339 <tr>
340 <td></td>
341 <td></td>
342 <td class="md" nowrap>size_t&nbsp;</td>
343 <td class="mdname" nowrap>&nbsp; <em>max</em>, </td>
344 </tr>
345 <tr>
346 <td></td>
347 <td></td>
348 <td class="md" nowrap>const char *&nbsp;</td>
349 <td class="mdname" nowrap>&nbsp; <em>source</em></td>
350 </tr>
351 <tr>
352 <td></td>
353 <td class="md">)&nbsp;</td>
354 <td class="md" colspan="2"></td>
355 </tr>
356
357 </table>
358 </td>
359 </tr>
360</table>
361<table cellspacing=5 cellpadding=0 border=0>
362 <tr>
363 <td>
364 &nbsp;
365 </td>
366 <td>
367
368<p>
369Copy at most <code>max</code> characters from <code>source</code> to <code>target</code>.
370<p>
371<dl compact><dt><b>Parameters: </b></dt><dd>
372<table border=0 cellspacing=2 cellpadding=0>
373<tr><td valign=top><em>target</em>&nbsp;</td><td>
374Target string. </td></tr>
375<tr><td valign=top><em>max</em>&nbsp;</td><td>
376Maximum number of characters to append. </td></tr>
377<tr><td valign=top><em>source</em>&nbsp;</td><td>
378Source string. </td></tr>
379</table>
380</dl><dl compact><dt><b>Returns: </b></dt><dd>
381Boolean value indicating success or failure.</dl><dl compact><dt><b>Precondition: </b></dt><dd>
382<code>target</code> must point to a memory chunk with sufficient room to contain the <code>source</code> string (at most <code>max</code> characters). <dd>
383No boundary checking is performed, so insufficient memory will result in a buffer overrun. </dl><dl compact><dt><b>Postcondition: </b></dt><dd>
384<code>target</code> will be zero terminated. </dl> </td>
385 </tr>
386</table>
387<a name="a5" doxytag="triostr-macro.c::trio_create"></a><p>
388<table width="100%" cellpadding="2" cellspacing="0" border="0">
389 <tr>
390 <td class="md">
391 <table cellpadding="0" cellspacing="0" border="0">
392 <tr>
393 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING char* trio_create </td>
394 <td class="md" valign="top">(&nbsp;</td>
395 <td class="md" nowrap valign="top">size_t&nbsp;</td>
396 <td class="mdname1" valign="top" nowrap>&nbsp; <em>size</em> </td>
397 <td class="md" valign="top">)&nbsp;</td>
398 <td class="md" nowrap></td>
399 </tr>
400
401 </table>
402 </td>
403 </tr>
404</table>
405<table cellspacing=5 cellpadding=0 border=0>
406 <tr>
407 <td>
408 &nbsp;
409 </td>
410 <td>
411
412<p>
413Create new string.
414<p>
415<dl compact><dt><b>Parameters: </b></dt><dd>
416<table border=0 cellspacing=2 cellpadding=0>
417<tr><td valign=top><em>size</em>&nbsp;</td><td>
418Size of new string. </td></tr>
419</table>
420</dl><dl compact><dt><b>Returns: </b></dt><dd>
421Pointer to string, or NULL if allocation failed. </dl> </td>
422 </tr>
423</table>
424<a name="a6" doxytag="triostr-macro.c::trio_destroy"></a><p>
425<table width="100%" cellpadding="2" cellspacing="0" border="0">
426 <tr>
427 <td class="md">
428 <table cellpadding="0" cellspacing="0" border="0">
429 <tr>
430 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING void trio_destroy </td>
431 <td class="md" valign="top">(&nbsp;</td>
432 <td class="md" nowrap valign="top">char *&nbsp;</td>
433 <td class="mdname1" valign="top" nowrap>&nbsp; <em>string</em> </td>
434 <td class="md" valign="top">)&nbsp;</td>
435 <td class="md" nowrap></td>
436 </tr>
437
438 </table>
439 </td>
440 </tr>
441</table>
442<table cellspacing=5 cellpadding=0 border=0>
443 <tr>
444 <td>
445 &nbsp;
446 </td>
447 <td>
448
449<p>
450Destroy string.
451<p>
452<dl compact><dt><b>Parameters: </b></dt><dd>
453<table border=0 cellspacing=2 cellpadding=0>
454<tr><td valign=top><em>string</em>&nbsp;</td><td>
455String to be freed. </td></tr>
456</table>
457</dl> </td>
458 </tr>
459</table>
460<a name="a13" doxytag="triostr-macro.c::trio_duplicate"></a><p>
461<table width="100%" cellpadding="2" cellspacing="0" border="0">
462 <tr>
463 <td class="md">
464 <table cellpadding="0" cellspacing="0" border="0">
465 <tr>
466 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING char* trio_duplicate </td>
467 <td class="md" valign="top">(&nbsp;</td>
468 <td class="md" nowrap valign="top">const char *&nbsp;</td>
469 <td class="mdname1" valign="top" nowrap>&nbsp; <em>source</em> </td>
470 <td class="md" valign="top">)&nbsp;</td>
471 <td class="md" nowrap></td>
472 </tr>
473
474 </table>
475 </td>
476 </tr>
477</table>
478<table cellspacing=5 cellpadding=0 border=0>
479 <tr>
480 <td>
481 &nbsp;
482 </td>
483 <td>
484
485<p>
486Duplicate <code>source</code>.
487<p>
488<dl compact><dt><b>Parameters: </b></dt><dd>
489<table border=0 cellspacing=2 cellpadding=0>
490<tr><td valign=top><em>source</em>&nbsp;</td><td>
491Source string. </td></tr>
492</table>
493</dl><dl compact><dt><b>Returns: </b></dt><dd>
494A copy of the <code>source</code> string.</dl><dl compact><dt><b>Postcondition: </b></dt><dd>
495<code>target</code> will be zero terminated. </dl> </td>
496 </tr>
497</table>
498<a name="a14" doxytag="triostr-macro.c::trio_duplicate_max"></a><p>
499<table width="100%" cellpadding="2" cellspacing="0" border="0">
500 <tr>
501 <td class="md">
502 <table cellpadding="0" cellspacing="0" border="0">
503 <tr>
504 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING char* trio_duplicate_max </td>
505 <td class="md" valign="top">(&nbsp;</td>
506 <td class="md" nowrap valign="top">const char *&nbsp;</td>
507 <td class="mdname" nowrap>&nbsp; <em>source</em>, </td>
508 </tr>
509 <tr>
510 <td></td>
511 <td></td>
512 <td class="md" nowrap>size_t&nbsp;</td>
513 <td class="mdname" nowrap>&nbsp; <em>max</em></td>
514 </tr>
515 <tr>
516 <td></td>
517 <td class="md">)&nbsp;</td>
518 <td class="md" colspan="2"></td>
519 </tr>
520
521 </table>
522 </td>
523 </tr>
524</table>
525<table cellspacing=5 cellpadding=0 border=0>
526 <tr>
527 <td>
528 &nbsp;
529 </td>
530 <td>
531
532<p>
533Duplicate at most <code>max</code> characters of <code>source</code>.
534<p>
535<dl compact><dt><b>Parameters: </b></dt><dd>
536<table border=0 cellspacing=2 cellpadding=0>
537<tr><td valign=top><em>source</em>&nbsp;</td><td>
538Source string. </td></tr>
539<tr><td valign=top><em>max</em>&nbsp;</td><td>
540Maximum number of characters to duplicate. </td></tr>
541</table>
542</dl><dl compact><dt><b>Returns: </b></dt><dd>
543A copy of the <code>source</code> string.</dl><dl compact><dt><b>Postcondition: </b></dt><dd>
544<code>target</code> will be zero terminated. </dl> </td>
545 </tr>
546</table>
547<a name="a15" doxytag="triostr-macro.c::trio_equal"></a><p>
548<table width="100%" cellpadding="2" cellspacing="0" border="0">
549 <tr>
550 <td class="md">
551 <table cellpadding="0" cellspacing="0" border="0">
552 <tr>
553 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_equal </td>
554 <td class="md" valign="top">(&nbsp;</td>
555 <td class="md" nowrap valign="top">const char *&nbsp;</td>
556 <td class="mdname" nowrap>&nbsp; <em>first</em>, </td>
557 </tr>
558 <tr>
559 <td></td>
560 <td></td>
561 <td class="md" nowrap>const char *&nbsp;</td>
562 <td class="mdname" nowrap>&nbsp; <em>second</em></td>
563 </tr>
564 <tr>
565 <td></td>
566 <td class="md">)&nbsp;</td>
567 <td class="md" colspan="2"></td>
568 </tr>
569
570 </table>
571 </td>
572 </tr>
573</table>
574<table cellspacing=5 cellpadding=0 border=0>
575 <tr>
576 <td>
577 &nbsp;
578 </td>
579 <td>
580
581<p>
582Compare if two strings are equal.
583<p>
584<dl compact><dt><b>Parameters: </b></dt><dd>
585<table border=0 cellspacing=2 cellpadding=0>
586<tr><td valign=top><em>first</em>&nbsp;</td><td>
587First string. </td></tr>
588<tr><td valign=top><em>second</em>&nbsp;</td><td>
589Second string. </td></tr>
590</table>
591</dl><dl compact><dt><b>Returns: </b></dt><dd>
592Boolean indicating whether the two strings are equal or not.</dl>Case-insensitive comparison. </td>
593 </tr>
594</table>
595<a name="a16" doxytag="triostr-macro.c::trio_equal_case"></a><p>
596<table width="100%" cellpadding="2" cellspacing="0" border="0">
597 <tr>
598 <td class="md">
599 <table cellpadding="0" cellspacing="0" border="0">
600 <tr>
601 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_equal_case </td>
602 <td class="md" valign="top">(&nbsp;</td>
603 <td class="md" nowrap valign="top">const char *&nbsp;</td>
604 <td class="mdname" nowrap>&nbsp; <em>first</em>, </td>
605 </tr>
606 <tr>
607 <td></td>
608 <td></td>
609 <td class="md" nowrap>const char *&nbsp;</td>
610 <td class="mdname" nowrap>&nbsp; <em>second</em></td>
611 </tr>
612 <tr>
613 <td></td>
614 <td class="md">)&nbsp;</td>
615 <td class="md" colspan="2"></td>
616 </tr>
617
618 </table>
619 </td>
620 </tr>
621</table>
622<table cellspacing=5 cellpadding=0 border=0>
623 <tr>
624 <td>
625 &nbsp;
626 </td>
627 <td>
628
629<p>
630Compare if two strings are equal.
631<p>
632<dl compact><dt><b>Parameters: </b></dt><dd>
633<table border=0 cellspacing=2 cellpadding=0>
634<tr><td valign=top><em>first</em>&nbsp;</td><td>
635First string. </td></tr>
636<tr><td valign=top><em>second</em>&nbsp;</td><td>
637Second string. </td></tr>
638</table>
639</dl><dl compact><dt><b>Returns: </b></dt><dd>
640Boolean indicating whether the two strings are equal or not.</dl>Case-sensitive comparison. </td>
641 </tr>
642</table>
643<a name="a17" doxytag="triostr-macro.c::trio_equal_case_max"></a><p>
644<table width="100%" cellpadding="2" cellspacing="0" border="0">
645 <tr>
646 <td class="md">
647 <table cellpadding="0" cellspacing="0" border="0">
648 <tr>
649 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_equal_case_max </td>
650 <td class="md" valign="top">(&nbsp;</td>
651 <td class="md" nowrap valign="top">const char *&nbsp;</td>
652 <td class="mdname" nowrap>&nbsp; <em>first</em>, </td>
653 </tr>
654 <tr>
655 <td></td>
656 <td></td>
657 <td class="md" nowrap>size_t&nbsp;</td>
658 <td class="mdname" nowrap>&nbsp; <em>max</em>, </td>
659 </tr>
660 <tr>
661 <td></td>
662 <td></td>
663 <td class="md" nowrap>const char *&nbsp;</td>
664 <td class="mdname" nowrap>&nbsp; <em>second</em></td>
665 </tr>
666 <tr>
667 <td></td>
668 <td class="md">)&nbsp;</td>
669 <td class="md" colspan="2"></td>
670 </tr>
671
672 </table>
673 </td>
674 </tr>
675</table>
676<table cellspacing=5 cellpadding=0 border=0>
677 <tr>
678 <td>
679 &nbsp;
680 </td>
681 <td>
682
683<p>
684Compare if two strings up until the first <code>max</code> characters are equal.
685<p>
686<dl compact><dt><b>Parameters: </b></dt><dd>
687<table border=0 cellspacing=2 cellpadding=0>
688<tr><td valign=top><em>first</em>&nbsp;</td><td>
689First string. </td></tr>
690<tr><td valign=top><em>max</em>&nbsp;</td><td>
691Maximum number of characters to compare. </td></tr>
692<tr><td valign=top><em>second</em>&nbsp;</td><td>
693Second string. </td></tr>
694</table>
695</dl><dl compact><dt><b>Returns: </b></dt><dd>
696Boolean indicating whether the two strings are equal or not.</dl>Case-sensitive comparison. </td>
697 </tr>
698</table>
699<a name="a18" doxytag="triostr-macro.c::trio_equal_locale"></a><p>
700<table width="100%" cellpadding="2" cellspacing="0" border="0">
701 <tr>
702 <td class="md">
703 <table cellpadding="0" cellspacing="0" border="0">
704 <tr>
705 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_equal_locale </td>
706 <td class="md" valign="top">(&nbsp;</td>
707 <td class="md" nowrap valign="top">const char *&nbsp;</td>
708 <td class="mdname" nowrap>&nbsp; <em>first</em>, </td>
709 </tr>
710 <tr>
711 <td></td>
712 <td></td>
713 <td class="md" nowrap>const char *&nbsp;</td>
714 <td class="mdname" nowrap>&nbsp; <em>second</em></td>
715 </tr>
716 <tr>
717 <td></td>
718 <td class="md">)&nbsp;</td>
719 <td class="md" colspan="2"></td>
720 </tr>
721
722 </table>
723 </td>
724 </tr>
725</table>
726<table cellspacing=5 cellpadding=0 border=0>
727 <tr>
728 <td>
729 &nbsp;
730 </td>
731 <td>
732
733<p>
734Compare if two strings are equal.
735<p>
736<dl compact><dt><b>Parameters: </b></dt><dd>
737<table border=0 cellspacing=2 cellpadding=0>
738<tr><td valign=top><em>first</em>&nbsp;</td><td>
739First string. </td></tr>
740<tr><td valign=top><em>second</em>&nbsp;</td><td>
741Second string. </td></tr>
742</table>
743</dl><dl compact><dt><b>Returns: </b></dt><dd>
744Boolean indicating whether the two strings are equal or not.</dl>Collating characters are considered equal. </td>
745 </tr>
746</table>
747<a name="a19" doxytag="triostr-macro.c::trio_equal_max"></a><p>
748<table width="100%" cellpadding="2" cellspacing="0" border="0">
749 <tr>
750 <td class="md">
751 <table cellpadding="0" cellspacing="0" border="0">
752 <tr>
753 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_equal_max </td>
754 <td class="md" valign="top">(&nbsp;</td>
755 <td class="md" nowrap valign="top">const char *&nbsp;</td>
756 <td class="mdname" nowrap>&nbsp; <em>first</em>, </td>
757 </tr>
758 <tr>
759 <td></td>
760 <td></td>
761 <td class="md" nowrap>size_t&nbsp;</td>
762 <td class="mdname" nowrap>&nbsp; <em>max</em>, </td>
763 </tr>
764 <tr>
765 <td></td>
766 <td></td>
767 <td class="md" nowrap>const char *&nbsp;</td>
768 <td class="mdname" nowrap>&nbsp; <em>second</em></td>
769 </tr>
770 <tr>
771 <td></td>
772 <td class="md">)&nbsp;</td>
773 <td class="md" colspan="2"></td>
774 </tr>
775
776 </table>
777 </td>
778 </tr>
779</table>
780<table cellspacing=5 cellpadding=0 border=0>
781 <tr>
782 <td>
783 &nbsp;
784 </td>
785 <td>
786
787<p>
788Compare if two strings up until the first <code>max</code> characters are equal.
789<p>
790<dl compact><dt><b>Parameters: </b></dt><dd>
791<table border=0 cellspacing=2 cellpadding=0>
792<tr><td valign=top><em>first</em>&nbsp;</td><td>
793First string. </td></tr>
794<tr><td valign=top><em>max</em>&nbsp;</td><td>
795Maximum number of characters to compare. </td></tr>
796<tr><td valign=top><em>second</em>&nbsp;</td><td>
797Second string. </td></tr>
798</table>
799</dl><dl compact><dt><b>Returns: </b></dt><dd>
800Boolean indicating whether the two strings are equal or not.</dl>Case-insensitive comparison. </td>
801 </tr>
802</table>
803<a name="a20" doxytag="triostr-macro.c::trio_error"></a><p>
804<table width="100%" cellpadding="2" cellspacing="0" border="0">
805 <tr>
806 <td class="md">
807 <table cellpadding="0" cellspacing="0" border="0">
808 <tr>
809 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING const char* trio_error </td>
810 <td class="md" valign="top">(&nbsp;</td>
811 <td class="md" nowrap valign="top">int&nbsp;</td>
812 <td class="mdname1" valign="top" nowrap>&nbsp; <em>error_number</em> </td>
813 <td class="md" valign="top">)&nbsp;</td>
814 <td class="md" nowrap></td>
815 </tr>
816
817 </table>
818 </td>
819 </tr>
820</table>
821<table cellspacing=5 cellpadding=0 border=0>
822 <tr>
823 <td>
824 &nbsp;
825 </td>
826 <td>
827
828<p>
829Provide a textual description of an error code (errno).
830<p>
831<dl compact><dt><b>Parameters: </b></dt><dd>
832<table border=0 cellspacing=2 cellpadding=0>
833<tr><td valign=top><em>error_number</em>&nbsp;</td><td>
834Error number. </td></tr>
835</table>
836</dl><dl compact><dt><b>Returns: </b></dt><dd>
837Textual description of <code>error_number</code>. </dl> </td>
838 </tr>
839</table>
840<a name="a21" doxytag="triostr-macro.c::trio_format_date_max"></a><p>
841<table width="100%" cellpadding="2" cellspacing="0" border="0">
842 <tr>
843 <td class="md">
844 <table cellpadding="0" cellspacing="0" border="0">
845 <tr>
846 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING size_t trio_format_date_max </td>
847 <td class="md" valign="top">(&nbsp;</td>
848 <td class="md" nowrap valign="top">char *&nbsp;</td>
849 <td class="mdname" nowrap>&nbsp; <em>target</em>, </td>
850 </tr>
851 <tr>
852 <td></td>
853 <td></td>
854 <td class="md" nowrap>size_t&nbsp;</td>
855 <td class="mdname" nowrap>&nbsp; <em>max</em>, </td>
856 </tr>
857 <tr>
858 <td></td>
859 <td></td>
860 <td class="md" nowrap>const char *&nbsp;</td>
861 <td class="mdname" nowrap>&nbsp; <em>format</em>, </td>
862 </tr>
863 <tr>
864 <td></td>
865 <td></td>
866 <td class="md" nowrap>const struct tm *&nbsp;</td>
867 <td class="mdname" nowrap>&nbsp; <em>datetime</em></td>
868 </tr>
869 <tr>
870 <td></td>
871 <td class="md">)&nbsp;</td>
872 <td class="md" colspan="2"></td>
873 </tr>
874
875 </table>
876 </td>
877 </tr>
878</table>
879<table cellspacing=5 cellpadding=0 border=0>
880 <tr>
881 <td>
882 &nbsp;
883 </td>
884 <td>
885
886<p>
887Format the date/time according to <code>format</code>.
888<p>
889<dl compact><dt><b>Parameters: </b></dt><dd>
890<table border=0 cellspacing=2 cellpadding=0>
891<tr><td valign=top><em>target</em>&nbsp;</td><td>
892Target string. </td></tr>
893<tr><td valign=top><em>max</em>&nbsp;</td><td>
894Maximum number of characters to format. </td></tr>
895<tr><td valign=top><em>format</em>&nbsp;</td><td>
896Formatting string. </td></tr>
897<tr><td valign=top><em>datetime</em>&nbsp;</td><td>
898Date/time structure. </td></tr>
899</table>
900</dl><dl compact><dt><b>Returns: </b></dt><dd>
901Number of formatted characters.</dl>The formatting string accepts the same specifiers as the standard C function strftime. </td>
902 </tr>
903</table>
904<a name="a22" doxytag="triostr-macro.c::trio_hash"></a><p>
905<table width="100%" cellpadding="2" cellspacing="0" border="0">
906 <tr>
907 <td class="md">
908 <table cellpadding="0" cellspacing="0" border="0">
909 <tr>
910 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING unsigned long trio_hash </td>
911 <td class="md" valign="top">(&nbsp;</td>
912 <td class="md" nowrap valign="top">const char *&nbsp;</td>
913 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
914 </tr>
915 <tr>
916 <td></td>
917 <td></td>
918 <td class="md" nowrap>int&nbsp;</td>
919 <td class="mdname" nowrap>&nbsp; <em>type</em></td>
920 </tr>
921 <tr>
922 <td></td>
923 <td class="md">)&nbsp;</td>
924 <td class="md" colspan="2"></td>
925 </tr>
926
927 </table>
928 </td>
929 </tr>
930</table>
931<table cellspacing=5 cellpadding=0 border=0>
932 <tr>
933 <td>
934 &nbsp;
935 </td>
936 <td>
937
938<p>
939Calculate a hash value for a string.
940<p>
941<dl compact><dt><b>Parameters: </b></dt><dd>
942<table border=0 cellspacing=2 cellpadding=0>
943<tr><td valign=top><em>string</em>&nbsp;</td><td>
944String to be calculated on. </td></tr>
945<tr><td valign=top><em>type</em>&nbsp;</td><td>
946Hash function. </td></tr>
947</table>
948</dl><dl compact><dt><b>Returns: </b></dt><dd>
949Calculated hash value.</dl><code>type</code> can be one of the following <ul>
950<li> <code>TRIO_HASH_PLAIN</code> Plain hash function. </ul>
951 </td>
952 </tr>
953</table>
954<a name="a23" doxytag="triostr-macro.c::trio_index"></a><p>
955<table width="100%" cellpadding="2" cellspacing="0" border="0">
956 <tr>
957 <td class="md">
958 <table cellpadding="0" cellspacing="0" border="0">
959 <tr>
960 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING char* trio_index </td>
961 <td class="md" valign="top">(&nbsp;</td>
962 <td class="md" nowrap valign="top">const char *&nbsp;</td>
963 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
964 </tr>
965 <tr>
966 <td></td>
967 <td></td>
968 <td class="md" nowrap>int&nbsp;</td>
969 <td class="mdname" nowrap>&nbsp; <em>character</em></td>
970 </tr>
971 <tr>
972 <td></td>
973 <td class="md">)&nbsp;</td>
974 <td class="md" colspan="2"></td>
975 </tr>
976
977 </table>
978 </td>
979 </tr>
980</table>
981<table cellspacing=5 cellpadding=0 border=0>
982 <tr>
983 <td>
984 &nbsp;
985 </td>
986 <td>
987
988<p>
989Find first occurrence of a character in a string.
990<p>
991<dl compact><dt><b>Parameters: </b></dt><dd>
992<table border=0 cellspacing=2 cellpadding=0>
993<tr><td valign=top><em>string</em>&nbsp;</td><td>
994String to be searched. </td></tr>
995<tr><td valign=top><em>character</em>&nbsp;</td><td>
996Character to be found. </td></tr>
997</table>
998</dl><dl compact><dt><b>Returns: </b></dt><dd>
999A pointer to the found character, or NULL if character was not found. </dl> </td>
1000 </tr>
1001</table>
1002<a name="a24" doxytag="triostr-macro.c::trio_index_last"></a><p>
1003<table width="100%" cellpadding="2" cellspacing="0" border="0">
1004 <tr>
1005 <td class="md">
1006 <table cellpadding="0" cellspacing="0" border="0">
1007 <tr>
1008 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING char* trio_index_last </td>
1009 <td class="md" valign="top">(&nbsp;</td>
1010 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1011 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
1012 </tr>
1013 <tr>
1014 <td></td>
1015 <td></td>
1016 <td class="md" nowrap>int&nbsp;</td>
1017 <td class="mdname" nowrap>&nbsp; <em>character</em></td>
1018 </tr>
1019 <tr>
1020 <td></td>
1021 <td class="md">)&nbsp;</td>
1022 <td class="md" colspan="2"></td>
1023 </tr>
1024
1025 </table>
1026 </td>
1027 </tr>
1028</table>
1029<table cellspacing=5 cellpadding=0 border=0>
1030 <tr>
1031 <td>
1032 &nbsp;
1033 </td>
1034 <td>
1035
1036<p>
1037Find last occurrence of a character in a string.
1038<p>
1039<dl compact><dt><b>Parameters: </b></dt><dd>
1040<table border=0 cellspacing=2 cellpadding=0>
1041<tr><td valign=top><em>string</em>&nbsp;</td><td>
1042String to be searched. </td></tr>
1043<tr><td valign=top><em>character</em>&nbsp;</td><td>
1044Character to be found. </td></tr>
1045</table>
1046</dl><dl compact><dt><b>Returns: </b></dt><dd>
1047A pointer to the found character, or NULL if character was not found. </dl> </td>
1048 </tr>
1049</table>
1050<a name="a7" doxytag="triostr-macro.c::trio_length"></a><p>
1051<table width="100%" cellpadding="2" cellspacing="0" border="0">
1052 <tr>
1053 <td class="md">
1054 <table cellpadding="0" cellspacing="0" border="0">
1055 <tr>
1056 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING size_t trio_length </td>
1057 <td class="md" valign="top">(&nbsp;</td>
1058 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1059 <td class="mdname1" valign="top" nowrap>&nbsp; <em>string</em> </td>
1060 <td class="md" valign="top">)&nbsp;</td>
1061 <td class="md" nowrap></td>
1062 </tr>
1063
1064 </table>
1065 </td>
1066 </tr>
1067</table>
1068<table cellspacing=5 cellpadding=0 border=0>
1069 <tr>
1070 <td>
1071 &nbsp;
1072 </td>
1073 <td>
1074
1075<p>
1076Count the number of characters in a string.
1077<p>
1078<dl compact><dt><b>Parameters: </b></dt><dd>
1079<table border=0 cellspacing=2 cellpadding=0>
1080<tr><td valign=top><em>string</em>&nbsp;</td><td>
1081String to measure. </td></tr>
1082</table>
1083</dl><dl compact><dt><b>Returns: </b></dt><dd>
1084Number of characters in <code>string</code>. </dl> </td>
1085 </tr>
1086</table>
1087<a name="a40" doxytag="triostr.c::trio_length_max"></a><p>
1088<table width="100%" cellpadding="2" cellspacing="0" border="0">
1089 <tr>
1090 <td class="md">
1091 <table cellpadding="0" cellspacing="0" border="0">
1092 <tr>
1093 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING size_t trio_length_max </td>
1094 <td class="md" valign="top">(&nbsp;</td>
1095 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1096 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
1097 </tr>
1098 <tr>
1099 <td></td>
1100 <td></td>
1101 <td class="md" nowrap>size_t&nbsp;</td>
1102 <td class="mdname" nowrap>&nbsp; <em>max</em></td>
1103 </tr>
1104 <tr>
1105 <td></td>
1106 <td class="md">)&nbsp;</td>
1107 <td class="md" colspan="2"></td>
1108 </tr>
1109
1110 </table>
1111 </td>
1112 </tr>
1113</table>
1114<table cellspacing=5 cellpadding=0 border=0>
1115 <tr>
1116 <td>
1117 &nbsp;
1118 </td>
1119 <td>
1120
1121<p>
1122Count at most <code>max</code> characters in a string.
1123<p>
1124<dl compact><dt><b>Parameters: </b></dt><dd>
1125<table border=0 cellspacing=2 cellpadding=0>
1126<tr><td valign=top><em>string</em>&nbsp;</td><td>
1127String to measure. </td></tr>
1128<tr><td valign=top><em>max</em>&nbsp;</td><td>
1129Maximum number of characters to count. </td></tr>
1130</table>
1131</dl><dl compact><dt><b>Returns: </b></dt><dd>
1132The maximum value of <code>max</code> and number of characters in <code>string</code>. </dl> </td>
1133 </tr>
1134</table>
1135<a name="a25" doxytag="triostr-macro.c::trio_lower"></a><p>
1136<table width="100%" cellpadding="2" cellspacing="0" border="0">
1137 <tr>
1138 <td class="md">
1139 <table cellpadding="0" cellspacing="0" border="0">
1140 <tr>
1141 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_lower </td>
1142 <td class="md" valign="top">(&nbsp;</td>
1143 <td class="md" nowrap valign="top">char *&nbsp;</td>
1144 <td class="mdname1" valign="top" nowrap>&nbsp; <em>target</em> </td>
1145 <td class="md" valign="top">)&nbsp;</td>
1146 <td class="md" nowrap></td>
1147 </tr>
1148
1149 </table>
1150 </td>
1151 </tr>
1152</table>
1153<table cellspacing=5 cellpadding=0 border=0>
1154 <tr>
1155 <td>
1156 &nbsp;
1157 </td>
1158 <td>
1159
1160<p>
1161Convert the alphabetic letters in the string to lower-case.
1162<p>
1163<dl compact><dt><b>Parameters: </b></dt><dd>
1164<table border=0 cellspacing=2 cellpadding=0>
1165<tr><td valign=top><em>target</em>&nbsp;</td><td>
1166String to be converted. </td></tr>
1167</table>
1168</dl><dl compact><dt><b>Returns: </b></dt><dd>
1169Number of processed characters (converted or not). </dl> </td>
1170 </tr>
1171</table>
1172<a name="a26" doxytag="triostr-macro.c::trio_match"></a><p>
1173<table width="100%" cellpadding="2" cellspacing="0" border="0">
1174 <tr>
1175 <td class="md">
1176 <table cellpadding="0" cellspacing="0" border="0">
1177 <tr>
1178 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_match </td>
1179 <td class="md" valign="top">(&nbsp;</td>
1180 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1181 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
1182 </tr>
1183 <tr>
1184 <td></td>
1185 <td></td>
1186 <td class="md" nowrap>const char *&nbsp;</td>
1187 <td class="mdname" nowrap>&nbsp; <em>pattern</em></td>
1188 </tr>
1189 <tr>
1190 <td></td>
1191 <td class="md">)&nbsp;</td>
1192 <td class="md" colspan="2"></td>
1193 </tr>
1194
1195 </table>
1196 </td>
1197 </tr>
1198</table>
1199<table cellspacing=5 cellpadding=0 border=0>
1200 <tr>
1201 <td>
1202 &nbsp;
1203 </td>
1204 <td>
1205
1206<p>
1207Compare two strings using wildcards.
1208<p>
1209<dl compact><dt><b>Parameters: </b></dt><dd>
1210<table border=0 cellspacing=2 cellpadding=0>
1211<tr><td valign=top><em>string</em>&nbsp;</td><td>
1212String to be searched. </td></tr>
1213<tr><td valign=top><em>pattern</em>&nbsp;</td><td>
1214Pattern, including wildcards, to search for. </td></tr>
1215</table>
1216</dl><dl compact><dt><b>Returns: </b></dt><dd>
1217Boolean value indicating success or failure.</dl>Case-insensitive comparison.
1218<p>
1219The following wildcards can be used <ul>
1220<li> <code>*</code> Match any number of characters. <li> ? <code>Match</code> a single character. </ul>
1221 </td>
1222 </tr>
1223</table>
1224<a name="a27" doxytag="triostr-macro.c::trio_match_case"></a><p>
1225<table width="100%" cellpadding="2" cellspacing="0" border="0">
1226 <tr>
1227 <td class="md">
1228 <table cellpadding="0" cellspacing="0" border="0">
1229 <tr>
1230 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_match_case </td>
1231 <td class="md" valign="top">(&nbsp;</td>
1232 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1233 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
1234 </tr>
1235 <tr>
1236 <td></td>
1237 <td></td>
1238 <td class="md" nowrap>const char *&nbsp;</td>
1239 <td class="mdname" nowrap>&nbsp; <em>pattern</em></td>
1240 </tr>
1241 <tr>
1242 <td></td>
1243 <td class="md">)&nbsp;</td>
1244 <td class="md" colspan="2"></td>
1245 </tr>
1246
1247 </table>
1248 </td>
1249 </tr>
1250</table>
1251<table cellspacing=5 cellpadding=0 border=0>
1252 <tr>
1253 <td>
1254 &nbsp;
1255 </td>
1256 <td>
1257
1258<p>
1259Compare two strings using wildcards.
1260<p>
1261<dl compact><dt><b>Parameters: </b></dt><dd>
1262<table border=0 cellspacing=2 cellpadding=0>
1263<tr><td valign=top><em>string</em>&nbsp;</td><td>
1264String to be searched. </td></tr>
1265<tr><td valign=top><em>pattern</em>&nbsp;</td><td>
1266Pattern, including wildcards, to search for. </td></tr>
1267</table>
1268</dl><dl compact><dt><b>Returns: </b></dt><dd>
1269Boolean value indicating success or failure.</dl>Case-sensitive comparison.
1270<p>
1271The following wildcards can be used <ul>
1272<li> <code>*</code> Match any number of characters. <li> ? <code>Match</code> a single character. </ul>
1273 </td>
1274 </tr>
1275</table>
1276<a name="a28" doxytag="triostr-macro.c::trio_span_function"></a><p>
1277<table width="100%" cellpadding="2" cellspacing="0" border="0">
1278 <tr>
1279 <td class="md">
1280 <table cellpadding="0" cellspacing="0" border="0">
1281 <tr>
1282 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING size_t trio_span_function </td>
1283 <td class="md" valign="top">(&nbsp;</td>
1284 <td class="md" nowrap valign="top">char *&nbsp;</td>
1285 <td class="mdname" nowrap>&nbsp; <em>target</em>, </td>
1286 </tr>
1287 <tr>
1288 <td></td>
1289 <td></td>
1290 <td class="md" nowrap>const char *&nbsp;</td>
1291 <td class="mdname" nowrap>&nbsp; <em>source</em>, </td>
1292 </tr>
1293 <tr>
1294 <td></td>
1295 <td></td>
1296 <td class="md" nowrap>int(*&nbsp;</td>
1297 <td class="mdname" nowrap>&nbsp; <em>Function</em>)(int)</td>
1298 </tr>
1299 <tr>
1300 <td></td>
1301 <td class="md">)&nbsp;</td>
1302 <td class="md" colspan="2"></td>
1303 </tr>
1304
1305 </table>
1306 </td>
1307 </tr>
1308</table>
1309<table cellspacing=5 cellpadding=0 border=0>
1310 <tr>
1311 <td>
1312 &nbsp;
1313 </td>
1314 <td>
1315
1316<p>
1317Execute a function on each character in string.
1318<p>
1319<dl compact><dt><b>Parameters: </b></dt><dd>
1320<table border=0 cellspacing=2 cellpadding=0>
1321<tr><td valign=top><em>target</em>&nbsp;</td><td>
1322Target string. </td></tr>
1323<tr><td valign=top><em>source</em>&nbsp;</td><td>
1324Source string. </td></tr>
1325<tr><td valign=top><em>Function</em>&nbsp;</td><td>
1326Function to be executed. </td></tr>
1327</table>
1328</dl><dl compact><dt><b>Returns: </b></dt><dd>
1329Number of processed characters. </dl> </td>
1330 </tr>
1331</table>
1332<a name="a29" doxytag="triostr-macro.c::trio_substring"></a><p>
1333<table width="100%" cellpadding="2" cellspacing="0" border="0">
1334 <tr>
1335 <td class="md">
1336 <table cellpadding="0" cellspacing="0" border="0">
1337 <tr>
1338 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING char* trio_substring </td>
1339 <td class="md" valign="top">(&nbsp;</td>
1340 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1341 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
1342 </tr>
1343 <tr>
1344 <td></td>
1345 <td></td>
1346 <td class="md" nowrap>const char *&nbsp;</td>
1347 <td class="mdname" nowrap>&nbsp; <em>substring</em></td>
1348 </tr>
1349 <tr>
1350 <td></td>
1351 <td class="md">)&nbsp;</td>
1352 <td class="md" colspan="2"></td>
1353 </tr>
1354
1355 </table>
1356 </td>
1357 </tr>
1358</table>
1359<table cellspacing=5 cellpadding=0 border=0>
1360 <tr>
1361 <td>
1362 &nbsp;
1363 </td>
1364 <td>
1365
1366<p>
1367Search for a substring in a string.
1368<p>
1369<dl compact><dt><b>Parameters: </b></dt><dd>
1370<table border=0 cellspacing=2 cellpadding=0>
1371<tr><td valign=top><em>string</em>&nbsp;</td><td>
1372String to be searched. </td></tr>
1373<tr><td valign=top><em>substring</em>&nbsp;</td><td>
1374String to be found. </td></tr>
1375</table>
1376</dl><dl compact><dt><b>Returns: </b></dt><dd>
1377Pointer to first occurrence of <code>substring</code> in <code>string</code>, or NULL if no match was found. </dl> </td>
1378 </tr>
1379</table>
1380<a name="a30" doxytag="triostr-macro.c::trio_substring_max"></a><p>
1381<table width="100%" cellpadding="2" cellspacing="0" border="0">
1382 <tr>
1383 <td class="md">
1384 <table cellpadding="0" cellspacing="0" border="0">
1385 <tr>
1386 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING char* trio_substring_max </td>
1387 <td class="md" valign="top">(&nbsp;</td>
1388 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1389 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
1390 </tr>
1391 <tr>
1392 <td></td>
1393 <td></td>
1394 <td class="md" nowrap>size_t&nbsp;</td>
1395 <td class="mdname" nowrap>&nbsp; <em>max</em>, </td>
1396 </tr>
1397 <tr>
1398 <td></td>
1399 <td></td>
1400 <td class="md" nowrap>const char *&nbsp;</td>
1401 <td class="mdname" nowrap>&nbsp; <em>substring</em></td>
1402 </tr>
1403 <tr>
1404 <td></td>
1405 <td class="md">)&nbsp;</td>
1406 <td class="md" colspan="2"></td>
1407 </tr>
1408
1409 </table>
1410 </td>
1411 </tr>
1412</table>
1413<table cellspacing=5 cellpadding=0 border=0>
1414 <tr>
1415 <td>
1416 &nbsp;
1417 </td>
1418 <td>
1419
1420<p>
1421Search for a substring in the first <code>max</code> characters of a string.
1422<p>
1423<dl compact><dt><b>Parameters: </b></dt><dd>
1424<table border=0 cellspacing=2 cellpadding=0>
1425<tr><td valign=top><em>string</em>&nbsp;</td><td>
1426String to be searched. </td></tr>
1427<tr><td valign=top><em>max</em>&nbsp;</td><td>
1428Maximum characters to be searched. </td></tr>
1429<tr><td valign=top><em>substring</em>&nbsp;</td><td>
1430String to be found. </td></tr>
1431</table>
1432</dl><dl compact><dt><b>Returns: </b></dt><dd>
1433Pointer to first occurrence of <code>substring</code> in <code>string</code>, or NULL if no match was found. </dl> </td>
1434 </tr>
1435</table>
1436<a name="a33" doxytag="triostr-macro.c::trio_to_double"></a><p>
1437<table width="100%" cellpadding="2" cellspacing="0" border="0">
1438 <tr>
1439 <td class="md">
1440 <table cellpadding="0" cellspacing="0" border="0">
1441 <tr>
1442 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING double trio_to_double </td>
1443 <td class="md" valign="top">(&nbsp;</td>
1444 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1445 <td class="mdname" nowrap>&nbsp; <em>source</em>, </td>
1446 </tr>
1447 <tr>
1448 <td></td>
1449 <td></td>
1450 <td class="md" nowrap>char **&nbsp;</td>
1451 <td class="mdname" nowrap>&nbsp; <em>endp</em></td>
1452 </tr>
1453 <tr>
1454 <td></td>
1455 <td class="md">)&nbsp;</td>
1456 <td class="md" colspan="2"></td>
1457 </tr>
1458
1459 </table>
1460 </td>
1461 </tr>
1462</table>
1463<table cellspacing=5 cellpadding=0 border=0>
1464 <tr>
1465 <td>
1466 &nbsp;
1467 </td>
1468 <td>
1469
1470<p>
1471Convert string to floating-point number.
1472<p>
1473<dl compact><dt><b>Parameters: </b></dt><dd>
1474<table border=0 cellspacing=2 cellpadding=0>
1475<tr><td valign=top><em>source</em>&nbsp;</td><td>
1476String to be converted. </td></tr>
1477<tr><td valign=top><em>endp</em>&nbsp;</td><td>
1478Pointer to end of the converted string. </td></tr>
1479</table>
1480</dl><dl compact><dt><b>Returns: </b></dt><dd>
1481A floating-point number.</dl>See <a class="el" href="group___static_strings.html#a32">Static String Functions.</a>. </td>
1482 </tr>
1483</table>
1484<a name="a34" doxytag="triostr-macro.c::trio_to_float"></a><p>
1485<table width="100%" cellpadding="2" cellspacing="0" border="0">
1486 <tr>
1487 <td class="md">
1488 <table cellpadding="0" cellspacing="0" border="0">
1489 <tr>
1490 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING float trio_to_float </td>
1491 <td class="md" valign="top">(&nbsp;</td>
1492 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1493 <td class="mdname" nowrap>&nbsp; <em>source</em>, </td>
1494 </tr>
1495 <tr>
1496 <td></td>
1497 <td></td>
1498 <td class="md" nowrap>char **&nbsp;</td>
1499 <td class="mdname" nowrap>&nbsp; <em>endp</em></td>
1500 </tr>
1501 <tr>
1502 <td></td>
1503 <td class="md">)&nbsp;</td>
1504 <td class="md" colspan="2"></td>
1505 </tr>
1506
1507 </table>
1508 </td>
1509 </tr>
1510</table>
1511<table cellspacing=5 cellpadding=0 border=0>
1512 <tr>
1513 <td>
1514 &nbsp;
1515 </td>
1516 <td>
1517
1518<p>
1519Convert string to floating-point number.
1520<p>
1521<dl compact><dt><b>Parameters: </b></dt><dd>
1522<table border=0 cellspacing=2 cellpadding=0>
1523<tr><td valign=top><em>source</em>&nbsp;</td><td>
1524String to be converted. </td></tr>
1525<tr><td valign=top><em>endp</em>&nbsp;</td><td>
1526Pointer to end of the converted string. </td></tr>
1527</table>
1528</dl><dl compact><dt><b>Returns: </b></dt><dd>
1529A floating-point number.</dl>See <a class="el" href="group___static_strings.html#a32">Static String Functions.</a>. </td>
1530 </tr>
1531</table>
1532<a name="a35" doxytag="triostr-macro.c::trio_to_long"></a><p>
1533<table width="100%" cellpadding="2" cellspacing="0" border="0">
1534 <tr>
1535 <td class="md">
1536 <table cellpadding="0" cellspacing="0" border="0">
1537 <tr>
1538 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING long trio_to_long </td>
1539 <td class="md" valign="top">(&nbsp;</td>
1540 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1541 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
1542 </tr>
1543 <tr>
1544 <td></td>
1545 <td></td>
1546 <td class="md" nowrap>char **&nbsp;</td>
1547 <td class="mdname" nowrap>&nbsp; <em>endp</em>, </td>
1548 </tr>
1549 <tr>
1550 <td></td>
1551 <td></td>
1552 <td class="md" nowrap>int&nbsp;</td>
1553 <td class="mdname" nowrap>&nbsp; <em>base</em></td>
1554 </tr>
1555 <tr>
1556 <td></td>
1557 <td class="md">)&nbsp;</td>
1558 <td class="md" colspan="2"></td>
1559 </tr>
1560
1561 </table>
1562 </td>
1563 </tr>
1564</table>
1565<table cellspacing=5 cellpadding=0 border=0>
1566 <tr>
1567 <td>
1568 &nbsp;
1569 </td>
1570 <td>
1571
1572<p>
1573Convert string to signed integer.
1574<p>
1575<dl compact><dt><b>Parameters: </b></dt><dd>
1576<table border=0 cellspacing=2 cellpadding=0>
1577<tr><td valign=top><em>string</em>&nbsp;</td><td>
1578String to be converted. </td></tr>
1579<tr><td valign=top><em>endp</em>&nbsp;</td><td>
1580Pointer to end of converted string. </td></tr>
1581<tr><td valign=top><em>base</em>&nbsp;</td><td>
1582Radix number of number. </td></tr>
1583</table>
1584</dl> </td>
1585 </tr>
1586</table>
1587<a name="a32" doxytag="triostr-macro.c::trio_to_long_double"></a><p>
1588<table width="100%" cellpadding="2" cellspacing="0" border="0">
1589 <tr>
1590 <td class="md">
1591 <table cellpadding="0" cellspacing="0" border="0">
1592 <tr>
1593 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING trio_long_double_t trio_to_long_double </td>
1594 <td class="md" valign="top">(&nbsp;</td>
1595 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1596 <td class="mdname" nowrap>&nbsp; <em>source</em>, </td>
1597 </tr>
1598 <tr>
1599 <td></td>
1600 <td></td>
1601 <td class="md" nowrap>char **&nbsp;</td>
1602 <td class="mdname" nowrap>&nbsp; <em>endp</em></td>
1603 </tr>
1604 <tr>
1605 <td></td>
1606 <td class="md">)&nbsp;</td>
1607 <td class="md" colspan="2"></td>
1608 </tr>
1609
1610 </table>
1611 </td>
1612 </tr>
1613</table>
1614<table cellspacing=5 cellpadding=0 border=0>
1615 <tr>
1616 <td>
1617 &nbsp;
1618 </td>
1619 <td>
1620
1621<p>
1622Convert string to floating-point number.
1623<p>
1624<dl compact><dt><b>Parameters: </b></dt><dd>
1625<table border=0 cellspacing=2 cellpadding=0>
1626<tr><td valign=top><em>source</em>&nbsp;</td><td>
1627String to be converted. </td></tr>
1628<tr><td valign=top><em>endp</em>&nbsp;</td><td>
1629Pointer to end of the converted string. </td></tr>
1630</table>
1631</dl><dl compact><dt><b>Returns: </b></dt><dd>
1632A floating-point number.</dl>The following Extended Backus-Naur form is used <div class="fragment"><pre>
1633 double ::= [ &lt;sign&gt; ]
1634 ( &lt;number&gt; |
1635 &lt;number&gt; &lt;decimal_point&gt; &lt;number&gt; |
1636 &lt;decimal_point&gt; &lt;number&gt; )
1637 [ &lt;exponential&gt; [ &lt;sign&gt; ] &lt;number&gt; ]
1638 number ::= 1*( &lt;digit&gt; )
1639 digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
1640 exponential ::= ( 'e' | 'E' )
1641 sign ::= ( '-' | '+' )
1642 decimal_point ::= '.'
1643 </pre></div> </td>
1644 </tr>
1645</table>
1646<a name="a36" doxytag="triostr-macro.c::trio_to_lower"></a><p>
1647<table width="100%" cellpadding="2" cellspacing="0" border="0">
1648 <tr>
1649 <td class="md">
1650 <table cellpadding="0" cellspacing="0" border="0">
1651 <tr>
1652 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_to_lower </td>
1653 <td class="md" valign="top">(&nbsp;</td>
1654 <td class="md" nowrap valign="top">int&nbsp;</td>
1655 <td class="mdname1" valign="top" nowrap>&nbsp; <em>source</em> </td>
1656 <td class="md" valign="top">)&nbsp;</td>
1657 <td class="md" nowrap></td>
1658 </tr>
1659
1660 </table>
1661 </td>
1662 </tr>
1663</table>
1664<table cellspacing=5 cellpadding=0 border=0>
1665 <tr>
1666 <td>
1667 &nbsp;
1668 </td>
1669 <td>
1670
1671<p>
1672Convert one alphabetic letter to lower-case.
1673<p>
1674<dl compact><dt><b>Parameters: </b></dt><dd>
1675<table border=0 cellspacing=2 cellpadding=0>
1676<tr><td valign=top><em>source</em>&nbsp;</td><td>
1677The letter to be converted. </td></tr>
1678</table>
1679</dl><dl compact><dt><b>Returns: </b></dt><dd>
1680The converted letter. </dl> </td>
1681 </tr>
1682</table>
1683<a name="a37" doxytag="triostr-macro.c::trio_to_unsigned_long"></a><p>
1684<table width="100%" cellpadding="2" cellspacing="0" border="0">
1685 <tr>
1686 <td class="md">
1687 <table cellpadding="0" cellspacing="0" border="0">
1688 <tr>
1689 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING unsigned long trio_to_unsigned_long </td>
1690 <td class="md" valign="top">(&nbsp;</td>
1691 <td class="md" nowrap valign="top">const char *&nbsp;</td>
1692 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
1693 </tr>
1694 <tr>
1695 <td></td>
1696 <td></td>
1697 <td class="md" nowrap>char **&nbsp;</td>
1698 <td class="mdname" nowrap>&nbsp; <em>endp</em>, </td>
1699 </tr>
1700 <tr>
1701 <td></td>
1702 <td></td>
1703 <td class="md" nowrap>int&nbsp;</td>
1704 <td class="mdname" nowrap>&nbsp; <em>base</em></td>
1705 </tr>
1706 <tr>
1707 <td></td>
1708 <td class="md">)&nbsp;</td>
1709 <td class="md" colspan="2"></td>
1710 </tr>
1711
1712 </table>
1713 </td>
1714 </tr>
1715</table>
1716<table cellspacing=5 cellpadding=0 border=0>
1717 <tr>
1718 <td>
1719 &nbsp;
1720 </td>
1721 <td>
1722
1723<p>
1724Convert string to unsigned integer.
1725<p>
1726<dl compact><dt><b>Parameters: </b></dt><dd>
1727<table border=0 cellspacing=2 cellpadding=0>
1728<tr><td valign=top><em>string</em>&nbsp;</td><td>
1729String to be converted. </td></tr>
1730<tr><td valign=top><em>endp</em>&nbsp;</td><td>
1731Pointer to end of converted string. </td></tr>
1732<tr><td valign=top><em>base</em>&nbsp;</td><td>
1733Radix number of number. </td></tr>
1734</table>
1735</dl> </td>
1736 </tr>
1737</table>
1738<a name="a38" doxytag="triostr-macro.c::trio_to_upper"></a><p>
1739<table width="100%" cellpadding="2" cellspacing="0" border="0">
1740 <tr>
1741 <td class="md">
1742 <table cellpadding="0" cellspacing="0" border="0">
1743 <tr>
1744 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_to_upper </td>
1745 <td class="md" valign="top">(&nbsp;</td>
1746 <td class="md" nowrap valign="top">int&nbsp;</td>
1747 <td class="mdname1" valign="top" nowrap>&nbsp; <em>source</em> </td>
1748 <td class="md" valign="top">)&nbsp;</td>
1749 <td class="md" nowrap></td>
1750 </tr>
1751
1752 </table>
1753 </td>
1754 </tr>
1755</table>
1756<table cellspacing=5 cellpadding=0 border=0>
1757 <tr>
1758 <td>
1759 &nbsp;
1760 </td>
1761 <td>
1762
1763<p>
1764Convert one alphabetic letter to upper-case.
1765<p>
1766<dl compact><dt><b>Parameters: </b></dt><dd>
1767<table border=0 cellspacing=2 cellpadding=0>
1768<tr><td valign=top><em>source</em>&nbsp;</td><td>
1769The letter to be converted. </td></tr>
1770</table>
1771</dl><dl compact><dt><b>Returns: </b></dt><dd>
1772The converted letter. </dl> </td>
1773 </tr>
1774</table>
1775<a name="a31" doxytag="triostr-macro.c::trio_tokenize"></a><p>
1776<table width="100%" cellpadding="2" cellspacing="0" border="0">
1777 <tr>
1778 <td class="md">
1779 <table cellpadding="0" cellspacing="0" border="0">
1780 <tr>
1781 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING char* trio_tokenize </td>
1782 <td class="md" valign="top">(&nbsp;</td>
1783 <td class="md" nowrap valign="top">char *&nbsp;</td>
1784 <td class="mdname" nowrap>&nbsp; <em>string</em>, </td>
1785 </tr>
1786 <tr>
1787 <td></td>
1788 <td></td>
1789 <td class="md" nowrap>const char *&nbsp;</td>
1790 <td class="mdname" nowrap>&nbsp; <em>delimiters</em></td>
1791 </tr>
1792 <tr>
1793 <td></td>
1794 <td class="md">)&nbsp;</td>
1795 <td class="md" colspan="2"></td>
1796 </tr>
1797
1798 </table>
1799 </td>
1800 </tr>
1801</table>
1802<table cellspacing=5 cellpadding=0 border=0>
1803 <tr>
1804 <td>
1805 &nbsp;
1806 </td>
1807 <td>
1808
1809<p>
1810Tokenize string.
1811<p>
1812<dl compact><dt><b>Parameters: </b></dt><dd>
1813<table border=0 cellspacing=2 cellpadding=0>
1814<tr><td valign=top><em>string</em>&nbsp;</td><td>
1815String to be tokenized. </td></tr>
1816<tr><td valign=top><em>delimiters</em>&nbsp;</td><td>
1817String containing list of delimiting characters. </td></tr>
1818</table>
1819</dl><dl compact><dt><b>Returns: </b></dt><dd>
1820Start of new token.</dl><dl compact><dt><b>Warning: </b></dt><dd>
1821<code>string</code> will be destroyed. </dl> </td>
1822 </tr>
1823</table>
1824<a name="a39" doxytag="triostr-macro.c::trio_upper"></a><p>
1825<table width="100%" cellpadding="2" cellspacing="0" border="0">
1826 <tr>
1827 <td class="md">
1828 <table cellpadding="0" cellspacing="0" border="0">
1829 <tr>
1830 <td class="md" nowrap valign="top"> TRIO_PUBLIC_STRING int trio_upper </td>
1831 <td class="md" valign="top">(&nbsp;</td>
1832 <td class="md" nowrap valign="top">char *&nbsp;</td>
1833 <td class="mdname1" valign="top" nowrap>&nbsp; <em>target</em> </td>
1834 <td class="md" valign="top">)&nbsp;</td>
1835 <td class="md" nowrap></td>
1836 </tr>
1837
1838 </table>
1839 </td>
1840 </tr>
1841</table>
1842<table cellspacing=5 cellpadding=0 border=0>
1843 <tr>
1844 <td>
1845 &nbsp;
1846 </td>
1847 <td>
1848
1849<p>
1850Convert the alphabetic letters in the string to upper-case.
1851<p>
1852<dl compact><dt><b>Parameters: </b></dt><dd>
1853<table border=0 cellspacing=2 cellpadding=0>
1854<tr><td valign=top><em>target</em>&nbsp;</td><td>
1855The string to be converted. </td></tr>
1856</table>
1857</dl><dl compact><dt><b>Returns: </b></dt><dd>
1858The number of processed characters (converted or not). </dl> </td>
1859 </tr>
1860</table>
1861<HR>
1862<center class="copyright">Copyright (C) 2001 - 2006 Bj&oslash;rn Reese and Daniel Stenberg.</center>
1863</body>
1864</html>
diff --git a/gs/trio/html/group___user_defined.html b/gs/trio/html/group___user_defined.html
new file mode 100644
index 000000000..d22ba1a76
--- /dev/null
+++ b/gs/trio/html/group___user_defined.html
@@ -0,0 +1,391 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
5 <title>TRIO</title>
6 <link href="trio.css" rel="stylesheet" type="text/css">
7</head>
8<body>
9<!-- Generated by Doxygen 1.2.18 -->
10<center>
11<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; </center>
12<hr><h1>User-defined Formatted Printing Functions.</h1>Functions for using customized formatting specifiers.
13<a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0>
14<tr><td></td></tr>
15<tr><td colspan=2><br><h2>Functions</h2></td></tr>
16<tr><td nowrap align=right valign=top>trio_pointer_t&nbsp;</td><td valign=bottom><a class="el" href="group___user_defined.html#a0">trio_register</a> (trio_callback_t callback, const char *name)</td></tr>
17<tr><td>&nbsp;</td><td><font size=-1><em>Register new user-defined specifier.</em> <a href="#a0"></a><em></em></font><br><br></td></tr>
18<tr><td nowrap align=right valign=top>void&nbsp;</td><td valign=bottom><a class="el" href="group___user_defined.html#a1">trio_unregister</a> (trio_pointer_t handle)</td></tr>
19<tr><td>&nbsp;</td><td><font size=-1><em>Unregister an existing user-defined specifier.</em> <a href="#a1"></a><em></em></font><br><br></td></tr>
20</table>
21<hr><a name="_details"></a><h2>Detailed Description</h2>
22Functions for using customized formatting specifiers.
23<p>
24<b>SYNOPSIS</b>
25<p>
26<div class="fragment"><pre>
27cc ... -ltrio -lm
28
29#include &lt;trio.h&gt;
30#include &lt;triop.h&gt;
31</pre></div>
32<p>
33<b>DESCRIPTION</b>
34<p>
35This documentation is incomplete.
36<p>
37<b>User-defined</b> <b>Specifier</b>
38<p>
39The user-defined specifier consists of a start character (\074 = '&lt;'), an optional namespace string followed by a namespace separator (\072 = ':'), a format string, an optional skipping separator (\174 = '|'), and an end character (\076 = '&gt;').
40<p>
41The namespace string can consist of alphanumeric characters, and is used to define a named reference (see below). The namespace is case-sensitive. If no namespace is specified, then we use an unnamed reference (see below).
42<p>
43The format can consist of any character except the end character ('&gt;'), the namespace separator (':'), the skipping separator ('|'), and the nil character (\000).
44<p>
45Any modifier can be used together with the user-defined specifier.
46<p>
47There are two formats for invoking a user-defined specifier. The first format is an extension of the normal printf/scanf formatting. It uses the percent character (\045 = '%') followed by optional qualifiers and a specifier. For example:
48<p>
49<div class="fragment"><pre>
50 trio_printf("%&lt;format&gt;\n", my_handle, my_data);
51</pre></div>
52<p>
53Some C compilers can issue a warning if there is a mismatch between specifiers and arguments. Unfortunately, these warnings does not work with the first format for user-defined specifiers. Therefore the second format has been introduced. The second format can only be applied to user-defined specifiers.
54<p>
55The second format starts with a dollar character (\044 = '$') instead of the percent character, and is followed by optional qualifiers and the user-defined specifier. If the specifier contains a pipe character (\174 = '|'), then everything between the pipe character and the end character ('&gt;') is ignored. The ignored part can be used to list the normal specifiers that the C compiler uses to determine mismatches. For example:
56<p>
57<div class="fragment"><pre>
58 trio_printf("$&lt;format|%p%p&gt;\n", my_handle, my_data);
59</pre></div>
60<p>
61<b>Registering</b>
62<p>
63A user-defined specifier must be registered before it can be used. Unregistered user-defined specifiers are ignored. The <a class="el" href="group___user_defined.html#a243">User-defined Formatted Printing Functions.</a> function is used to register a user-defined specifier. It takes two argument, a callback function and a namespace, and it returns a handle. The handle must be used to unregister the specifier later.
64<p>
65The following example registers a user-define specifier with the "my_namespace" namespace:
66<p>
67<div class="fragment"><pre>
68 my_handle = trio_register(my_callback, "my_namespace");
69</pre></div>
70<p>
71There can only be one user-defined specifier with a given namespace. There can be an unlimited number (subject to maximum length of the namespace) of different user-defined specifiers.
72<p>
73Passing NULL as the namespace argument results in an anonymous reference. There can be an unlimited number of anonymous references.
74<p>
75<b>REFERENCES</b>
76<p>
77There are two ways that a registered callback can be called. Either the user-defined specifier must contain the registered namespace in the format string, or the handle is passed as an argument to the formatted printing function.
78<p>
79If the namespace is used, then a user-defined pointer must be passed as an argument:
80<p>
81<div class="fragment"><pre>
82 trio_printf("%&lt;my_namespace:format&gt;\n", my_data);
83</pre></div>
84<p>
85If the handle is used, then the user-defined specifier must not contain a namespace. Instead the handle must be passed as an argument, followed by a user-defined pointer:
86<p>
87<div class="fragment"><pre>
88 trio_printf("%&lt;format&gt;\n", my_handle, my_data);
89</pre></div>
90<p>
91The two examples above are equivalent.
92<p>
93There must be exactly one user-defined pointer per user-defined specifier. This pointer can be used within the callback function with the trio_get_argument getter function (see below).
94<p>
95The format string is optional. It can be used within the callback function with the trio_get_format getter function.
96<p>
97<b>Anonymous</b> <b>References</b> Anonymous references are specified by passing NULL as the namespace.
98<p>
99The handle must be passed as an argument followed by a user-defined pointer. No namespace can be specified.
100<p>
101<div class="fragment"><pre>
102 anon_handle = trio_register(callback, NULL);
103 trio_printf("%&lt;format&gt;\n", anon_handle, my_data);
104</pre></div>
105<p>
106<b>Restrictions</b>
107<p>
108<ul>
109<li> The length of the namespace string cannot exceed 63 characters. <li> The length of the user-defined format string cannot exceed 255 characters. <li> User-defined formatting cannot re-define existing specifiers. This restriction was imposed because the existing formatting specifiers have a well-defined behaviour, and any re-definition would apply globally to an application (imagine a third-party library changing the behaviour of a specifier that is crusial to your application).</ul>
110<b>CALLBACK</b> <b>FUNCTION</b>
111<p>
112The callback function will be called if a matching user-defined specifier is found within the formatting string. The callback function takes one input parameter, an opaque reference which is needed by the private functions. It returns an <code>int</code>, which is currently ignored. The prototype is
113<p>
114<div class="fragment"><pre>
115 int (*trio_callback_t)(void *ref);
116</pre></div>
117<p>
118See the Example section for full examples.
119<p>
120<b>PRINTING</b> <b>FUNCTIONS</b>
121<p>
122The following printing functions must only be used inside a callback function. These functions will print to the same output medium as the printf function which invoked the callback function. For example, if the user-defined specifier is used in an sprintf function, then these print functions will output their result to the same string.
123<p>
124<b>Elementary</b> <b>Printing</b>
125<p>
126There are a number of function to print elementary data types.
127<p>
128<ul>
129<li> trio_print_int Print a signed integer. For example: <div class="fragment"><pre>
130 trio_print_int(42);
131</pre></div> <li> trio_print_uint Print an unsigned integer. <li> trio_print_double Print a floating-point number. <li> trio_print_string Print a string. For example: <div class="fragment"><pre>
132 trio_print_string("Hello World");
133 trio_print_string(trio_get_format());
134</pre></div> <li> trio_print_pointer Print a pointer.</ul>
135<b>Formatted</b> <b>Printing</b>
136<p>
137The functions trio_print_ref, trio_vprint_ref, and trio_printv_ref outputs a formatted string just like its printf equivalents.
138<p>
139<div class="fragment"><pre>
140 trio_print_ref(ref, "There are %d towels\n", 42);
141 trio_print_ref(ref, "%&lt;recursive&gt;\n", recursive_writer, trio_get_argument(ref));
142</pre></div>
143<p>
144<b>GETTER</b> <b>AND</b> <b>SETTER</b> <b>FUNCTIONS</b>
145<p>
146The following getter and setter functions must only be used inside a callback function. They can either operate on the modifiers or on special data.
147<p>
148<b>Modifiers</b>
149<p>
150The value of a modifier, or a boolean indication of its presence or absence, can be found or set with the getter and setter functions. The generic prototypes of the these getter and setter functions are
151<p>
152<div class="fragment"><pre>
153 int trio_get_???(void *ref);
154 void trio_set_???(void *ref, int);
155</pre></div>
156<p>
157where ??? <code>refers</code> to a modifier. For example, to get the width of the user-defined specifier use
158<p>
159<div class="fragment"><pre>
160 int width = trio_get_width(ref);
161</pre></div>
162<p>
163<b>Special</b> <b>Data</b>
164<p>
165Consider the following user-defined specifier, in its two possible referencing presentations.
166<p>
167<div class="fragment"><pre>
168 trio_printf("%&lt;format&gt;\n", namespace_writer, argument);
169 trio_printf("%&lt;namespace:format&gt;\n", argument);
170</pre></div>
171<p>
172trio_get_format will get the <code>format</code> string, and trio_get_argument} will get the <code>argument</code> parameter. There are no associated setter functions.
173<p>
174<b>EXAMPLES</b>
175<p>
176The following examples show various types of user-defined specifiers. Although each specifier is demonstrated in isolation, they can all co-exist within the same application.
177<p>
178<b>Time</b> <b>Example</b>
179<p>
180Print the time in the format "HOUR:MINUTE:SECOND" if "time" is specified inside the user-defined specifier.
181<p>
182<div class="fragment"><pre>
183 static int time_print(void *ref)
184 {
185 const char *format;
186 time_t *data;
187 char buffer[256];
188
189 format = trio_get_format(ref);
190 if ((format) &amp;&amp; (strcmp(format, "time") == 0)) {
191 data = trio_get_argument(ref);
192 if (data == NULL)
193 return -1;
194 strftime(buffer, sizeof(buffer), "%H:%M:%S", localtime(data));
195 trio_print_string(ref, buffer);
196 }
197 return 0;
198 }
199</pre></div>
200<p>
201<div class="fragment"><pre>
202 int main(void)
203 {
204 void *handle;
205 time_t now = time(NULL);
206
207 handle = trio_register(time_print, "my_time");
208
209 trio_printf("%&lt;time&gt;\n", handle, &amp;now);
210 trio_printf("%&lt;my_time:time&gt;\n", &amp;now);
211
212 trio_unregister(handle);
213 return 0;
214 }
215</pre></div>
216<p>
217<b>Complex</b> <b>Numbers</b> <b>Example</b>
218<p>
219Consider a complex number consisting of a real part, re, and an imaginary part, im.
220<p>
221<div class="fragment"><pre>
222 struct Complex {
223 double re;
224 double im;
225 };
226</pre></div>
227<p>
228This example can print such a complex number in one of two formats. The default format is "re + i im". If the alternative modifier is used, then the format is "r exp(i theta)", where r is the length of the complex vector (re, im) and theta is its angle.
229<p>
230<div class="fragment"><pre>
231 static int complex_print(void *ref)
232 {
233 struct Complex *data;
234 const char *format;
235
236 data = (struct Complex *)trio_get_argument(ref);
237 if (data) {
238 format = trio_get_format(ref);
239
240 if (trio_get_alternative(ref)) {
241 double r, theta;
242
243 r = sqrt(pow(data-&gt;re, 2) + pow(data-&gt;im, 2));
244 theta = acos(data-&gt;re / r);
245 trio_print_ref(ref, "%#f exp(i %#f)", r, theta);
246
247 } else {
248 trio_print_ref(ref, "%#f + i %#f", data-&gt;re, data-&gt;im);
249 }
250 }
251 return 0;
252 }
253</pre></div>
254<p>
255<div class="fragment"><pre>
256 int main(void)
257 {
258 void *handle;
259
260 handle = trio_register(complex_print, "complex");
261
262 /* Normal format. With handle and the with namespace
263 trio_printf("%&lt;&gt;\n", handle, &amp;complex);
264 trio_printf("%&lt;complex:&gt;\n", &amp;complex);
265 /* In exponential notation
266 trio_printf("%#&lt;&gt;\n", handle, &amp;complex);
267 trio_printf("%#&lt;complex:unused data&gt;\n", &amp;complex);
268
269 trio_unregister(handle);
270 return 0;
271 }
272</pre></div>
273<p>
274<b>RETURN</b> <b>VALUES</b>
275<p>
276<a class="el" href="group___user_defined.html#a243">User-defined Formatted Printing Functions.</a> returns a handle, or NULL if an error occured.
277<p>
278<b>SEE</b> <b>ALSO</b>
279<p>
280<a class="el" href="group___printf.html#a218">Formatted Printing Functions.</a>
281<p>
282<b>NOTES</b>
283<p>
284User-defined specifiers, <a class="el" href="group___user_defined.html#a243">User-defined Formatted Printing Functions.</a>, and <a class="el" href="group___user_defined.html#a244">User-defined Formatted Printing Functions.</a> are not thread-safe. In multi-threaded applications they must be guarded by mutexes. Trio provides two special callback functions, called ":enter" and ":leave", which are invoked every time a thread-unsafe operation is attempted. As the thread model is determined by the application, these callback functions must be implemented by the application.
285<p>
286The following callback functions are for demonstration-purposes only. Replace their bodies with locking and unlocking of a mutex to achieve thread-safety. <div class="fragment"><pre>
287 static int enter_region(void *ref)
288 {
289 fprintf(stderr, "Enter Region\n");
290 return 1;
291 }
292
293 static int leave_region(void *ref)
294 {
295 fprintf(stderr, "Leave Region\n");
296 return 1;
297 }
298</pre></div> These two callbacks must be registered before other callbacks are registered. <div class="fragment"><pre>
299 trio_register(enter_region, ":enter");
300 trio_register(leave_region, ":leave");
301
302 another_handle = trio_register(another_callback, NULL);
303</pre></div> <hr><h2>Function Documentation</h2>
304<a name="a0" doxytag="trio-cdetect.c::trio_register"></a><p>
305<table width="100%" cellpadding="2" cellspacing="0" border="0">
306 <tr>
307 <td class="md">
308 <table cellpadding="0" cellspacing="0" border="0">
309 <tr>
310 <td class="md" nowrap valign="top"> trio_pointer_t trio_register </td>
311 <td class="md" valign="top">(&nbsp;</td>
312 <td class="md" nowrap valign="top">trio_callback_t&nbsp;</td>
313 <td class="mdname" nowrap>&nbsp; <em>callback</em>, </td>
314 </tr>
315 <tr>
316 <td></td>
317 <td></td>
318 <td class="md" nowrap>const char *&nbsp;</td>
319 <td class="mdname" nowrap>&nbsp; <em>name</em></td>
320 </tr>
321 <tr>
322 <td></td>
323 <td class="md">)&nbsp;</td>
324 <td class="md" colspan="2"></td>
325 </tr>
326
327 </table>
328 </td>
329 </tr>
330</table>
331<table cellspacing=5 cellpadding=0 border=0>
332 <tr>
333 <td>
334 &nbsp;
335 </td>
336 <td>
337
338<p>
339Register new user-defined specifier.
340<p>
341<dl compact><dt><b>Parameters: </b></dt><dd>
342<table border=0 cellspacing=2 cellpadding=0>
343<tr><td valign=top><em>callback</em>&nbsp;</td><td>
344</td></tr>
345<tr><td valign=top><em>name</em>&nbsp;</td><td>
346</td></tr>
347</table>
348</dl><dl compact><dt><b>Returns: </b></dt><dd>
349Handle. </dl> </td>
350 </tr>
351</table>
352<a name="a1" doxytag="trio-cdetect.c::trio_unregister"></a><p>
353<table width="100%" cellpadding="2" cellspacing="0" border="0">
354 <tr>
355 <td class="md">
356 <table cellpadding="0" cellspacing="0" border="0">
357 <tr>
358 <td class="md" nowrap valign="top"> void trio_unregister </td>
359 <td class="md" valign="top">(&nbsp;</td>
360 <td class="md" nowrap valign="top">trio_pointer_t&nbsp;</td>
361 <td class="mdname1" valign="top" nowrap>&nbsp; <em>handle</em> </td>
362 <td class="md" valign="top">)&nbsp;</td>
363 <td class="md" nowrap></td>
364 </tr>
365
366 </table>
367 </td>
368 </tr>
369</table>
370<table cellspacing=5 cellpadding=0 border=0>
371 <tr>
372 <td>
373 &nbsp;
374 </td>
375 <td>
376
377<p>
378Unregister an existing user-defined specifier.
379<p>
380<dl compact><dt><b>Parameters: </b></dt><dd>
381<table border=0 cellspacing=2 cellpadding=0>
382<tr><td valign=top><em>handle</em>&nbsp;</td><td>
383</td></tr>
384</table>
385</dl> </td>
386 </tr>
387</table>
388<HR>
389<center class="copyright">Copyright (C) 2001 - 2006 Bj&oslash;rn Reese and Daniel Stenberg.</center>
390</body>
391</html>
diff --git a/gs/trio/html/index.html b/gs/trio/html/index.html
new file mode 100644
index 000000000..415a3a19c
--- /dev/null
+++ b/gs/trio/html/index.html
@@ -0,0 +1,89 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
5 <title>TRIO</title>
6 <link href="trio.css" rel="stylesheet" type="text/css">
7</head>
8<body>
9<!-- Generated by Doxygen 1.2.18 -->
10<center>
11<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; </center>
12<hr><h1>TRIO Documentation</h1>
13<p>
14
15<p>
16<dl compact><dt><b>Author: </b></dt><dd>
17Bjørn Reese , Daniel Stenberg</dl><h2><a name="intro">Introduction</a>
18</h2>
19<p>
20Trio is a fully matured and stable set of printf and string functions designed be used by applications with focus on portability or with the need for additional features that are not supported by standard stdio implementation.
21<p>
22There are several cases where you may want to consider using trio:
23<p>
24<ul>
25<li> Portability across heterogeneous platforms. <li> Embedded systems without stdio support. <li> Extendability of unsupported features. <li> Your native version does not do everything you need.</ul>
26When you write applications that must be portable to a wide range of platforms you often have to deal with inadequate implementations of the stdio library functions. Most notably is the lack of secure formatting functions, such as snprintf, or the lack of parameter reordering commonly used for the internationalization of applications, such as the &lt;num&gt;$ modifier. Sometimes the feature you need is simply not present in stdio. So you end up spending much effort on determining which platforms supports what, and to write your own versions of various features. This is where trio can help you. Trio is a platform-independent implementation of the stdio printf and scanf functions and the string library functions.
27<p>
28The functionality described in the stdio standards is a compromise, and does unfortunately not include a mechanism to extend the functionality for an individual application. Oftentimes an application has the need for an extra feature, and the application code can become much more clear and readable by using an extension mechanism. Trio supports a range of useful extensions such as user-defined specifiers, passing of arguments in arrays, localized string scanning, thousand-separators, and arbitrary integer bases.
29<p>
30Trio fully implements the C99 (ISO/IEC 9899:1999) and UNIX98 (the Single Unix Specification, Version 2) standards, as well as many features from other implemenations, e.g. the GNU libc and BSD4.
31<p>
32<h2><a name="examples">Examples</a>
33</h2>
34<p>
35<h3><a name="ex1">Binary Numbers</a>
36</h3> Output an integer as a binary number using a trio extension. <div class="fragment"><pre>
37 trio_printf("%..2i\n", number);
38</pre></div>
39<p>
40<h3><a name="ex2">Thousand-separator</a>
41</h3> Output a number with thousand-separator using a trio extension. <div class="fragment"><pre>
42 trio_printf("%'f\n", 12345.6);
43</pre></div> The thousand-separator described by the locale is used.
44<p>
45<h3><a name="ex3">Fixed Length Array and Sticky Modifier</a>
46</h3> Output an fixed length array of floating-point numbers. <div class="fragment"><pre>
47 double array[] = {1.0, 2.0, 3.0};
48 printf("%.2f %.2f %.2f\n", array[0], array[1], array[2]);
49</pre></div> The same with two trio extensions (arguments are passed in an array, and the first formatting specifier sets the sticky option so we do not have to type all the formatting modifiers for the remaining formatting specifiers) <div class="fragment"><pre>
50 trio_printfv("%!.2f %f %f\n", array);
51</pre></div> Another, and more powerful, application of being able to pass arguments in an array is the creation of the printf/scanf statement at run-time, where the formatting string, and thus the argument list, is based on an external configuration file.
52<p>
53<h3><a name="ex4">Localized scanning</a>
54</h3> Parse a string consisting of one or more upper-case alphabetic characters followed by one or more numeric characters. <div class="fragment"><pre>
55 sscanf(buffer, "%[A-Z]%[0-9]", alphabetic, numeric);
56</pre></div> The same but with locale using a trio extension. <div class="fragment"><pre>
57 trio_sscanf(buffer, "%[[:upper:]]%[[:digit:]]", alphabetic, numeric);
58</pre></div>
59<p>
60<h2><a name="legal">Legal Issues</a>
61</h2> Trio is distributed under the following license, which allows practically anybody to use it in almost any kind of software, including proprietary software, without difficulty.
62<p>
63"Copyright (C) 1998-2001 Bjorn Reese and Daniel Stenberg.
64<p>
65Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
66<p>
67THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER."
68<p>
69<h2><a name="contribution">Contribution</a>
70</h2>
71<p>
72<h3><a name="contribute">Contribute</a>
73</h3> We appreciate any type of contribution, from ideas over improvements to error corrections.
74<p>
75The project space contains references to bug and feature tracking, mailing-list, and the CVS repository. We prefer communication via the mailing-list, but do not require you to be subscribed, because trio is a small project.
76<p>
77The project space is located at <a href="http://sourceforge.net/projects/ctrio/">http://sourceforge.net/projects/ctrio/</a>
78<p>
79<h3><a name="contributors">Contributors</a>
80</h3> We have received contributions from the following persons (in alphabetic order sorted by surname)
81<p>
82<ul>
83<li> Craig Berry <li> Karl Bochert <li> Stan Boehm <li> David Byron <li> Brian Chapman <li> Robert Collins <li> Danny Dulai <li> Bob Friesenhahn <li> Jon Foster <li> John Fotheringham <li> Markus Henke <li> Ken Gibson <li> Paul Janzen <li> Patrick Jessee <li> Richard Jinks <li> Tero Jänkä <li> Howard Kapustein <li> Rune Enggaard Lausen <li> Mehdi Lavasani <li> Alexander Lukyanov <li> Andreas Maus <li> Mikey Menezes <li> Emmanuel Mogenet <li> Jacob Navia <li> Jose Ortiz <li> Joe Orton <li> Gisli Ottarsson <li> Mark Pickelmann <li> Olli Savia <li> Shaun Tancheff <li> Marc Werwerft <li> Igor Zlatkovic</ul>
84Please let us know, and accept our apology, if we have omitted anybody.
85<p>
86<HR>
87<center class="copyright">Copyright (C) 2001 - 2006 Bj&oslash;rn Reese and Daniel Stenberg.</center>
88</body>
89</html>
diff --git a/gs/trio/html/modules.html b/gs/trio/html/modules.html
new file mode 100644
index 000000000..568e81a70
--- /dev/null
+++ b/gs/trio/html/modules.html
@@ -0,0 +1,23 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
5 <title>TRIO</title>
6 <link href="trio.css" rel="stylesheet" type="text/css">
7</head>
8<body>
9<!-- Generated by Doxygen 1.2.18 -->
10<center>
11<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; </center>
12<hr><h1>TRIO Modules</h1>Here is a list of all modules:<ul>
13<li><a class="el" href="group___printf.html">Formatted Printing Functions.</a>
14<li><a class="el" href="group___user_defined.html">User-defined Formatted Printing Functions.</a>
15<li><a class="el" href="group___scanf.html">Formatted Scanning Functions.</a>
16<li><a class="el" href="group___special_quantities.html">Special Quantifies.</a>
17<li><a class="el" href="group___static_strings.html">Static String Functions.</a>
18<li><a class="el" href="group___dynamic_strings.html">Dynamic String Functions.</a>
19</ul>
20<HR>
21<center class="copyright">Copyright (C) 2001 - 2006 Bj&oslash;rn Reese and Daniel Stenberg.</center>
22</body>
23</html>
diff --git a/gs/trio/html/trio.css b/gs/trio/html/trio.css
new file mode 100644
index 000000000..1b3a99261
--- /dev/null
+++ b/gs/trio/html/trio.css
@@ -0,0 +1,35 @@
1/* HTML tags */
2
3BODY {
4 background-color: white;
5 color: darkblue;
6}
7
8TD { color: darkblue; }
9
10H1 { text-align: center; }
11
12H3 { font-style: italic; }
13
14HR {
15 width: 85%;
16 align: center;
17}
18
19.copyright { color: darkblue; }
20
21/* Links */
22
23:link { color: blue; }
24
25:visited { color: purple; }
26
27:active { color: red; }
28
29.el:link { font-style: italic; }
30
31/* Examples */
32
33DIV.fragment {
34 color: maroon;
35}
diff --git a/gs/trio/install-sh b/gs/trio/install-sh
new file mode 100755
index 000000000..e8436696c
--- /dev/null
+++ b/gs/trio/install-sh
@@ -0,0 +1,250 @@
1#!/bin/sh
2#
3# install - install a program, script, or datafile
4# This comes from X11R5 (mit/util/scripts/install.sh).
5#
6# Copyright 1991 by the Massachusetts Institute of Technology
7#
8# Permission to use, copy, modify, distribute, and sell this software and its
9# documentation for any purpose is hereby granted without fee, provided that
10# the above copyright notice appear in all copies and that both that
11# copyright notice and this permission notice appear in supporting
12# documentation, and that the name of M.I.T. not be used in advertising or
13# publicity pertaining to distribution of the software without specific,
14# written prior permission. M.I.T. makes no representations about the
15# suitability of this software for any purpose. It is provided "as is"
16# without express or implied warranty.
17#
18# Calling this script install-sh is preferred over install.sh, to prevent
19# `make' implicit rules from creating a file called install from it
20# when there is no Makefile.
21#
22# This script is compatible with the BSD install script, but was written
23# from scratch. It can only install one file at a time, a restriction
24# shared with many OS's install programs.
25
26
27# set DOITPROG to echo to test this script
28
29# Don't use :- since 4.3BSD and earlier shells don't like it.
30doit="${DOITPROG-}"
31
32
33# put in absolute paths if you don't have them in your path; or use env. vars.
34
35mvprog="${MVPROG-mv}"
36cpprog="${CPPROG-cp}"
37chmodprog="${CHMODPROG-chmod}"
38chownprog="${CHOWNPROG-chown}"
39chgrpprog="${CHGRPPROG-chgrp}"
40stripprog="${STRIPPROG-strip}"
41rmprog="${RMPROG-rm}"
42mkdirprog="${MKDIRPROG-mkdir}"
43
44transformbasename=""
45transform_arg=""
46instcmd="$mvprog"
47chmodcmd="$chmodprog 0755"
48chowncmd=""
49chgrpcmd=""
50stripcmd=""
51rmcmd="$rmprog -f"
52mvcmd="$mvprog"
53src=""
54dst=""
55dir_arg=""
56
57while [ x"$1" != x ]; do
58 case $1 in
59 -c) instcmd="$cpprog"
60 shift
61 continue;;
62
63 -d) dir_arg=true
64 shift
65 continue;;
66
67 -m) chmodcmd="$chmodprog $2"
68 shift
69 shift
70 continue;;
71
72 -o) chowncmd="$chownprog $2"
73 shift
74 shift
75 continue;;
76
77 -g) chgrpcmd="$chgrpprog $2"
78 shift
79 shift
80 continue;;
81
82 -s) stripcmd="$stripprog"
83 shift
84 continue;;
85
86 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
87 shift
88 continue;;
89
90 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
91 shift
92 continue;;
93
94 *) if [ x"$src" = x ]
95 then
96 src=$1
97 else
98 # this colon is to work around a 386BSD /bin/sh bug
99 :
100 dst=$1
101 fi
102 shift
103 continue;;
104 esac
105done
106
107if [ x"$src" = x ]
108then
109 echo "install: no input file specified"
110 exit 1
111else
112 true
113fi
114
115if [ x"$dir_arg" != x ]; then
116 dst=$src
117 src=""
118
119 if [ -d $dst ]; then
120 instcmd=:
121 else
122 instcmd=mkdir
123 fi
124else
125
126# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
127# might cause directories to be created, which would be especially bad
128# if $src (and thus $dsttmp) contains '*'.
129
130 if [ -f $src -o -d $src ]
131 then
132 true
133 else
134 echo "install: $src does not exist"
135 exit 1
136 fi
137
138 if [ x"$dst" = x ]
139 then
140 echo "install: no destination specified"
141 exit 1
142 else
143 true
144 fi
145
146# If destination is a directory, append the input filename; if your system
147# does not like double slashes in filenames, you may need to add some logic
148
149 if [ -d $dst ]
150 then
151 dst="$dst"/`basename $src`
152 else
153 true
154 fi
155fi
156
157## this sed command emulates the dirname command
158dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
159
160# Make sure that the destination directory exists.
161# this part is taken from Noah Friedman's mkinstalldirs script
162
163# Skip lots of stat calls in the usual case.
164if [ ! -d "$dstdir" ]; then
165defaultIFS='
166'
167IFS="${IFS-${defaultIFS}}"
168
169oIFS="${IFS}"
170# Some sh's can't handle IFS=/ for some reason.
171IFS='%'
172set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
173IFS="${oIFS}"
174
175pathcomp=''
176
177while [ $# -ne 0 ] ; do
178 pathcomp="${pathcomp}${1}"
179 shift
180
181 if [ ! -d "${pathcomp}" ] ;
182 then
183 $mkdirprog "${pathcomp}"
184 else
185 true
186 fi
187
188 pathcomp="${pathcomp}/"
189done
190fi
191
192if [ x"$dir_arg" != x ]
193then
194 $doit $instcmd $dst &&
195
196 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
197 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
198 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
199 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
200else
201
202# If we're going to rename the final executable, determine the name now.
203
204 if [ x"$transformarg" = x ]
205 then
206 dstfile=`basename $dst`
207 else
208 dstfile=`basename $dst $transformbasename |
209 sed $transformarg`$transformbasename
210 fi
211
212# don't allow the sed command to completely eliminate the filename
213
214 if [ x"$dstfile" = x ]
215 then
216 dstfile=`basename $dst`
217 else
218 true
219 fi
220
221# Make a temp file name in the proper directory.
222
223 dsttmp=$dstdir/#inst.$$#
224
225# Move or copy the file name to the temp name
226
227 $doit $instcmd $src $dsttmp &&
228
229 trap "rm -f ${dsttmp}" 0 &&
230
231# and set any options; do chmod last to preserve setuid bits
232
233# If any of these fail, we abort the whole thing. If we want to
234# ignore errors from any of these, just make sure not to ignore
235# errors from the above "$doit $instcmd $src $dsttmp" command.
236
237 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
238 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
239 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
240 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
241
242# Now rename the file to the real destination.
243
244 $doit $rmcmd -f $dstdir/$dstfile &&
245 $doit $mvcmd $dsttmp $dstdir/$dstfile
246
247fi &&
248
249
250exit 0
diff --git a/gs/trio/maketgz b/gs/trio/maketgz
new file mode 100755
index 000000000..aed8cf506
--- /dev/null
+++ b/gs/trio/maketgz
@@ -0,0 +1,46 @@
1#! /bin/sh
2# Script to build archives with
3#
4
5echo "Version number?"
6read version
7
8# get current dir
9dir=`pwd`
10
11# Get basename
12orig=`basename $dir`
13
14# Get the left part of the dash (-)
15new=`echo $orig | cut -d- -f1`
16
17# Build new directory name
18n=$new-$version;
19
20# Tell the world what we're doing
21echo "creates $n.tar.gz";
22
23if [ -r $n ]; then
24 echo "Directory already exists!"
25 exit
26fi
27
28# Create the new dir
29mkdir $n
30
31# Copy all relevant files, with path and permissions!
32tar -cf - `cat FILES` | (cd $n; tar -xBpf -) || exit 1
33
34(cd $n && sh autogen.sh) || exit 1
35
36# Make a tar archive of it all
37tar -cvf $n.tar $n
38
39# gzip the archive
40gzip $n.tar
41
42# Make it world readable
43chmod a+r $n.tar.gz ;
44
45# Delete the temp dir
46rm -rf $n
diff --git a/gs/trio/regression.c b/gs/trio/regression.c
new file mode 100644
index 000000000..57c0347e0
--- /dev/null
+++ b/gs/trio/regression.c
@@ -0,0 +1,1640 @@
1/*************************************************************************
2 * Regression test
3 */
4
5#include "triodef.h"
6#if defined(TRIO_COMPILER_ANCIENT)
7# include <varargs.h>
8#else
9# include <stdarg.h>
10#endif
11#include <math.h>
12#include <limits.h>
13#include <float.h>
14#include <errno.h>
15
16#include "trio.h"
17#include "triop.h"
18#if defined(TRIO_EMBED_NAN)
19# define TRIO_PUBLIC_NAN static
20# define TRIO_FUNC_NINF
21# define TRIO_FUNC_PINF
22# define TRIO_FUNC_NAN
23# define TRIO_FUNC_ISINF
24# define TRIO_FUNC_ISNAN
25# if TRIO_FEATURE_FLOAT
26# define TRIO_FUNC_NZERO
27# endif
28#endif
29#include "trionan.h"
30#if defined(TRIO_EMBED_STRING)
31# define TRIO_PUBLIC_STRING static
32# define TRIO_FUNC_EQUAL_CASE
33#endif
34#include "triostr.h"
35#undef printf
36
37#if TRIO_FEATURE_WIDECHAR
38# include <wchar.h>
39#endif
40
41#define QUOTE(x) #x
42
43#define DOUBLE_EQUAL(x,y) (((x)>(y)-DBL_EPSILON) && ((x)<(y)+DBL_EPSILON))
44#define FLOAT_EQUAL(x,y) (((x)>(y)-FLT_EPSILON) && ((x)<(y)+FLT_EPSILON))
45
46static TRIO_CONST char rcsid[] = "@(#)$Id: regression.c,v 1.67 2010/01/26 13:02:02 breese Exp $";
47
48#if defined(TRIO_EMBED_NAN)
49# include "trionan.c"
50#endif
51#if defined(TRIO_EMBED_STRING)
52# include "triostr.c"
53#endif
54
55/*************************************************************************
56 *
57 */
58static void
59Dump
60TRIO_ARGS2((buffer, rc),
61 char *buffer,
62 int rc)
63{
64 if (rc < 0)
65 {
66 printf("Err = %d (%s), Pos = %d\n",
67 TRIO_ERROR_CODE(rc),
68 TRIO_ERROR_NAME(rc),
69 TRIO_ERROR_POSITION(rc));
70 }
71 else if (buffer)
72 printf("buffer[% 3d] = \"%s\"\n", rc, buffer);
73}
74
75/*************************************************************************
76 *
77 */
78static void
79Report0
80TRIO_ARGS2((file, line),
81 TRIO_CONST char *file,
82 int line)
83{
84 printf("Verification failed in %s:%d.\n", file, line);
85}
86
87/*************************************************************************
88 *
89 */
90static void
91Report
92TRIO_ARGS4((file, line, expected, got),
93 TRIO_CONST char *file,
94 int line,
95 TRIO_CONST char *expected,
96 TRIO_CONST char *got)
97{
98 Report0(file, line);
99 printf(" Expected \"%s\"\n", expected);
100 printf(" Got \"%s\"\n", got);
101}
102
103/*************************************************************************
104 *
105 */
106int
107Verify
108TRIO_VARGS5((file, line, result, fmt, va_alist),
109 TRIO_CONST char *file,
110 int line,
111 TRIO_CONST char *result,
112 TRIO_CONST char *fmt,
113 TRIO_VA_DECL)
114{
115 int rc;
116 va_list args;
117 char buffer[4096];
118
119 TRIO_VA_START(args, fmt);
120 rc = trio_vsnprintf(buffer, sizeof(buffer), fmt, args);
121 if (rc < 0)
122 Dump(buffer, rc);
123 TRIO_VA_END(args);
124
125 if (!trio_equal_case(result, buffer))
126 {
127 Report(file, line, result, buffer);
128 return 1;
129 }
130 return 0;
131}
132
133/*************************************************************************
134 *
135 */
136int
137VerifyReturnValues(TRIO_NOARGS)
138{
139 int nerrors = 0;
140 int rc;
141 int count;
142 char *expected;
143 char buffer[4096];
144 char result[4096];
145
146 rc = trio_sprintf(buffer, "%s%n", "0123456789", &count);
147 trio_sprintf(result, "%d %d %s", rc, count, buffer);
148 expected = "10 10 0123456789";
149 if (!trio_equal_case(result, expected))
150 {
151 nerrors++;
152 Report(__FILE__, __LINE__, expected, result);
153 }
154
155 rc = trio_snprintf(buffer, sizeof(buffer), "%s%n", "0123456789", &count);
156 trio_sprintf(result, "%d %d %s", rc, count, buffer);
157 expected = "10 10 0123456789";
158 if (!trio_equal_case(result, expected))
159 {
160 nerrors++;
161 Report(__FILE__, __LINE__, expected, result);
162 }
163
164 rc = trio_snprintf(buffer, 4, "%s%n", "0123456789", &count);
165 trio_sprintf(result, "%d %d %s", rc, count, buffer);
166 expected = "10 3 012";
167 if (!trio_equal_case(result, expected))
168 {
169 nerrors++;
170 Report(__FILE__, __LINE__, expected, result);
171 }
172
173 /* The output buffer contains the empty string */
174 rc = trio_snprintf(buffer, 1, "%s%n", "0123456789", &count);
175 trio_sprintf(result, "%d %d %s", rc, count, buffer);
176 expected = "10 0 ";
177 if (!trio_equal_case(result, expected))
178 {
179 nerrors++;
180 Report(__FILE__, __LINE__, expected, result);
181 }
182
183 /* The output buffer should be left untouched when max size is 0 */
184 trio_sprintf(buffer, "DO NOT TOUCH");
185 rc = trio_snprintf(buffer, 0, "%s%n", "0123456789", &count);
186 trio_sprintf(result, "%d %d %s", rc, count, buffer);
187 expected = "10 0 DO NOT TOUCH";
188 if (!trio_equal_case(result, expected))
189 {
190 nerrors++;
191 Report(__FILE__, __LINE__, expected, result);
192 }
193
194 return nerrors;
195}
196
197/*************************************************************************
198 *
199 */
200#define TEST_STRING "0123456789"
201
202int
203VerifyAllocate(TRIO_NOARGS)
204{
205 int nerrors = 0;
206#if TRIO_FEATURE_DYNAMICSTRING
207 int rc;
208 char *string;
209 int count;
210 int test_size = sizeof(TEST_STRING) - 1;
211
212 /* Allocate a string with the result */
213 rc = trio_asprintf(&string, "%s%n", TEST_STRING, &count);
214 if (rc < 0)
215 {
216 nerrors++;
217 Dump(string, rc);
218 }
219 else if (count != test_size)
220 {
221 nerrors++;
222 printf("Validation failed in %s:%d\n", __FILE__, __LINE__);
223 printf(" Expected %%n = %d\n", test_size);
224 printf(" Got %%n = %d\n", count);
225 }
226 else if (!trio_equal_case(string, TEST_STRING))
227 {
228 nerrors++;
229 Report(__FILE__, __LINE__, TEST_STRING, string);
230 }
231 if (string)
232 free(string);
233#endif
234
235 return nerrors;
236}
237
238
239/*************************************************************************
240 *
241 */
242int
243VerifyFormattingStrings(TRIO_NOARGS)
244{
245 int nerrors = 0;
246
247 /* Normal text */
248 nerrors += Verify(__FILE__, __LINE__, "Hello world",
249 "Hello world");
250 /* String */
251 nerrors += Verify(__FILE__, __LINE__, "Hello world",
252 "%s", "Hello world");
253
254 return nerrors;
255}
256
257/*************************************************************************
258 *
259 */
260int
261VerifyFormattingIntegers(TRIO_NOARGS)
262{
263 int nerrors = 0;
264 char buffer[256];
265
266 /* Integer */
267 nerrors += Verify(__FILE__, __LINE__, "Number 42",
268 "Number %d", 42);
269 nerrors += Verify(__FILE__, __LINE__, "Number -42",
270 "Number %d", -42);
271 nerrors += Verify(__FILE__, __LINE__, "Number 42",
272 "Number %ld", 42L);
273 nerrors += Verify(__FILE__, __LINE__, "Number -42",
274 "Number %ld", -42L);
275 /* Integer width */
276 nerrors += Verify(__FILE__, __LINE__, " 1234",
277 "%6d", 1234);
278 nerrors += Verify(__FILE__, __LINE__, " 1234",
279 "%*d", 6, 1234);
280 /* Integer width overrun */
281 nerrors += Verify(__FILE__, __LINE__, "123456",
282 "%4d", 123456);
283 /* Integer precision */
284 nerrors += Verify(__FILE__, __LINE__, "0012",
285 "%.4d", 12);
286 nerrors += Verify(__FILE__, __LINE__, "0012",
287 "%.*d", 4, 12);
288 nerrors += Verify(__FILE__, __LINE__, " 0012",
289 "%6.*d", 4, 12);
290 nerrors += Verify(__FILE__, __LINE__, " 0012",
291 "%*.*d", 6, 4, 12);
292 nerrors += Verify(__FILE__, __LINE__, " 0012",
293 "%*.*.*d", 6, 4, 2, 12);
294 nerrors += Verify(__FILE__, __LINE__, " 0012",
295 "%*.*.*i", 6, 4, 10, 12);
296 /* Integer sign, zero-padding, and width */
297 nerrors += Verify(__FILE__, __LINE__, "+01234",
298 "%+06d", 1234);
299 nerrors += Verify(__FILE__, __LINE__, " 01234",
300 "% 06d", 1234);
301 nerrors += Verify(__FILE__, __LINE__, "+01234",
302 "% +06d", 1234);
303 /* Integer adjust, zero-padding, and width */
304 nerrors += Verify(__FILE__, __LINE__, "12 ",
305 "%-08d", 12);
306 /* Integer zero-padding, width, and precision */
307 nerrors += Verify(__FILE__, __LINE__, " 000012",
308 "%08.6d", 12);
309 /* Integer base */
310 nerrors += Verify(__FILE__, __LINE__, "42",
311 "%u", 42);
312 nerrors += Verify(__FILE__, __LINE__, "-1",
313 "%d", -1);
314 nerrors += Verify(__FILE__, __LINE__, "52",
315 "%o", 42);
316 nerrors += Verify(__FILE__, __LINE__, "052",
317 "%#o", 42);
318 nerrors += Verify(__FILE__, __LINE__, "0",
319 "%#o", 0);
320 nerrors += Verify(__FILE__, __LINE__, "2a",
321 "%x", 42);
322 nerrors += Verify(__FILE__, __LINE__, "2A",
323 "%X", 42);
324 nerrors += Verify(__FILE__, __LINE__, "0x2a",
325 "%#x", 42);
326 nerrors += Verify(__FILE__, __LINE__, "0X2A",
327 "%#X", 42);
328 nerrors += Verify(__FILE__, __LINE__, "0x00c ",
329 "%-#6.3x", 12);
330 nerrors += Verify(__FILE__, __LINE__, "",
331 "%.d", 0);
332 nerrors += Verify(__FILE__, __LINE__, "",
333 "%#.d", 0);
334 nerrors += Verify(__FILE__, __LINE__, "42",
335 "%.d", 42);
336 nerrors += Verify(__FILE__, __LINE__, "",
337 "%.o", 0);
338 nerrors += Verify(__FILE__, __LINE__, " 0000",
339 "%8.4o", 0);
340 nerrors += Verify(__FILE__, __LINE__, " 0",
341 "%8o", 0);
342 nerrors += Verify(__FILE__, __LINE__, "00000000",
343 "%08o", 0);
344 nerrors += Verify(__FILE__, __LINE__, "0",
345 "%#.o", 0);
346 nerrors += Verify(__FILE__, __LINE__, "52",
347 "%.o", 42);
348 nerrors += Verify(__FILE__, __LINE__, "",
349 "%.x", 0);
350 nerrors += Verify(__FILE__, __LINE__, "",
351 "%#.x", 0);
352 nerrors += Verify(__FILE__, __LINE__, "2a",
353 "%.x", 42);
354 sprintf(buffer, "%u", UINT_MAX);
355 nerrors += Verify(__FILE__, __LINE__, buffer,
356 "%u", -1);
357 sprintf(buffer, "%x", UINT_MAX);
358 nerrors += Verify(__FILE__, __LINE__, buffer,
359 "%x", -1);
360
361 return nerrors;
362}
363
364/*************************************************************************
365 *
366 */
367int
368VerifyFormattingFloats(TRIO_NOARGS)
369{
370 int nerrors = 0;
371
372#if TRIO_FEATURE_FLOAT
373 /* Double */
374 nerrors += Verify(__FILE__, __LINE__, "3141.000000",
375 "%f", 3141.0);
376 nerrors += Verify(__FILE__, __LINE__, "3141.500000",
377 "%f", 3141.5);
378 nerrors += Verify(__FILE__, __LINE__, "3.141000e+03",
379 "%e", 3141.0);
380 nerrors += Verify(__FILE__, __LINE__, " -2.3420e-02",
381 "%16.4e", -2.342E-02);
382 nerrors += Verify(__FILE__, __LINE__, " -2.3420e-22",
383 "%16.4e", -2.342E-22);
384 nerrors += Verify(__FILE__, __LINE__, " 2.3420e-02",
385 "% 16.4e", 2.342E-02);
386 nerrors += Verify(__FILE__, __LINE__, " 2.3420e-02",
387 "% 1.4e", 2.342E-02);
388 nerrors += Verify(__FILE__, __LINE__, "3.141000E-44",
389 "%E", 3.141e-44);
390 nerrors += Verify(__FILE__, __LINE__, "0",
391 "%g", 0.0);
392 nerrors += Verify(__FILE__, __LINE__, "-0",
393 "%g", trio_nzero());
394 nerrors += Verify(__FILE__, __LINE__, "3141.5",
395 "%g", 3141.5);
396 nerrors += Verify(__FILE__, __LINE__, "3.1415E-06",
397 "%G", 3.1415e-6);
398 nerrors += Verify(__FILE__, __LINE__, "+3141.000000",
399 "%+f", 3141.0);
400 nerrors += Verify(__FILE__, __LINE__, "-3141.000000",
401 "%+f", -3141.0);
402 nerrors += Verify(__FILE__, __LINE__, "0.333333",
403 "%f", 1.0/3.0);
404 nerrors += Verify(__FILE__, __LINE__, "0.666667",
405 "%f", 2.0/3.0);
406 /* Beyond accuracy */
407 nerrors += Verify(__FILE__, __LINE__, "0.000000",
408 "%f", 1.234567890123456789e-20);
409# if defined(TRIO_BREESE)
410 nerrors += Verify(__FILE__, __LINE__, "1.3999999999999999111821580299875",
411 "%.32g", 1.4);
412 nerrors += Verify(__FILE__, __LINE__, "1.39999999999999991118215802998748",
413 "%.32f", 1.4);
414 nerrors += Verify(__FILE__, __LINE__, "1.3999999999999999111821580300",
415 "%.28f", 1.4);
416 nerrors += Verify(__FILE__, __LINE__, "1.399999999999999911182158",
417 "%.24f", 1.4);
418 nerrors += Verify(__FILE__, __LINE__, "1.39999999999999991",
419 "%.17f", 1.4);
420 nerrors += Verify(__FILE__, __LINE__, "1.40000000000000",
421 "%.14f", 1.4);
422 nerrors += Verify(__FILE__, __LINE__, "39413.800000000002910383045673370361",
423 "%.30f", 39413.80);
424# endif
425 /* 2^-1 + 2^-15 */
426 nerrors += Verify(__FILE__, __LINE__, "0.500030517578125",
427 "%.*g", DBL_DIG + 10, 0.500030517578125);
428 /* Double decimal point */
429 nerrors += Verify(__FILE__, __LINE__, "3141",
430 "%.0f", 3141.0);
431 nerrors += Verify(__FILE__, __LINE__, "3142",
432 "%.0f", 3141.5);
433 nerrors += Verify(__FILE__, __LINE__, "3141",
434 "%.f", 3141.0);
435 nerrors += Verify(__FILE__, __LINE__, "12",
436 "%.f", 12.34);
437 nerrors += Verify(__FILE__, __LINE__, "3141.000",
438 "%.3f", 3141.0);
439 nerrors += Verify(__FILE__, __LINE__, "3141.000000",
440 "%#f", 3141.0);
441 nerrors += Verify(__FILE__, __LINE__, "0.0000",
442 "%#.4f", 0.0);
443 nerrors += Verify(__FILE__, __LINE__, "0.000",
444 "%#.4g", 0.0);
445 nerrors += Verify(__FILE__, __LINE__, "0.001000",
446 "%#.4g", 1e-3);
447 nerrors += Verify(__FILE__, __LINE__, "3141.0000",
448 "%#.4f", 3141.0);
449 nerrors += Verify(__FILE__, __LINE__, "3141.",
450 "%#.0f", 3141.0);
451 nerrors += Verify(__FILE__, __LINE__, "3141.",
452 "%#.f", 3141.0);
453 nerrors += Verify(__FILE__, __LINE__, "11.0000",
454 "%#.4f", 11.0);
455 nerrors += Verify(__FILE__, __LINE__, "100.00",
456 "%.2f", 99.9999);
457 nerrors += Verify(__FILE__, __LINE__, "3e+03",
458 "%.e", 3141.0);
459 nerrors += Verify(__FILE__, __LINE__, "3.e+03",
460 "%#.e", 3141.0);
461 nerrors += Verify(__FILE__, __LINE__, "1.23457e+06",
462 "%g", 1234567.0);
463 nerrors += Verify(__FILE__, __LINE__, "1e+02",
464 "%.2g", 99.9999);
465 nerrors += Verify(__FILE__, __LINE__, "1.0e+02",
466 "%#.2g", 99.9999);
467 nerrors += Verify(__FILE__, __LINE__, "0.123",
468 "%0g", 0.123);
469 nerrors += Verify(__FILE__, __LINE__, "1.00e+00",
470 "%.2e", 0.9999);
471 nerrors += Verify(__FILE__, __LINE__, "1",
472 "%.2g", 0.9999);
473 nerrors += Verify(__FILE__, __LINE__, "2",
474 "%.0g", 1.5);
475 nerrors += Verify(__FILE__, __LINE__, "2",
476 "%.g", 1.5);
477 nerrors += Verify(__FILE__, __LINE__, "0.01",
478 "%.2g", 0.01);
479 nerrors += Verify(__FILE__, __LINE__, "0.010",
480 "%#.2g", 0.01);
481 nerrors += Verify(__FILE__, __LINE__, "1e-04",
482 "%5.g", 0.999999e-4);
483 /* Double width and precision */
484 nerrors += Verify(__FILE__, __LINE__, " 1e-05",
485 "%11.5g", 1e-5);
486 nerrors += Verify(__FILE__, __LINE__, " 0.0001",
487 "%11.5g", 1e-4);
488 nerrors += Verify(__FILE__, __LINE__, " 0.001",
489 "%11.5g", 1e-3);
490 nerrors += Verify(__FILE__, __LINE__, " 0.01",
491 "%11.5g", 1e-2);
492 nerrors += Verify(__FILE__, __LINE__, " 0.1",
493 "%11.5g", 1e-1);
494 nerrors += Verify(__FILE__, __LINE__, " 1",
495 "%11.5g", 1e0);
496 nerrors += Verify(__FILE__, __LINE__, " 10",
497 "%11.5g", 1e1);
498 nerrors += Verify(__FILE__, __LINE__, " 100",
499 "%11.5g", 1e2);
500 nerrors += Verify(__FILE__, __LINE__, " 1000",
501 "%11.5g", 1e3);
502 nerrors += Verify(__FILE__, __LINE__, " 10000",
503 "%11.5g", 1e4);
504 nerrors += Verify(__FILE__, __LINE__, " 1e+05",
505 "%11.5g", 1e5);
506 nerrors += Verify(__FILE__, __LINE__, " 9.9e-05",
507 "%11.2g", 0.99e-4);
508 nerrors += Verify(__FILE__, __LINE__, " 0.00099",
509 "%11.2g", 0.99e-3);
510 nerrors += Verify(__FILE__, __LINE__, " 0.0099",
511 "%11.2g", 0.99e-2);
512 nerrors += Verify(__FILE__, __LINE__, " 0.099",
513 "%11.2g", 0.99e-1);
514 nerrors += Verify(__FILE__, __LINE__, " 0.99",
515 "%11.2g", 0.99e0);
516 nerrors += Verify(__FILE__, __LINE__, " 9.9",
517 "%11.2g", 0.99e1);
518 nerrors += Verify(__FILE__, __LINE__, " 99",
519 "%11.2g", 0.99e2);
520 nerrors += Verify(__FILE__, __LINE__, " 9.9e+02",
521 "%11.2g", 0.99e3);
522 nerrors += Verify(__FILE__, __LINE__, " 9.9e+03",
523 "%11.2g", 0.99e4);
524 nerrors += Verify(__FILE__, __LINE__, " 9.9e+04",
525 "%11.2g", 0.99e5);
526 /* Double width, precision, and alternative */
527 nerrors += Verify(__FILE__, __LINE__, " 1.0000e-05",
528 "%#11.5g", 1e-5);
529 nerrors += Verify(__FILE__, __LINE__, " 0.00010000",
530 "%#11.5g", 1e-4);
531 nerrors += Verify(__FILE__, __LINE__, " 0.0010000",
532 "%#11.5g", 1e-3);
533 nerrors += Verify(__FILE__, __LINE__, " 0.0010000",
534 "%#11.5g", 0.999999e-3);
535 nerrors += Verify(__FILE__, __LINE__, " 0.010000",
536 "%#11.5g", 1e-2);
537 nerrors += Verify(__FILE__, __LINE__, " 0.010000",
538 "%#11.5g", 0.999999e-2);
539 nerrors += Verify(__FILE__, __LINE__, " 0.10000",
540 "%#11.5g", 1e-1);
541 nerrors += Verify(__FILE__, __LINE__, " 0.10000",
542 "%#11.5g", 0.999999e-1);
543 nerrors += Verify(__FILE__, __LINE__, " 1.0000",
544 "%#11.5g", 1e0);
545 nerrors += Verify(__FILE__, __LINE__, " 1.0000",
546 "%#11.5g", 0.999999e0);
547 nerrors += Verify(__FILE__, __LINE__, " 10.000",
548 "%#11.5g", 1e1);
549 nerrors += Verify(__FILE__, __LINE__, " 100.00",
550 "%#11.5g", 1e2);
551 nerrors += Verify(__FILE__, __LINE__, " 1000.0",
552 "%#11.5g", 1e3);
553 nerrors += Verify(__FILE__, __LINE__, " 10000.",
554 "%#11.5g", 1e4);
555 nerrors += Verify(__FILE__, __LINE__, " 1.0000e+05",
556 "%#11.5g", 1e5);
557 nerrors += Verify(__FILE__, __LINE__, " 9.9e-05",
558 "%#11.2g", 0.99e-4);
559 nerrors += Verify(__FILE__, __LINE__, " 0.00099",
560 "%#11.2g", 0.99e-3);
561 nerrors += Verify(__FILE__, __LINE__, " 0.0099",
562 "%#11.2g", 0.99e-2);
563 nerrors += Verify(__FILE__, __LINE__, " 0.099",
564 "%#11.2g", 0.99e-1);
565 nerrors += Verify(__FILE__, __LINE__, " 0.99",
566 "%#11.2g", 0.99e0);
567 nerrors += Verify(__FILE__, __LINE__, " 9.9",
568 "%#11.2g", 0.99e1);
569 nerrors += Verify(__FILE__, __LINE__, " 99.",
570 "%#11.2g", 0.99e2);
571 nerrors += Verify(__FILE__, __LINE__, " 9.9e+02",
572 "%#11.2g", 0.99e3);
573 nerrors += Verify(__FILE__, __LINE__, " 9.9e+03",
574 "%#11.2g", 0.99e4);
575 nerrors += Verify(__FILE__, __LINE__, " 9.9e+04",
576 "%#11.2g", 0.99e5);
577 /* Double width, precision, and zero padding */
578 nerrors += Verify(__FILE__, __LINE__, "00003.141500e+03",
579 "%016e", 3141.5);
580 nerrors += Verify(__FILE__, __LINE__, " 3.141500e+03",
581 "%16e", 3141.5);
582 nerrors += Verify(__FILE__, __LINE__, "3.141500e+03 ",
583 "%-16e", 3141.5);
584 nerrors += Verify(__FILE__, __LINE__, "03.142e+03",
585 "%010.3e", 3141.5);
586#if !defined(TRIO_COMPILER_ANCIENT)
587 /* Long double */
588 nerrors += Verify(__FILE__, __LINE__, "1.400000",
589 "%Lf", 1.4L);
590#endif
591
592 /* Special cases */
593 nerrors += Verify(__FILE__, __LINE__, "1.00",
594 "%.2f", 0.999);
595 nerrors += Verify(__FILE__, __LINE__, "100",
596 "%.0f", 99.9);
597 nerrors += Verify(__FILE__, __LINE__, "inf",
598 "%f", trio_pinf());
599 nerrors += Verify(__FILE__, __LINE__, "-inf",
600 "%f", trio_ninf());
601 nerrors += Verify(__FILE__, __LINE__, "INF",
602 "%F", trio_pinf());
603 nerrors += Verify(__FILE__, __LINE__, "-INF",
604 "%F", trio_ninf());
605 /* May fail if NaN is unsupported */
606 nerrors += Verify(__FILE__, __LINE__, "nan",
607 "%f", trio_nan());
608 nerrors += Verify(__FILE__, __LINE__, "NAN",
609 "%F", trio_nan());
610
611# if TRIO_FEATURE_HEXFLOAT
612 nerrors += Verify(__FILE__, __LINE__, "0x2.ap+4",
613 "%a", 42.0);
614 nerrors += Verify(__FILE__, __LINE__, "-0x2.ap+4",
615 "%a", -42.0);
616 nerrors += Verify(__FILE__, __LINE__, "0x1.8p+0",
617 "%a", 1.5);
618 nerrors += Verify(__FILE__, __LINE__, "0x1.6666666666666p+0",
619 "%a", 1.4);
620 nerrors += Verify(__FILE__, __LINE__, "0xc.45p+8",
621 "%a", 3141.0);
622 nerrors += Verify(__FILE__, __LINE__, "0XC.45P+8",
623 "%A", 3141.0);
624 nerrors += Verify(__FILE__, __LINE__, "0xb.351c434a98fa8p-148",
625 "%a", 3.141e-44);
626# endif
627
628#endif /* TRIO_FEATURE_FLOAT */
629
630 return nerrors;
631}
632
633/*************************************************************************
634 *
635 */
636#if TRIO_EXTENSION
637int number_writer(void *ref)
638{
639 const char *format;
640 int *data;
641
642 format = trio_get_format(ref);
643 if ((format) && trio_equal(format, "integer"))
644 {
645 data = trio_get_argument(ref);
646 if (data)
647 {
648 trio_print_int(ref, *data);
649 }
650 }
651 return 0;
652}
653
654#endif
655
656int
657VerifyFormattingUserDefined(TRIO_NOARGS)
658{
659 int nerrors = 0;
660#if TRIO_EXTENSION
661 void *number_handle;
662 int integer = 123;
663
664 number_handle = trio_register(number_writer, "number");
665
666 /* Old style */
667 nerrors += Verify(__FILE__, __LINE__, "123",
668 "%<number:integer>", &integer);
669
670 /* New style */
671 nerrors += Verify(__FILE__, __LINE__, "123",
672 "$<number:integer|%p>", &integer);
673 nerrors += Verify(__FILE__, __LINE__, "123",
674 "$<integer|%p%p>", number_handle, &integer);
675 nerrors += Verify(__FILE__, __LINE__, "$<integer|123",
676 "$<integer|%d", 123);
677 nerrors += Verify(__FILE__, __LINE__, "$integer|123>",
678 "$integer|%d>", 123);
679
680 trio_unregister(number_handle);
681#endif
682
683 return nerrors;
684}
685
686/*************************************************************************
687 *
688 */
689int
690VerifyFormattingRegression(TRIO_NOARGS)
691{
692 int nerrors = 0;
693
694#if TRIO_FEATURE_FLOAT
695 /* 0.6 was formatted as 0.600000e+00 */
696 nerrors += Verify(__FILE__, __LINE__, "5.000000e-01",
697 "%e", 0.5);
698 nerrors += Verify(__FILE__, __LINE__, "6.000000e-01",
699 "%e", 0.6);
700#endif
701
702 return nerrors;
703}
704
705/*************************************************************************
706 *
707 */
708int
709VerifyFormatting(TRIO_NOARGS)
710{
711 int nerrors = 0;
712#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
713 char buffer[256];
714#endif
715
716 nerrors += VerifyFormattingStrings();
717 nerrors += VerifyFormattingIntegers();
718 nerrors += VerifyFormattingFloats();
719 nerrors += VerifyFormattingRegression();
720 nerrors += VerifyFormattingUserDefined();
721
722 /* Pointer */
723 if (sizeof(void *) == 4)
724 {
725 nerrors += Verify(__FILE__, __LINE__, "Pointer 0x01234567",
726 "Pointer %p", 0x1234567);
727 }
728#if defined(TRIO_COMPILER_SUPPORTS_LL)
729 else if (sizeof(void *) == 8)
730 {
731 nerrors += Verify(__FILE__, __LINE__, "Pointer 0x0123456789012345",
732 "Pointer %p", 0x123456789012345LL);
733 }
734#endif
735 /* Nil pointer */
736 nerrors += Verify(__FILE__, __LINE__, "Pointer (nil)",
737 "Pointer %p", NULL);
738
739 /* Char width alignment */
740 nerrors += Verify(__FILE__, __LINE__, "Char X .",
741 "Char %-4c.", 'X');
742 /* String width / precision */
743 nerrors += Verify(__FILE__, __LINE__, " testing",
744 "%8s", "testing");
745 nerrors += Verify(__FILE__, __LINE__, "testing ",
746 "%-8s", "testing");
747 nerrors += Verify(__FILE__, __LINE__, " testing",
748 "%*s", 8, "testing");
749 nerrors += Verify(__FILE__, __LINE__, "testing ",
750 "%*s", -8, "testing");
751 nerrors += Verify(__FILE__, __LINE__, "test",
752 "%.4s", "testing");
753 nerrors += Verify(__FILE__, __LINE__, "test",
754 "%.*s", 4, "testing");
755 nerrors += Verify(__FILE__, __LINE__, "testing",
756 "%.*s", -4, "testing");
757#if TRIO_FEATURE_POSITIONAL
758 /* Positional */
759 nerrors += Verify(__FILE__, __LINE__, "222 111",
760 "%2$s %1$s", "111", "222");
761 nerrors += Verify(__FILE__, __LINE__, "123456 12345 0001234 00123",
762 "%4$d %3$*8$d %2$.*7$d %1$*6$.*5$d",
763 123, 1234, 12345, 123456, 5, 6, 7, 8);
764#endif
765
766#if TRIO_FEATURE_SIZE_T_UPPER
767 nerrors += Verify(__FILE__, __LINE__, "256",
768 "%Zd", sizeof(buffer));
769#endif
770
771#if TRIO_FEATURE_ERRNO
772 errno = EINTR;
773# if defined(TRIO_PLATFORM_LYNX)
774# if defined(PREDEF_STANDARD_POSIX_1996)
775 nerrors += Verify(__FILE__, __LINE__, "Interrupted system call ",
776 "%m");
777# else
778 nerrors += Verify(__FILE__, __LINE__, "System call interrupted",
779 "%m");
780# endif
781# else
782 nerrors += Verify(__FILE__, __LINE__, "Interrupted system call",
783 "%m");
784# endif
785#endif
786
787#if TRIO_FEATURE_QUAD
788# if defined(TRIO_COMPILER_SUPPORTS_LL)
789 /* This may fail if the preprocessor does not recognize LL */
790 nerrors += Verify(__FILE__, __LINE__, "42",
791 "%qd", 42LL);
792# endif
793#endif
794
795#if TRIO_FEATURE_SIZE_T
796 nerrors += Verify(__FILE__, __LINE__, "256",
797 "%zd", sizeof(buffer));
798#endif
799#if TRIO_FEATURE_PTRDIFF_T
800 nerrors += Verify(__FILE__, __LINE__, "42",
801 "%td", 42);
802#endif
803#if TRIO_FEATURE_INTMAX_T
804# if defined(TRIO_COMPILER_SUPPORTS_LL)
805 /* Some compilers may not handle the LL suffix correctly */
806 nerrors += Verify(__FILE__, __LINE__, "42",
807 "%jd", 42LL);
808# endif
809#endif
810
811#if TRIO_FEATURE_WIDECHAR
812 nerrors += Verify(__FILE__, __LINE__, "Hello World",
813 "%ls", L"Hello World");
814 nerrors += Verify(__FILE__, __LINE__, "\\aHello World",
815 "%#ls", L"\aHello World");
816 nerrors += Verify(__FILE__, __LINE__, "A",
817 "%lc", L'A');
818 nerrors += Verify(__FILE__, __LINE__, "\\a",
819 "%#lc", L'\a');
820#endif
821
822#if TRIO_FEATURE_FIXED_SIZE
823 nerrors += Verify(__FILE__, __LINE__, "42",
824 "%I8d", 42);
825 nerrors += Verify(__FILE__, __LINE__, "ffffffff",
826 "%I16x", -1);
827#endif
828
829#if TRIO_EXTENSION
830 nerrors += Verify(__FILE__, __LINE__, " 42 86",
831 "%!4d %d", 42, 86);
832 nerrors += Verify(__FILE__, __LINE__, "0042 0086",
833 "%!04d %d", 42, 86);
834 nerrors += Verify(__FILE__, __LINE__, "42",
835 "%&d", sizeof(long), 42L);
836 /* Non-printable string */
837 nerrors += Verify(__FILE__, __LINE__, "NonPrintable \\x01 \\a \\\\",
838 "NonPrintable %#s", "\01 \07 \\");
839 nerrors += Verify(__FILE__, __LINE__, "\\a \\b \\t \\n \\v \\f \\r",
840 "%#s", "\007 \010 \011 \012 \013 \014 \015");
841 /* Quote flag */
842 nerrors += Verify(__FILE__, __LINE__, "Another \"quoted\" string",
843 "Another %'s string", "quoted");
844 /* Integer base */
845 nerrors += Verify(__FILE__, __LINE__, "Number 42 == 1120 (base 3)",
846 "Number %d == %..3i (base 3)", 42, 42);
847 /* Integer base (specifier base must be used instead of base modifier) */
848 nerrors += Verify(__FILE__, __LINE__, "42",
849 "%..3d", 42);
850 nerrors += Verify(__FILE__, __LINE__, "52",
851 "%..3o", 42);
852 nerrors += Verify(__FILE__, __LINE__, "2a",
853 "%..3x", 42);
854 /* Integer thousand separator */
855 nerrors += Verify(__FILE__, __LINE__, "Number 100",
856 "Number %'d", 100);
857 nerrors += Verify(__FILE__, __LINE__, "Number 1,000,000",
858 "Number %'d", 1000000);
859# if TRIO_FEATURE_FLOAT
860 /* Float thousand separator */
861 nerrors += Verify(__FILE__, __LINE__, "31,415.200000",
862 "%'f", 31415.2);
863 nerrors += Verify(__FILE__, __LINE__, "1,000,000.000000",
864 "%'f", 1000000.0);
865 /* Rounding modifier */
866 nerrors += Verify(__FILE__, __LINE__, "1.4",
867 "%.32Rf", 1.4);
868 nerrors += Verify(__FILE__, __LINE__, "1.4",
869 "%.17Rf", 1.4);
870 nerrors += Verify(__FILE__, __LINE__, "39413.8",
871 "%.30Rf", 39413.80);
872# if !defined(TRIO_COMPILER_ANCIENT)
873 /* Long double */
874 nerrors += Verify(__FILE__, __LINE__, "1.4",
875 "%RLf", 1.4L);
876 nerrors += Verify(__FILE__, __LINE__, "1.4",
877 "%.30RLf", 1.4L);
878# endif
879# endif
880#endif
881
882#if defined(TRIO_BREESE)
883 /*
884 * These results depends on issues beyond our control. For example,
885 * the accuracy of floating-point numbers depends on the underlying
886 * floating-point hardware (e.g. whether IEEE 754 double or extended-
887 * double format is used).
888 *
889 * These tests are therefore not part of the normal regression test,
890 * but we keep them here for development purposes.
891 */
892 nerrors += Verify(__FILE__, __LINE__, "123456789012345680868.000000",
893 "%f", 1.234567890123456789e20);
894 nerrors += Verify(__FILE__, __LINE__, "1.23456789012345677901e-20",
895 "%.20e", 1.2345678901234567e-20);
896 nerrors += Verify(__FILE__, __LINE__, "0.666666666666666629659233",
897 "%.*g", DBL_DIG + 10, 2.0/3.0);
898 nerrors += Verify(__FILE__, __LINE__, "123456789012345700000",
899 "%Rf", 1.234567890123456789e20);
900# if !defined(TRIO_COMPILER_ANCIENT)
901 nerrors += Verify(__FILE__, __LINE__, "0.666666666666666667",
902 "%RLf", (2.0L/3.0L));
903 nerrors += Verify(__FILE__, __LINE__, "0.666666666666666667",
904 "%.30RLf", (2.0L/3.0L));
905# endif
906#endif
907
908 return nerrors;
909}
910
911/*************************************************************************
912 *
913 */
914int
915VerifyErrors(TRIO_NOARGS)
916{
917 char buffer[512];
918 int rc;
919 int nerrors = 0;
920
921 /* Error: Invalid argument 1 */
922 rc = trio_snprintf(buffer, sizeof(buffer), "%d %r", 42, "text");
923#if TRIO_FEATURE_ERRORCODE
924# if TRIO_FEATURE_STRERR
925 trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
926 TRIO_ERROR_CODE(rc),
927 TRIO_ERROR_NAME(rc),
928 TRIO_ERROR_POSITION(rc));
929 nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 5",
930 "%s", buffer);
931# else
932 trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
933 TRIO_ERROR_CODE(rc),
934 TRIO_ERROR_POSITION(rc));
935 nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 5",
936 "%s", buffer);
937# endif
938#else
939 nerrors += (rc != -1);
940#endif
941
942 /* Error: Invalid argument 2 */
943 rc = trio_snprintf(buffer, sizeof(buffer), "%#");
944#if TRIO_FEATURE_ERRORCODE
945# if TRIO_FEATURE_STRERR
946 trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
947 TRIO_ERROR_CODE(rc),
948 TRIO_ERROR_NAME(rc),
949 TRIO_ERROR_POSITION(rc));
950 nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 3",
951 "%s", buffer);
952# else
953 trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
954 TRIO_ERROR_CODE(rc),
955 TRIO_ERROR_POSITION(rc));
956 nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 3",
957 "%s", buffer);
958# endif
959#else
960 nerrors += (rc != -1);
961#endif
962
963 /* Error: Invalid argument 3 */
964 rc = trio_snprintf(buffer, sizeof(buffer), "%hhhd", 42);
965#if TRIO_FEATURE_ERRORCODE
966# if TRIO_FEATURE_STRERR
967 trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
968 TRIO_ERROR_CODE(rc),
969 TRIO_ERROR_NAME(rc),
970 TRIO_ERROR_POSITION(rc));
971 nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 4",
972 "%s", buffer);
973# else
974 trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
975 TRIO_ERROR_CODE(rc),
976 TRIO_ERROR_POSITION(rc));
977 nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 4",
978 "%s", buffer);
979# endif
980#else
981 nerrors += (rc != -1);
982#endif
983
984 /* Error: Double reference */
985 rc = trio_snprintf(buffer, sizeof(buffer), "hello %1$d %1$d", 31, 32);
986#if TRIO_FEATURE_ERRORCODE
987# if TRIO_FEATURE_STRERR
988 trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
989 TRIO_ERROR_CODE(rc),
990 TRIO_ERROR_NAME(rc),
991 TRIO_ERROR_POSITION(rc));
992# if TRIO_UNIX98
993 nerrors += Verify(__FILE__, __LINE__, "Err = 4 (Double reference), Pos = 0",
994 "%s", buffer);
995# else
996 nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 9",
997 "%s", buffer);
998# endif
999# else
1000 trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
1001 TRIO_ERROR_CODE(rc),
1002 TRIO_ERROR_POSITION(rc));
1003# if TRIO_UNIX98
1004 nerrors += Verify(__FILE__, __LINE__, "Err = 4, Pos = 0",
1005 "%s", buffer);
1006# else
1007 nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 9",
1008 "%s", buffer);
1009# endif
1010# endif
1011#else
1012 nerrors += (rc != -1);
1013#endif
1014
1015 /* Error: Reference gap */
1016 rc = trio_snprintf(buffer, sizeof(buffer), "%3$d %1$d", 31, 32, 33);
1017#if TRIO_FEATURE_ERRORCODE
1018# if TRIO_FEATURE_STRERR
1019 trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
1020 TRIO_ERROR_CODE(rc),
1021 TRIO_ERROR_NAME(rc),
1022 TRIO_ERROR_POSITION(rc));
1023# if TRIO_UNIX98
1024 nerrors += Verify(__FILE__, __LINE__, "Err = 5 (Reference gap), Pos = 1",
1025 "%s", buffer);
1026# else
1027 nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 3",
1028 "%s", buffer);
1029# endif
1030# else
1031 trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
1032 TRIO_ERROR_CODE(rc),
1033 TRIO_ERROR_POSITION(rc));
1034# if TRIO_UNIX98
1035 nerrors += Verify(__FILE__, __LINE__, "Err = 5, Pos = 1",
1036 "%s", buffer);
1037# else
1038 nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 3",
1039 "%s", buffer);
1040# endif
1041# endif
1042#else
1043 nerrors += (rc != -1);
1044#endif
1045
1046 return nerrors;
1047}
1048
1049/*************************************************************************
1050 *
1051 */
1052#if TRIO_FEATURE_SCANF
1053int
1054VerifyScanningOneInteger
1055TRIO_ARGS5((file, line, expected, format, original),
1056 TRIO_CONST char *file,
1057 int line,
1058 TRIO_CONST char *expected,
1059 TRIO_CONST char *format,
1060 int original)
1061{
1062 int number;
1063 char data[512];
1064
1065 trio_snprintf(data, sizeof(data), format, original);
1066 trio_sscanf(data, format, &number);
1067 return Verify(file, line, expected, format, number);
1068}
1069
1070int
1071VerifyScanningIntegers(TRIO_NOARGS)
1072{
1073 int nerrors = 0;
1074
1075 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
1076 "%i", 42);
1077 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
1078 "%d", 42);
1079 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "-42",
1080 "%d", -42);
1081 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "2147483647",
1082 "%d", 2147483647);
1083 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
1084 "%u", 42);
1085 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "2a",
1086 "%x", 42);
1087 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "52",
1088 "%o", 42);
1089 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "101010",
1090 "%..2i", 42);
1091 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "0x2a",
1092 "%#x", 42);
1093 nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "052",
1094 "%#o", 42);
1095
1096 return nerrors;
1097}
1098#endif
1099
1100/*************************************************************************
1101 *
1102 */
1103#if TRIO_FEATURE_SCANF
1104int
1105VerifyScanningOneFloat
1106TRIO_ARGS5((file, line, expected, format, original),
1107 TRIO_CONST char *file,
1108 int line,
1109 TRIO_CONST char *expected,
1110 TRIO_CONST char *format,
1111 double original)
1112{
1113 float number;
1114 char data[512];
1115
1116 trio_snprintf(data, sizeof(data), format, original);
1117 trio_sscanf(data, format, &number);
1118 return Verify(file, line, expected, format, number);
1119}
1120
1121int
1122VerifyScanningOneDouble
1123TRIO_ARGS5((file, line, expected, format, original),
1124 TRIO_CONST char *file,
1125 int line,
1126 TRIO_CONST char *expected,
1127 TRIO_CONST char *format,
1128 double original)
1129{
1130 double number;
1131 char data[512];
1132
1133 trio_snprintf(data, sizeof(data), format, original);
1134 trio_sscanf(data, format, &number);
1135 return Verify(file, line, expected, format, number);
1136}
1137
1138int
1139VerifyScanningFloats(TRIO_NOARGS)
1140{
1141 int nerrors = 0;
1142
1143#if TRIO_FEATURE_FLOAT
1144 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "42.000000",
1145 "%f", 42.0);
1146 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "-42.000000",
1147 "%f", -42.0);
1148 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "4.200000e+01",
1149 "%e", 42.0);
1150 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "4.200000E+01",
1151 "%E", 42.0);
1152 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "42",
1153 "%g", 42.0);
1154 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e+06",
1155 "%g", 1234567.0);
1156 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e-06",
1157 "%g", 1.234567e-6);
1158 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457E+06",
1159 "%G", 1234567.0);
1160 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234567e+06",
1161 "%12e", 1234567.0);
1162 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234500e+00",
1163 "%6e", 1234567.0);
1164 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234567e+06",
1165 "%.6e", 1234567.0);
1166 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.2345670000e+06",
1167 "%.10e", 1234567.0);
1168 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e+06",
1169 "%.6g", 1234567.0);
1170 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1234567",
1171 "%.10g", 1234567.0);
1172# if TRIO_FEATURE_HEXFLOAT
1173 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0x2.ap+4",
1174 "%a", 42.0);
1175 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0x1.2d687p+20",
1176 "%a", 1234567.0);
1177 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0X1.2D687P+20",
1178 "%A", 1234567.0);
1179# endif
1180 nerrors += VerifyScanningOneDouble(__FILE__, __LINE__, "1.79769e+308",
1181 "%lg", 1.79769e+308);
1182 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "nan",
1183 "%f", trio_nan());
1184 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "NAN",
1185 "%F", trio_nan());
1186 nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "-inf",
1187 "%f", trio_ninf());
1188#endif
1189
1190 return nerrors;
1191}
1192#endif
1193
1194/*************************************************************************
1195 *
1196 */
1197#if TRIO_FEATURE_SCANF
1198int
1199VerifyScanningOneString
1200TRIO_ARGS5((file, line, expected, format, original),
1201 TRIO_CONST char *file,
1202 int line,
1203 TRIO_CONST char *expected,
1204 TRIO_CONST char *format,
1205 char *original)
1206{
1207 char string[512];
1208 char data[512];
1209
1210 trio_snprintf(data, sizeof(data), "%s", original);
1211 string[0] = 0;
1212 trio_sscanf(data, format, string);
1213 return Verify(file, line, expected, "%s", string);
1214}
1215
1216int
1217VerifyScanningStrings(TRIO_NOARGS)
1218{
1219 int nerrors = 0;
1220
1221 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "",
1222 "hello", "hello");
1223 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "",
1224 "", "");
1225 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
1226 "%s", "hello");
1227 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
1228 "%s", "hello world");
1229 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello world",
1230 "%[^\n]", "hello world");
1231 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "(nil)",
1232 "%s", NULL);
1233 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
1234 "%20s", "hello");
1235 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "he",
1236 "%2s", "hello");
1237 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "ab",
1238 "%[ab]", "abcba");
1239 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
1240 "%[abc]", "abcba");
1241 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
1242 "%[a-c]", "abcba");
1243#if TRIO_EXTENSION
1244 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
1245 "%[[:alpha:]]", "abcba");
1246#endif
1247 nerrors += VerifyScanningOneString(__FILE__, __LINE__, "ba",
1248 "%*[ab]c%[^\n]", "abcba");
1249
1250 return nerrors;
1251}
1252#endif
1253
1254/*************************************************************************
1255 *
1256 */
1257#if TRIO_FEATURE_SCANF
1258int
1259VerifyScanningRegression(TRIO_NOARGS)
1260{
1261 int nerrors = 0;
1262 int rc;
1263#if TRIO_FEATURE_FLOAT
1264 int offset;
1265 double dnumber;
1266# if defined(TRIO_BREESE)
1267 trio_long_double_t ldnumber;
1268# endif
1269#endif
1270 long lnumber;
1271 int number;
1272 char ch;
1273 char buffer[4096];
1274 FILE *stream;
1275
1276#if TRIO_FEATURE_FLOAT
1277 rc = trio_sscanf("1.5", "%lf%n", &dnumber, &offset);
1278 nerrors += Verify(__FILE__, __LINE__, "1 3 1.500000",
1279 "%d %d %f", rc, offset, dnumber);
1280#endif
1281 rc = trio_sscanf("q 123", "%c%ld", &ch, &lnumber);
1282 nerrors += Verify(__FILE__, __LINE__, "q 123",
1283 "%c %ld", ch, lnumber);
1284 rc = trio_sscanf("abc", "%*s%n", &number);
1285 nerrors += Verify(__FILE__, __LINE__, "0 3",
1286 "%d %d", rc, number);
1287 rc = trio_sscanf("abc def", "%*s%n", &number);
1288 nerrors += Verify(__FILE__, __LINE__, "0 3",
1289 "%d %d", rc, number);
1290#if TRIO_FEATURE_FLOAT
1291 rc = trio_sscanf("0.141882295971771490", "%lf", &dnumber);
1292 /* FIXME: Verify */
1293#endif
1294 number = 33;
1295 rc = trio_sscanf("total 1", "total %d", &number);
1296 nerrors += Verify(__FILE__, __LINE__, "1 1",
1297 "%d %d", rc, number);
1298#if defined(TRIO_BREESE)
1299# if TRIO_FEATURE_FLOAT
1300 nerrors += Verify(__FILE__, __LINE__, "1 0.141882295971771488",
1301 "%d %.18f", rc, dnumber);
1302 rc = trio_sscanf("0.141882295971771490", "%Lf", &ldnumber);
1303 nerrors += Verify(__FILE__, __LINE__, "1 0.141882295971771490",
1304 "%d %.18Lf", rc, ldnumber);
1305# endif
1306#endif
1307#if TRIO_FEATURE_FLOAT
1308 rc = trio_sscanf("1.e-6", "%lg", &dnumber);
1309 nerrors += Verify(__FILE__, __LINE__, "1e-06",
1310 "%g", dnumber);
1311 rc = trio_sscanf("1e-6", "%lg", &dnumber);
1312 nerrors += Verify(__FILE__, __LINE__, "1e-06",
1313 "%g", dnumber);
1314#endif
1315
1316 /* Do not overwrite result on matching error */
1317 ch = 'a';
1318 rc = trio_sscanf("0123456789", "%1[c]", &ch);
1319 nerrors += Verify(__FILE__, __LINE__, "a",
1320 "%c", ch);
1321
1322 /* Scan plus prefix for unsigned integer */
1323 rc = trio_sscanf("+42", "%u", &number);
1324 nerrors += Verify(__FILE__, __LINE__, "1 42",
1325 "%d %u", rc, number);
1326
1327 /* Scan minus prefix even for unsigned integer */
1328 rc = trio_sscanf("-42", "%u", &number);
1329 sprintf(buffer, "1 %u", -42U);
1330 nerrors += Verify(__FILE__, __LINE__, buffer,
1331 "%d %u", rc, number);
1332
1333 /* A scangroup match failure should not bind its argument,
1334 * i.e., it shouldn't match the empty string. */
1335 sprintf(buffer, "SPQR");
1336 rc = trio_sscanf("asdf", "%[c]", buffer);
1337 nerrors += Verify(__FILE__, __LINE__, "0 SPQR",
1338 "%d %s", rc, buffer);
1339
1340 /* Even whitespace scanning shouldn't try to read past EOF */
1341 stream = tmpfile();
1342 trio_fprintf(stream, "");
1343 rewind(stream);
1344 rc = trio_fscanf(stream, " ");
1345 nerrors += Verify(__FILE__, __LINE__, "0",
1346 "%d", rc);
1347 fclose(stream);
1348
1349 /* Idem, after a succesfull read */
1350 stream = tmpfile();
1351 trio_fprintf(stream, "123");
1352 rewind(stream);
1353 rc = trio_fscanf(stream, "%i ", &number);
1354 nerrors += Verify(__FILE__, __LINE__, "1 123",
1355 "%d %i", rc, number);
1356 fclose(stream);
1357
1358 /* The scanner should unget its read-ahead char */
1359 stream = tmpfile();
1360 trio_fprintf(stream, "123");
1361 rewind(stream);
1362 trio_fscanf(stream, "%*c");
1363 trio_fscanf(stream, "%c", &ch);
1364 nerrors += Verify(__FILE__, __LINE__, "2",
1365 "%c", ch);
1366 fclose(stream);
1367
1368 return nerrors;
1369}
1370#endif
1371
1372/*************************************************************************
1373 *
1374 */
1375int
1376VerifyScanning(TRIO_NOARGS)
1377{
1378 int nerrors = 0;
1379#if TRIO_FEATURE_SCANF
1380 nerrors += VerifyScanningIntegers();
1381 nerrors += VerifyScanningFloats();
1382 nerrors += VerifyScanningStrings();
1383 nerrors += VerifyScanningRegression();
1384#endif
1385 return nerrors;
1386}
1387
1388/*************************************************************************
1389 *
1390 */
1391int
1392VerifyStrings(TRIO_NOARGS)
1393{
1394 int nerrors = 0;
1395#if !defined(TRIO_MINIMAL)
1396 char buffer[512];
1397#if TRIO_FEATURE_FLOAT
1398 double dnumber;
1399 float fnumber;
1400#endif
1401 char *end;
1402
1403 /* Comparison */
1404 trio_copy(buffer, "Find me now");
1405 if (trio_length(buffer) != sizeof("Find me now") - 1) {
1406 nerrors++;
1407 Report0(__FILE__, __LINE__);
1408 }
1409 if (!trio_equal(buffer, "Find me now")) {
1410 nerrors++;
1411 Report0(__FILE__, __LINE__);
1412 }
1413 if (!trio_equal_case(buffer, "Find me now")) {
1414 nerrors++;
1415 Report0(__FILE__, __LINE__);
1416 }
1417 if (trio_equal_case(buffer, "FIND ME NOW")) {
1418 nerrors++;
1419 Report0(__FILE__, __LINE__);
1420 }
1421 if (!trio_equal_max(buffer, sizeof("Find me") - 1, "Find ME")) {
1422 nerrors++;
1423 Report0(__FILE__, __LINE__);
1424 }
1425 if (!trio_contains(buffer, "me")) {
1426 nerrors++;
1427 Report0(__FILE__, __LINE__);
1428 }
1429 if (trio_contains(buffer, "and me")) {
1430 nerrors++;
1431 Report0(__FILE__, __LINE__);
1432 }
1433 if (trio_substring(buffer, "me") == NULL) {
1434 nerrors++;
1435 Report0(__FILE__, __LINE__);
1436 }
1437 if (trio_substring_max(buffer, 4, "me") != NULL) {
1438 nerrors++;
1439 Report0(__FILE__, __LINE__);
1440 }
1441 if (!trio_match(buffer, "* me *")) {
1442 nerrors++;
1443 Report0(__FILE__, __LINE__);
1444 }
1445 if (trio_match_case(buffer, "* ME *")) {
1446 nerrors++;
1447 Report0(__FILE__, __LINE__);
1448 }
1449 if (trio_index(buffer, 'n') == NULL) {
1450 nerrors++;
1451 Report0(__FILE__, __LINE__);
1452 }
1453 if (trio_index(buffer, '_') != NULL) {
1454 nerrors++;
1455 Report0(__FILE__, __LINE__);
1456 }
1457 if (trio_index_last(buffer, 'n') == NULL) {
1458 nerrors++;
1459 Report0(__FILE__, __LINE__);
1460 }
1461
1462 /* Append */
1463 trio_copy(buffer, "Find me now");
1464 if (!trio_append(buffer, " and again")) {
1465 nerrors++;
1466 Report0(__FILE__, __LINE__);
1467 }
1468 if (!trio_equal(buffer, "Find me now and again")) {
1469 nerrors++;
1470 Report0(__FILE__, __LINE__);
1471 }
1472 if (!trio_append_max(buffer, 0, "should not appear")) {
1473 nerrors++;
1474 Report0(__FILE__, __LINE__);
1475 }
1476 if (!trio_equal(buffer, "Find me now and again")) {
1477 nerrors++;
1478 Report0(__FILE__, __LINE__);
1479 }
1480
1481 /* To upper/lower */
1482 trio_copy(buffer, "Find me now");
1483 trio_upper(buffer);
1484 if (!trio_equal_case(buffer, "FIND ME NOW")) {
1485 nerrors++;
1486 Report0(__FILE__, __LINE__);
1487 }
1488 trio_lower(buffer);
1489 if (!trio_equal_case(buffer, "find me now")) {
1490 nerrors++;
1491 Report0(__FILE__, __LINE__);
1492 }
1493
1494#if TRIO_FEATURE_FLOAT
1495 /* Double conversion */
1496 trio_copy(buffer, "3.1415");
1497 dnumber = trio_to_double(buffer, NULL);
1498 if (!DOUBLE_EQUAL(dnumber, 3.1415)) {
1499 nerrors++;
1500 Report0(__FILE__, __LINE__);
1501 }
1502 fnumber = trio_to_float(buffer, NULL);
1503 if (!FLOAT_EQUAL(fnumber, 3.1415)) {
1504 nerrors++;
1505 Report0(__FILE__, __LINE__);
1506 }
1507#endif
1508
1509 /* Long conversion */
1510 trio_copy(buffer, "3.1415");
1511 if (trio_to_long(buffer, NULL, 10) != 3L) {
1512 nerrors++;
1513 Report0(__FILE__, __LINE__);
1514 }
1515 if (trio_to_long(buffer, NULL, 4) != 3L) {
1516 nerrors++;
1517 Report0(__FILE__, __LINE__);
1518 }
1519 trio_to_long(buffer, &end, 2);
1520 if (end != buffer) {
1521 nerrors++;
1522 Report0(__FILE__, __LINE__);
1523 }
1524
1525#endif /* !defined(TRIO_MINIMAL) */
1526 return nerrors;
1527}
1528
1529/*************************************************************************
1530 *
1531 */
1532int
1533VerifyDynamicStrings(TRIO_NOARGS)
1534{
1535 int nerrors = 0;
1536#if !defined(TRIO_MINIMAL)
1537 trio_string_t *string;
1538 const char no_terminate[5] = { 'h', 'e', 'l', 'l', 'o' };
1539
1540 string = trio_xstring_duplicate("Find me now");
1541 if (string == NULL) {
1542 nerrors++;
1543 goto error;
1544 }
1545 if (!trio_xstring_equal(string, "FIND ME NOW"))
1546 nerrors++;
1547 if (!trio_xstring_append(string, " and again") ||
1548 !trio_xstring_equal(string, "FIND ME NOW AND AGAIN"))
1549 nerrors++;
1550 if (!trio_xstring_contains(string, "me"))
1551 nerrors++;
1552 if (trio_xstring_contains(string, "ME"))
1553 nerrors++;
1554 if (!trio_xstring_match(string, "* me *"))
1555 nerrors++;
1556 if (trio_xstring_match_case(string, "* ME *"))
1557 nerrors++;
1558 if (!trio_xstring_append_max(string, no_terminate, 5) ||
1559 !trio_xstring_equal(string, "FIND ME NOW AND AGAINhello"))
1560 nerrors++;
1561
1562 error:
1563 if (string)
1564 trio_string_destroy(string);
1565
1566#endif /* !defined(TRIO_MINIMAL) */
1567 return nerrors;
1568}
1569
1570/*************************************************************************
1571 *
1572 */
1573int
1574VerifyNaN(TRIO_NOARGS)
1575{
1576 double ninf_number = trio_ninf();
1577 double pinf_number = trio_pinf();
1578 double nan_number = trio_nan();
1579 int nerrors = 0;
1580
1581 nerrors += Verify(__FILE__, __LINE__, "-1",
1582 "%d", trio_isinf(ninf_number));
1583 nerrors += Verify(__FILE__, __LINE__, "0",
1584 "%d", trio_isinf(42.0));
1585 nerrors += Verify(__FILE__, __LINE__, "1",
1586 "%d", trio_isinf(pinf_number));
1587 nerrors += Verify(__FILE__, __LINE__, "1",
1588 "%d", trio_isnan(nan_number));
1589 nerrors += Verify(__FILE__, __LINE__, "0",
1590 "%d", trio_isnan(42.0));
1591
1592 return nerrors;
1593}
1594
1595/*************************************************************************
1596 *
1597 */
1598int
1599main(TRIO_NOARGS)
1600{
1601 int nerrors = 0;
1602
1603 printf("%s\n", rcsid);
1604
1605#if TRIO_EXTENSION
1606 /* Override system locale settings */
1607 trio_locale_set_decimal_point(".");
1608 trio_locale_set_thousand_separator(",");
1609 trio_locale_set_grouping("\3");
1610#endif
1611
1612 printf("Verifying strings\n");
1613 nerrors += VerifyStrings();
1614
1615 printf("Verifying dynamic strings\n");
1616 nerrors += VerifyDynamicStrings();
1617
1618 printf("Verifying special quantities\n");
1619 nerrors += VerifyNaN();
1620
1621 printf("Verifying formatting\n");
1622 nerrors += VerifyFormatting();
1623
1624 printf("Verifying scanning\n");
1625 nerrors += VerifyScanning();
1626
1627 printf("Verifying return values\n");
1628 nerrors += VerifyErrors();
1629 nerrors += VerifyReturnValues();
1630
1631 printf("Verifying allocation\n");
1632 nerrors += VerifyAllocate();
1633
1634 if (nerrors == 0)
1635 printf("Regression test succeeded\n");
1636 else
1637 printf("Regression test failed in %d instance(s)\n", nerrors);
1638
1639 return nerrors ? 1 : 0;
1640}
diff --git a/gs/trio/strio.h b/gs/trio/strio.h
new file mode 100644
index 000000000..d90cfcfd8
--- /dev/null
+++ b/gs/trio/strio.h
@@ -0,0 +1,73 @@
1/*************************************************************************
2 *
3 * $Id: strio.h,v 1.11 2001/12/27 17:29:20 breese Exp $
4 *
5 * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************
17 *
18 * This maintains backwards compatibility with the strio functions.
19 *
20 ************************************************************************/
21
22#ifndef TRIO_STRIO_H
23#define TRIO_STRIO_H
24
25#if !(defined(DEBUG) || defined(NDEBUG))
26# define NDEBUG
27#endif
28#include "triostr.h"
29
30enum {
31 STRIO_HASH_NONE = TRIO_HASH_NONE,
32 STRIO_HASH_PLAIN = TRIO_HASH_PLAIN,
33 STRIO_HASH_TWOSIGNED = TRIO_HASH_TWOSIGNED
34};
35
36#define StrAlloc(n) trio_create(n)
37#define StrAppend(x,y) ((void)trio_append((x),(y)),(x))
38#define StrAppendMax(x,n,y) ((void)trio_append_max((x),(n),(y)),(x))
39#define StrContains(x,y) trio_contains((x),(y))
40#define StrCopy(x,y) ((void)trio_copy((x),(y)),(x))
41#define StrCopyMax(x,n,y) ((void)trio_copy_max((x),(n),(y)),(x))
42#define StrDuplicate(x) trio_duplicate(x)
43#define StrDuplicateMax(x,n) trio_duplicate((x),(n))
44#define StrEqual(x,y) trio_equal((x),(y))
45#define StrEqualCase(x,y) trio_equal_case((x),(y))
46#define StrEqualCaseMax(x,n,y) trio_equal_case_max((x),(n),(y))
47#define StrEqualLocale(x,y) trio_equal_locale((x),(y))
48#define StrEqualMax(x,n,y) trio_equal_max((x),(n),(y))
49#define StrError(n) trio_error(n)
50#define StrFree(x) trio_destroy(x)
51#define StrFormat trio_sprintf
52#define StrFormatAlloc trio_aprintf
53#define StrFormatAppendMax trio_snprintfcat
54#define StrFormatDateMax(x,n,y,t) trio_format_date_max((x),(n),(y),(t))
55#define StrFormatMax trio_snprintf
56#define StrHash(x,n) trio_hash((x),(n))
57#define StrIndex(x,y) trio_index((x),(y))
58#define StrIndexLast(x,y) trio_index_last((x),(y))
59#define StrLength(x) trio_length((x))
60#define StrMatch(x,y) trio_match((x),(y))
61#define StrMatchCase(x,y) trio_match_case((x),(y))
62#define StrScan trio_sscanf
63#define StrSpanFunction(x,f) trio_span_function((x),(f))
64#define StrSubstring(x,y) trio_substring((x),(y))
65#define StrSubstringMax(x,n,y) trio_substring_max((x),(n),(y))
66#define StrToDouble(x,y) trio_to_double((x),(y))
67#define StrToFloat(x,y) trio_to_float((x),(y))
68#define StrTokenize(x,y) trio_tokenize((x),(y))
69#define StrToLong(x,y,n) trio_to_long((x),(y),(n))
70#define StrToUnsignedLong(x,y,n) trio_to_unsigned_long((x),(n),(y))
71#define StrToUpper(x) trio_upper(x)
72
73#endif /* TRIO_STRIO_H */
diff --git a/gs/trio/trio.c b/gs/trio/trio.c
new file mode 100644
index 000000000..1393d9c79
--- /dev/null
+++ b/gs/trio/trio.c
@@ -0,0 +1,7771 @@
1/*************************************************************************
2 *
3 * $Id: trio.c,v 1.129 2009/09/20 11:37:15 breese Exp $
4 *
5 * Copyright (C) 1998, 2009 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 *************************************************************************
17 *
18 * A note to trio contributors:
19 *
20 * Avoid heap allocation at all costs to ensure that the trio functions
21 * are async-safe. The exceptions are the printf/fprintf functions, which
22 * uses fputc, and the asprintf functions and the <alloc> modifier, which
23 * by design are required to allocate form the heap.
24 *
25 ************************************************************************/
26
27/*
28 * TODO:
29 * - Scan is probably too permissive about its modifiers.
30 * - C escapes in %#[] ?
31 * - Multibyte characters (done for format parsing, except scan groups)
32 * - Complex numbers? (C99 _Complex)
33 * - Boolean values? (C99 _Bool)
34 * - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used
35 * to print the mantissa, e.g. NaN(0xc000000000000000)
36 * - Should we support the GNU %a alloc modifier? GNU has an ugly hack
37 * for %a, because C99 used %a for other purposes. If specified as
38 * %as or %a[ it is interpreted as the alloc modifier, otherwise as
39 * the C99 hex-float. This means that you cannot scan %as as a hex-float
40 * immediately followed by an 's'.
41 * - Scanning of collating symbols.
42 */
43
44/*************************************************************************
45 * Trio include files
46 */
47#include "triodef.h"
48#include "trio.h"
49#include "triop.h"
50
51#if defined(TRIO_EMBED_NAN)
52# define TRIO_PUBLIC_NAN static
53# if TRIO_FEATURE_FLOAT
54# define TRIO_FUNC_NAN
55# define TRIO_FUNC_NINF
56# define TRIO_FUNC_PINF
57# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT
58# define TRIO_FUNC_ISINF
59# endif
60#endif
61#include "trionan.h"
62
63#if defined(TRIO_EMBED_STRING)
64# define TRIO_PUBLIC_STRING static
65# define TRIO_FUNC_LENGTH
66# define TRIO_FUNC_LENGTH_MAX
67# define TRIO_FUNC_TO_LONG
68# if TRIO_FEATURE_LOCALE
69# define TRIO_FUNC_COPY_MAX
70# endif
71# if TRIO_FEATURE_DYNAMICSTRING
72# define TRIO_FUNC_XSTRING_DUPLICATE
73# endif
74# if TRIO_EXTENSION && TRIO_FEATURE_SCANF
75# define TRIO_FUNC_EQUAL_LOCALE
76# endif
77# if TRIO_FEATURE_ERRNO
78# define TRIO_FUNC_ERROR
79# endif
80# if TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF
81# define TRIO_FUNC_TO_DOUBLE
82# endif
83# if TRIO_FEATURE_DYNAMICSTRING
84# define TRIO_FUNC_STRING_EXTRACT
85# endif
86# if TRIO_FEATURE_DYNAMICSTRING
87# define TRIO_FUNC_STRING_TERMINATE
88# endif
89# if TRIO_FEATURE_USER_DEFINED
90# define TRIO_FUNC_DUPLICATE
91# endif
92# if TRIO_FEATURE_DYNAMICSTRING
93# define TRIO_FUNC_STRING_DESTROY
94# endif
95# if TRIO_FEATURE_USER_DEFINED
96# define TRIO_FUNC_DESTROY
97# endif
98# if TRIO_FEATURE_USER_DEFINED || (TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF)
99# define TRIO_FUNC_EQUAL
100# endif
101# if TRIO_FEATURE_USER_DEFINED || TRIO_FEATURE_SCANF
102# define TRIO_FUNC_EQUAL_CASE
103# endif
104# if (TRIO_EXTENSION && TRIO_FEATURE_SCANF)
105# define TRIO_FUNC_EQUAL_MAX
106# endif
107# if TRIO_FEATURE_SCANF
108# define TRIO_FUNC_TO_UPPER
109# endif
110# if TRIO_FEATURE_DYNAMICSTRING
111# define TRIO_FUNC_XSTRING_APPEND_CHAR
112# endif
113#endif
114#include "triostr.h"
115
116/**************************************************************************
117 *
118 * Definitions
119 *
120 *************************************************************************/
121
122#include <limits.h>
123#if TRIO_FEATURE_FLOAT
124# include <math.h>
125# include <float.h>
126#endif
127
128#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_FEATURE_WIDECHAR
129# if !defined(TRIO_PLATFORM_WINCE)
130# define TRIO_COMPILER_SUPPORTS_MULTIBYTE
131# if !defined(MB_LEN_MAX)
132# define MB_LEN_MAX 6
133# endif
134# endif
135#endif
136
137#if (defined(TRIO_COMPILER_VISUALC) && (TRIO_COMPILER_VISUALC - 0 >= 1100)) || defined(TRIO_COMPILER_BORLAND)
138# define TRIO_COMPILER_SUPPORTS_VISUALC_INT
139#endif
140
141#if TRIO_FEATURE_FLOAT
142# if defined(PREDEF_STANDARD_C99) \
143 || defined(PREDEF_STANDARD_UNIX03)
144# if !defined(HAVE_FLOORL) && !defined(TRIO_NO_FLOORL)
145# define HAVE_FLOORL
146# endif
147# if !defined(HAVE_CEILL) && !defined(TRIO_NO_CEILL)
148# define HAVE_CEILL
149# endif
150# if !defined(HAVE_POWL) && !defined(TRIO_NO_POWL)
151# define HAVE_POWL
152# endif
153# if !defined(HAVE_FMODL) && !defined(TRIO_NO_FMODL)
154# define HAVE_FMODL
155# endif
156# if !defined(HAVE_LOG10L) && !defined(TRIO_NO_LOG10L)
157# define HAVE_LOG10L
158# endif
159# endif
160# if defined(TRIO_COMPILER_VISUALC)
161# if defined(floorl)
162# define HAVE_FLOORL
163# endif
164# if defined(ceill)
165# define HAVE_CEILL
166# endif
167# if defined(powl)
168# define HAVE_POWL
169# endif
170# if defined(fmodl)
171# define HAVE_FMODL
172# endif
173# if defined(log10l)
174# define HAVE_LOG10L
175# endif
176# endif
177#endif
178
179/*************************************************************************
180 * Generic definitions
181 */
182
183#if !(defined(DEBUG) || defined(NDEBUG))
184# define NDEBUG
185#endif
186
187#include <assert.h>
188#include <ctype.h>
189#if defined(PREDEF_STANDARD_C99) && !defined(isascii)
190# define isascii(x) ((x) & 0x7F)
191#endif
192#if defined(TRIO_COMPILER_ANCIENT)
193# include <varargs.h>
194#else
195# include <stdarg.h>
196#endif
197#include <stddef.h>
198#if defined(TRIO_PLATFORM_WINCE)
199extern int errno;
200#else
201# include <errno.h>
202#endif
203
204#ifndef NULL
205# define NULL 0
206#endif
207#define NIL ((char)0)
208#ifndef FALSE
209# define FALSE (1 == 0)
210# define TRUE (! FALSE)
211#endif
212#define BOOLEAN_T int
213
214/* mincore() can be used for debugging purposes */
215#define VALID(x) (NULL != (x))
216
217#if TRIO_FEATURE_ERRORCODE
218 /*
219 * Encode the error code and the position. This is decoded
220 * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION.
221 */
222# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))
223#else
224# define TRIO_ERROR_RETURN(x,y) (-1)
225#endif
226
227typedef unsigned long trio_flags_t;
228
229
230/*************************************************************************
231 * Platform specific definitions
232 */
233#if defined(TRIO_PLATFORM_UNIX)
234# include <unistd.h>
235# include <signal.h>
236# include <locale.h>
237# if !defined(TRIO_FEATURE_LOCALE)
238# define USE_LOCALE
239# endif
240#endif /* TRIO_PLATFORM_UNIX */
241#if defined(TRIO_PLATFORM_VMS)
242# include <unistd.h>
243#endif
244#if defined(TRIO_PLATFORM_WIN32)
245# if defined(TRIO_PLATFORM_WINCE)
246int read(int handle, char *buffer, unsigned int length);
247int write(int handle, const char *buffer, unsigned int length);
248# else
249# include <io.h>
250# define read _read
251# define write _write
252# endif
253#endif /* TRIO_PLATFORM_WIN32 */
254
255#if TRIO_FEATURE_WIDECHAR
256# if defined(PREDEF_STANDARD_C94)
257# include <wchar.h>
258# include <wctype.h>
259typedef wchar_t trio_wchar_t;
260typedef wint_t trio_wint_t;
261# else
262typedef char trio_wchar_t;
263typedef int trio_wint_t;
264# define WCONST(x) L ## x
265# define WEOF EOF
266# define iswalnum(x) isalnum(x)
267# define iswalpha(x) isalpha(x)
268# define iswcntrl(x) iscntrl(x)
269# define iswdigit(x) isdigit(x)
270# define iswgraph(x) isgraph(x)
271# define iswlower(x) islower(x)
272# define iswprint(x) isprint(x)
273# define iswpunct(x) ispunct(x)
274# define iswspace(x) isspace(x)
275# define iswupper(x) isupper(x)
276# define iswxdigit(x) isxdigit(x)
277# endif
278#endif
279
280
281/*************************************************************************
282 * Compiler dependent definitions
283 */
284
285/* Support for long long */
286#ifndef __cplusplus
287# if !defined(USE_LONGLONG)
288# if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__)
289# define USE_LONGLONG
290# else
291# if defined(TRIO_COMPILER_SUNPRO)
292# define USE_LONGLONG
293# else
294# if defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1400)
295# define USE_LONGLONG
296# else
297# if defined(_LONG_LONG) || defined(_LONGLONG)
298# define USE_LONGLONG
299# endif
300# endif
301# endif
302# endif
303# endif
304#endif
305
306/* The extra long numbers */
307#if defined(USE_LONGLONG)
308typedef signed long long int trio_longlong_t;
309typedef unsigned long long int trio_ulonglong_t;
310#else
311# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)
312typedef signed __int64 trio_longlong_t;
313typedef unsigned __int64 trio_ulonglong_t;
314# else
315typedef TRIO_SIGNED long int trio_longlong_t;
316typedef unsigned long int trio_ulonglong_t;
317# endif
318#endif
319
320/* Maximal and fixed integer types */
321#if defined(PREDEF_STANDARD_C99)
322# include <stdint.h>
323typedef intmax_t trio_intmax_t;
324typedef uintmax_t trio_uintmax_t;
325typedef int8_t trio_int8_t;
326typedef int16_t trio_int16_t;
327typedef int32_t trio_int32_t;
328typedef int64_t trio_int64_t;
329#else
330# if defined(PREDEF_STANDARD_UNIX98)
331# include <inttypes.h>
332typedef intmax_t trio_intmax_t;
333typedef uintmax_t trio_uintmax_t;
334typedef int8_t trio_int8_t;
335typedef int16_t trio_int16_t;
336typedef int32_t trio_int32_t;
337typedef int64_t trio_int64_t;
338# else
339# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)
340typedef trio_longlong_t trio_intmax_t;
341typedef trio_ulonglong_t trio_uintmax_t;
342typedef __int8 trio_int8_t;
343typedef __int16 trio_int16_t;
344typedef __int32 trio_int32_t;
345typedef __int64 trio_int64_t;
346# else
347typedef trio_longlong_t trio_intmax_t;
348typedef trio_ulonglong_t trio_uintmax_t;
349# if defined(TRIO_INT8_T)
350typedef TRIO_INT8_T trio_int8_t;
351# else
352typedef TRIO_SIGNED char trio_int8_t;
353# endif
354# if defined(TRIO_INT16_T)
355typedef TRIO_INT16_T trio_int16_t;
356# else
357typedef TRIO_SIGNED short trio_int16_t;
358# endif
359# if defined(TRIO_INT32_T)
360typedef TRIO_INT32_T trio_int32_t;
361# else
362typedef TRIO_SIGNED int trio_int32_t;
363# endif
364# if defined(TRIO_INT64_T)
365typedef TRIO_INT64_T trio_int64_t;
366# else
367typedef trio_longlong_t trio_int64_t;
368# endif
369# endif
370# endif
371#endif
372
373#if defined(HAVE_FLOORL)
374# define trio_floor(x) floorl((x))
375#else
376# define trio_floor(x) floor((double)(x))
377#endif
378
379#if defined(HAVE_CEILL)
380# define trio_ceil(x) ceill((x))
381#else
382# define trio_ceil(x) ceil((double)(x))
383#endif
384
385#if defined(HAVE_FMODL)
386# define trio_fmod(x,y) fmodl((x),(y))
387#else
388# define trio_fmod(x,y) fmod((double)(x),(double)(y))
389#endif
390
391#if defined(HAVE_POWL)
392# define trio_pow(x,y) powl((x),(y))
393#else
394# define trio_pow(x,y) pow((double)(x),(double)(y))
395#endif
396
397#if defined(HAVE_LOG10L)
398# define trio_log10(x) log10l((x))
399#else
400# define trio_log10(x) log10((double)(x))
401#endif
402
403#if TRIO_FEATURE_FLOAT
404# define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))
405#endif
406
407/*************************************************************************
408 * Internal Definitions
409 */
410
411#if TRIO_FEATURE_FLOAT
412
413# if !defined(DECIMAL_DIG)
414# define DECIMAL_DIG DBL_DIG
415# endif
416
417/* Long double sizes */
418# ifdef LDBL_DIG
419# define MAX_MANTISSA_DIGITS LDBL_DIG
420# define MAX_EXPONENT_DIGITS 4
421# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP
422# else
423# define MAX_MANTISSA_DIGITS DECIMAL_DIG
424# define MAX_EXPONENT_DIGITS 3
425# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP
426# endif
427
428# if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)
429# undef LDBL_DIG
430# undef LDBL_MANT_DIG
431# undef LDBL_EPSILON
432# define LDBL_DIG DBL_DIG
433# define LDBL_MANT_DIG DBL_MANT_DIG
434# define LDBL_EPSILON DBL_EPSILON
435# endif
436
437#endif /* TRIO_FEATURE_FLOAT */
438
439/* The maximal number of digits is for base 2 */
440#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)
441/* The width of a pointer. The number of bits in a hex digit is 4 */
442#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)
443
444#if TRIO_FEATURE_FLOAT
445/* Infinite and Not-A-Number for floating-point */
446# define INFINITE_LOWER "inf"
447# define INFINITE_UPPER "INF"
448# define LONG_INFINITE_LOWER "infinite"
449# define LONG_INFINITE_UPPER "INFINITE"
450# define NAN_LOWER "nan"
451# define NAN_UPPER "NAN"
452#endif
453
454/* Various constants */
455enum {
456 TYPE_PRINT = 1,
457#if TRIO_FEATURE_SCANF
458 TYPE_SCAN = 2,
459#endif
460
461 /* Flags. FLAGS_LAST must be less than ULONG_MAX */
462 FLAGS_NEW = 0,
463 FLAGS_STICKY = 1,
464 FLAGS_SPACE = 2 * FLAGS_STICKY,
465 FLAGS_SHOWSIGN = 2 * FLAGS_SPACE,
466 FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN,
467 FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST,
468 FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE,
469 FLAGS_SHORTSHORT = 2 * FLAGS_SHORT,
470 FLAGS_LONG = 2 * FLAGS_SHORTSHORT,
471 FLAGS_QUAD = 2 * FLAGS_LONG,
472 FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD,
473 FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE,
474 FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T,
475 FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T,
476 FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T,
477 FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING,
478 FLAGS_UPPER = 2 * FLAGS_UNSIGNED,
479 FLAGS_WIDTH = 2 * FLAGS_UPPER,
480 FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH,
481 FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER,
482 FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION,
483 FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER,
484 FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE,
485 FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER,
486 FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E,
487 FLAGS_QUOTE = 2 * FLAGS_FLOAT_G,
488 FLAGS_WIDECHAR = 2 * FLAGS_QUOTE,
489 FLAGS_IGNORE = 2 * FLAGS_WIDECHAR,
490 FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE,
491 FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER,
492 FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER,
493 FLAGS_LAST = FLAGS_FIXED_SIZE,
494 /* Reused flags */
495 FLAGS_EXCLUDE = FLAGS_SHORT,
496 FLAGS_USER_DEFINED = FLAGS_IGNORE,
497 FLAGS_USER_DEFINED_PARAMETER = FLAGS_IGNORE_PARAMETER,
498 FLAGS_ROUNDING = FLAGS_INTMAX_T,
499 /* Compounded flags */
500 FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T,
501 FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT,
502
503 NO_POSITION = -1,
504 NO_WIDTH = 0,
505 NO_PRECISION = -1,
506 NO_SIZE = -1,
507
508 /* Do not change these */
509 NO_BASE = -1,
510 MIN_BASE = 2,
511 MAX_BASE = 36,
512 BASE_BINARY = 2,
513 BASE_OCTAL = 8,
514 BASE_DECIMAL = 10,
515 BASE_HEX = 16,
516
517 /* Maximal number of allowed parameters */
518 MAX_PARAMETERS = 64,
519 /* Maximal number of characters in class */
520 MAX_CHARACTER_CLASS = UCHAR_MAX + 1,
521
522#if TRIO_FEATURE_USER_DEFINED
523 /* Maximal string lengths for user-defined specifiers */
524 MAX_USER_NAME = 64,
525 MAX_USER_DATA = 256,
526#endif
527
528 /* Maximal length of locale separator strings */
529 MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX,
530 /* Maximal number of integers in grouping */
531 MAX_LOCALE_GROUPS = 64
532};
533
534#define NO_GROUPING ((int)CHAR_MAX)
535
536/* Fundamental formatting parameter types */
537#define FORMAT_SENTINEL -1 /* marks end of parameters array */
538#define FORMAT_UNKNOWN 0
539#define FORMAT_INT 1
540#define FORMAT_DOUBLE 2
541#define FORMAT_CHAR 3
542#define FORMAT_STRING 4
543#define FORMAT_POINTER 5
544#define FORMAT_COUNT 6
545#define FORMAT_PARAMETER 7
546#define FORMAT_GROUP 8
547#define FORMAT_ERRNO 9
548#define FORMAT_USER_DEFINED 10
549
550/* Character constants */
551#define CHAR_IDENTIFIER '%'
552#define CHAR_ALT_IDENTIFIER '$'
553#define CHAR_BACKSLASH '\\'
554#define CHAR_QUOTE '\"'
555#define CHAR_ADJUST ' '
556
557#if TRIO_EXTENSION
558/* Character class expressions */
559# define CLASS_ALNUM "[:alnum:]"
560# define CLASS_ALPHA "[:alpha:]"
561# define CLASS_BLANK "[:blank:]"
562# define CLASS_CNTRL "[:cntrl:]"
563# define CLASS_DIGIT "[:digit:]"
564# define CLASS_GRAPH "[:graph:]"
565# define CLASS_LOWER "[:lower:]"
566# define CLASS_PRINT "[:print:]"
567# define CLASS_PUNCT "[:punct:]"
568# define CLASS_SPACE "[:space:]"
569# define CLASS_UPPER "[:upper:]"
570# define CLASS_XDIGIT "[:xdigit:]"
571#endif
572
573/*
574 * SPECIFIERS:
575 *
576 *
577 * a Hex-float
578 * A Hex-float
579 * c Character
580 * C Widechar character (wint_t)
581 * d Decimal
582 * e Float
583 * E Float
584 * F Float
585 * F Float
586 * g Float
587 * G Float
588 * i Integer
589 * m Error message
590 * n Count
591 * o Octal
592 * p Pointer
593 * s String
594 * S Widechar string (wchar_t *)
595 * u Unsigned
596 * x Hex
597 * X Hex
598 * [] Group
599 * <> User-defined
600 *
601 * Reserved:
602 *
603 * D Binary Coded Decimal %D(length,precision) (OS/390)
604 */
605#define SPECIFIER_CHAR 'c'
606#define SPECIFIER_STRING 's'
607#define SPECIFIER_DECIMAL 'd'
608#define SPECIFIER_INTEGER 'i'
609#define SPECIFIER_UNSIGNED 'u'
610#define SPECIFIER_OCTAL 'o'
611#define SPECIFIER_HEX 'x'
612#define SPECIFIER_HEX_UPPER 'X'
613#if TRIO_FEATURE_FLOAT
614# define SPECIFIER_FLOAT_E 'e'
615# define SPECIFIER_FLOAT_E_UPPER 'E'
616# define SPECIFIER_FLOAT_F 'f'
617# define SPECIFIER_FLOAT_F_UPPER 'F'
618# define SPECIFIER_FLOAT_G 'g'
619# define SPECIFIER_FLOAT_G_UPPER 'G'
620#endif
621#define SPECIFIER_POINTER 'p'
622#if TRIO_FEATURE_SCANF
623# define SPECIFIER_GROUP '['
624# define SPECIFIER_UNGROUP ']'
625#endif
626#define SPECIFIER_COUNT 'n'
627#if TRIO_UNIX98
628# define SPECIFIER_CHAR_UPPER 'C'
629# define SPECIFIER_STRING_UPPER 'S'
630#endif
631#define SPECIFIER_HEXFLOAT 'a'
632#define SPECIFIER_HEXFLOAT_UPPER 'A'
633#define SPECIFIER_ERRNO 'm'
634#if TRIO_FEATURE_BINARY
635# define SPECIFIER_BINARY 'b'
636# define SPECIFIER_BINARY_UPPER 'B'
637#endif
638#if TRIO_FEATURE_USER_DEFINED
639# define SPECIFIER_USER_DEFINED_BEGIN '<'
640# define SPECIFIER_USER_DEFINED_END '>'
641# define SPECIFIER_USER_DEFINED_SEPARATOR ':'
642# define SPECIFIER_USER_DEFINED_EXTRA '|'
643#endif
644
645/*
646 * QUALIFIERS:
647 *
648 *
649 * Numbers = d,i,o,u,x,X
650 * Float = a,A,e,E,f,F,g,G
651 * String = s
652 * Char = c
653 *
654 *
655 * 9$ Position
656 * Use the 9th parameter. 9 can be any number between 1 and
657 * the maximal argument
658 *
659 * 9 Width
660 * Set width to 9. 9 can be any number, but must not be postfixed
661 * by '$'
662 *
663 * h Short
664 * Numbers:
665 * (unsigned) short int
666 *
667 * hh Short short
668 * Numbers:
669 * (unsigned) char
670 *
671 * l Long
672 * Numbers:
673 * (unsigned) long int
674 * String:
675 * as the S specifier
676 * Char:
677 * as the C specifier
678 *
679 * ll Long Long
680 * Numbers:
681 * (unsigned) long long int
682 *
683 * L Long Double
684 * Float
685 * long double
686 *
687 * # Alternative
688 * Float:
689 * Decimal-point is always present
690 * String:
691 * non-printable characters are handled as \number
692 *
693 * Spacing
694 *
695 * + Sign
696 *
697 * - Alignment
698 *
699 * . Precision
700 *
701 * * Parameter
702 * print: use parameter
703 * scan: no parameter (ignore)
704 *
705 * q Quad
706 *
707 * Z size_t
708 *
709 * w Widechar
710 *
711 * ' Thousands/quote
712 * Numbers:
713 * Integer part grouped in thousands
714 * Binary numbers:
715 * Number grouped in nibbles (4 bits)
716 * String:
717 * Quoted string
718 *
719 * j intmax_t
720 * t prtdiff_t
721 * z size_t
722 *
723 * ! Sticky
724 * @ Parameter (for both print and scan)
725 *
726 * I n-bit Integer
727 * Numbers:
728 * The following options exists
729 * I8 = 8-bit integer
730 * I16 = 16-bit integer
731 * I32 = 32-bit integer
732 * I64 = 64-bit integer
733 */
734#define QUALIFIER_POSITION '$'
735#define QUALIFIER_SHORT 'h'
736#define QUALIFIER_LONG 'l'
737#define QUALIFIER_LONG_UPPER 'L'
738#define QUALIFIER_ALTERNATIVE '#'
739#define QUALIFIER_SPACE ' '
740#define QUALIFIER_PLUS '+'
741#define QUALIFIER_MINUS '-'
742#define QUALIFIER_DOT '.'
743#define QUALIFIER_STAR '*'
744#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */
745#define QUALIFIER_SIZE_T 'z'
746#define QUALIFIER_PTRDIFF_T 't'
747#define QUALIFIER_INTMAX_T 'j'
748#define QUALIFIER_QUAD 'q'
749#define QUALIFIER_SIZE_T_UPPER 'Z'
750#if TRIO_MISC
751# define QUALIFIER_WIDECHAR 'w'
752#endif
753#define QUALIFIER_FIXED_SIZE 'I'
754#define QUALIFIER_QUOTE '\''
755#define QUALIFIER_STICKY '!'
756#define QUALIFIER_VARSIZE '&' /* This should remain undocumented */
757#define QUALIFIER_ROUNDING_UPPER 'R'
758#if TRIO_EXTENSION
759# define QUALIFIER_PARAM '@' /* Experimental */
760# define QUALIFIER_COLON ':' /* For scanlists */
761# define QUALIFIER_EQUAL '=' /* For scanlists */
762#endif
763
764
765/*************************************************************************
766 *
767 * Internal Structures
768 *
769 *************************************************************************/
770
771/* Parameters */
772typedef struct {
773 /* An indication of which entry in the data union is used */
774 int type;
775 /* The flags */
776 trio_flags_t flags;
777 /* The width qualifier */
778 int width;
779 /* The precision qualifier */
780 int precision;
781 /* The base qualifier */
782 int base;
783 /* Base from specifier */
784 int baseSpecifier;
785 /* The size for the variable size qualifier */
786 int varsize;
787 /* Offset of the first character of the specifier */
788 int beginOffset;
789 /* Offset of the first character after the specifier */
790 int endOffset;
791 /* Position in the argument list that this parameter refers to */
792 int position;
793 /* The data from the argument list */
794 union {
795 char *string;
796#if TRIO_FEATURE_WIDECHAR
797 trio_wchar_t *wstring;
798#endif
799 trio_pointer_t pointer;
800 union {
801 trio_intmax_t as_signed;
802 trio_uintmax_t as_unsigned;
803 } number;
804#if TRIO_FEATURE_FLOAT
805 double doubleNumber;
806 double *doublePointer;
807 trio_long_double_t longdoubleNumber;
808 trio_long_double_t *longdoublePointer;
809#endif
810 int errorNumber;
811 } data;
812#if TRIO_FEATURE_USER_DEFINED
813 /* For the user-defined specifier */
814 union {
815 char namespace[MAX_USER_NAME];
816 int handler; /* if flags & FLAGS_USER_DEFINED_PARAMETER */
817 } user_defined;
818 char user_data[MAX_USER_DATA];
819#endif
820} trio_parameter_t;
821
822/* Container for customized functions */
823typedef struct {
824 union {
825 trio_outstream_t out;
826 trio_instream_t in;
827 } stream;
828 trio_pointer_t closure;
829} trio_custom_t;
830
831/* General trio "class" */
832typedef struct _trio_class_t {
833 /*
834 * The function to write characters to a stream.
835 */
836 void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int));
837 /*
838 * The function to read characters from a stream.
839 */
840 void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *));
841 /*
842 * The function to undo read characters from a stream.
843 */
844 void (*UndoStream) TRIO_PROTO((struct _trio_class_t *));
845 /*
846 * The current location in the stream.
847 */
848 trio_pointer_t location;
849 /*
850 * The character currently being processed.
851 */
852 int current;
853 /*
854 * The number of characters that would have been written/read
855 * if there had been sufficient space.
856 */
857 int processed;
858 union {
859 /*
860 * The number of characters that are actually written. Processed and
861 * committed will only differ for the *nprintf functions.
862 */
863 int committed;
864 /*
865 * The number of look-ahead characters read.
866 */
867 int cached;
868 } actually;
869 /*
870 * The upper limit of characters that may be written/read.
871 */
872 int max;
873 /*
874 * The last output error that was detected.
875 */
876 int error;
877} trio_class_t;
878
879/* References (for user-defined callbacks) */
880typedef struct _trio_reference_t {
881 trio_class_t *data;
882 trio_parameter_t *parameter;
883} trio_reference_t;
884
885#if TRIO_FEATURE_USER_DEFINED
886/* Registered entries (for user-defined callbacks) */
887typedef struct _trio_userdef_t {
888 struct _trio_userdef_t *next;
889 trio_callback_t callback;
890 char *name;
891} trio_userdef_t;
892#endif
893
894/*************************************************************************
895 *
896 * Internal Variables
897 *
898 *************************************************************************/
899
900static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.129 2009/09/20 11:37:15 breese Exp $";
901
902#if TRIO_FEATURE_FLOAT
903/*
904 * Need this to workaround a parser bug in HP C/iX compiler that fails
905 * to resolves macro definitions that includes type 'long double',
906 * e.g: va_arg(arg_ptr, long double)
907 */
908# if defined(TRIO_PLATFORM_MPEIX)
909static TRIO_CONST trio_long_double_t ___dummy_long_double = 0;
910# endif
911#endif
912
913static TRIO_CONST char internalNullString[] = "(nil)";
914
915#if defined(USE_LOCALE)
916static struct lconv *internalLocaleValues = NULL;
917#endif
918
919/*
920 * UNIX98 says "in a locale where the radix character is not defined,
921 * the radix character defaults to a period (.)"
922 */
923#if TRIO_FEATURE_FLOAT || TRIO_FEATURE_LOCALE || defined(USE_LOCALE)
924static int internalDecimalPointLength = 1;
925static char internalDecimalPoint = '.';
926static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";
927#endif
928#if TRIO_FEATURE_QUOTE || TRIO_FEATURE_LOCALE || TRIO_EXTENSION
929static int internalThousandSeparatorLength = 1;
930static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ",";
931static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };
932#endif
933
934static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz";
935static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
936#if TRIO_FEATURE_SCANF
937static BOOLEAN_T internalDigitsUnconverted = TRUE;
938static int internalDigitArray[128];
939# if TRIO_EXTENSION
940static BOOLEAN_T internalCollationUnconverted = TRUE;
941static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS];
942# endif
943#endif
944
945#if TRIO_FEATURE_USER_DEFINED
946static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL;
947static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL;
948static trio_userdef_t *internalUserDef = NULL;
949#endif
950
951
952/*************************************************************************
953 *
954 * Internal Functions
955 *
956 ************************************************************************/
957
958#if defined(TRIO_EMBED_NAN)
959# include "trionan.c"
960#endif
961
962#if defined(TRIO_EMBED_STRING)
963# include "triostr.c"
964#endif
965
966/*************************************************************************
967 * TrioInitializeParameter
968 *
969 * Description:
970 * Initialize a trio_parameter_t struct.
971 */
972TRIO_PRIVATE void
973TrioInitializeParameter
974TRIO_ARGS1((parameter),
975 trio_parameter_t *parameter)
976{
977 parameter->type = FORMAT_UNKNOWN;
978 parameter->flags = 0;
979 parameter->width = 0;
980 parameter->precision = 0;
981 parameter->base = 0;
982 parameter->baseSpecifier = 0;
983 parameter->varsize = 0;
984 parameter->beginOffset = 0;
985 parameter->endOffset = 0;
986 parameter->position = 0;
987 parameter->data.pointer = 0;
988#if TRIO_FEATURE_USER_DEFINED
989 parameter->user_defined.handler = 0;
990 parameter->user_data[0] = 0;
991#endif
992}
993
994/*************************************************************************
995 * TrioCopyParameter
996 *
997 * Description:
998 * Copies one trio_parameter_t struct to another.
999 */
1000TRIO_PRIVATE void
1001TrioCopyParameter
1002TRIO_ARGS2((target, source),
1003 trio_parameter_t *target,
1004 TRIO_CONST trio_parameter_t *source)
1005{
1006#if TRIO_FEATURE_USER_DEFINED
1007 size_t i;
1008#endif
1009
1010 target->type = source->type;
1011 target->flags = source->flags;
1012 target->width = source->width;
1013 target->precision = source->precision;
1014 target->base = source->base;
1015 target->baseSpecifier = source->baseSpecifier;
1016 target->varsize = source->varsize;
1017 target->beginOffset = source->beginOffset;
1018 target->endOffset = source->endOffset;
1019 target->position = source->position;
1020 target->data = source->data;
1021
1022#if TRIO_FEATURE_USER_DEFINED
1023 target->user_defined = source->user_defined;
1024
1025 for (i = 0U; i < sizeof(target->user_data); ++i)
1026 {
1027 if ((target->user_data[i] = source->user_data[i]) == NIL)
1028 break;
1029 }
1030#endif
1031}
1032
1033/*************************************************************************
1034 * TrioIsQualifier
1035 *
1036 * Description:
1037 * Remember to add all new qualifiers to this function.
1038 * QUALIFIER_POSITION must not be added.
1039 */
1040TRIO_PRIVATE BOOLEAN_T
1041TrioIsQualifier
1042TRIO_ARGS1((character),
1043 TRIO_CONST char character)
1044{
1045 /* QUALIFIER_POSITION is not included */
1046 switch (character)
1047 {
1048 case '0': case '1': case '2': case '3': case '4':
1049 case '5': case '6': case '7': case '8': case '9':
1050 case QUALIFIER_PLUS:
1051 case QUALIFIER_MINUS:
1052 case QUALIFIER_SPACE:
1053 case QUALIFIER_DOT:
1054 case QUALIFIER_STAR:
1055 case QUALIFIER_ALTERNATIVE:
1056 case QUALIFIER_SHORT:
1057 case QUALIFIER_LONG:
1058 case QUALIFIER_CIRCUMFLEX:
1059 case QUALIFIER_LONG_UPPER:
1060 case QUALIFIER_SIZE_T:
1061 case QUALIFIER_PTRDIFF_T:
1062 case QUALIFIER_INTMAX_T:
1063 case QUALIFIER_QUAD:
1064 case QUALIFIER_SIZE_T_UPPER:
1065#if defined(QUALIFIER_WIDECHAR)
1066 case QUALIFIER_WIDECHAR:
1067#endif
1068 case QUALIFIER_QUOTE:
1069 case QUALIFIER_STICKY:
1070 case QUALIFIER_VARSIZE:
1071#if defined(QUALIFIER_PARAM)
1072 case QUALIFIER_PARAM:
1073#endif
1074 case QUALIFIER_FIXED_SIZE:
1075 case QUALIFIER_ROUNDING_UPPER:
1076 return TRUE;
1077 default:
1078 return FALSE;
1079 }
1080}
1081
1082/*************************************************************************
1083 * TrioSetLocale
1084 */
1085#if defined(USE_LOCALE)
1086TRIO_PRIVATE void
1087TrioSetLocale(TRIO_NOARGS)
1088{
1089 internalLocaleValues = (struct lconv *)localeconv();
1090 if (internalLocaleValues)
1091 {
1092 if ((internalLocaleValues->decimal_point) &&
1093 (internalLocaleValues->decimal_point[0] != NIL))
1094 {
1095 internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point);
1096 if (internalDecimalPointLength == 1)
1097 {
1098 internalDecimalPoint = internalLocaleValues->decimal_point[0];
1099 }
1100 else
1101 {
1102 internalDecimalPoint = NIL;
1103 trio_copy_max(internalDecimalPointString,
1104 sizeof(internalDecimalPointString),
1105 internalLocaleValues->decimal_point);
1106 }
1107 }
1108# if TRIO_EXTENSION
1109 if ((internalLocaleValues->thousands_sep) &&
1110 (internalLocaleValues->thousands_sep[0] != NIL))
1111 {
1112 trio_copy_max(internalThousandSeparator,
1113 sizeof(internalThousandSeparator),
1114 internalLocaleValues->thousands_sep);
1115 internalThousandSeparatorLength = trio_length(internalThousandSeparator);
1116 }
1117# endif
1118# if TRIO_EXTENSION
1119 if ((internalLocaleValues->grouping) &&
1120 (internalLocaleValues->grouping[0] != NIL))
1121 {
1122 trio_copy_max(internalGrouping,
1123 sizeof(internalGrouping),
1124 internalLocaleValues->grouping);
1125 }
1126# endif
1127 }
1128}
1129#endif /* defined(USE_LOCALE) */
1130
1131#if TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE
1132TRIO_PRIVATE int
1133TrioCalcThousandSeparatorLength
1134TRIO_ARGS1((digits),
1135 int digits)
1136{
1137 int count = 0;
1138 int step = NO_GROUPING;
1139 char *groupingPointer = internalGrouping;
1140
1141 while (digits > 0)
1142 {
1143 if (*groupingPointer == CHAR_MAX)
1144 {
1145 /* Disable grouping */
1146 break; /* while */
1147 }
1148 else if (*groupingPointer == 0)
1149 {
1150 /* Repeat last group */
1151 if (step == NO_GROUPING)
1152 {
1153 /* Error in locale */
1154 break; /* while */
1155 }
1156 }
1157 else
1158 {
1159 step = *groupingPointer++;
1160 }
1161 if (digits > step)
1162 count += internalThousandSeparatorLength;
1163 digits -= step;
1164 }
1165 return count;
1166}
1167#endif /* TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE */
1168
1169#if TRIO_FEATURE_QUOTE
1170TRIO_PRIVATE BOOLEAN_T
1171TrioFollowedBySeparator
1172TRIO_ARGS1((position),
1173 int position)
1174{
1175 int step = 0;
1176 char *groupingPointer = internalGrouping;
1177
1178 position--;
1179 if (position == 0)
1180 return FALSE;
1181 while (position > 0)
1182 {
1183 if (*groupingPointer == CHAR_MAX)
1184 {
1185 /* Disable grouping */
1186 break; /* while */
1187 }
1188 else if (*groupingPointer != 0)
1189 {
1190 step = *groupingPointer++;
1191 }
1192 if (step == 0)
1193 break;
1194 position -= step;
1195 }
1196 return (position == 0);
1197}
1198#endif /* TRIO_FEATURE_QUOTE */
1199
1200/*************************************************************************
1201 * TrioGetPosition
1202 *
1203 * Get the %n$ position.
1204 */
1205TRIO_PRIVATE int
1206TrioGetPosition
1207TRIO_ARGS2((format, offsetPointer),
1208 TRIO_CONST char *format,
1209 int *offsetPointer)
1210{
1211#if TRIO_FEATURE_POSITIONAL
1212 char *tmpformat;
1213 int number = 0;
1214 int offset = *offsetPointer;
1215
1216 number = (int)trio_to_long(&format[offset], &tmpformat, BASE_DECIMAL);
1217 offset = (int)(tmpformat - format);
1218 if ((number != 0) && (QUALIFIER_POSITION == format[offset++]))
1219 {
1220 *offsetPointer = offset;
1221 /*
1222 * number is decreased by 1, because n$ starts from 1, whereas
1223 * the array it is indexing starts from 0.
1224 */
1225 return number - 1;
1226 }
1227#endif
1228 return NO_POSITION;
1229}
1230
1231/*************************************************************************
1232 * TrioFindNamespace
1233 *
1234 * Find registered user-defined specifier.
1235 * The prev argument is used for optimization only.
1236 */
1237#if TRIO_FEATURE_USER_DEFINED
1238TRIO_PRIVATE trio_userdef_t *
1239TrioFindNamespace
1240TRIO_ARGS2((name, prev),
1241 TRIO_CONST char *name,
1242 trio_userdef_t **prev)
1243{
1244 trio_userdef_t *def;
1245
1246 if (internalEnterCriticalRegion)
1247 (void)internalEnterCriticalRegion(NULL);
1248
1249 for (def = internalUserDef; def; def = def->next)
1250 {
1251 /* Case-sensitive string comparison */
1252 if (trio_equal_case(def->name, name))
1253 break;
1254
1255 if (prev)
1256 *prev = def;
1257 }
1258
1259 if (internalLeaveCriticalRegion)
1260 (void)internalLeaveCriticalRegion(NULL);
1261
1262 return def;
1263}
1264#endif
1265
1266/*************************************************************************
1267 * TrioPower
1268 *
1269 * Description:
1270 * Calculate pow(base, exponent), where number and exponent are integers.
1271 */
1272#if TRIO_FEATURE_FLOAT
1273TRIO_PRIVATE trio_long_double_t
1274TrioPower
1275TRIO_ARGS2((number, exponent),
1276 int number,
1277 int exponent)
1278{
1279 trio_long_double_t result;
1280
1281 if (number == 10)
1282 {
1283 switch (exponent)
1284 {
1285 /* Speed up calculation of common cases */
1286 case 0:
1287 result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1);
1288 break;
1289 case 1:
1290 result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0);
1291 break;
1292 case 2:
1293 result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1);
1294 break;
1295 case 3:
1296 result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2);
1297 break;
1298 case 4:
1299 result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3);
1300 break;
1301 case 5:
1302 result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4);
1303 break;
1304 case 6:
1305 result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5);
1306 break;
1307 case 7:
1308 result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6);
1309 break;
1310 case 8:
1311 result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7);
1312 break;
1313 case 9:
1314 result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8);
1315 break;
1316 default:
1317 result = trio_pow((trio_long_double_t)number,
1318 (trio_long_double_t)exponent);
1319 break;
1320 }
1321 }
1322 else
1323 {
1324 return trio_pow((trio_long_double_t)number,
1325 (trio_long_double_t)exponent);
1326 }
1327 return result;
1328}
1329#endif /* TRIO_FEATURE_FLOAT */
1330
1331/*************************************************************************
1332 * TrioLogarithm
1333 */
1334#if TRIO_FEATURE_FLOAT
1335TRIO_PRIVATE trio_long_double_t
1336TrioLogarithm
1337TRIO_ARGS2((number, base),
1338 trio_long_double_t number,
1339 int base)
1340{
1341 trio_long_double_t result;
1342
1343 if (number <= 0.0)
1344 {
1345 /* xlC crashes on log(0) */
1346 result = (number == 0.0) ? trio_ninf() : trio_nan();
1347 }
1348 else
1349 {
1350 if (base == 10)
1351 {
1352 result = trio_log10(number);
1353 }
1354 else
1355 {
1356 result = trio_log10(number) / trio_log10((double)base);
1357 }
1358 }
1359 return result;
1360}
1361#endif /* TRIO_FEATURE_FLOAT */
1362
1363/*************************************************************************
1364 * TrioLogarithmBase
1365 */
1366#if TRIO_FEATURE_FLOAT
1367TRIO_PRIVATE double
1368TrioLogarithmBase
1369TRIO_ARGS1((base),
1370 int base)
1371{
1372 switch (base)
1373 {
1374 case BASE_BINARY : return 1.0;
1375 case BASE_OCTAL : return 3.0;
1376 case BASE_DECIMAL: return 3.321928094887362345;
1377 case BASE_HEX : return 4.0;
1378 default : return TrioLogarithm((double)base, 2);
1379 }
1380}
1381#endif /* TRIO_FEATURE_FLOAT */
1382
1383/*************************************************************************
1384 * TrioParseQualifiers
1385 *
1386 * Description:
1387 * Parse the qualifiers of a potential conversion specifier
1388 */
1389TRIO_PRIVATE int
1390TrioParseQualifiers
1391TRIO_ARGS4((type, format, offset, parameter),
1392 int type,
1393 TRIO_CONST char *format,
1394 int offset,
1395 trio_parameter_t *parameter)
1396{
1397 char ch;
1398 int dots = 0; /* Count number of dots in modifier part */
1399 char *tmpformat;
1400
1401 parameter->beginOffset = offset - 1;
1402 parameter->flags = FLAGS_NEW;
1403 parameter->position = TrioGetPosition(format, &offset);
1404
1405 /* Default values */
1406 parameter->width = NO_WIDTH;
1407 parameter->precision = NO_PRECISION;
1408 parameter->base = NO_BASE;
1409 parameter->varsize = NO_SIZE;
1410
1411 while (TrioIsQualifier(format[offset]))
1412 {
1413 ch = format[offset++];
1414
1415 switch (ch)
1416 {
1417 case QUALIFIER_SPACE:
1418 parameter->flags |= FLAGS_SPACE;
1419 break;
1420
1421 case QUALIFIER_PLUS:
1422 parameter->flags |= FLAGS_SHOWSIGN;
1423 break;
1424
1425 case QUALIFIER_MINUS:
1426 parameter->flags |= FLAGS_LEFTADJUST;
1427 parameter->flags &= ~FLAGS_NILPADDING;
1428 break;
1429
1430 case QUALIFIER_ALTERNATIVE:
1431 parameter->flags |= FLAGS_ALTERNATIVE;
1432 break;
1433
1434 case QUALIFIER_DOT:
1435 if (dots == 0) /* Precision */
1436 {
1437 dots++;
1438
1439 /* Skip if no precision */
1440 if (QUALIFIER_DOT == format[offset])
1441 break;
1442
1443 /* After the first dot we have the precision */
1444 parameter->flags |= FLAGS_PRECISION;
1445 if ((QUALIFIER_STAR == format[offset])
1446#if defined(QUALIFIER_PARAM)
1447 || (QUALIFIER_PARAM == format[offset])
1448#endif
1449 )
1450 {
1451 offset++;
1452 parameter->flags |= FLAGS_PRECISION_PARAMETER;
1453 parameter->precision = TrioGetPosition(format, &offset);
1454 }
1455 else
1456 {
1457 parameter->precision = trio_to_long(&format[offset],
1458 &tmpformat,
1459 BASE_DECIMAL);
1460 offset = (int)(tmpformat - format);
1461 }
1462 }
1463 else if (dots == 1) /* Base */
1464 {
1465 dots++;
1466
1467 /* After the second dot we have the base */
1468 parameter->flags |= FLAGS_BASE;
1469 if ((QUALIFIER_STAR == format[offset])
1470#if defined(QUALIFIER_PARAM)
1471 || (QUALIFIER_PARAM == format[offset])
1472#endif
1473 )
1474 {
1475 offset++;
1476 parameter->flags |= FLAGS_BASE_PARAMETER;
1477 parameter->base = TrioGetPosition(format, &offset);
1478 }
1479 else
1480 {
1481 parameter->base = trio_to_long(&format[offset],
1482 &tmpformat,
1483 BASE_DECIMAL);
1484 if (parameter->base > MAX_BASE)
1485 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1486 offset = (int)(tmpformat - format);
1487 }
1488 }
1489 else
1490 {
1491 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1492 }
1493 break; /* QUALIFIER_DOT */
1494
1495#if defined(QUALIFIER_PARAM)
1496 case QUALIFIER_PARAM:
1497 parameter->type = TYPE_PRINT;
1498 /* FALLTHROUGH */
1499#endif
1500 case QUALIFIER_STAR:
1501 /* This has different meanings for print and scan */
1502 if (TYPE_PRINT == type)
1503 {
1504 /* Read with from parameter */
1505 int width = TrioGetPosition(format, &offset);
1506 parameter->flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER);
1507 if (NO_POSITION != width)
1508 parameter->width = width;
1509 /* else keep parameter->width = NO_WIDTH which != NO_POSITION */
1510 }
1511#if TRIO_FEATURE_SCANF
1512 else
1513 {
1514 /* Scan, but do not store result */
1515 parameter->flags |= FLAGS_IGNORE;
1516 }
1517#endif
1518 break; /* QUALIFIER_STAR */
1519
1520 case '0':
1521 if (! (parameter->flags & FLAGS_LEFTADJUST))
1522 parameter->flags |= FLAGS_NILPADDING;
1523 /* FALLTHROUGH */
1524 case '1': case '2': case '3': case '4':
1525 case '5': case '6': case '7': case '8': case '9':
1526 parameter->flags |= FLAGS_WIDTH;
1527 /*
1528 * &format[offset - 1] is used to "rewind" the read
1529 * character from format
1530 */
1531 parameter->width = trio_to_long(&format[offset - 1],
1532 &tmpformat,
1533 BASE_DECIMAL);
1534 offset = (int)(tmpformat - format);
1535 break;
1536
1537 case QUALIFIER_SHORT:
1538 if (parameter->flags & FLAGS_SHORTSHORT)
1539 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1540 else if (parameter->flags & FLAGS_SHORT)
1541 parameter->flags |= FLAGS_SHORTSHORT;
1542 else
1543 parameter->flags |= FLAGS_SHORT;
1544 break;
1545
1546 case QUALIFIER_LONG:
1547 if (parameter->flags & FLAGS_QUAD)
1548 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1549 else if (parameter->flags & FLAGS_LONG)
1550 parameter->flags |= FLAGS_QUAD;
1551 else
1552 parameter->flags |= FLAGS_LONG;
1553 break;
1554
1555#if TRIO_FEATURE_LONGDOUBLE
1556 case QUALIFIER_LONG_UPPER:
1557 parameter->flags |= FLAGS_LONGDOUBLE;
1558 break;
1559#endif
1560
1561#if TRIO_FEATURE_SIZE_T
1562 case QUALIFIER_SIZE_T:
1563 parameter->flags |= FLAGS_SIZE_T;
1564 /* Modify flags for later truncation of number */
1565 if (sizeof(size_t) == sizeof(trio_ulonglong_t))
1566 parameter->flags |= FLAGS_QUAD;
1567 else if (sizeof(size_t) == sizeof(long))
1568 parameter->flags |= FLAGS_LONG;
1569 break;
1570#endif
1571
1572#if TRIO_FEATURE_PTRDIFF_T
1573 case QUALIFIER_PTRDIFF_T:
1574 parameter->flags |= FLAGS_PTRDIFF_T;
1575 if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t))
1576 parameter->flags |= FLAGS_QUAD;
1577 else if (sizeof(ptrdiff_t) == sizeof(long))
1578 parameter->flags |= FLAGS_LONG;
1579 break;
1580#endif
1581
1582#if TRIO_FEATURE_INTMAX_T
1583 case QUALIFIER_INTMAX_T:
1584 parameter->flags |= FLAGS_INTMAX_T;
1585 if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t))
1586 parameter->flags |= FLAGS_QUAD;
1587 else if (sizeof(trio_intmax_t) == sizeof(long))
1588 parameter->flags |= FLAGS_LONG;
1589 break;
1590#endif
1591
1592#if TRIO_FEATURE_QUAD
1593 case QUALIFIER_QUAD:
1594 parameter->flags |= FLAGS_QUAD;
1595 break;
1596#endif
1597
1598#if TRIO_FEATURE_FIXED_SIZE
1599 case QUALIFIER_FIXED_SIZE:
1600 if (parameter->flags & FLAGS_FIXED_SIZE)
1601 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1602
1603 if (parameter->flags & (FLAGS_ALL_SIZES |
1604 FLAGS_LONGDOUBLE |
1605 FLAGS_WIDECHAR |
1606 FLAGS_VARSIZE_PARAMETER))
1607 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1608
1609 if ((format[offset] == '6') &&
1610 (format[offset + 1] == '4'))
1611 {
1612 parameter->varsize = sizeof(trio_int64_t);
1613 offset += 2;
1614 }
1615 else if ((format[offset] == '3') &&
1616 (format[offset + 1] == '2'))
1617 {
1618 parameter->varsize = sizeof(trio_int32_t);
1619 offset += 2;
1620 }
1621 else if ((format[offset] == '1') &&
1622 (format[offset + 1] == '6'))
1623 {
1624 parameter->varsize = sizeof(trio_int16_t);
1625 offset += 2;
1626 }
1627 else if (format[offset] == '8')
1628 {
1629 parameter->varsize = sizeof(trio_int8_t);
1630 offset++;
1631 }
1632 else
1633 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1634
1635 parameter->flags |= FLAGS_FIXED_SIZE;
1636 break;
1637#endif /* TRIO_FEATURE_FIXED_SIZE */
1638
1639#if defined(QUALIFIER_WIDECHAR)
1640 case QUALIFIER_WIDECHAR:
1641 parameter->flags |= FLAGS_WIDECHAR;
1642 break;
1643#endif
1644
1645#if TRIO_FEATURE_SIZE_T_UPPER
1646 case QUALIFIER_SIZE_T_UPPER:
1647 break;
1648#endif
1649
1650#if TRIO_FEATURE_QUOTE
1651 case QUALIFIER_QUOTE:
1652 parameter->flags |= FLAGS_QUOTE;
1653 break;
1654#endif
1655
1656#if TRIO_FEATURE_STICKY
1657 case QUALIFIER_STICKY:
1658 parameter->flags |= FLAGS_STICKY;
1659 break;
1660#endif
1661
1662#if TRIO_FEATURE_VARSIZE
1663 case QUALIFIER_VARSIZE:
1664 parameter->flags |= FLAGS_VARSIZE_PARAMETER;
1665 break;
1666#endif
1667
1668#if TRIO_FEATURE_ROUNDING
1669 case QUALIFIER_ROUNDING_UPPER:
1670 parameter->flags |= FLAGS_ROUNDING;
1671 break;
1672#endif
1673
1674 default:
1675 /* Bail out completely to make the error more obvious */
1676 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1677 }
1678 } /* while qualifier */
1679
1680 parameter->endOffset = offset;
1681
1682 return 0;
1683}
1684
1685/*************************************************************************
1686 * TrioParseSpecifier
1687 *
1688 * Description:
1689 * Parse the specifier part of a potential conversion specifier
1690 */
1691TRIO_PRIVATE int
1692TrioParseSpecifier
1693TRIO_ARGS4((type, format, offset, parameter),
1694 int type,
1695 TRIO_CONST char *format,
1696 int offset,
1697 trio_parameter_t *parameter)
1698{
1699 parameter->baseSpecifier = NO_BASE;
1700
1701 switch (format[offset++])
1702 {
1703#if defined(SPECIFIER_CHAR_UPPER)
1704 case SPECIFIER_CHAR_UPPER:
1705 parameter->flags |= FLAGS_WIDECHAR;
1706 /* FALLTHROUGH */
1707#endif
1708 case SPECIFIER_CHAR:
1709 if (parameter->flags & FLAGS_LONG)
1710 parameter->flags |= FLAGS_WIDECHAR;
1711 else if (parameter->flags & FLAGS_SHORT)
1712 parameter->flags &= ~FLAGS_WIDECHAR;
1713 parameter->type = FORMAT_CHAR;
1714 break;
1715
1716#if defined(SPECIFIER_STRING_UPPER)
1717 case SPECIFIER_STRING_UPPER:
1718 parameter->flags |= FLAGS_WIDECHAR;
1719 /* FALLTHROUGH */
1720#endif
1721 case SPECIFIER_STRING:
1722 if (parameter->flags & FLAGS_LONG)
1723 parameter->flags |= FLAGS_WIDECHAR;
1724 else if (parameter->flags & FLAGS_SHORT)
1725 parameter->flags &= ~FLAGS_WIDECHAR;
1726 parameter->type = FORMAT_STRING;
1727 break;
1728
1729#if defined(SPECIFIER_GROUP)
1730 case SPECIFIER_GROUP:
1731 if (TYPE_SCAN == type)
1732 {
1733 int depth = 1;
1734 parameter->type = FORMAT_GROUP;
1735 if (format[offset] == QUALIFIER_CIRCUMFLEX)
1736 offset++;
1737 if (format[offset] == SPECIFIER_UNGROUP)
1738 offset++;
1739 if (format[offset] == QUALIFIER_MINUS)
1740 offset++;
1741 /* Skip nested brackets */
1742 while (format[offset] != NIL)
1743 {
1744 if (format[offset] == SPECIFIER_GROUP)
1745 {
1746 depth++;
1747 }
1748 else if (format[offset] == SPECIFIER_UNGROUP)
1749 {
1750 if (--depth <= 0)
1751 {
1752 offset++;
1753 break;
1754 }
1755 }
1756 offset++;
1757 }
1758 }
1759 break;
1760#endif /* defined(SPECIFIER_GROUP) */
1761
1762 case SPECIFIER_INTEGER:
1763 parameter->type = FORMAT_INT;
1764 break;
1765
1766 case SPECIFIER_UNSIGNED:
1767 parameter->flags |= FLAGS_UNSIGNED;
1768 parameter->type = FORMAT_INT;
1769 break;
1770
1771 case SPECIFIER_DECIMAL:
1772 parameter->baseSpecifier = BASE_DECIMAL;
1773 parameter->type = FORMAT_INT;
1774 break;
1775
1776 case SPECIFIER_OCTAL:
1777 parameter->flags |= FLAGS_UNSIGNED;
1778 parameter->baseSpecifier = BASE_OCTAL;
1779 parameter->type = FORMAT_INT;
1780 break;
1781
1782#if TRIO_FEATURE_BINARY
1783 case SPECIFIER_BINARY_UPPER:
1784 parameter->flags |= FLAGS_UPPER;
1785 /* FALLTHROUGH */
1786 case SPECIFIER_BINARY:
1787 parameter->flags |= FLAGS_NILPADDING;
1788 parameter->baseSpecifier = BASE_BINARY;
1789 parameter->type = FORMAT_INT;
1790 break;
1791#endif
1792
1793 case SPECIFIER_HEX_UPPER:
1794 parameter->flags |= FLAGS_UPPER;
1795 /* FALLTHROUGH */
1796 case SPECIFIER_HEX:
1797 parameter->flags |= FLAGS_UNSIGNED;
1798 parameter->baseSpecifier = BASE_HEX;
1799 parameter->type = FORMAT_INT;
1800 break;
1801
1802#if defined(SPECIFIER_FLOAT_E)
1803# if defined(SPECIFIER_FLOAT_E_UPPER)
1804 case SPECIFIER_FLOAT_E_UPPER:
1805 parameter->flags |= FLAGS_UPPER;
1806 /* FALLTHROUGH */
1807# endif
1808 case SPECIFIER_FLOAT_E:
1809 parameter->flags |= FLAGS_FLOAT_E;
1810 parameter->type = FORMAT_DOUBLE;
1811 break;
1812#endif
1813
1814#if defined(SPECIFIER_FLOAT_G)
1815# if defined(SPECIFIER_FLOAT_G_UPPER)
1816 case SPECIFIER_FLOAT_G_UPPER:
1817 parameter->flags |= FLAGS_UPPER;
1818 /* FALLTHROUGH */
1819# endif
1820 case SPECIFIER_FLOAT_G:
1821 parameter->flags |= FLAGS_FLOAT_G;
1822 parameter->type = FORMAT_DOUBLE;
1823 break;
1824#endif
1825
1826#if defined(SPECIFIER_FLOAT_F)
1827# if defined(SPECIFIER_FLOAT_F_UPPER)
1828 case SPECIFIER_FLOAT_F_UPPER:
1829 parameter->flags |= FLAGS_UPPER;
1830 /* FALLTHROUGH */
1831# endif
1832 case SPECIFIER_FLOAT_F:
1833 parameter->type = FORMAT_DOUBLE;
1834 break;
1835#endif
1836
1837#if defined(TRIO_COMPILER_VISUALC)
1838# pragma warning( push )
1839# pragma warning( disable : 4127 ) /* Conditional expression is constant */
1840#endif
1841 case SPECIFIER_POINTER:
1842 if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))
1843 parameter->flags |= FLAGS_QUAD;
1844 else if (sizeof(trio_pointer_t) == sizeof(long))
1845 parameter->flags |= FLAGS_LONG;
1846 parameter->type = FORMAT_POINTER;
1847 break;
1848#if defined(TRIO_COMPILER_VISUALC)
1849# pragma warning( pop )
1850#endif
1851
1852 case SPECIFIER_COUNT:
1853 parameter->type = FORMAT_COUNT;
1854 break;
1855
1856#if TRIO_FEATURE_HEXFLOAT
1857 case SPECIFIER_HEXFLOAT_UPPER:
1858 parameter->flags |= FLAGS_UPPER;
1859 /* FALLTHROUGH */
1860 case SPECIFIER_HEXFLOAT:
1861 parameter->baseSpecifier = BASE_HEX;
1862 parameter->type = FORMAT_DOUBLE;
1863 break;
1864#endif
1865
1866#if TRIO_FEATURE_ERRNO
1867 case SPECIFIER_ERRNO:
1868 parameter->type = FORMAT_ERRNO;
1869 break;
1870#endif
1871
1872#if TRIO_FEATURE_USER_DEFINED
1873 case SPECIFIER_USER_DEFINED_BEGIN:
1874 {
1875 unsigned int max;
1876 int without_namespace = TRUE;
1877 char* tmpformat = (char *)&format[offset];
1878 int ch;
1879
1880 parameter->type = FORMAT_USER_DEFINED;
1881 parameter->user_defined.namespace[0] = NIL;
1882
1883 while ((ch = format[offset]) != NIL)
1884 {
1885 offset++;
1886 if ((ch == SPECIFIER_USER_DEFINED_END) || (ch == SPECIFIER_USER_DEFINED_EXTRA))
1887 {
1888 if (without_namespace)
1889 /* No namespace, handler will be passed as an argument */
1890 parameter->flags |= FLAGS_USER_DEFINED_PARAMETER;
1891
1892 /* Copy the user data */
1893 max = (unsigned int)(&format[offset] - tmpformat);
1894 if (max > MAX_USER_DATA)
1895 max = MAX_USER_DATA;
1896 trio_copy_max(parameter->user_data, max, tmpformat);
1897
1898 /* Skip extra data (which is only there to keep the compiler happy) */
1899 while ((ch != NIL) && (ch != SPECIFIER_USER_DEFINED_END))
1900 ch = format[offset++];
1901
1902 break; /* while */
1903 }
1904
1905 if (ch == SPECIFIER_USER_DEFINED_SEPARATOR)
1906 {
1907 without_namespace = FALSE;
1908 /* Copy the namespace for later looking-up */
1909 max = (int)(&format[offset] - tmpformat);
1910 if (max > MAX_USER_NAME)
1911 max = MAX_USER_NAME;
1912 trio_copy_max(parameter->user_defined.namespace, max, tmpformat);
1913 tmpformat = (char *)&format[offset];
1914 }
1915 }
1916
1917 if (ch != SPECIFIER_USER_DEFINED_END)
1918 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1919 }
1920 break;
1921#endif /* TRIO_FEATURE_USER_DEFINED */
1922
1923 default:
1924 /* Bail out completely to make the error more obvious */
1925 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1926 }
1927
1928 parameter->endOffset = offset;
1929
1930 return 0;
1931}
1932
1933/*************************************************************************
1934 * TrioParse
1935 *
1936 * Description:
1937 * Parse the format string
1938 */
1939TRIO_PRIVATE int
1940TrioParse
1941TRIO_ARGS5((type, format, parameters, arglist, argarray),
1942 int type,
1943 TRIO_CONST char *format,
1944 trio_parameter_t *parameters,
1945 va_list arglist,
1946 trio_pointer_t *argarray)
1947{
1948 /* Count the number of times a parameter is referenced */
1949 unsigned short usedEntries[MAX_PARAMETERS];
1950 /* Parameter counters */
1951 int parameterPosition;
1952 int maxParam = -1;
1953 /* Utility variables */
1954 int offset; /* Offset into formatting string */
1955 BOOLEAN_T positional; /* Does the specifier have a positional? */
1956#if TRIO_FEATURE_STICKY
1957 BOOLEAN_T gotSticky = FALSE; /* Are there any sticky modifiers at all? */
1958#endif
1959 /*
1960 * indices specifies the order in which the parameters must be
1961 * read from the va_args (this is necessary to handle positionals)
1962 */
1963 int indices[MAX_PARAMETERS];
1964 int pos = 0;
1965 /* Various variables */
1966#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
1967 int charlen;
1968#endif
1969 int save_errno;
1970 int i = -1;
1971 int num;
1972 trio_parameter_t workParameter;
1973 int status;
1974
1975 /*
1976 * The 'parameters' array is not initialized, but we need to
1977 * know which entries we have used.
1978 */
1979 memset(usedEntries, 0, sizeof(usedEntries));
1980
1981 save_errno = errno;
1982 offset = 0;
1983 parameterPosition = 0;
1984#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
1985 charlen = mblen(NULL, 0);
1986#endif
1987
1988 while (format[offset])
1989 {
1990 TrioInitializeParameter(&workParameter);
1991
1992#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
1993 if (! isascii(format[offset]))
1994 {
1995 /*
1996 * Multibyte characters cannot be legal specifiers or
1997 * modifiers, so we skip over them.
1998 */
1999 charlen = mblen(&format[offset], MB_LEN_MAX);
2000 offset += (charlen > 0) ? charlen : 1;
2001 continue; /* while */
2002 }
2003#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
2004
2005 switch(format[offset++]) {
2006
2007 case CHAR_IDENTIFIER:
2008 {
2009 if (CHAR_IDENTIFIER == format[offset])
2010 {
2011 /* skip double "%" */
2012 offset++;
2013 continue; /* while */
2014 }
2015
2016 status = TrioParseQualifiers(type, format, offset, &workParameter);
2017 if (status < 0)
2018 return status; /* Return qualifier syntax error */
2019
2020 status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter);
2021 if (status < 0)
2022 return status; /* Return specifier syntax error */
2023 }
2024 break;
2025
2026#if TRIO_EXTENSION
2027 case CHAR_ALT_IDENTIFIER:
2028 {
2029 status = TrioParseQualifiers(type, format, offset, &workParameter);
2030 if (status < 0)
2031 continue; /* False alert, not a user defined specifier */
2032
2033 status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter);
2034 if ((status < 0) || (FORMAT_USER_DEFINED != workParameter.type))
2035 continue; /* False alert, not a user defined specifier */
2036 }
2037 break;
2038#endif
2039
2040 default:
2041 continue; /* while */
2042 }
2043
2044 /* now handle the parsed conversion specification */
2045 positional = (NO_POSITION != workParameter.position);
2046
2047 /*
2048 * Parameters only need the type and value. The value is
2049 * read later.
2050 */
2051 if (workParameter.flags & FLAGS_WIDTH_PARAMETER)
2052 {
2053 if (workParameter.width == NO_WIDTH)
2054 {
2055 workParameter.width = parameterPosition++;
2056 }
2057 else
2058 {
2059 if (! positional)
2060 workParameter.position = workParameter.width + 1;
2061 }
2062
2063 usedEntries[workParameter.width] += 1;
2064 if (workParameter.width > maxParam)
2065 maxParam = workParameter.width;
2066 parameters[pos].type = FORMAT_PARAMETER;
2067 parameters[pos].flags = 0;
2068 indices[workParameter.width] = pos;
2069 workParameter.width = pos++;
2070 }
2071 if (workParameter.flags & FLAGS_PRECISION_PARAMETER)
2072 {
2073 if (workParameter.precision == NO_PRECISION)
2074 {
2075 workParameter.precision = parameterPosition++;
2076 }
2077 else
2078 {
2079 if (! positional)
2080 workParameter.position = workParameter.precision + 1;
2081 }
2082
2083 usedEntries[workParameter.precision] += 1;
2084 if (workParameter.precision > maxParam)
2085 maxParam = workParameter.precision;
2086 parameters[pos].type = FORMAT_PARAMETER;
2087 parameters[pos].flags = 0;
2088 indices[workParameter.precision] = pos;
2089 workParameter.precision = pos++;
2090 }
2091 if (workParameter.flags & FLAGS_BASE_PARAMETER)
2092 {
2093 if (workParameter.base == NO_BASE)
2094 {
2095 workParameter.base = parameterPosition++;
2096 }
2097 else
2098 {
2099 if (! positional)
2100 workParameter.position = workParameter.base + 1;
2101 }
2102
2103 usedEntries[workParameter.base] += 1;
2104 if (workParameter.base > maxParam)
2105 maxParam = workParameter.base;
2106 parameters[pos].type = FORMAT_PARAMETER;
2107 parameters[pos].flags = 0;
2108 indices[workParameter.base] = pos;
2109 workParameter.base = pos++;
2110 }
2111#if TRIO_FEATURE_VARSIZE
2112 if (workParameter.flags & FLAGS_VARSIZE_PARAMETER)
2113 {
2114 workParameter.varsize = parameterPosition++;
2115
2116 usedEntries[workParameter.varsize] += 1;
2117 if (workParameter.varsize > maxParam)
2118 maxParam = workParameter.varsize;
2119 parameters[pos].type = FORMAT_PARAMETER;
2120 parameters[pos].flags = 0;
2121 indices[workParameter.varsize] = pos;
2122 workParameter.varsize = pos++;
2123 }
2124#endif
2125#if TRIO_FEATURE_USER_DEFINED
2126 if (workParameter.flags & FLAGS_USER_DEFINED_PARAMETER)
2127 {
2128 workParameter.user_defined.handler = parameterPosition++;
2129
2130 usedEntries[workParameter.user_defined.handler] += 1;
2131 if (workParameter.user_defined.handler > maxParam)
2132 maxParam = workParameter.user_defined.handler;
2133 parameters[pos].type = FORMAT_PARAMETER;
2134 parameters[pos].flags = FLAGS_USER_DEFINED;
2135 indices[workParameter.user_defined.handler] = pos;
2136 workParameter.user_defined.handler = pos++;
2137 }
2138#endif
2139
2140 if (NO_POSITION == workParameter.position)
2141 {
2142 workParameter.position = parameterPosition++;
2143 }
2144
2145 if (workParameter.position > maxParam)
2146 maxParam = workParameter.position;
2147
2148 if (workParameter.position >= MAX_PARAMETERS)
2149 {
2150 /* Bail out completely to make the error more obvious */
2151 return TRIO_ERROR_RETURN(TRIO_ETOOMANY, offset);
2152 }
2153
2154 indices[workParameter.position] = pos;
2155
2156 /* Count the number of times this entry has been used */
2157 usedEntries[workParameter.position] += 1;
2158
2159 /* Find last sticky parameters */
2160#if TRIO_FEATURE_STICKY
2161 if (workParameter.flags & FLAGS_STICKY)
2162 {
2163 gotSticky = TRUE;
2164 }
2165 else if (gotSticky)
2166 {
2167 for (i = pos - 1; i >= 0; i--)
2168 {
2169 if (parameters[i].type == FORMAT_PARAMETER)
2170 continue;
2171 if ((parameters[i].flags & FLAGS_STICKY) &&
2172 (parameters[i].type == workParameter.type))
2173 {
2174 /* Do not overwrite current qualifiers */
2175 workParameter.flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY);
2176 if (workParameter.width == NO_WIDTH)
2177 workParameter.width = parameters[i].width;
2178 if (workParameter.precision == NO_PRECISION)
2179 workParameter.precision = parameters[i].precision;
2180 if (workParameter.base == NO_BASE)
2181 workParameter.base = parameters[i].base;
2182 break;
2183 }
2184 }
2185 }
2186#endif
2187
2188 if (workParameter.base == NO_BASE)
2189 workParameter.base = BASE_DECIMAL;
2190
2191 offset = workParameter.endOffset;
2192
2193 TrioCopyParameter(&parameters[pos++], &workParameter);
2194 } /* while format characters left */
2195
2196 parameters[pos].type = FORMAT_SENTINEL; /* end parameter array with sentinel */
2197 parameters[pos].beginOffset = offset;
2198
2199 for (num = 0; num <= maxParam; num++)
2200 {
2201 if (usedEntries[num] != 1)
2202 {
2203 if (usedEntries[num] == 0) /* gap detected */
2204 return TRIO_ERROR_RETURN(TRIO_EGAP, num);
2205 else /* double references detected */
2206 return TRIO_ERROR_RETURN(TRIO_EDBLREF, num);
2207 }
2208
2209 i = indices[num];
2210
2211 /*
2212 * FORMAT_PARAMETERS are only present if they must be read,
2213 * so it makes no sense to check the ignore flag (besides,
2214 * the flags variable is not set for that particular type)
2215 */
2216 if ((parameters[i].type != FORMAT_PARAMETER) &&
2217 (parameters[i].flags & FLAGS_IGNORE))
2218 continue; /* for all arguments */
2219
2220 /*
2221 * The stack arguments are read according to ANSI C89
2222 * default argument promotions:
2223 *
2224 * char = int
2225 * short = int
2226 * unsigned char = unsigned int
2227 * unsigned short = unsigned int
2228 * float = double
2229 *
2230 * In addition to the ANSI C89 these types are read (the
2231 * default argument promotions of C99 has not been
2232 * considered yet)
2233 *
2234 * long long
2235 * long double
2236 * size_t
2237 * ptrdiff_t
2238 * intmax_t
2239 */
2240 switch (parameters[i].type)
2241 {
2242 case FORMAT_GROUP:
2243 case FORMAT_STRING:
2244#if TRIO_FEATURE_WIDECHAR
2245 if (parameters[i].flags & FLAGS_WIDECHAR)
2246 {
2247 parameters[i].data.wstring = (argarray == NULL)
2248 ? va_arg(arglist, trio_wchar_t *)
2249 : (trio_wchar_t *)(argarray[num]);
2250 }
2251 else
2252#endif
2253 {
2254 parameters[i].data.string = (argarray == NULL)
2255 ? va_arg(arglist, char *)
2256 : (char *)(argarray[num]);
2257 }
2258 break;
2259
2260#if TRIO_FEATURE_USER_DEFINED
2261 case FORMAT_USER_DEFINED:
2262#endif
2263 case FORMAT_POINTER:
2264 case FORMAT_COUNT:
2265 case FORMAT_UNKNOWN:
2266 parameters[i].data.pointer = (argarray == NULL)
2267 ? va_arg(arglist, trio_pointer_t )
2268 : argarray[num];
2269 break;
2270
2271 case FORMAT_CHAR:
2272 case FORMAT_INT:
2273#if TRIO_FEATURE_SCANF
2274 if (TYPE_SCAN == type)
2275 {
2276 if (argarray == NULL)
2277 parameters[i].data.pointer =
2278 (trio_pointer_t)va_arg(arglist, trio_pointer_t);
2279 else
2280 {
2281 if (parameters[i].type == FORMAT_CHAR)
2282 parameters[i].data.pointer =
2283 (trio_pointer_t)((char *)argarray[num]);
2284 else if (parameters[i].flags & FLAGS_SHORT)
2285 parameters[i].data.pointer =
2286 (trio_pointer_t)((short *)argarray[num]);
2287 else
2288 parameters[i].data.pointer =
2289 (trio_pointer_t)((int *)argarray[num]);
2290 }
2291 }
2292 else
2293#endif /* TRIO_FEATURE_SCANF */
2294 {
2295#if TRIO_FEATURE_VARSIZE || TRIO_FEATURE_FIXED_SIZE
2296 if (parameters[i].flags
2297 & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE))
2298 {
2299 int varsize;
2300 if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER)
2301 {
2302 /*
2303 * Variable sizes are mapped onto the fixed sizes, in
2304 * accordance with integer promotion.
2305 *
2306 * Please note that this may not be portable, as we
2307 * only guess the size, not the layout of the numbers.
2308 * For example, if int is little-endian, and long is
2309 * big-endian, then this will fail.
2310 */
2311 varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned;
2312 }
2313 else
2314 {
2315 /* Used for the I<bits> modifiers */
2316 varsize = parameters[i].varsize;
2317 }
2318 parameters[i].flags &= ~FLAGS_ALL_VARSIZES;
2319
2320 if (varsize <= (int)sizeof(int))
2321 ;
2322 else if (varsize <= (int)sizeof(long))
2323 parameters[i].flags |= FLAGS_LONG;
2324#if TRIO_FEATURE_INTMAX_T
2325 else if (varsize <= (int)sizeof(trio_longlong_t))
2326 parameters[i].flags |= FLAGS_QUAD;
2327 else
2328 parameters[i].flags |= FLAGS_INTMAX_T;
2329#else
2330 else
2331 parameters[i].flags |= FLAGS_QUAD;
2332#endif
2333 }
2334#endif /* TRIO_FEATURE_VARSIZE */
2335#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
2336 if (parameters[i].flags & FLAGS_SIZE_T)
2337 parameters[i].data.number.as_unsigned = (argarray == NULL)
2338 ? (trio_uintmax_t)va_arg(arglist, size_t)
2339 : (trio_uintmax_t)(*((size_t *)argarray[num]));
2340 else
2341#endif
2342#if TRIO_FEATURE_PTRDIFF_T
2343 if (parameters[i].flags & FLAGS_PTRDIFF_T)
2344 parameters[i].data.number.as_unsigned = (argarray == NULL)
2345 ? (trio_uintmax_t)va_arg(arglist, ptrdiff_t)
2346 : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
2347 else
2348#endif
2349#if TRIO_FEATURE_INTMAX_T
2350 if (parameters[i].flags & FLAGS_INTMAX_T)
2351 parameters[i].data.number.as_unsigned = (argarray == NULL)
2352 ? (trio_uintmax_t)va_arg(arglist, trio_intmax_t)
2353 : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
2354 else
2355#endif
2356 if (parameters[i].flags & FLAGS_QUAD)
2357 parameters[i].data.number.as_unsigned = (argarray == NULL)
2358 ? (trio_uintmax_t)va_arg(arglist, trio_ulonglong_t)
2359 : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
2360 else if (parameters[i].flags & FLAGS_LONG)
2361 parameters[i].data.number.as_unsigned = (argarray == NULL)
2362 ? (trio_uintmax_t)va_arg(arglist, long)
2363 : (trio_uintmax_t)(*((long *)argarray[num]));
2364 else
2365 {
2366 if (argarray == NULL)
2367 parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(arglist, int);
2368 else
2369 {
2370 if (parameters[i].type == FORMAT_CHAR)
2371 parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num]));
2372 else if (parameters[i].flags & FLAGS_SHORT)
2373 parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num]));
2374 else
2375 parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num]));
2376 }
2377 }
2378 }
2379 break;
2380
2381 case FORMAT_PARAMETER:
2382 /*
2383 * The parameter for the user-defined specifier is a pointer,
2384 * whereas the rest (width, precision, base) uses an integer.
2385 */
2386 if (parameters[i].flags & FLAGS_USER_DEFINED)
2387 parameters[i].data.pointer = (argarray == NULL)
2388 ? va_arg(arglist, trio_pointer_t )
2389 : argarray[num];
2390 else
2391 parameters[i].data.number.as_unsigned = (argarray == NULL)
2392 ? (trio_uintmax_t)va_arg(arglist, int)
2393 : (trio_uintmax_t)(*((int *)argarray[num]));
2394 break;
2395
2396#if TRIO_FEATURE_FLOAT
2397 case FORMAT_DOUBLE:
2398# if TRIO_FEATURE_SCANF
2399 if (TYPE_SCAN == type)
2400 {
2401 if (parameters[i].flags & FLAGS_LONGDOUBLE)
2402 parameters[i].data.longdoublePointer = (argarray == NULL)
2403 ? va_arg(arglist, trio_long_double_t *)
2404 : (trio_long_double_t *)argarray[num];
2405 else
2406 {
2407 if (parameters[i].flags & FLAGS_LONG)
2408 parameters[i].data.doublePointer = (argarray == NULL)
2409 ? va_arg(arglist, double *)
2410 : (double *)argarray[num];
2411 else
2412 parameters[i].data.doublePointer = (argarray == NULL)
2413 ? (double *)va_arg(arglist, float *)
2414 : (double *)((float *)argarray[num]);
2415 }
2416 }
2417 else
2418# endif /* TRIO_FEATURE_SCANF */
2419 {
2420 if (parameters[i].flags & FLAGS_LONGDOUBLE)
2421 parameters[i].data.longdoubleNumber = (argarray == NULL)
2422 ? va_arg(arglist, trio_long_double_t)
2423 : (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
2424 else
2425 {
2426 if (argarray == NULL)
2427 parameters[i].data.longdoubleNumber =
2428 (trio_long_double_t)va_arg(arglist, double);
2429 else
2430 {
2431 if (parameters[i].flags & FLAGS_SHORT)
2432 parameters[i].data.longdoubleNumber =
2433 (trio_long_double_t)(*((float *)argarray[num]));
2434 else
2435 parameters[i].data.longdoubleNumber =
2436 (trio_long_double_t)(*((double *)argarray[num]));
2437 }
2438 }
2439 }
2440 break;
2441#endif /* TRIO_FEATURE_FLOAT */
2442
2443#if TRIO_FEATURE_ERRNO
2444 case FORMAT_ERRNO:
2445 parameters[i].data.errorNumber = save_errno;
2446 break;
2447#endif
2448
2449 default:
2450 break;
2451 }
2452 } /* for all specifiers */
2453 return num;
2454}
2455
2456
2457/*************************************************************************
2458 *
2459 * FORMATTING
2460 *
2461 ************************************************************************/
2462
2463
2464/*************************************************************************
2465 * TrioWriteNumber
2466 *
2467 * Description:
2468 * Output a number.
2469 * The complexity of this function is a result of the complexity
2470 * of the dependencies of the flags.
2471 */
2472TRIO_PRIVATE void
2473TrioWriteNumber
2474TRIO_ARGS6((self, number, flags, width, precision, base),
2475 trio_class_t *self,
2476 trio_uintmax_t number,
2477 trio_flags_t flags,
2478 int width,
2479 int precision,
2480 int base)
2481{
2482 BOOLEAN_T isNegative;
2483 BOOLEAN_T isNumberZero;
2484 BOOLEAN_T isPrecisionZero;
2485 BOOLEAN_T ignoreNumber;
2486 char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1];
2487 char *bufferend;
2488 char *pointer;
2489 TRIO_CONST char *digits;
2490 int i;
2491#if TRIO_FEATURE_QUOTE
2492 int length;
2493 char *p;
2494#endif
2495 int count;
2496 int digitOffset;
2497
2498 assert(VALID(self));
2499 assert(VALID(self->OutStream));
2500 assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
2501
2502 digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
2503 if (base == NO_BASE)
2504 base = BASE_DECIMAL;
2505
2506 isNumberZero = (number == 0);
2507 isPrecisionZero = (precision == 0);
2508 ignoreNumber = (isNumberZero
2509 && isPrecisionZero
2510 && !((flags & FLAGS_ALTERNATIVE) && (base == BASE_OCTAL)));
2511
2512 if (flags & FLAGS_UNSIGNED)
2513 {
2514 isNegative = FALSE;
2515 flags &= ~FLAGS_SHOWSIGN;
2516 }
2517 else
2518 {
2519 isNegative = ((trio_intmax_t)number < 0);
2520 if (isNegative)
2521 number = -((trio_intmax_t)number);
2522 }
2523
2524 if (flags & FLAGS_QUAD)
2525 number &= (trio_ulonglong_t)-1;
2526 else if (flags & FLAGS_LONG)
2527 number &= (unsigned long)-1;
2528 else
2529 number &= (unsigned int)-1;
2530
2531 /* Build number */
2532 pointer = bufferend = &buffer[sizeof(buffer) - 1];
2533 *pointer-- = NIL;
2534 for (i = 1; i < (int)sizeof(buffer); i++)
2535 {
2536 digitOffset = number % base;
2537 *pointer-- = digits[digitOffset];
2538 number /= base;
2539 if (number == 0)
2540 break;
2541
2542#if TRIO_FEATURE_QUOTE
2543 if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1))
2544 {
2545 /*
2546 * We are building the number from the least significant
2547 * to the most significant digit, so we have to copy the
2548 * thousand separator backwards
2549 */
2550 length = internalThousandSeparatorLength;
2551 if (((int)(pointer - buffer) - length) > 0)
2552 {
2553 p = &internalThousandSeparator[length - 1];
2554 while (length-- > 0)
2555 *pointer-- = *p--;
2556 }
2557 }
2558#endif
2559 }
2560
2561 if (! ignoreNumber)
2562 {
2563 /* Adjust width */
2564 width -= (bufferend - pointer) - 1;
2565 }
2566
2567 /* Adjust precision */
2568 if (NO_PRECISION != precision)
2569 {
2570 precision -= (bufferend - pointer) - 1;
2571 if (precision < 0)
2572 precision = 0;
2573 flags |= FLAGS_NILPADDING;
2574 }
2575
2576 /* Calculate padding */
2577 count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION)))
2578 ? precision
2579 : 0;
2580
2581 /* Adjust width further */
2582 if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
2583 width--;
2584 if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)
2585 {
2586 switch (base)
2587 {
2588 case BASE_BINARY:
2589 case BASE_HEX:
2590 width -= 2;
2591 break;
2592 case BASE_OCTAL:
2593 if (!(flags & FLAGS_NILPADDING) || (count == 0))
2594 width--;
2595 break;
2596 default:
2597 break;
2598 }
2599 }
2600
2601 /* Output prefixes spaces if needed */
2602 if (! ((flags & FLAGS_LEFTADJUST) ||
2603 ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION))))
2604 {
2605 while (width-- > count)
2606 self->OutStream(self, CHAR_ADJUST);
2607 }
2608
2609 /* width has been adjusted for signs and alternatives */
2610 if (isNegative)
2611 self->OutStream(self, '-');
2612 else if (flags & FLAGS_SHOWSIGN)
2613 self->OutStream(self, '+');
2614 else if (flags & FLAGS_SPACE)
2615 self->OutStream(self, ' ');
2616
2617 /* Prefix is not written when the value is zero */
2618 if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)
2619 {
2620 switch (base)
2621 {
2622 case BASE_BINARY:
2623 self->OutStream(self, '0');
2624 self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b');
2625 break;
2626
2627 case BASE_OCTAL:
2628 if (!(flags & FLAGS_NILPADDING) || (count == 0))
2629 self->OutStream(self, '0');
2630 break;
2631
2632 case BASE_HEX:
2633 self->OutStream(self, '0');
2634 self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
2635 break;
2636
2637 default:
2638 break;
2639 } /* switch base */
2640 }
2641
2642 /* Output prefixed zero padding if needed */
2643 if (flags & FLAGS_NILPADDING)
2644 {
2645 if (precision == NO_PRECISION)
2646 precision = width;
2647 while (precision-- > 0)
2648 {
2649 self->OutStream(self, '0');
2650 width--;
2651 }
2652 }
2653
2654 if (! ignoreNumber)
2655 {
2656 /* Output the number itself */
2657 while (*(++pointer))
2658 {
2659 self->OutStream(self, *pointer);
2660 }
2661 }
2662
2663 /* Output trailing spaces if needed */
2664 if (flags & FLAGS_LEFTADJUST)
2665 {
2666 while (width-- > 0)
2667 self->OutStream(self, CHAR_ADJUST);
2668 }
2669}
2670
2671/*************************************************************************
2672 * TrioWriteStringCharacter
2673 *
2674 * Description:
2675 * Output a single character of a string
2676 */
2677TRIO_PRIVATE void
2678TrioWriteStringCharacter
2679TRIO_ARGS3((self, ch, flags),
2680 trio_class_t *self,
2681 int ch,
2682 trio_flags_t flags)
2683{
2684 if (flags & FLAGS_ALTERNATIVE)
2685 {
2686 if (! isprint(ch))
2687 {
2688 /*
2689 * Non-printable characters are converted to C escapes or
2690 * \number, if no C escape exists.
2691 */
2692 self->OutStream(self, CHAR_BACKSLASH);
2693 switch (ch)
2694 {
2695 case '\007': self->OutStream(self, 'a'); break;
2696 case '\b': self->OutStream(self, 'b'); break;
2697 case '\f': self->OutStream(self, 'f'); break;
2698 case '\n': self->OutStream(self, 'n'); break;
2699 case '\r': self->OutStream(self, 'r'); break;
2700 case '\t': self->OutStream(self, 't'); break;
2701 case '\v': self->OutStream(self, 'v'); break;
2702 case '\\': self->OutStream(self, '\\'); break;
2703 default:
2704 self->OutStream(self, 'x');
2705 TrioWriteNumber(self, (trio_uintmax_t)ch,
2706 FLAGS_UNSIGNED | FLAGS_NILPADDING,
2707 2, 2, BASE_HEX);
2708 break;
2709 }
2710 }
2711 else if (ch == CHAR_BACKSLASH)
2712 {
2713 self->OutStream(self, CHAR_BACKSLASH);
2714 self->OutStream(self, CHAR_BACKSLASH);
2715 }
2716 else
2717 {
2718 self->OutStream(self, ch);
2719 }
2720 }
2721 else
2722 {
2723 self->OutStream(self, ch);
2724 }
2725}
2726
2727/*************************************************************************
2728 * TrioWriteString
2729 *
2730 * Description:
2731 * Output a string
2732 */
2733TRIO_PRIVATE void
2734TrioWriteString
2735TRIO_ARGS5((self, string, flags, width, precision),
2736 trio_class_t *self,
2737 TRIO_CONST char *string,
2738 trio_flags_t flags,
2739 int width,
2740 int precision)
2741{
2742 int length;
2743 int ch;
2744
2745 assert(VALID(self));
2746 assert(VALID(self->OutStream));
2747
2748 if (string == NULL)
2749 {
2750 string = internalNullString;
2751 length = sizeof(internalNullString) - 1;
2752#if TRIO_FEATURE_QUOTE
2753 /* Disable quoting for the null pointer */
2754 flags &= (~FLAGS_QUOTE);
2755#endif
2756 width = 0;
2757 }
2758 else
2759 {
2760 if (precision == 0)
2761 {
2762 length = trio_length(string);
2763 }
2764 else
2765 {
2766 length = trio_length_max(string, precision);
2767 }
2768 }
2769 if ((NO_PRECISION != precision) &&
2770 (precision < length))
2771 {
2772 length = precision;
2773 }
2774 width -= length;
2775
2776#if TRIO_FEATURE_QUOTE
2777 if (flags & FLAGS_QUOTE)
2778 self->OutStream(self, CHAR_QUOTE);
2779#endif
2780
2781 if (! (flags & FLAGS_LEFTADJUST))
2782 {
2783 while (width-- > 0)
2784 self->OutStream(self, CHAR_ADJUST);
2785 }
2786
2787 while (length-- > 0)
2788 {
2789 /* The ctype parameters must be an unsigned char (or EOF) */
2790 ch = (int)((unsigned char)(*string++));
2791 TrioWriteStringCharacter(self, ch, flags);
2792 }
2793
2794 if (flags & FLAGS_LEFTADJUST)
2795 {
2796 while (width-- > 0)
2797 self->OutStream(self, CHAR_ADJUST);
2798 }
2799#if TRIO_FEATURE_QUOTE
2800 if (flags & FLAGS_QUOTE)
2801 self->OutStream(self, CHAR_QUOTE);
2802#endif
2803}
2804
2805/*************************************************************************
2806 * TrioWriteWideStringCharacter
2807 *
2808 * Description:
2809 * Output a wide string as a multi-byte sequence
2810 */
2811#if TRIO_FEATURE_WIDECHAR
2812TRIO_PRIVATE int
2813TrioWriteWideStringCharacter
2814TRIO_ARGS4((self, wch, flags, width),
2815 trio_class_t *self,
2816 trio_wchar_t wch,
2817 trio_flags_t flags,
2818 int width)
2819{
2820 int size;
2821 int i;
2822 int ch;
2823 char *string;
2824 char buffer[MB_LEN_MAX + 1];
2825
2826 if (width == NO_WIDTH)
2827 width = sizeof(buffer);
2828
2829 size = wctomb(buffer, wch);
2830 if ((size <= 0) || (size > width) || (buffer[0] == NIL))
2831 return 0;
2832
2833 string = buffer;
2834 i = size;
2835 while ((width >= i) && (width-- > 0) && (i-- > 0))
2836 {
2837 /* The ctype parameters must be an unsigned char (or EOF) */
2838 ch = (int)((unsigned char)(*string++));
2839 TrioWriteStringCharacter(self, ch, flags);
2840 }
2841 return size;
2842}
2843#endif /* TRIO_FEATURE_WIDECHAR */
2844
2845/*************************************************************************
2846 * TrioWriteWideString
2847 *
2848 * Description:
2849 * Output a wide character string as a multi-byte string
2850 */
2851#if TRIO_FEATURE_WIDECHAR
2852TRIO_PRIVATE void
2853TrioWriteWideString
2854TRIO_ARGS5((self, wstring, flags, width, precision),
2855 trio_class_t *self,
2856 TRIO_CONST trio_wchar_t *wstring,
2857 trio_flags_t flags,
2858 int width,
2859 int precision)
2860{
2861 int length;
2862 int size;
2863
2864 assert(VALID(self));
2865 assert(VALID(self->OutStream));
2866
2867#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
2868 /* Required by TrioWriteWideStringCharacter */
2869 length = mblen(NULL, 0);
2870#endif
2871
2872 if (wstring == NULL)
2873 {
2874 TrioWriteString(self, NULL, flags, width, precision);
2875 return;
2876 }
2877
2878 if (NO_PRECISION == precision)
2879 {
2880 length = INT_MAX;
2881 }
2882 else
2883 {
2884 length = precision;
2885 width -= length;
2886 }
2887
2888#if TRIO_FEATURE_QUOTE
2889 if (flags & FLAGS_QUOTE)
2890 self->OutStream(self, CHAR_QUOTE);
2891#endif
2892
2893 if (! (flags & FLAGS_LEFTADJUST))
2894 {
2895 while (width-- > 0)
2896 self->OutStream(self, CHAR_ADJUST);
2897 }
2898
2899 while (length > 0)
2900 {
2901 size = TrioWriteWideStringCharacter(self, *wstring++, flags, length);
2902 if (size == 0)
2903 break; /* while */
2904 length -= size;
2905 }
2906
2907 if (flags & FLAGS_LEFTADJUST)
2908 {
2909 while (width-- > 0)
2910 self->OutStream(self, CHAR_ADJUST);
2911 }
2912#if TRIO_FEATURE_QUOTE
2913 if (flags & FLAGS_QUOTE)
2914 self->OutStream(self, CHAR_QUOTE);
2915#endif
2916}
2917#endif /* TRIO_FEATURE_WIDECHAR */
2918
2919/*************************************************************************
2920 * TrioWriteDouble
2921 *
2922 * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm
2923 *
2924 * "5.2.4.2.2 paragraph #4
2925 *
2926 * The accuracy [...] is implementation defined, as is the accuracy
2927 * of the conversion between floating-point internal representations
2928 * and string representations performed by the libray routine in
2929 * <stdio.h>"
2930 */
2931/* FIXME: handle all instances of constant long-double number (L)
2932 * and *l() math functions.
2933 */
2934#if TRIO_FEATURE_FLOAT
2935TRIO_PRIVATE void
2936TrioWriteDouble
2937TRIO_ARGS6((self, number, flags, width, precision, base),
2938 trio_class_t *self,
2939 trio_long_double_t number,
2940 trio_flags_t flags,
2941 int width,
2942 int precision,
2943 int base)
2944{
2945 trio_long_double_t integerNumber;
2946 trio_long_double_t fractionNumber;
2947 trio_long_double_t workNumber;
2948 int integerDigits;
2949 int fractionDigits;
2950 int exponentDigits;
2951 int workDigits;
2952 int baseDigits;
2953 int integerThreshold;
2954 int fractionThreshold;
2955 int expectedWidth;
2956 int exponent = 0;
2957 unsigned int uExponent = 0;
2958 int exponentBase;
2959 trio_long_double_t dblBase;
2960 trio_long_double_t dblFractionBase;
2961 trio_long_double_t integerAdjust;
2962 trio_long_double_t fractionAdjust;
2963 trio_long_double_t workFractionNumber;
2964 trio_long_double_t workFractionAdjust;
2965 int fractionDigitsInspect;
2966 BOOLEAN_T isNegative;
2967 BOOLEAN_T isExponentNegative = FALSE;
2968 BOOLEAN_T requireTwoDigitExponent;
2969 BOOLEAN_T isHex;
2970 TRIO_CONST char *digits;
2971# if TRIO_FEATURE_QUOTE
2972 char *groupingPointer;
2973# endif
2974 int i;
2975 int offset;
2976 BOOLEAN_T hasOnlyZeroes;
2977 int leadingFractionZeroes = -1;
2978 register int trailingZeroes;
2979 BOOLEAN_T keepTrailingZeroes;
2980 BOOLEAN_T keepDecimalPoint;
2981 trio_long_double_t epsilon;
2982 BOOLEAN_T adjustNumber = FALSE;
2983
2984 assert(VALID(self));
2985 assert(VALID(self->OutStream));
2986 assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
2987
2988 /* Determine sign and look for special quantities */
2989 switch (trio_fpclassify_and_signbit(number, &isNegative))
2990 {
2991 case TRIO_FP_NAN:
2992 TrioWriteString(self,
2993 (flags & FLAGS_UPPER)
2994 ? NAN_UPPER
2995 : NAN_LOWER,
2996 flags, width, precision);
2997 return;
2998
2999 case TRIO_FP_INFINITE:
3000 if (isNegative)
3001 {
3002 /* Negative infinity */
3003 TrioWriteString(self,
3004 (flags & FLAGS_UPPER)
3005 ? "-" INFINITE_UPPER
3006 : "-" INFINITE_LOWER,
3007 flags, width, precision);
3008 return;
3009 }
3010 else
3011 {
3012 /* Positive infinity */
3013 TrioWriteString(self,
3014 (flags & FLAGS_UPPER)
3015 ? INFINITE_UPPER
3016 : INFINITE_LOWER,
3017 flags, width, precision);
3018 return;
3019 }
3020
3021 default:
3022 /* Finitude */
3023 break;
3024 }
3025
3026 /* Normal numbers */
3027 if (flags & FLAGS_LONGDOUBLE)
3028 {
3029 baseDigits = (base == 10)
3030 ? LDBL_DIG
3031 : (int)trio_floor(LDBL_MANT_DIG / TrioLogarithmBase(base));
3032 epsilon = LDBL_EPSILON;
3033 }
3034 else if (flags & FLAGS_SHORT)
3035 {
3036 baseDigits = (base == BASE_DECIMAL)
3037 ? FLT_DIG
3038 : (int)trio_floor(FLT_MANT_DIG / TrioLogarithmBase(base));
3039 epsilon = FLT_EPSILON;
3040 }
3041 else
3042 {
3043 baseDigits = (base == BASE_DECIMAL)
3044 ? DBL_DIG
3045 : (int)trio_floor(DBL_MANT_DIG / TrioLogarithmBase(base));
3046 epsilon = DBL_EPSILON;
3047 }
3048
3049 digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
3050 isHex = (base == BASE_HEX);
3051 if (base == NO_BASE)
3052 base = BASE_DECIMAL;
3053 dblBase = (trio_long_double_t)base;
3054 keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) ||
3055 ( (flags & FLAGS_FLOAT_G) &&
3056 !(flags & FLAGS_ALTERNATIVE) ) );
3057
3058# if TRIO_FEATURE_ROUNDING
3059 if (flags & FLAGS_ROUNDING)
3060 {
3061 precision = baseDigits;
3062 }
3063# endif
3064
3065 if (precision == NO_PRECISION)
3066 {
3067 if (isHex)
3068 {
3069 keepTrailingZeroes = FALSE;
3070 precision = FLT_MANT_DIG;
3071 }
3072 else
3073 {
3074 precision = FLT_DIG;
3075 }
3076 }
3077
3078 if (isNegative)
3079 {
3080 number = -number;
3081 }
3082
3083 if (isHex)
3084 {
3085 flags |= FLAGS_FLOAT_E;
3086 }
3087
3088 reprocess:
3089
3090 if (flags & FLAGS_FLOAT_G)
3091 {
3092 if (precision == 0)
3093 precision = 1;
3094
3095#if 0 /* GS Modification */
3096 if ( (number < TRIO_SUFFIX_LONG(1.0E-4)) ||
3097 (number >= TrioPower(base, (trio_long_double_t)precision)) )
3098#else /* GS Modification */
3099 /* This gives us a better match to the trip over point that we want */
3100 if ( (number < TRIO_SUFFIX_LONG(9.9999989999999991e-05)) ||
3101 (number >= TrioPower(base, (trio_long_double_t)precision)) )
3102#endif /* GS Modification */
3103 {
3104 /* Use scientific notation */
3105 flags |= FLAGS_FLOAT_E;
3106 }
3107 else if (number < 1.0)
3108 {
3109 /*
3110 * Use normal notation. If the integer part of the number is
3111 * zero, then adjust the precision to include leading fractional
3112 * zeros.
3113 */
3114 workNumber = TrioLogarithm(number, base);
3115 workNumber = TRIO_FABS(workNumber);
3116 if (workNumber - trio_floor(workNumber) < epsilon)
3117 workNumber--;
3118 leadingFractionZeroes = (int)trio_floor(workNumber);
3119 }
3120 }
3121
3122 if (flags & FLAGS_FLOAT_E)
3123 {
3124 /* Scale the number */
3125 workNumber = TrioLogarithm(number, base);
3126 if (trio_isinf(workNumber) == -1)
3127 {
3128 exponent = 0;
3129 /* Undo setting */
3130 if (flags & FLAGS_FLOAT_G)
3131 flags &= ~FLAGS_FLOAT_E;
3132 }
3133 else
3134 {
3135 exponent = (int)trio_floor(workNumber);
3136 workNumber = number;
3137 /*
3138 * The expression A * 10^-B is equivalent to A / 10^B but the former
3139 * usually gives better accuracy.
3140 */
3141 workNumber *= TrioPower(dblBase, (trio_long_double_t)-exponent);
3142 if (trio_isinf(workNumber)) {
3143 /*
3144 * Scaling is done it two steps to avoid problems with subnormal
3145 * numbers.
3146 */
3147 workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent / 2));
3148 workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent - (exponent / 2)));
3149 }
3150 number = workNumber;
3151 isExponentNegative = (exponent < 0);
3152 uExponent = (isExponentNegative) ? -exponent : exponent;
3153 if (isHex)
3154 uExponent *= 4; /* log16(2) */
3155#if TRIO_FEATURE_QUOTE
3156 /* No thousand separators */
3157 flags &= ~FLAGS_QUOTE;
3158#endif
3159 }
3160 }
3161
3162 integerNumber = trio_floor(number);
3163 fractionNumber = number - integerNumber;
3164
3165 /*
3166 * Truncated number.
3167 *
3168 * Precision is number of significant digits for FLOAT_G and number of
3169 * fractional digits for others.
3170 */
3171 integerDigits = 1;
3172 if (integerNumber > epsilon)
3173 {
3174 integerDigits += (int)TrioLogarithm(integerNumber, base);
3175 }
3176
3177 fractionDigits = precision;
3178 if (flags & FLAGS_FLOAT_G)
3179 {
3180 if (leadingFractionZeroes > 0)
3181 {
3182 fractionDigits += leadingFractionZeroes;
3183 }
3184 if ((integerNumber > epsilon) || (number <= epsilon))
3185 {
3186 fractionDigits -= integerDigits;
3187 }
3188 }
3189
3190 dblFractionBase = TrioPower(base, fractionDigits);
3191
3192 if (integerNumber < 1.0)
3193 {
3194 workNumber = number * dblFractionBase + TRIO_SUFFIX_LONG(0.5);
3195 if (trio_floor(number * dblFractionBase) != trio_floor(workNumber))
3196 {
3197 adjustNumber = TRUE;
3198 /* Remove a leading fraction zero if fraction is rounded up */
3199 if ((int)TrioLogarithm(number * dblFractionBase, base) != (int)TrioLogarithm(workNumber, base))
3200 {
3201 --leadingFractionZeroes;
3202 }
3203 }
3204 workNumber /= dblFractionBase;
3205 }
3206 else
3207 {
3208 workNumber = number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase;
3209 adjustNumber = (trio_floor(number) != trio_floor(workNumber));
3210 }
3211 if (adjustNumber)
3212 {
3213 if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_FLOAT_E))
3214 {
3215 /* The adjustment may require a change to scientific notation */
3216 if ( (workNumber < TRIO_SUFFIX_LONG(1.0E-4)) ||
3217 (workNumber >= TrioPower(base, (trio_long_double_t)precision)) )
3218 {
3219 /* Use scientific notation */
3220 flags |= FLAGS_FLOAT_E;
3221 goto reprocess;
3222 }
3223 }
3224
3225 if (flags & FLAGS_FLOAT_E)
3226 {
3227 workDigits = 1 + TrioLogarithm(trio_floor(workNumber), base);
3228 if (integerDigits == workDigits)
3229 {
3230 /* Adjust if the same number of digits are used */
3231 number += TRIO_SUFFIX_LONG(0.5) / dblFractionBase;
3232 integerNumber = trio_floor(number);
3233 fractionNumber = number - integerNumber;
3234 }
3235 else
3236 {
3237 /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */
3238 exponent++;
3239 isExponentNegative = (exponent < 0);
3240 uExponent = (isExponentNegative) ? -exponent : exponent;
3241 if (isHex)
3242 uExponent *= 4; /* log16(2) */
3243 workNumber = (number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase) / dblBase;
3244 integerNumber = trio_floor(workNumber);
3245 fractionNumber = workNumber - integerNumber;
3246 }
3247 }
3248 else
3249 {
3250 if (workNumber > 1.0)
3251 {
3252 /* Adjust if number was rounded up one digit (ie. 99 to 100) */
3253 integerNumber = trio_floor(workNumber);
3254 fractionNumber = 0.0;
3255 integerDigits = (integerNumber > epsilon)
3256 ? 1 + (int)TrioLogarithm(integerNumber, base)
3257 : 1;
3258 if (flags & FLAGS_FLOAT_G)
3259 {
3260 if (flags & FLAGS_ALTERNATIVE)
3261 {
3262 if ((integerNumber > epsilon) || (number <= epsilon))
3263 {
3264 fractionDigits -= integerDigits;
3265 }
3266 }
3267 else
3268 {
3269 fractionDigits = 0;
3270 }
3271 }
3272 }
3273 else
3274 {
3275 integerNumber = trio_floor(workNumber);
3276 fractionNumber = workNumber - integerNumber;
3277 if (flags & FLAGS_FLOAT_G)
3278 {
3279 if (flags & FLAGS_ALTERNATIVE)
3280 {
3281 fractionDigits = precision;
3282 if (leadingFractionZeroes > 0)
3283 {
3284 fractionDigits += leadingFractionZeroes;
3285 }
3286 if ((integerNumber > epsilon) || (number <= epsilon))
3287 {
3288 fractionDigits -= integerDigits;
3289 }
3290 }
3291 }
3292 }
3293 }
3294 }
3295
3296 /* Estimate accuracy */
3297 integerAdjust = fractionAdjust = TRIO_SUFFIX_LONG(0.5);
3298# if TRIO_FEATURE_ROUNDING
3299 if (flags & FLAGS_ROUNDING)
3300 {
3301 if (integerDigits > baseDigits)
3302 {
3303 integerThreshold = baseDigits;
3304 fractionDigits = 0;
3305 dblFractionBase = 1.0;
3306 fractionThreshold = 0;
3307 precision = 0; /* Disable decimal-point */
3308 integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1);
3309 fractionAdjust = 0.0;
3310 }
3311 else
3312 {
3313 integerThreshold = integerDigits;
3314 fractionThreshold = fractionDigits - integerThreshold;
3315 fractionAdjust = 1.0;
3316 }
3317 }
3318 else
3319# endif
3320 {
3321 integerThreshold = INT_MAX;
3322 fractionThreshold = INT_MAX;
3323 }
3324
3325 /*
3326 * Calculate expected width.
3327 * sign + integer part + thousands separators + decimal point
3328 * + fraction + exponent
3329 */
3330 fractionAdjust /= dblFractionBase;
3331 hasOnlyZeroes = (trio_floor((fractionNumber + fractionAdjust) *
3332 dblFractionBase) < epsilon);
3333 keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) ||
3334 !((precision == 0) ||
3335 (!keepTrailingZeroes && hasOnlyZeroes)) );
3336
3337 expectedWidth = integerDigits + fractionDigits;
3338
3339 if (!keepTrailingZeroes)
3340 {
3341 trailingZeroes = 0;
3342 workFractionNumber = fractionNumber;
3343 workFractionAdjust = fractionAdjust;
3344 fractionDigitsInspect = fractionDigits;
3345
3346 if (integerDigits > integerThreshold)
3347 {
3348 fractionDigitsInspect = 0;
3349 }
3350 else if (fractionThreshold <= fractionDigits)
3351 {
3352 fractionDigitsInspect = fractionThreshold + 1;
3353 }
3354
3355 trailingZeroes = fractionDigits - fractionDigitsInspect;
3356 for (i = 0; i < fractionDigitsInspect; i++)
3357 {
3358 workFractionNumber *= dblBase;
3359 workFractionAdjust *= dblBase;
3360 workNumber = trio_floor(workFractionNumber + workFractionAdjust);
3361 workFractionNumber -= workNumber;
3362 offset = (int)trio_fmod(workNumber, dblBase);
3363 if (offset == 0)
3364 {
3365 trailingZeroes++;
3366 }
3367 else
3368 {
3369 trailingZeroes = 0;
3370 }
3371 }
3372 expectedWidth -= trailingZeroes;
3373 }
3374
3375 if (keepDecimalPoint)
3376 {
3377 expectedWidth += internalDecimalPointLength;
3378 }
3379
3380#if TRIO_FEATURE_QUOTE
3381 if (flags & FLAGS_QUOTE)
3382 {
3383 expectedWidth += TrioCalcThousandSeparatorLength(integerDigits);
3384 }
3385#endif
3386
3387 if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
3388 {
3389 expectedWidth += sizeof("-") - 1;
3390 }
3391
3392 exponentDigits = 0;
3393 if (flags & FLAGS_FLOAT_E)
3394 {
3395 exponentDigits = (uExponent == 0)
3396 ? 1
3397 : (int)trio_ceil(TrioLogarithm((double)(uExponent + 1),
3398 (isHex) ? 10 : base));
3399 }
3400 requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1));
3401 if (exponentDigits > 0)
3402 {
3403 expectedWidth += exponentDigits;
3404 expectedWidth += (requireTwoDigitExponent
3405 ? sizeof("E+0") - 1
3406 : sizeof("E+") - 1);
3407 }
3408
3409 if (isHex)
3410 {
3411 expectedWidth += sizeof("0X") - 1;
3412 }
3413
3414 /* Output prefixing */
3415 if (flags & FLAGS_NILPADDING)
3416 {
3417 /* Leading zeros must be after sign */
3418 if (isNegative)
3419 self->OutStream(self, '-');
3420 else if (flags & FLAGS_SHOWSIGN)
3421 self->OutStream(self, '+');
3422 else if (flags & FLAGS_SPACE)
3423 self->OutStream(self, ' ');
3424 if (isHex)
3425 {
3426 self->OutStream(self, '0');
3427 self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
3428 }
3429 if (!(flags & FLAGS_LEFTADJUST))
3430 {
3431 for (i = expectedWidth; i < width; i++)
3432 {
3433 self->OutStream(self, '0');
3434 }
3435 }
3436 }
3437 else
3438 {
3439 /* Leading spaces must be before sign */
3440 if (!(flags & FLAGS_LEFTADJUST))
3441 {
3442 for (i = expectedWidth; i < width; i++)
3443 {
3444 self->OutStream(self, CHAR_ADJUST);
3445 }
3446 }
3447 if (isNegative)
3448 self->OutStream(self, '-');
3449 else if (flags & FLAGS_SHOWSIGN)
3450 self->OutStream(self, '+');
3451 else if (flags & FLAGS_SPACE)
3452 self->OutStream(self, ' ');
3453 if (isHex)
3454 {
3455 self->OutStream(self, '0');
3456 self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
3457 }
3458 }
3459
3460 /* Output the integer part and thousand separators */
3461 for (i = 0; i < integerDigits; i++)
3462 {
3463 workNumber = trio_floor(((integerNumber + integerAdjust)
3464 / TrioPower(base, integerDigits - i - 1)));
3465 if (i > integerThreshold)
3466 {
3467 /* Beyond accuracy */
3468 self->OutStream(self, digits[0]);
3469 }
3470 else
3471 {
3472 self->OutStream(self, digits[(int)trio_fmod(workNumber, dblBase)]);
3473 }
3474
3475#if TRIO_FEATURE_QUOTE
3476 if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE)
3477 && TrioFollowedBySeparator(integerDigits - i))
3478 {
3479 for (groupingPointer = internalThousandSeparator;
3480 *groupingPointer != NIL;
3481 groupingPointer++)
3482 {
3483 self->OutStream(self, *groupingPointer);
3484 }
3485 }
3486#endif
3487 }
3488
3489 /* Insert decimal point and build the fraction part */
3490 trailingZeroes = 0;
3491
3492 if (keepDecimalPoint)
3493 {
3494 if (internalDecimalPoint)
3495 {
3496 self->OutStream(self, internalDecimalPoint);
3497 }
3498 else
3499 {
3500 for (i = 0; i < internalDecimalPointLength; i++)
3501 {
3502 self->OutStream(self, internalDecimalPointString[i]);
3503 }
3504 }
3505 }
3506
3507 for (i = 0; i < fractionDigits; i++)
3508 {
3509 if ((integerDigits > integerThreshold) || (i > fractionThreshold))
3510 {
3511 /* Beyond accuracy */
3512 trailingZeroes++;
3513 }
3514 else
3515 {
3516 fractionNumber *= dblBase;
3517 fractionAdjust *= dblBase;
3518 workNumber = trio_floor(fractionNumber + fractionAdjust);
3519 if (workNumber > fractionNumber)
3520 {
3521 /* fractionNumber should never become negative */
3522 fractionNumber = 0.0;
3523 fractionAdjust = 0.0;
3524 }
3525 else
3526 {
3527 fractionNumber -= workNumber;
3528 }
3529 offset = (int)trio_fmod(workNumber, dblBase);
3530 if (offset == 0)
3531 {
3532 trailingZeroes++;
3533 }
3534 else
3535 {
3536 while (trailingZeroes > 0)
3537 {
3538 /* Not trailing zeroes after all */
3539 self->OutStream(self, digits[0]);
3540 trailingZeroes--;
3541 }
3542 self->OutStream(self, digits[offset]);
3543 }
3544 }
3545 }
3546
3547 if (keepTrailingZeroes)
3548 {
3549 while (trailingZeroes > 0)
3550 {
3551 self->OutStream(self, digits[0]);
3552 trailingZeroes--;
3553 }
3554 }
3555
3556 /* Output exponent */
3557 if (exponentDigits > 0)
3558 {
3559 self->OutStream(self,
3560 isHex
3561 ? ((flags & FLAGS_UPPER) ? 'P' : 'p')
3562 : ((flags & FLAGS_UPPER) ? 'E' : 'e'));
3563 self->OutStream(self, (isExponentNegative) ? '-' : '+');
3564
3565 /* The exponent must contain at least two digits */
3566 if (requireTwoDigitExponent)
3567 self->OutStream(self, '0');
3568
3569 if (isHex)
3570 base = 10;
3571 exponentBase = (int)TrioPower(base, exponentDigits - 1);
3572 for (i = 0; i < exponentDigits; i++)
3573 {
3574 self->OutStream(self, digits[(uExponent / exponentBase) % base]);
3575 exponentBase /= base;
3576 }
3577 }
3578 /* Output trailing spaces */
3579 if (flags & FLAGS_LEFTADJUST)
3580 {
3581 for (i = expectedWidth; i < width; i++)
3582 {
3583 self->OutStream(self, CHAR_ADJUST);
3584 }
3585 }
3586}
3587#endif /* TRIO_FEATURE_FLOAT */
3588
3589/*************************************************************************
3590 * TrioFormatProcess
3591 *
3592 * Description:
3593 * This is the main engine for formatting output
3594 */
3595TRIO_PRIVATE int
3596TrioFormatProcess
3597TRIO_ARGS3((data, format, parameters),
3598 trio_class_t *data,
3599 TRIO_CONST char *format,
3600 trio_parameter_t *parameters)
3601{
3602 int i;
3603#if TRIO_FEATURE_ERRNO
3604 TRIO_CONST char *string;
3605#endif
3606 trio_pointer_t pointer;
3607 trio_flags_t flags;
3608 int width;
3609 int precision;
3610 int base;
3611 int offset;
3612
3613 offset = 0;
3614 i = 0;
3615
3616 for (;;)
3617 {
3618 /* Skip the parameter entries */
3619 while (parameters[i].type == FORMAT_PARAMETER)
3620 i++;
3621
3622 /* Copy non conversion-specifier part of format string */
3623 while (offset < parameters[i].beginOffset)
3624 {
3625 if (CHAR_IDENTIFIER == format[offset] && CHAR_IDENTIFIER == format[offset + 1])
3626 {
3627 data->OutStream(data, CHAR_IDENTIFIER);
3628 offset += 2;
3629 }
3630 else
3631 {
3632 data->OutStream(data, format[offset++]);
3633 }
3634 }
3635
3636 /* Abort if we reached end of format string */
3637 if (parameters[i].type == FORMAT_SENTINEL)
3638 break;
3639
3640 /* Ouput parameter */
3641 flags = parameters[i].flags;
3642
3643 /* Find width */
3644 width = parameters[i].width;
3645 if (flags & FLAGS_WIDTH_PARAMETER)
3646 {
3647 /* Get width from parameter list */
3648 width = (int)parameters[width].data.number.as_signed;
3649 if (width < 0)
3650 {
3651 /*
3652 * A negative width is the same as the - flag and
3653 * a positive width.
3654 */
3655 flags |= FLAGS_LEFTADJUST;
3656 flags &= ~FLAGS_NILPADDING;
3657 width = -width;
3658 }
3659 }
3660
3661 /* Find precision */
3662 if (flags & FLAGS_PRECISION)
3663 {
3664 precision = parameters[i].precision;
3665 if (flags & FLAGS_PRECISION_PARAMETER)
3666 {
3667 /* Get precision from parameter list */
3668 precision = (int)parameters[precision].data.number.as_signed;
3669 if (precision < 0)
3670 {
3671 /*
3672 * A negative precision is the same as no
3673 * precision
3674 */
3675 precision = NO_PRECISION;
3676 }
3677 }
3678 }
3679 else
3680 {
3681 precision = NO_PRECISION;
3682 }
3683
3684 /* Find base */
3685 if (NO_BASE != parameters[i].baseSpecifier)
3686 {
3687 /* Base from specifier has priority */
3688 base = parameters[i].baseSpecifier;
3689 }
3690 else if (flags & FLAGS_BASE_PARAMETER)
3691 {
3692 /* Get base from parameter list */
3693 base = parameters[i].base;
3694 base = (int)parameters[base].data.number.as_signed;
3695 }
3696 else
3697 {
3698 /* Use base from format string */
3699 base = parameters[i].base;
3700 }
3701
3702 switch (parameters[i].type)
3703 {
3704 case FORMAT_CHAR:
3705#if TRIO_FEATURE_QUOTE
3706 if (flags & FLAGS_QUOTE)
3707 data->OutStream(data, CHAR_QUOTE);
3708#endif
3709 if (! (flags & FLAGS_LEFTADJUST))
3710 {
3711 while (--width > 0)
3712 data->OutStream(data, CHAR_ADJUST);
3713 }
3714#if TRIO_FEATURE_WIDECHAR
3715 if (flags & FLAGS_WIDECHAR)
3716 {
3717 TrioWriteWideStringCharacter(data,
3718 (trio_wchar_t)parameters[i].data.number.as_signed,
3719 flags,
3720 NO_WIDTH);
3721 }
3722 else
3723#endif
3724 {
3725 TrioWriteStringCharacter(data,
3726 (int)parameters[i].data.number.as_signed,
3727 flags);
3728 }
3729
3730 if (flags & FLAGS_LEFTADJUST)
3731 {
3732 while(--width > 0)
3733 data->OutStream(data, CHAR_ADJUST);
3734 }
3735#if TRIO_FEATURE_QUOTE
3736 if (flags & FLAGS_QUOTE)
3737 data->OutStream(data, CHAR_QUOTE);
3738#endif
3739
3740 break; /* FORMAT_CHAR */
3741
3742 case FORMAT_INT:
3743 TrioWriteNumber(data,
3744 parameters[i].data.number.as_unsigned,
3745 flags,
3746 width,
3747 precision,
3748 base);
3749
3750 break; /* FORMAT_INT */
3751
3752#if TRIO_FEATURE_FLOAT
3753 case FORMAT_DOUBLE:
3754 TrioWriteDouble(data,
3755 parameters[i].data.longdoubleNumber,
3756 flags,
3757 width,
3758 precision,
3759 base);
3760 break; /* FORMAT_DOUBLE */
3761#endif
3762
3763 case FORMAT_STRING:
3764#if TRIO_FEATURE_WIDECHAR
3765 if (flags & FLAGS_WIDECHAR)
3766 {
3767 TrioWriteWideString(data,
3768 parameters[i].data.wstring,
3769 flags,
3770 width,
3771 precision);
3772 }
3773 else
3774#endif
3775 {
3776 TrioWriteString(data,
3777 parameters[i].data.string,
3778 flags,
3779 width,
3780 precision);
3781 }
3782 break; /* FORMAT_STRING */
3783
3784 case FORMAT_POINTER:
3785 {
3786 trio_reference_t reference;
3787
3788 reference.data = data;
3789 reference.parameter = &parameters[i];
3790 trio_print_pointer(&reference, parameters[i].data.pointer);
3791 }
3792 break; /* FORMAT_POINTER */
3793
3794 case FORMAT_COUNT:
3795 pointer = parameters[i].data.pointer;
3796 if (NULL != pointer)
3797 {
3798 /*
3799 * C99 paragraph 7.19.6.1.8 says "the number of
3800 * characters written to the output stream so far by
3801 * this call", which is data->actually.committed
3802 */
3803#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
3804 if (flags & FLAGS_SIZE_T)
3805 *(size_t *)pointer = (size_t)data->actually.committed;
3806 else
3807#endif
3808#if TRIO_FEATURE_PTRDIFF_T
3809 if (flags & FLAGS_PTRDIFF_T)
3810 *(ptrdiff_t *)pointer = (ptrdiff_t)data->actually.committed;
3811 else
3812#endif
3813#if TRIO_FEATURE_INTMAX_T
3814 if (flags & FLAGS_INTMAX_T)
3815 *(trio_intmax_t *)pointer = (trio_intmax_t)data->actually.committed;
3816 else
3817#endif
3818 if (flags & FLAGS_QUAD)
3819 {
3820 *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->actually.committed;
3821 }
3822 else if (flags & FLAGS_LONG)
3823 {
3824 *(long int *)pointer = (long int)data->actually.committed;
3825 }
3826 else if (flags & FLAGS_SHORT)
3827 {
3828 *(short int *)pointer = (short int)data->actually.committed;
3829 }
3830 else
3831 {
3832 *(int *)pointer = (int)data->actually.committed;
3833 }
3834 }
3835 break; /* FORMAT_COUNT */
3836
3837 case FORMAT_PARAMETER:
3838 break; /* FORMAT_PARAMETER */
3839
3840#if TRIO_FEATURE_ERRNO
3841 case FORMAT_ERRNO:
3842 string = trio_error(parameters[i].data.errorNumber);
3843 if (string)
3844 {
3845 TrioWriteString(data,
3846 string,
3847 flags,
3848 width,
3849 precision);
3850 }
3851 else
3852 {
3853 data->OutStream(data, '#');
3854 TrioWriteNumber(data,
3855 (trio_uintmax_t)parameters[i].data.errorNumber,
3856 flags,
3857 width,
3858 precision,
3859 BASE_DECIMAL);
3860 }
3861 break; /* FORMAT_ERRNO */
3862#endif /* TRIO_FEATURE_ERRNO */
3863
3864#if TRIO_FEATURE_USER_DEFINED
3865 case FORMAT_USER_DEFINED:
3866 {
3867 trio_reference_t reference;
3868 trio_userdef_t *def = NULL;
3869
3870 if (parameters[i].flags & FLAGS_USER_DEFINED_PARAMETER)
3871 {
3872 /* Use handle */
3873 if ((i > 0) ||
3874 (parameters[i - 1].type == FORMAT_PARAMETER))
3875 def = (trio_userdef_t *)parameters[i - 1].data.pointer;
3876 }
3877 else
3878 {
3879 /* Look up namespace */
3880 def = TrioFindNamespace(parameters[i].user_defined.namespace, NULL);
3881 }
3882 if (def)
3883 {
3884 reference.data = data;
3885 reference.parameter = &parameters[i];
3886 def->callback(&reference);
3887 }
3888 }
3889 break;
3890#endif /* TRIO_FEATURE_USER_DEFINED */
3891
3892 default:
3893 break;
3894 } /* switch parameter type */
3895
3896 /* Prepare for next */
3897 offset = parameters[i].endOffset;
3898 i++;
3899 }
3900
3901 return data->processed;
3902}
3903
3904/*************************************************************************
3905 * TrioFormatRef
3906 */
3907#if TRIO_EXTENSION
3908TRIO_PRIVATE int
3909TrioFormatRef
3910TRIO_ARGS4((reference, format, arglist, argarray),
3911 trio_reference_t *reference,
3912 TRIO_CONST char *format,
3913 va_list arglist,
3914 trio_pointer_t *argarray)
3915{
3916 int status;
3917 trio_parameter_t parameters[MAX_PARAMETERS];
3918
3919 status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
3920 if (status < 0)
3921 return status;
3922
3923 status = TrioFormatProcess(reference->data, format, parameters);
3924 if (reference->data->error != 0)
3925 {
3926 status = reference->data->error;
3927 }
3928 return status;
3929}
3930#endif /* TRIO_EXTENSION */
3931
3932/*************************************************************************
3933 * TrioFormat
3934 */
3935TRIO_PRIVATE int
3936TrioFormat
3937TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray),
3938 trio_pointer_t destination,
3939 size_t destinationSize,
3940 void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
3941 TRIO_CONST char *format,
3942 va_list arglist,
3943 trio_pointer_t *argarray)
3944{
3945 int status;
3946 trio_class_t data;
3947 trio_parameter_t parameters[MAX_PARAMETERS];
3948
3949 assert(VALID(OutStream));
3950 assert(VALID(format));
3951
3952 memset(&data, 0, sizeof(data));
3953 data.OutStream = OutStream;
3954 data.location = destination;
3955 data.max = destinationSize;
3956 data.error = 0;
3957
3958#if defined(USE_LOCALE)
3959 if (NULL == internalLocaleValues)
3960 {
3961 TrioSetLocale();
3962 }
3963#endif
3964
3965 status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
3966 if (status < 0)
3967 return status;
3968
3969 status = TrioFormatProcess(&data, format, parameters);
3970 if (data.error != 0)
3971 {
3972 status = data.error;
3973 }
3974 return status;
3975}
3976
3977/*************************************************************************
3978 * TrioOutStreamFile
3979 */
3980#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO
3981TRIO_PRIVATE void
3982TrioOutStreamFile
3983TRIO_ARGS2((self, output),
3984 trio_class_t *self,
3985 int output)
3986{
3987 FILE *file;
3988
3989 assert(VALID(self));
3990 assert(VALID(self->location));
3991
3992 file = (FILE *)self->location;
3993 self->processed++;
3994 if (fputc(output, file) == EOF)
3995 {
3996 self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0);
3997 }
3998 else
3999 {
4000 self->actually.committed++;
4001 }
4002}
4003#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */
4004
4005/*************************************************************************
4006 * TrioOutStreamFileDescriptor
4007 */
4008#if TRIO_FEATURE_FD
4009TRIO_PRIVATE void
4010TrioOutStreamFileDescriptor
4011TRIO_ARGS2((self, output),
4012 trio_class_t *self,
4013 int output)
4014{
4015 int fd;
4016 char ch;
4017
4018 assert(VALID(self));
4019
4020 fd = *((int *)self->location);
4021 ch = (char)output;
4022 self->processed++;
4023 if (write(fd, &ch, sizeof(char)) == -1)
4024 {
4025 self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
4026 }
4027 else
4028 {
4029 self->actually.committed++;
4030 }
4031}
4032#endif /* TRIO_FEATURE_FD */
4033
4034/*************************************************************************
4035 * TrioOutStreamCustom
4036 */
4037#if TRIO_FEATURE_CLOSURE
4038TRIO_PRIVATE void
4039TrioOutStreamCustom
4040TRIO_ARGS2((self, output),
4041 trio_class_t *self,
4042 int output)
4043{
4044 int status;
4045 trio_custom_t *data;
4046
4047 assert(VALID(self));
4048 assert(VALID(self->location));
4049
4050 data = (trio_custom_t *)self->location;
4051 if (data->stream.out)
4052 {
4053 status = (data->stream.out)(data->closure, output);
4054 if (status >= 0)
4055 {
4056 self->actually.committed++;
4057 }
4058 else
4059 {
4060 if (self->error == 0)
4061 {
4062 self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status);
4063 }
4064 }
4065 }
4066 self->processed++;
4067}
4068#endif /* TRIO_FEATURE_CLOSURE */
4069
4070/*************************************************************************
4071 * TrioOutStreamString
4072 */
4073TRIO_PRIVATE void
4074TrioOutStreamString
4075TRIO_ARGS2((self, output),
4076 trio_class_t *self,
4077 int output)
4078{
4079 char **buffer;
4080
4081 assert(VALID(self));
4082 assert(VALID(self->location));
4083
4084 buffer = (char **)self->location;
4085 **buffer = (char)output;
4086 (*buffer)++;
4087 self->processed++;
4088 self->actually.committed++;
4089}
4090
4091/*************************************************************************
4092 * TrioOutStreamStringMax
4093 */
4094TRIO_PRIVATE void
4095TrioOutStreamStringMax
4096TRIO_ARGS2((self, output),
4097 trio_class_t *self,
4098 int output)
4099{
4100 char **buffer;
4101
4102 assert(VALID(self));
4103 assert(VALID(self->location));
4104
4105 buffer = (char **)self->location;
4106
4107 if (self->processed < self->max)
4108 {
4109 **buffer = (char)output;
4110 (*buffer)++;
4111 self->actually.committed++;
4112 }
4113 self->processed++;
4114}
4115
4116/*************************************************************************
4117 * TrioOutStreamStringDynamic
4118 */
4119#if TRIO_FEATURE_DYNAMICSTRING
4120TRIO_PRIVATE void
4121TrioOutStreamStringDynamic
4122TRIO_ARGS2((self, output),
4123 trio_class_t *self,
4124 int output)
4125{
4126 assert(VALID(self));
4127 assert(VALID(self->location));
4128
4129 if (self->error == 0)
4130 {
4131 trio_xstring_append_char((trio_string_t *)self->location,
4132 (char)output);
4133 self->actually.committed++;
4134 }
4135 /* The processed variable must always be increased */
4136 self->processed++;
4137}
4138#endif /* TRIO_FEATURE_DYNAMICSTRING */
4139
4140/*************************************************************************
4141 *
4142 * Formatted printing functions
4143 *
4144 ************************************************************************/
4145
4146#if defined(TRIO_DOCUMENTATION)
4147# include "doc/doc_printf.h"
4148#endif
4149/** @addtogroup Printf
4150 @{
4151*/
4152
4153/*************************************************************************
4154 * printf
4155 */
4156
4157/**
4158 Print to standard output stream.
4159
4160 @param format Formatting string.
4161 @param ... Arguments.
4162 @return Number of printed characters.
4163 */
4164#if TRIO_FEATURE_STDIO
4165TRIO_PUBLIC int
4166trio_printf
4167TRIO_VARGS2((format, va_alist),
4168 TRIO_CONST char *format,
4169 TRIO_VA_DECL)
4170{
4171 int status;
4172 va_list args;
4173
4174 assert(VALID(format));
4175
4176 TRIO_VA_START(args, format);
4177 status = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL);
4178 TRIO_VA_END(args);
4179 return status;
4180}
4181#endif /* TRIO_FEATURE_STDIO */
4182
4183/**
4184 Print to standard output stream.
4185
4186 @param format Formatting string.
4187 @param args Arguments.
4188 @return Number of printed characters.
4189 */
4190#if TRIO_FEATURE_STDIO
4191TRIO_PUBLIC int
4192trio_vprintf
4193TRIO_ARGS2((format, args),
4194 TRIO_CONST char *format,
4195 va_list args)
4196{
4197 assert(VALID(format));
4198
4199 return TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL);
4200}
4201#endif /* TRIO_FEATURE_STDIO */
4202
4203/**
4204 Print to standard output stream.
4205
4206 @param format Formatting string.
4207 @param args Arguments.
4208 @return Number of printed characters.
4209 */
4210#if TRIO_FEATURE_STDIO
4211TRIO_PUBLIC int
4212trio_printfv
4213TRIO_ARGS2((format, args),
4214 TRIO_CONST char *format,
4215 trio_pointer_t * args)
4216{
4217 static va_list unused;
4218
4219 assert(VALID(format));
4220
4221 return TrioFormat(stdout, 0, TrioOutStreamFile, format, unused, args);
4222}
4223#endif /* TRIO_FEATURE_STDIO */
4224
4225/*************************************************************************
4226 * fprintf
4227 */
4228
4229/**
4230 Print to file.
4231
4232 @param file File pointer.
4233 @param format Formatting string.
4234 @param ... Arguments.
4235 @return Number of printed characters.
4236 */
4237#if TRIO_FEATURE_FILE
4238TRIO_PUBLIC int
4239trio_fprintf
4240TRIO_VARGS3((file, format, va_alist),
4241 FILE *file,
4242 TRIO_CONST char *format,
4243 TRIO_VA_DECL)
4244{
4245 int status;
4246 va_list args;
4247
4248 assert(VALID(file));
4249 assert(VALID(format));
4250
4251 TRIO_VA_START(args, format);
4252 status = TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL);
4253 TRIO_VA_END(args);
4254 return status;
4255}
4256#endif /* TRIO_FEATURE_FILE */
4257
4258/**
4259 Print to file.
4260
4261 @param file File pointer.
4262 @param format Formatting string.
4263 @param args Arguments.
4264 @return Number of printed characters.
4265 */
4266#if TRIO_FEATURE_FILE
4267TRIO_PUBLIC int
4268trio_vfprintf
4269TRIO_ARGS3((file, format, args),
4270 FILE *file,
4271 TRIO_CONST char *format,
4272 va_list args)
4273{
4274 assert(VALID(file));
4275 assert(VALID(format));
4276
4277 return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL);
4278}
4279#endif /* TRIO_FEATURE_FILE */
4280
4281/**
4282 Print to file.
4283
4284 @param file File pointer.
4285 @param format Formatting string.
4286 @param args Arguments.
4287 @return Number of printed characters.
4288 */
4289#if TRIO_FEATURE_FILE
4290TRIO_PUBLIC int
4291trio_fprintfv
4292TRIO_ARGS3((file, format, args),
4293 FILE *file,
4294 TRIO_CONST char *format,
4295 trio_pointer_t * args)
4296{
4297 static va_list unused;
4298
4299 assert(VALID(file));
4300 assert(VALID(format));
4301
4302 return TrioFormat(file, 0, TrioOutStreamFile, format, unused, args);
4303}
4304#endif /* TRIO_FEATURE_FILE */
4305
4306/*************************************************************************
4307 * dprintf
4308 */
4309
4310/**
4311 Print to file descriptor.
4312
4313 @param fd File descriptor.
4314 @param format Formatting string.
4315 @param ... Arguments.
4316 @return Number of printed characters.
4317 */
4318#if TRIO_FEATURE_FD
4319TRIO_PUBLIC int
4320trio_dprintf
4321TRIO_VARGS3((fd, format, va_alist),
4322 int fd,
4323 TRIO_CONST char *format,
4324 TRIO_VA_DECL)
4325{
4326 int status;
4327 va_list args;
4328
4329 assert(VALID(format));
4330
4331 TRIO_VA_START(args, format);
4332 status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL);
4333 TRIO_VA_END(args);
4334 return status;
4335}
4336#endif /* TRIO_FEATURE_FD */
4337
4338/**
4339 Print to file descriptor.
4340
4341 @param fd File descriptor.
4342 @param format Formatting string.
4343 @param args Arguments.
4344 @return Number of printed characters.
4345 */
4346#if TRIO_FEATURE_FD
4347TRIO_PUBLIC int
4348trio_vdprintf
4349TRIO_ARGS3((fd, format, args),
4350 int fd,
4351 TRIO_CONST char *format,
4352 va_list args)
4353{
4354 assert(VALID(format));
4355
4356 return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL);
4357}
4358#endif /* TRIO_FEATURE_FD */
4359
4360/**
4361 Print to file descriptor.
4362
4363 @param fd File descriptor.
4364 @param format Formatting string.
4365 @param args Arguments.
4366 @return Number of printed characters.
4367 */
4368#if TRIO_FEATURE_FD
4369TRIO_PUBLIC int
4370trio_dprintfv
4371TRIO_ARGS3((fd, format, args),
4372 int fd,
4373 TRIO_CONST char *format,
4374 trio_pointer_t *args)
4375{
4376 static va_list unused;
4377
4378 assert(VALID(format));
4379
4380 return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, unused, args);
4381}
4382#endif /* TRIO_FEATURE_FD */
4383
4384/*************************************************************************
4385 * cprintf
4386 */
4387#if TRIO_FEATURE_CLOSURE
4388TRIO_PUBLIC int
4389trio_cprintf
4390TRIO_VARGS4((stream, closure, format, va_alist),
4391 trio_outstream_t stream,
4392 trio_pointer_t closure,
4393 TRIO_CONST char *format,
4394 TRIO_VA_DECL)
4395{
4396 int status;
4397 va_list args;
4398 trio_custom_t data;
4399
4400 assert(VALID(stream));
4401 assert(VALID(format));
4402
4403 TRIO_VA_START(args, format);
4404 data.stream.out = stream;
4405 data.closure = closure;
4406 status = TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL);
4407 TRIO_VA_END(args);
4408 return status;
4409}
4410#endif /* TRIO_FEATURE_CLOSURE */
4411
4412#if TRIO_FEATURE_CLOSURE
4413TRIO_PUBLIC int
4414trio_vcprintf
4415TRIO_ARGS4((stream, closure, format, args),
4416 trio_outstream_t stream,
4417 trio_pointer_t closure,
4418 TRIO_CONST char *format,
4419 va_list args)
4420{
4421 trio_custom_t data;
4422
4423 assert(VALID(stream));
4424 assert(VALID(format));
4425
4426 data.stream.out = stream;
4427 data.closure = closure;
4428 return TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL);
4429}
4430#endif /* TRIO_FEATURE_CLOSURE */
4431
4432#if TRIO_FEATURE_CLOSURE
4433TRIO_PUBLIC int
4434trio_cprintfv
4435TRIO_ARGS4((stream, closure, format, args),
4436 trio_outstream_t stream,
4437 trio_pointer_t closure,
4438 TRIO_CONST char *format,
4439 void **args)
4440{
4441 static va_list unused;
4442 trio_custom_t data;
4443
4444 assert(VALID(stream));
4445 assert(VALID(format));
4446
4447 data.stream.out = stream;
4448 data.closure = closure;
4449 return TrioFormat(&data, 0, TrioOutStreamCustom, format, unused, args);
4450}
4451#endif /* TRIO_FEATURE_CLOSURE */
4452
4453/*************************************************************************
4454 * sprintf
4455 */
4456
4457/**
4458 Print to string.
4459
4460 @param buffer Output string.
4461 @param format Formatting string.
4462 @param ... Arguments.
4463 @return Number of printed characters.
4464 */
4465TRIO_PUBLIC int
4466trio_sprintf
4467TRIO_VARGS3((buffer, format, va_alist),
4468 char *buffer,
4469 TRIO_CONST char *format,
4470 TRIO_VA_DECL)
4471{
4472 int status;
4473 va_list args;
4474
4475 assert(VALID(buffer));
4476 assert(VALID(format));
4477
4478 TRIO_VA_START(args, format);
4479 status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL);
4480 *buffer = NIL; /* Terminate with NIL character */
4481 TRIO_VA_END(args);
4482 return status;
4483}
4484
4485/**
4486 Print to string.
4487
4488 @param buffer Output string.
4489 @param format Formatting string.
4490 @param args Arguments.
4491 @return Number of printed characters.
4492 */
4493TRIO_PUBLIC int
4494trio_vsprintf
4495TRIO_ARGS3((buffer, format, args),
4496 char *buffer,
4497 TRIO_CONST char *format,
4498 va_list args)
4499{
4500 int status;
4501
4502 assert(VALID(buffer));
4503 assert(VALID(format));
4504
4505 status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL);
4506 *buffer = NIL;
4507 return status;
4508}
4509
4510/**
4511 Print to string.
4512
4513 @param buffer Output string.
4514 @param format Formatting string.
4515 @param args Arguments.
4516 @return Number of printed characters.
4517 */
4518TRIO_PUBLIC int
4519trio_sprintfv
4520TRIO_ARGS3((buffer, format, args),
4521 char *buffer,
4522 TRIO_CONST char *format,
4523 trio_pointer_t *args)
4524{
4525 static va_list unused;
4526 int status;
4527
4528 assert(VALID(buffer));
4529 assert(VALID(format));
4530
4531 status = TrioFormat(&buffer, 0, TrioOutStreamString, format, unused, args);
4532 *buffer = NIL;
4533 return status;
4534}
4535
4536/*************************************************************************
4537 * snprintf
4538 */
4539
4540/**
4541 Print at most @p max characters to string.
4542
4543 @param buffer Output string.
4544 @param max Maximum number of characters to print.
4545 @param format Formatting string.
4546 @param ... Arguments.
4547 @return Number of printed characters.
4548 */
4549TRIO_PUBLIC int
4550trio_snprintf
4551TRIO_VARGS4((buffer, max, format, va_alist),
4552 char *buffer,
4553 size_t max,
4554 TRIO_CONST char *format,
4555 TRIO_VA_DECL)
4556{
4557 int status;
4558 va_list args;
4559
4560 assert(VALID(buffer) || (max == 0));
4561 assert(VALID(format));
4562
4563 TRIO_VA_START(args, format);
4564 status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
4565 TrioOutStreamStringMax, format, args, NULL);
4566 if (max > 0)
4567 *buffer = NIL;
4568 TRIO_VA_END(args);
4569 return status;
4570}
4571
4572/**
4573 Print at most @p max characters to string.
4574
4575 @param buffer Output string.
4576 @param max Maximum number of characters to print.
4577 @param format Formatting string.
4578 @param args Arguments.
4579 @return Number of printed characters.
4580 */
4581TRIO_PUBLIC int
4582trio_vsnprintf
4583TRIO_ARGS4((buffer, max, format, args),
4584 char *buffer,
4585 size_t max,
4586 TRIO_CONST char *format,
4587 va_list args)
4588{
4589 int status;
4590
4591 assert(VALID(buffer) || (max == 0));
4592 assert(VALID(format));
4593
4594 status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
4595 TrioOutStreamStringMax, format, args, NULL);
4596 if (max > 0)
4597 *buffer = NIL;
4598 return status;
4599}
4600
4601/**
4602 Print at most @p max characters to string.
4603
4604 @param buffer Output string.
4605 @param max Maximum number of characters to print.
4606 @param format Formatting string.
4607 @param args Arguments.
4608 @return Number of printed characters.
4609 */
4610TRIO_PUBLIC int
4611trio_snprintfv
4612TRIO_ARGS4((buffer, max, format, args),
4613 char *buffer,
4614 size_t max,
4615 TRIO_CONST char *format,
4616 trio_pointer_t *args)
4617{
4618 static va_list unused;
4619 int status;
4620
4621 assert(VALID(buffer) || (max == 0));
4622 assert(VALID(format));
4623
4624 status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
4625 TrioOutStreamStringMax, format, unused, args);
4626 if (max > 0)
4627 *buffer = NIL;
4628 return status;
4629}
4630
4631/*************************************************************************
4632 * snprintfcat
4633 * Appends the new string to the buffer string overwriting the '\0'
4634 * character at the end of buffer.
4635 */
4636#if TRIO_EXTENSION
4637TRIO_PUBLIC int
4638trio_snprintfcat
4639TRIO_VARGS4((buffer, max, format, va_alist),
4640 char *buffer,
4641 size_t max,
4642 TRIO_CONST char *format,
4643 TRIO_VA_DECL)
4644{
4645 int status;
4646 va_list args;
4647 size_t buf_len;
4648
4649 TRIO_VA_START(args, format);
4650
4651 assert(VALID(buffer));
4652 assert(VALID(format));
4653
4654 buf_len = trio_length(buffer);
4655 buffer = &buffer[buf_len];
4656
4657 status = TrioFormat(&buffer, max - 1 - buf_len,
4658 TrioOutStreamStringMax, format, args, NULL);
4659 TRIO_VA_END(args);
4660 *buffer = NIL;
4661 return status;
4662}
4663#endif
4664
4665#if TRIO_EXTENSION
4666TRIO_PUBLIC int
4667trio_vsnprintfcat
4668TRIO_ARGS4((buffer, max, format, args),
4669 char *buffer,
4670 size_t max,
4671 TRIO_CONST char *format,
4672 va_list args)
4673{
4674 int status;
4675 size_t buf_len;
4676
4677 assert(VALID(buffer));
4678 assert(VALID(format));
4679
4680 buf_len = trio_length(buffer);
4681 buffer = &buffer[buf_len];
4682 status = TrioFormat(&buffer, max - 1 - buf_len,
4683 TrioOutStreamStringMax, format, args, NULL);
4684 *buffer = NIL;
4685 return status;
4686}
4687#endif
4688
4689/*************************************************************************
4690 * trio_aprintf
4691 */
4692
4693#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING
4694TRIO_PUBLIC char *
4695trio_aprintf
4696TRIO_VARGS2((format, va_alist),
4697 TRIO_CONST char *format,
4698 TRIO_VA_DECL)
4699{
4700 va_list args;
4701 trio_string_t *info;
4702 char *result = NULL;
4703
4704 assert(VALID(format));
4705
4706 info = trio_xstring_duplicate("");
4707 if (info)
4708 {
4709 TRIO_VA_START(args, format);
4710 (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
4711 format, args, NULL);
4712 TRIO_VA_END(args);
4713
4714 trio_string_terminate(info);
4715 result = trio_string_extract(info);
4716 trio_string_destroy(info);
4717 }
4718 return result;
4719}
4720#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */
4721
4722#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING
4723TRIO_PUBLIC char *
4724trio_vaprintf
4725TRIO_ARGS2((format, args),
4726 TRIO_CONST char *format,
4727 va_list args)
4728{
4729 trio_string_t *info;
4730 char *result = NULL;
4731
4732 assert(VALID(format));
4733
4734 info = trio_xstring_duplicate("");
4735 if (info)
4736 {
4737 (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
4738 format, args, NULL);
4739 trio_string_terminate(info);
4740 result = trio_string_extract(info);
4741 trio_string_destroy(info);
4742 }
4743 return result;
4744}
4745#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */
4746
4747/**
4748 Allocate and print to string.
4749 The memory allocated and returned by @p result must be freed by the
4750 calling application.
4751
4752 @param result Output string.
4753 @param format Formatting string.
4754 @param ... Arguments.
4755 @return Number of printed characters.
4756 */
4757#if TRIO_FEATURE_DYNAMICSTRING
4758TRIO_PUBLIC int
4759trio_asprintf
4760TRIO_VARGS3((result, format, va_alist),
4761 char **result,
4762 TRIO_CONST char *format,
4763 TRIO_VA_DECL)
4764{
4765 va_list args;
4766 int status;
4767 trio_string_t *info;
4768
4769 assert(VALID(format));
4770
4771 *result = NULL;
4772
4773 info = trio_xstring_duplicate("");
4774 if (info == NULL)
4775 {
4776 status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
4777 }
4778 else
4779 {
4780 TRIO_VA_START(args, format);
4781 status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
4782 format, args, NULL);
4783 TRIO_VA_END(args);
4784 if (status >= 0)
4785 {
4786 trio_string_terminate(info);
4787 *result = trio_string_extract(info);
4788 }
4789 trio_string_destroy(info);
4790 }
4791 return status;
4792}
4793#endif /* TRIO_FEATURE_DYNAMICSTRING */
4794
4795/**
4796 Allocate and print to string.
4797 The memory allocated and returned by @p result must be freed by the
4798 calling application.
4799
4800 @param result Output string.
4801 @param format Formatting string.
4802 @param args Arguments.
4803 @return Number of printed characters.
4804 */
4805#if TRIO_FEATURE_DYNAMICSTRING
4806TRIO_PUBLIC int
4807trio_vasprintf
4808TRIO_ARGS3((result, format, args),
4809 char **result,
4810 TRIO_CONST char *format,
4811 va_list args)
4812{
4813 int status;
4814 trio_string_t *info;
4815
4816 assert(VALID(format));
4817
4818 *result = NULL;
4819
4820 info = trio_xstring_duplicate("");
4821 if (info == NULL)
4822 {
4823 status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
4824 }
4825 else
4826 {
4827 status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
4828 format, args, NULL);
4829 if (status >= 0)
4830 {
4831 trio_string_terminate(info);
4832 *result = trio_string_extract(info);
4833 }
4834 trio_string_destroy(info);
4835 }
4836 return status;
4837}
4838#endif /* TRIO_FEATURE_DYNAMICSTRING */
4839
4840/**
4841 Allocate and print to string.
4842 The memory allocated and returned by @p result must be freed by the
4843 calling application.
4844
4845 @param result Output string.
4846 @param format Formatting string.
4847 @param args Arguments.
4848 @return Number of printed characters.
4849 */
4850#if TRIO_FEATURE_DYNAMICSTRING
4851TRIO_PUBLIC int
4852trio_asprintfv
4853TRIO_ARGS3((result, format, args),
4854 char **result,
4855 TRIO_CONST char *format,
4856 trio_pointer_t * args)
4857{
4858 static va_list unused;
4859 int status;
4860 trio_string_t *info;
4861
4862 assert(VALID(format));
4863
4864 *result = NULL;
4865
4866 info = trio_xstring_duplicate("");
4867 if (info == NULL)
4868 {
4869 status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
4870 }
4871 else
4872 {
4873 status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
4874 format, unused, args);
4875 if (status >= 0)
4876 {
4877 trio_string_terminate(info);
4878 *result = trio_string_extract(info);
4879 }
4880 trio_string_destroy(info);
4881 }
4882 return status;
4883}
4884#endif /* TRIO_FEATURE_DYNAMICSTRING */
4885
4886/** @} End of Printf documentation module */
4887
4888/*************************************************************************
4889 *
4890 * CALLBACK
4891 *
4892 ************************************************************************/
4893
4894#if defined(TRIO_DOCUMENTATION)
4895# include "doc/doc_register.h"
4896#endif
4897/**
4898 @addtogroup UserDefined
4899 @{
4900*/
4901
4902#if TRIO_FEATURE_USER_DEFINED
4903
4904/*************************************************************************
4905 * trio_register
4906 */
4907
4908/**
4909 Register new user-defined specifier.
4910
4911 @param callback
4912 @param name
4913 @return Handle.
4914 */
4915TRIO_PUBLIC trio_pointer_t
4916trio_register
4917TRIO_ARGS2((callback, name),
4918 trio_callback_t callback,
4919 TRIO_CONST char *name)
4920{
4921 trio_userdef_t *def;
4922 trio_userdef_t *prev = NULL;
4923
4924 if (callback == NULL)
4925 return NULL;
4926
4927 if (name)
4928 {
4929 /* Handle built-in namespaces */
4930 if (name[0] == ':')
4931 {
4932 if (trio_equal(name, ":enter"))
4933 {
4934 internalEnterCriticalRegion = callback;
4935 }
4936 else if (trio_equal(name, ":leave"))
4937 {
4938 internalLeaveCriticalRegion = callback;
4939 }
4940 return NULL;
4941 }
4942
4943 /* Bail out if namespace is too long */
4944 if (trio_length(name) >= MAX_USER_NAME)
4945 return NULL;
4946
4947 /* Bail out if namespace already is registered */
4948 def = TrioFindNamespace(name, &prev);
4949 if (def)
4950 return NULL;
4951 }
4952
4953 def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t));
4954 if (def)
4955 {
4956 if (internalEnterCriticalRegion)
4957 (void)internalEnterCriticalRegion(NULL);
4958
4959 if (name)
4960 {
4961 /* Link into internal list */
4962 if (prev == NULL)
4963 internalUserDef = def;
4964 else
4965 prev->next = def;
4966 }
4967 /* Initialize */
4968 def->callback = callback;
4969 def->name = (name == NULL)
4970 ? NULL
4971 : trio_duplicate(name);
4972 def->next = NULL;
4973
4974 if (internalLeaveCriticalRegion)
4975 (void)internalLeaveCriticalRegion(NULL);
4976 }
4977 return (trio_pointer_t)def;
4978}
4979
4980/**
4981 Unregister an existing user-defined specifier.
4982
4983 @param handle
4984 */
4985void
4986trio_unregister
4987TRIO_ARGS1((handle),
4988 trio_pointer_t handle)
4989{
4990 trio_userdef_t *self = (trio_userdef_t *)handle;
4991 trio_userdef_t *def;
4992 trio_userdef_t *prev = NULL;
4993
4994 assert(VALID(self));
4995
4996 if (self->name)
4997 {
4998 def = TrioFindNamespace(self->name, &prev);
4999 if (def)
5000 {
5001 if (internalEnterCriticalRegion)
5002 (void)internalEnterCriticalRegion(NULL);
5003
5004 if (prev == NULL)
5005 internalUserDef = internalUserDef->next;
5006 else
5007 prev->next = def->next;
5008
5009 if (internalLeaveCriticalRegion)
5010 (void)internalLeaveCriticalRegion(NULL);
5011 }
5012 trio_destroy(self->name);
5013 }
5014 TRIO_FREE(self);
5015}
5016
5017/*************************************************************************
5018 * trio_get_format [public]
5019 */
5020TRIO_CONST char *
5021trio_get_format
5022TRIO_ARGS1((ref),
5023 trio_pointer_t ref)
5024{
5025#if TRIO_FEATURE_USER_DEFINED
5026 assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
5027#endif
5028
5029 return (((trio_reference_t *)ref)->parameter->user_data);
5030}
5031
5032/*************************************************************************
5033 * trio_get_argument [public]
5034 */
5035TRIO_CONST trio_pointer_t
5036trio_get_argument
5037TRIO_ARGS1((ref),
5038 trio_pointer_t ref)
5039{
5040#if TRIO_FEATURE_USER_DEFINED
5041 assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
5042#endif
5043
5044 return ((trio_reference_t *)ref)->parameter->data.pointer;
5045}
5046
5047/*************************************************************************
5048 * trio_get_width / trio_set_width [public]
5049 */
5050int
5051trio_get_width
5052TRIO_ARGS1((ref),
5053 trio_pointer_t ref)
5054{
5055 return ((trio_reference_t *)ref)->parameter->width;
5056}
5057
5058void
5059trio_set_width
5060TRIO_ARGS2((ref, width),
5061 trio_pointer_t ref,
5062 int width)
5063{
5064 ((trio_reference_t *)ref)->parameter->width = width;
5065}
5066
5067/*************************************************************************
5068 * trio_get_precision / trio_set_precision [public]
5069 */
5070int
5071trio_get_precision
5072TRIO_ARGS1((ref),
5073 trio_pointer_t ref)
5074{
5075 return (((trio_reference_t *)ref)->parameter->precision);
5076}
5077
5078void
5079trio_set_precision
5080TRIO_ARGS2((ref, precision),
5081 trio_pointer_t ref,
5082 int precision)
5083{
5084 ((trio_reference_t *)ref)->parameter->precision = precision;
5085}
5086
5087/*************************************************************************
5088 * trio_get_base / trio_set_base [public]
5089 */
5090int
5091trio_get_base
5092TRIO_ARGS1((ref),
5093 trio_pointer_t ref)
5094{
5095 return (((trio_reference_t *)ref)->parameter->base);
5096}
5097
5098void
5099trio_set_base
5100TRIO_ARGS2((ref, base),
5101 trio_pointer_t ref,
5102 int base)
5103{
5104 ((trio_reference_t *)ref)->parameter->base = base;
5105}
5106
5107/*************************************************************************
5108 * trio_get_long / trio_set_long [public]
5109 */
5110int
5111trio_get_long
5112TRIO_ARGS1((ref),
5113 trio_pointer_t ref)
5114{
5115 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG)
5116 ? TRUE
5117 : FALSE;
5118}
5119
5120void
5121trio_set_long
5122TRIO_ARGS2((ref, is_long),
5123 trio_pointer_t ref,
5124 int is_long)
5125{
5126 if (is_long)
5127 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG;
5128 else
5129 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG;
5130}
5131
5132/*************************************************************************
5133 * trio_get_longlong / trio_set_longlong [public]
5134 */
5135int
5136trio_get_longlong
5137TRIO_ARGS1((ref),
5138 trio_pointer_t ref)
5139{
5140 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD)
5141 ? TRUE
5142 : FALSE;
5143}
5144
5145void
5146trio_set_longlong
5147TRIO_ARGS2((ref, is_longlong),
5148 trio_pointer_t ref,
5149 int is_longlong)
5150{
5151 if (is_longlong)
5152 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD;
5153 else
5154 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD;
5155}
5156
5157/*************************************************************************
5158 * trio_get_longdouble / trio_set_longdouble [public]
5159 */
5160# if TRIO_FEATURE_FLOAT
5161int
5162trio_get_longdouble
5163TRIO_ARGS1((ref),
5164 trio_pointer_t ref)
5165{
5166 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE)
5167 ? TRUE
5168 : FALSE;
5169}
5170
5171void
5172trio_set_longdouble
5173TRIO_ARGS2((ref, is_longdouble),
5174 trio_pointer_t ref,
5175 int is_longdouble)
5176{
5177 if (is_longdouble)
5178 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE;
5179 else
5180 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE;
5181}
5182# endif /* TRIO_FEATURE_FLOAT */
5183
5184/*************************************************************************
5185 * trio_get_short / trio_set_short [public]
5186 */
5187int
5188trio_get_short
5189TRIO_ARGS1((ref),
5190 trio_pointer_t ref)
5191{
5192 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT)
5193 ? TRUE
5194 : FALSE;
5195}
5196
5197void
5198trio_set_short
5199TRIO_ARGS2((ref, is_short),
5200 trio_pointer_t ref,
5201 int is_short)
5202{
5203 if (is_short)
5204 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT;
5205 else
5206 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT;
5207}
5208
5209/*************************************************************************
5210 * trio_get_shortshort / trio_set_shortshort [public]
5211 */
5212int
5213trio_get_shortshort
5214TRIO_ARGS1((ref),
5215 trio_pointer_t ref)
5216{
5217 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT)
5218 ? TRUE
5219 : FALSE;
5220}
5221
5222void
5223trio_set_shortshort
5224TRIO_ARGS2((ref, is_shortshort),
5225 trio_pointer_t ref,
5226 int is_shortshort)
5227{
5228 if (is_shortshort)
5229 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT;
5230 else
5231 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT;
5232}
5233
5234/*************************************************************************
5235 * trio_get_alternative / trio_set_alternative [public]
5236 */
5237int
5238trio_get_alternative
5239TRIO_ARGS1((ref),
5240 trio_pointer_t ref)
5241{
5242 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE)
5243 ? TRUE
5244 : FALSE;
5245}
5246
5247void
5248trio_set_alternative
5249TRIO_ARGS2((ref, is_alternative),
5250 trio_pointer_t ref,
5251 int is_alternative)
5252{
5253 if (is_alternative)
5254 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE;
5255 else
5256 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE;
5257}
5258
5259/*************************************************************************
5260 * trio_get_alignment / trio_set_alignment [public]
5261 */
5262int
5263trio_get_alignment
5264TRIO_ARGS1((ref),
5265 trio_pointer_t ref)
5266{
5267 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST)
5268 ? TRUE
5269 : FALSE;
5270}
5271
5272void
5273trio_set_alignment
5274TRIO_ARGS2((ref, is_leftaligned),
5275 trio_pointer_t ref,
5276 int is_leftaligned)
5277{
5278 if (is_leftaligned)
5279 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST;
5280 else
5281 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST;
5282}
5283
5284/*************************************************************************
5285 * trio_get_spacing /trio_set_spacing [public]
5286 */
5287int
5288trio_get_spacing
5289TRIO_ARGS1((ref),
5290 trio_pointer_t ref)
5291{
5292 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE)
5293 ? TRUE
5294 : FALSE;
5295}
5296
5297void
5298trio_set_spacing
5299TRIO_ARGS2((ref, is_space),
5300 trio_pointer_t ref,
5301 int is_space)
5302{
5303 if (is_space)
5304 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE;
5305 else
5306 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE;
5307}
5308
5309/*************************************************************************
5310 * trio_get_sign / trio_set_sign [public]
5311 */
5312int
5313trio_get_sign
5314TRIO_ARGS1((ref),
5315 trio_pointer_t ref)
5316{
5317 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN)
5318 ? TRUE
5319 : FALSE;
5320}
5321
5322void
5323trio_set_sign
5324TRIO_ARGS2((ref, is_sign),
5325 trio_pointer_t ref,
5326 int is_sign)
5327{
5328 if (is_sign)
5329 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN;
5330 else
5331 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN;
5332}
5333
5334/*************************************************************************
5335 * trio_get_padding / trio_set_padding [public]
5336 */
5337int
5338trio_get_padding
5339TRIO_ARGS1((ref),
5340 trio_pointer_t ref)
5341{
5342 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING)
5343 ? TRUE
5344 : FALSE;
5345}
5346
5347void
5348trio_set_padding
5349TRIO_ARGS2((ref, is_padding),
5350 trio_pointer_t ref,
5351 int is_padding)
5352{
5353 if (is_padding)
5354 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING;
5355 else
5356 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING;
5357}
5358
5359/*************************************************************************
5360 * trio_get_quote / trio_set_quote [public]
5361 */
5362# if TRIO_FEATURE_QUOTE
5363int
5364trio_get_quote
5365TRIO_ARGS1((ref),
5366 trio_pointer_t ref)
5367{
5368 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE)
5369 ? TRUE
5370 : FALSE;
5371}
5372
5373void
5374trio_set_quote
5375TRIO_ARGS2((ref, is_quote),
5376 trio_pointer_t ref,
5377 int is_quote)
5378{
5379 if (is_quote)
5380 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE;
5381 else
5382 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE;
5383}
5384#endif /* TRIO_FEATURE_QUOTE */
5385
5386/*************************************************************************
5387 * trio_get_upper / trio_set_upper [public]
5388 */
5389int
5390trio_get_upper
5391TRIO_ARGS1((ref),
5392 trio_pointer_t ref)
5393{
5394 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER)
5395 ? TRUE
5396 : FALSE;
5397}
5398
5399void
5400trio_set_upper
5401TRIO_ARGS2((ref, is_upper),
5402 trio_pointer_t ref,
5403 int is_upper)
5404{
5405 if (is_upper)
5406 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER;
5407 else
5408 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER;
5409}
5410
5411/*************************************************************************
5412 * trio_get_largest / trio_set_largest [public]
5413 */
5414#if TRIO_FEATURE_INTMAX_T
5415int
5416trio_get_largest
5417TRIO_ARGS1((ref),
5418 trio_pointer_t ref)
5419{
5420 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T)
5421 ? TRUE
5422 : FALSE;
5423}
5424
5425void
5426trio_set_largest
5427TRIO_ARGS2((ref, is_largest),
5428 trio_pointer_t ref,
5429 int is_largest)
5430{
5431 if (is_largest)
5432 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T;
5433 else
5434 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T;
5435}
5436#endif /* TRIO_FEATURE_INTMAX_T */
5437
5438/*************************************************************************
5439 * trio_get_ptrdiff / trio_set_ptrdiff [public]
5440 */
5441#if TRIO_FEATURE_PTRDIFF_T
5442int
5443trio_get_ptrdiff
5444TRIO_ARGS1((ref),
5445 trio_pointer_t ref)
5446{
5447 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T)
5448 ? TRUE
5449 : FALSE;
5450}
5451
5452void
5453trio_set_ptrdiff
5454TRIO_ARGS2((ref, is_ptrdiff),
5455 trio_pointer_t ref,
5456 int is_ptrdiff)
5457{
5458 if (is_ptrdiff)
5459 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T;
5460 else
5461 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T;
5462}
5463#endif /* TRIO_FEATURE_PTRDIFF_T */
5464
5465/*************************************************************************
5466 * trio_get_size / trio_set_size [public]
5467 */
5468#if TRIO_FEATURE_SIZE_T
5469int
5470trio_get_size
5471TRIO_ARGS1((ref),
5472 trio_pointer_t ref)
5473{
5474 return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T)
5475 ? TRUE
5476 : FALSE;
5477}
5478
5479void
5480trio_set_size
5481TRIO_ARGS2((ref, is_size),
5482 trio_pointer_t ref,
5483 int is_size)
5484{
5485 if (is_size)
5486 ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T;
5487 else
5488 ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T;
5489}
5490#endif /* TRIO_FEATURE_SIZE_T */
5491
5492/*************************************************************************
5493 * trio_print_int [public]
5494 */
5495void
5496trio_print_int
5497TRIO_ARGS2((ref, number),
5498 trio_pointer_t ref,
5499 int number)
5500{
5501 trio_reference_t *self = (trio_reference_t *)ref;
5502
5503 TrioWriteNumber(self->data,
5504 (trio_uintmax_t)number,
5505 self->parameter->flags,
5506 self->parameter->width,
5507 self->parameter->precision,
5508 self->parameter->base);
5509}
5510
5511/*************************************************************************
5512 * trio_print_uint [public]
5513 */
5514void
5515trio_print_uint
5516TRIO_ARGS2((ref, number),
5517 trio_pointer_t ref,
5518 unsigned int number)
5519{
5520 trio_reference_t *self = (trio_reference_t *)ref;
5521
5522 TrioWriteNumber(self->data,
5523 (trio_uintmax_t)number,
5524 self->parameter->flags | FLAGS_UNSIGNED,
5525 self->parameter->width,
5526 self->parameter->precision,
5527 self->parameter->base);
5528}
5529
5530/*************************************************************************
5531 * trio_print_double [public]
5532 */
5533#if TRIO_FEATURE_FLOAT
5534void
5535trio_print_double
5536TRIO_ARGS2((ref, number),
5537 trio_pointer_t ref,
5538 double number)
5539{
5540 trio_reference_t *self = (trio_reference_t *)ref;
5541
5542 TrioWriteDouble(self->data,
5543 number,
5544 self->parameter->flags,
5545 self->parameter->width,
5546 self->parameter->precision,
5547 self->parameter->base);
5548}
5549#endif /* TRIO_FEATURE_FLOAT */
5550
5551/*************************************************************************
5552 * trio_print_string [public]
5553 */
5554void
5555trio_print_string
5556TRIO_ARGS2((ref, string),
5557 trio_pointer_t ref,
5558 TRIO_CONST char *string)
5559{
5560 trio_reference_t *self = (trio_reference_t *)ref;
5561
5562 TrioWriteString(self->data,
5563 string,
5564 self->parameter->flags,
5565 self->parameter->width,
5566 self->parameter->precision);
5567}
5568
5569/*************************************************************************
5570 * trio_print_ref [public]
5571 */
5572int
5573trio_print_ref
5574TRIO_VARGS3((ref, format, va_alist),
5575 trio_pointer_t ref,
5576 TRIO_CONST char *format,
5577 TRIO_VA_DECL)
5578{
5579 int status;
5580 va_list arglist;
5581
5582 assert(VALID(format));
5583
5584 TRIO_VA_START(arglist, format);
5585 status = TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL);
5586 TRIO_VA_END(arglist);
5587 return status;
5588}
5589
5590/*************************************************************************
5591 * trio_vprint_ref [public]
5592 */
5593int
5594trio_vprint_ref
5595TRIO_ARGS3((ref, format, arglist),
5596 trio_pointer_t ref,
5597 TRIO_CONST char *format,
5598 va_list arglist)
5599{
5600 assert(VALID(format));
5601
5602 return TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL);
5603}
5604
5605/*************************************************************************
5606 * trio_printv_ref [public]
5607 */
5608int
5609trio_printv_ref
5610TRIO_ARGS3((ref, format, argarray),
5611 trio_pointer_t ref,
5612 TRIO_CONST char *format,
5613 trio_pointer_t *argarray)
5614{
5615 static va_list unused;
5616
5617 assert(VALID(format));
5618
5619 return TrioFormatRef((trio_reference_t *)ref, format, unused, argarray);
5620}
5621
5622#endif
5623
5624/*************************************************************************
5625 * trio_print_pointer [public]
5626 */
5627void
5628trio_print_pointer
5629TRIO_ARGS2((ref, pointer),
5630 trio_pointer_t ref,
5631 trio_pointer_t pointer)
5632{
5633 trio_reference_t *self = (trio_reference_t *)ref;
5634 trio_flags_t flags;
5635 trio_uintmax_t number;
5636
5637 if (NULL == pointer)
5638 {
5639 TRIO_CONST char *string = internalNullString;
5640 while (*string)
5641 self->data->OutStream(self->data, *string++);
5642 }
5643 else
5644 {
5645 /*
5646 * The subtraction of the null pointer is a workaround
5647 * to avoid a compiler warning. The performance overhead
5648 * is negligible (and likely to be removed by an
5649 * optimizing compiler). The (char *) casting is done
5650 * to please ANSI C++.
5651 */
5652 number = (trio_uintmax_t)((char *)pointer - (char *)0);
5653 /* Shrink to size of pointer */
5654 number &= (trio_uintmax_t)-1;
5655 flags = self->parameter->flags;
5656 flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE |
5657 FLAGS_NILPADDING);
5658 TrioWriteNumber(self->data,
5659 number,
5660 flags,
5661 POINTER_WIDTH,
5662 NO_PRECISION,
5663 BASE_HEX);
5664 }
5665}
5666
5667/** @} End of UserDefined documentation module */
5668
5669/*************************************************************************
5670 *
5671 * LOCALES
5672 *
5673 ************************************************************************/
5674
5675/*************************************************************************
5676 * trio_locale_set_decimal_point
5677 *
5678 * Decimal point can only be one character. The input argument is a
5679 * string to enable multibyte characters. At most MB_LEN_MAX characters
5680 * will be used.
5681 */
5682#if TRIO_FEATURE_LOCALE
5683TRIO_PUBLIC void
5684trio_locale_set_decimal_point
5685TRIO_ARGS1((decimalPoint),
5686 char *decimalPoint)
5687{
5688#if defined(USE_LOCALE)
5689 if (NULL == internalLocaleValues)
5690 {
5691 TrioSetLocale();
5692 }
5693#endif
5694 internalDecimalPointLength = trio_length(decimalPoint);
5695 if (internalDecimalPointLength == 1)
5696 {
5697 internalDecimalPoint = *decimalPoint;
5698 }
5699 else
5700 {
5701 internalDecimalPoint = NIL;
5702 trio_copy_max(internalDecimalPointString,
5703 sizeof(internalDecimalPointString),
5704 decimalPoint);
5705 }
5706}
5707#endif
5708
5709/*************************************************************************
5710 * trio_locale_set_thousand_separator
5711 *
5712 * See trio_locale_set_decimal_point
5713 */
5714#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION
5715TRIO_PUBLIC void
5716trio_locale_set_thousand_separator
5717TRIO_ARGS1((thousandSeparator),
5718 char *thousandSeparator)
5719{
5720# if defined(USE_LOCALE)
5721 if (NULL == internalLocaleValues)
5722 {
5723 TrioSetLocale();
5724 }
5725# endif
5726 trio_copy_max(internalThousandSeparator,
5727 sizeof(internalThousandSeparator),
5728 thousandSeparator);
5729 internalThousandSeparatorLength = trio_length(internalThousandSeparator);
5730}
5731#endif
5732
5733/*************************************************************************
5734 * trio_locale_set_grouping
5735 *
5736 * Array of bytes. Reversed order.
5737 *
5738 * CHAR_MAX : No further grouping
5739 * 0 : Repeat last group for the remaining digits (not necessary
5740 * as C strings are zero-terminated)
5741 * n : Set current group to n
5742 *
5743 * Same order as the grouping attribute in LC_NUMERIC.
5744 */
5745#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION
5746TRIO_PUBLIC void
5747trio_locale_set_grouping
5748TRIO_ARGS1((grouping),
5749 char *grouping)
5750{
5751# if defined(USE_LOCALE)
5752 if (NULL == internalLocaleValues)
5753 {
5754 TrioSetLocale();
5755 }
5756# endif
5757 trio_copy_max(internalGrouping,
5758 sizeof(internalGrouping),
5759 grouping);
5760}
5761#endif
5762
5763
5764/*************************************************************************
5765 *
5766 * SCANNING
5767 *
5768 ************************************************************************/
5769
5770#if TRIO_FEATURE_SCANF
5771
5772/*************************************************************************
5773 * TrioSkipWhitespaces
5774 */
5775TRIO_PRIVATE int
5776TrioSkipWhitespaces
5777TRIO_ARGS1((self),
5778 trio_class_t *self)
5779{
5780 int ch;
5781
5782 ch = self->current;
5783 while (isspace(ch))
5784 {
5785 self->InStream(self, &ch);
5786 }
5787 return ch;
5788}
5789
5790/*************************************************************************
5791 * TrioGetCollation
5792 */
5793#if TRIO_EXTENSION
5794TRIO_PRIVATE void
5795TrioGetCollation(TRIO_NOARGS)
5796{
5797 int i;
5798 int j;
5799 int k;
5800 char first[2];
5801 char second[2];
5802
5803 /* This is computationally expensive */
5804 first[1] = NIL;
5805 second[1] = NIL;
5806 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
5807 {
5808 k = 0;
5809 first[0] = (char)i;
5810 for (j = 0; j < MAX_CHARACTER_CLASS; j++)
5811 {
5812 second[0] = (char)j;
5813 if (trio_equal_locale(first, second))
5814 internalCollationArray[i][k++] = (char)j;
5815 }
5816 internalCollationArray[i][k] = NIL;
5817 }
5818}
5819#endif
5820
5821/*************************************************************************
5822 * TrioGetCharacterClass
5823 *
5824 * FIXME:
5825 * multibyte
5826 */
5827TRIO_PRIVATE int
5828TrioGetCharacterClass
5829TRIO_ARGS4((format, offsetPointer, flagsPointer, characterclass),
5830 TRIO_CONST char *format,
5831 int *offsetPointer,
5832 trio_flags_t *flagsPointer,
5833 int *characterclass)
5834{
5835 int offset = *offsetPointer;
5836 int i;
5837 char ch;
5838 char range_begin;
5839 char range_end;
5840
5841 *flagsPointer &= ~FLAGS_EXCLUDE;
5842
5843 if (format[offset] == QUALIFIER_CIRCUMFLEX)
5844 {
5845 *flagsPointer |= FLAGS_EXCLUDE;
5846 offset++;
5847 }
5848 /*
5849 * If the ungroup character is at the beginning of the scanlist,
5850 * it will be part of the class, and a second ungroup character
5851 * must follow to end the group.
5852 */
5853 if (format[offset] == SPECIFIER_UNGROUP)
5854 {
5855 characterclass[(int)SPECIFIER_UNGROUP]++;
5856 offset++;
5857 }
5858 /*
5859 * Minus is used to specify ranges. To include minus in the class,
5860 * it must be at the beginning of the list
5861 */
5862 if (format[offset] == QUALIFIER_MINUS)
5863 {
5864 characterclass[(int)QUALIFIER_MINUS]++;
5865 offset++;
5866 }
5867 /* Collect characters */
5868 for (ch = format[offset];
5869 (ch != SPECIFIER_UNGROUP) && (ch != NIL);
5870 ch = format[++offset])
5871 {
5872 switch (ch)
5873 {
5874 case QUALIFIER_MINUS: /* Scanlist ranges */
5875
5876 /*
5877 * Both C99 and UNIX98 describes ranges as implementation-
5878 * defined.
5879 *
5880 * We support the following behaviour (although this may
5881 * change as we become wiser)
5882 * - only increasing ranges, ie. [a-b] but not [b-a]
5883 * - transitive ranges, ie. [a-b-c] == [a-c]
5884 * - trailing minus, ie. [a-] is interpreted as an 'a'
5885 * and a '-'
5886 * - duplicates (although we can easily convert these
5887 * into errors)
5888 */
5889 range_begin = format[offset - 1];
5890 range_end = format[++offset];
5891 if (range_end == SPECIFIER_UNGROUP)
5892 {
5893 /* Trailing minus is included */
5894 characterclass[(int)ch]++;
5895 ch = range_end;
5896 break; /* for */
5897 }
5898 if (range_end == NIL)
5899 return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
5900 if (range_begin > range_end)
5901 return TRIO_ERROR_RETURN(TRIO_ERANGE, offset);
5902
5903 for (i = (int)range_begin; i <= (int)range_end; i++)
5904 characterclass[i]++;
5905
5906 ch = range_end;
5907 break;
5908
5909#if TRIO_EXTENSION
5910
5911 case SPECIFIER_GROUP:
5912
5913 switch (format[offset + 1])
5914 {
5915 case QUALIFIER_DOT: /* Collating symbol */
5916 /*
5917 * FIXME: This will be easier to implement when multibyte
5918 * characters have been implemented. Until now, we ignore
5919 * this feature.
5920 */
5921 for (i = offset + 2; ; i++)
5922 {
5923 if (format[i] == NIL)
5924 /* Error in syntax */
5925 return -1;
5926 else if (format[i] == QUALIFIER_DOT)
5927 break; /* for */
5928 }
5929 if (format[++i] != SPECIFIER_UNGROUP)
5930 return -1;
5931
5932 offset = i;
5933 break;
5934
5935 case QUALIFIER_EQUAL: /* Equivalence class expressions */
5936 {
5937 unsigned int j;
5938 unsigned int k;
5939
5940 if (internalCollationUnconverted)
5941 {
5942 /* Lazy evaluation of collation array */
5943 TrioGetCollation();
5944 internalCollationUnconverted = FALSE;
5945 }
5946 for (i = offset + 2; ; i++)
5947 {
5948 if (format[i] == NIL)
5949 /* Error in syntax */
5950 return -1;
5951 else if (format[i] == QUALIFIER_EQUAL)
5952 break; /* for */
5953 else
5954 {
5955 /* Mark any equivalent character */
5956 k = (unsigned int)format[i];
5957 for (j = 0; internalCollationArray[k][j] != NIL; j++)
5958 characterclass[(int)internalCollationArray[k][j]]++;
5959 }
5960 }
5961 if (format[++i] != SPECIFIER_UNGROUP)
5962 return -1;
5963
5964 offset = i;
5965 }
5966 break;
5967
5968 case QUALIFIER_COLON: /* Character class expressions */
5969
5970 if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1,
5971 &format[offset]))
5972 {
5973 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
5974 if (isalnum(i))
5975 characterclass[i]++;
5976 offset += sizeof(CLASS_ALNUM) - 1;
5977 }
5978 else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1,
5979 &format[offset]))
5980 {
5981 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
5982 if (isalpha(i))
5983 characterclass[i]++;
5984 offset += sizeof(CLASS_ALPHA) - 1;
5985 }
5986 else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1,
5987 &format[offset]))
5988 {
5989 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
5990 if (iscntrl(i))
5991 characterclass[i]++;
5992 offset += sizeof(CLASS_CNTRL) - 1;
5993 }
5994 else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1,
5995 &format[offset]))
5996 {
5997 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
5998 if (isdigit(i))
5999 characterclass[i]++;
6000 offset += sizeof(CLASS_DIGIT) - 1;
6001 }
6002 else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1,
6003 &format[offset]))
6004 {
6005 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
6006 if (isgraph(i))
6007 characterclass[i]++;
6008 offset += sizeof(CLASS_GRAPH) - 1;
6009 }
6010 else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1,
6011 &format[offset]))
6012 {
6013 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
6014 if (islower(i))
6015 characterclass[i]++;
6016 offset += sizeof(CLASS_LOWER) - 1;
6017 }
6018 else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1,
6019 &format[offset]))
6020 {
6021 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
6022 if (isprint(i))
6023 characterclass[i]++;
6024 offset += sizeof(CLASS_PRINT) - 1;
6025 }
6026 else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1,
6027 &format[offset]))
6028 {
6029 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
6030 if (ispunct(i))
6031 characterclass[i]++;
6032 offset += sizeof(CLASS_PUNCT) - 1;
6033 }
6034 else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1,
6035 &format[offset]))
6036 {
6037 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
6038 if (isspace(i))
6039 characterclass[i]++;
6040 offset += sizeof(CLASS_SPACE) - 1;
6041 }
6042 else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1,
6043 &format[offset]))
6044 {
6045 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
6046 if (isupper(i))
6047 characterclass[i]++;
6048 offset += sizeof(CLASS_UPPER) - 1;
6049 }
6050 else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1,
6051 &format[offset]))
6052 {
6053 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
6054 if (isxdigit(i))
6055 characterclass[i]++;
6056 offset += sizeof(CLASS_XDIGIT) - 1;
6057 }
6058 else
6059 {
6060 characterclass[(int)ch]++;
6061 }
6062 break;
6063
6064 default:
6065 characterclass[(int)ch]++;
6066 break;
6067 }
6068 break;
6069
6070#endif /* TRIO_EXTENSION */
6071
6072 default:
6073 characterclass[(int)ch]++;
6074 break;
6075 }
6076 }
6077 return 0;
6078}
6079
6080/*************************************************************************
6081 * TrioReadNumber
6082 *
6083 * We implement our own number conversion in preference of strtol and
6084 * strtoul, because we must handle 'long long' and thousand separators.
6085 */
6086TRIO_PRIVATE BOOLEAN_T
6087TrioReadNumber
6088TRIO_ARGS5((self, target, flags, width, base),
6089 trio_class_t *self,
6090 trio_uintmax_t *target,
6091 trio_flags_t flags,
6092 int width,
6093 int base)
6094{
6095 trio_uintmax_t number = 0;
6096 int digit;
6097 int count;
6098 BOOLEAN_T isNegative = FALSE;
6099 BOOLEAN_T gotNumber = FALSE;
6100 int j;
6101
6102 assert(VALID(self));
6103 assert(VALID(self->InStream));
6104 assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE));
6105
6106 if (internalDigitsUnconverted)
6107 {
6108 /* Lazy evaluation of digits array */
6109 memset(internalDigitArray, -1, sizeof(internalDigitArray));
6110 for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++)
6111 {
6112 internalDigitArray[(int)internalDigitsLower[j]] = j;
6113 internalDigitArray[(int)internalDigitsUpper[j]] = j;
6114 }
6115 internalDigitsUnconverted = FALSE;
6116 }
6117
6118 TrioSkipWhitespaces(self);
6119
6120 /* Leading sign */
6121 if (self->current == '+')
6122 {
6123 self->InStream(self, NULL);
6124 }
6125 else if (self->current == '-')
6126 {
6127 self->InStream(self, NULL);
6128 isNegative = TRUE;
6129 }
6130
6131 count = self->processed;
6132
6133 if (flags & FLAGS_ALTERNATIVE)
6134 {
6135 switch (base)
6136 {
6137 case NO_BASE:
6138 case BASE_OCTAL:
6139 case BASE_HEX:
6140 case BASE_BINARY:
6141 if (self->current == '0')
6142 {
6143 self->InStream(self, NULL);
6144 if (self->current)
6145 {
6146 if ((base == BASE_HEX) &&
6147 (trio_to_upper(self->current) == 'X'))
6148 {
6149 self->InStream(self, NULL);
6150 }
6151 else if ((base == BASE_BINARY) &&
6152 (trio_to_upper(self->current) == 'B'))
6153 {
6154 self->InStream(self, NULL);
6155 }
6156 }
6157 }
6158 else
6159 return FALSE;
6160 break;
6161 default:
6162 break;
6163 }
6164 }
6165
6166 while (((width == NO_WIDTH) || (self->processed - count < width)) &&
6167 (! ((self->current == EOF) || isspace(self->current))))
6168 {
6169 if (isascii(self->current))
6170 {
6171 digit = internalDigitArray[self->current];
6172 /* Abort if digit is not allowed in the specified base */
6173 if ((digit == -1) || (digit >= base))
6174 break;
6175 }
6176#if TRIO_FEATURE_QUOTE
6177 else if (flags & FLAGS_QUOTE)
6178 {
6179 /* Compare with thousands separator */
6180 for (j = 0; internalThousandSeparator[j] && self->current; j++)
6181 {
6182 if (internalThousandSeparator[j] != self->current)
6183 break;
6184
6185 self->InStream(self, NULL);
6186 }
6187 if (internalThousandSeparator[j])
6188 break; /* Mismatch */
6189 else
6190 continue; /* Match */
6191 }
6192#endif
6193 else
6194 break;
6195
6196 number *= base;
6197 number += digit;
6198 gotNumber = TRUE; /* we need at least one digit */
6199
6200 self->InStream(self, NULL);
6201 }
6202
6203 /* Was anything read at all? */
6204 if (!gotNumber)
6205 return FALSE;
6206
6207 if (target)
6208 *target = (isNegative) ? (trio_uintmax_t)(-((trio_intmax_t)number)) : number;
6209 return TRUE;
6210}
6211
6212/*************************************************************************
6213 * TrioReadChar
6214 */
6215TRIO_PRIVATE int
6216TrioReadChar
6217TRIO_ARGS4((self, target, flags, width),
6218 trio_class_t *self,
6219 char *target,
6220 trio_flags_t flags,
6221 int width)
6222{
6223 int i;
6224 char ch;
6225 trio_uintmax_t number;
6226
6227 assert(VALID(self));
6228 assert(VALID(self->InStream));
6229
6230 for (i = 0;
6231 (self->current != EOF) && (i < width);
6232 i++)
6233 {
6234 ch = (char)self->current;
6235 self->InStream(self, NULL);
6236 if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH))
6237 {
6238 switch (self->current)
6239 {
6240 case '\\': ch = '\\'; break;
6241 case 'a': ch = '\007'; break;
6242 case 'b': ch = '\b'; break;
6243 case 'f': ch = '\f'; break;
6244 case 'n': ch = '\n'; break;
6245 case 'r': ch = '\r'; break;
6246 case 't': ch = '\t'; break;
6247 case 'v': ch = '\v'; break;
6248 default:
6249 if (isdigit(self->current))
6250 {
6251 /* Read octal number */
6252 if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL))
6253 return 0;
6254 ch = (char)number;
6255 }
6256 else if (trio_to_upper(self->current) == 'X')
6257 {
6258 /* Read hexadecimal number */
6259 self->InStream(self, NULL);
6260 if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX))
6261 return 0;
6262 ch = (char)number;
6263 }
6264 else
6265 {
6266 ch = (char)self->current;
6267 }
6268 break;
6269 }
6270 }
6271
6272 if (target)
6273 target[i] = ch;
6274 }
6275 return i + 1;
6276}
6277
6278/*************************************************************************
6279 * TrioReadString
6280 */
6281TRIO_PRIVATE BOOLEAN_T
6282TrioReadString
6283TRIO_ARGS4((self, target, flags, width),
6284 trio_class_t *self,
6285 char *target,
6286 trio_flags_t flags,
6287 int width)
6288{
6289 int i;
6290
6291 assert(VALID(self));
6292 assert(VALID(self->InStream));
6293
6294 TrioSkipWhitespaces(self);
6295
6296 /*
6297 * Continue until end of string is reached, a whitespace is encountered,
6298 * or width is exceeded
6299 */
6300 for (i = 0;
6301 ((width == NO_WIDTH) || (i < width)) &&
6302 (! ((self->current == EOF) || isspace(self->current)));
6303 i++)
6304 {
6305 if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0)
6306 break; /* for */
6307 }
6308 if (target)
6309 target[i] = NIL;
6310 return TRUE;
6311}
6312
6313/*************************************************************************
6314 * TrioReadWideChar
6315 */
6316#if TRIO_FEATURE_WIDECHAR
6317TRIO_PRIVATE int
6318TrioReadWideChar
6319TRIO_ARGS4((self, target, flags, width),
6320 trio_class_t *self,
6321 trio_wchar_t *target,
6322 trio_flags_t flags,
6323 int width)
6324{
6325 int i;
6326 int j;
6327 int size;
6328 int amount = 0;
6329 trio_wchar_t wch;
6330 char buffer[MB_LEN_MAX + 1];
6331
6332 assert(VALID(self));
6333 assert(VALID(self->InStream));
6334
6335 for (i = 0;
6336 (self->current != EOF) && (i < width);
6337 i++)
6338 {
6339 if (isascii(self->current))
6340 {
6341 if (TrioReadChar(self, buffer, flags, 1) == 0)
6342 return 0;
6343 buffer[1] = NIL;
6344 }
6345 else
6346 {
6347 /*
6348 * Collect a multibyte character, by enlarging buffer until
6349 * it contains a fully legal multibyte character, or the
6350 * buffer is full.
6351 */
6352 j = 0;
6353 do
6354 {
6355 buffer[j++] = (char)self->current;
6356 buffer[j] = NIL;
6357 self->InStream(self, NULL);
6358 }
6359 while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j));
6360 }
6361 if (target)
6362 {
6363 size = mbtowc(&wch, buffer, sizeof(buffer));
6364 if (size > 0)
6365 target[i] = wch;
6366 }
6367 amount += size;
6368 self->InStream(self, NULL);
6369 }
6370 return amount;
6371}
6372#endif /* TRIO_FEATURE_WIDECHAR */
6373
6374/*************************************************************************
6375 * TrioReadWideString
6376 */
6377#if TRIO_FEATURE_WIDECHAR
6378TRIO_PRIVATE BOOLEAN_T
6379TrioReadWideString
6380TRIO_ARGS4((self, target, flags, width),
6381 trio_class_t *self,
6382 trio_wchar_t *target,
6383 trio_flags_t flags,
6384 int width)
6385{
6386 int i;
6387 int size;
6388
6389 assert(VALID(self));
6390 assert(VALID(self->InStream));
6391
6392 TrioSkipWhitespaces(self);
6393
6394#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
6395 /* Required by TrioReadWideChar */
6396 size = mblen(NULL, 0);
6397#endif
6398
6399 /*
6400 * Continue until end of string is reached, a whitespace is encountered,
6401 * or width is exceeded
6402 */
6403 for (i = 0;
6404 ((width == NO_WIDTH) || (i < width)) &&
6405 (! ((self->current == EOF) || isspace(self->current)));
6406 )
6407 {
6408 size = TrioReadWideChar(self, &target[i], flags, 1);
6409 if (size == 0)
6410 break; /* for */
6411
6412 i += size;
6413 }
6414 if (target)
6415 target[i] = WCONST('\0');
6416 return TRUE;
6417}
6418#endif /* TRIO_FEATURE_WIDECHAR */
6419
6420/*************************************************************************
6421 * TrioReadGroup
6422 *
6423 * Reads non-empty character groups.
6424 *
6425 * FIXME: characterclass does not work with multibyte characters
6426 */
6427TRIO_PRIVATE BOOLEAN_T
6428TrioReadGroup
6429TRIO_ARGS5((self, target, characterclass, flags, width),
6430 trio_class_t *self,
6431 char *target,
6432 int *characterclass,
6433 trio_flags_t flags,
6434 int width)
6435{
6436 int ch;
6437 int i;
6438
6439 assert(VALID(self));
6440 assert(VALID(self->InStream));
6441
6442 ch = self->current;
6443 for (i = 0;
6444 ((width == NO_WIDTH) || (i < width)) &&
6445 (! ((ch == EOF) ||
6446 (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0))));
6447 i++)
6448 {
6449 if (target)
6450 target[i] = (char)ch;
6451 self->InStream(self, &ch);
6452 }
6453
6454 if (i == 0)
6455 return FALSE;
6456
6457 /* Terminate the string if input saved */
6458 if (target)
6459 target[i] = NIL;
6460 return TRUE;
6461}
6462
6463/*************************************************************************
6464 * TrioReadDouble
6465 *
6466 * FIXME:
6467 * add long double
6468 * handle base
6469 */
6470#if TRIO_FEATURE_FLOAT
6471TRIO_PRIVATE BOOLEAN_T
6472TrioReadDouble
6473TRIO_ARGS4((self, target, flags, width),
6474 trio_class_t *self,
6475 trio_pointer_t target,
6476 trio_flags_t flags,
6477 int width)
6478{
6479 int ch;
6480 char doubleString[512];
6481 int offset = 0;
6482 int start;
6483# if TRIO_FEATURE_QUOTE
6484 int j;
6485# endif
6486 BOOLEAN_T isHex = FALSE;
6487 trio_long_double_t infinity;
6488
6489 doubleString[0] = 0;
6490
6491 if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1))
6492 width = sizeof(doubleString) - 1;
6493
6494 TrioSkipWhitespaces(self);
6495
6496 /*
6497 * Read entire double number from stream. trio_to_double requires
6498 * a string as input, but InStream can be anything, so we have to
6499 * collect all characters.
6500 */
6501 ch = self->current;
6502 if ((ch == '+') || (ch == '-'))
6503 {
6504 doubleString[offset++] = (char)ch;
6505 self->InStream(self, &ch);
6506 width--;
6507 }
6508
6509 start = offset;
6510 switch (ch)
6511 {
6512 case 'n':
6513 case 'N':
6514 /* Not-a-number */
6515 if (offset != 0)
6516 break;
6517 /* FALLTHROUGH */
6518 case 'i':
6519 case 'I':
6520 /* Infinity */
6521 while (isalpha(ch) && (offset - start < width))
6522 {
6523 doubleString[offset++] = (char)ch;
6524 self->InStream(self, &ch);
6525 }
6526 doubleString[offset] = NIL;
6527
6528 /* Case insensitive string comparison */
6529 if (trio_equal(&doubleString[start], INFINITE_UPPER) ||
6530 trio_equal(&doubleString[start], LONG_INFINITE_UPPER))
6531 {
6532 infinity = ((start == 1) && (doubleString[0] == '-'))
6533 ? trio_ninf()
6534 : trio_pinf();
6535 if (flags & FLAGS_LONGDOUBLE)
6536 {
6537 *((trio_long_double_t *)target) = infinity;
6538 }
6539 else if (flags & FLAGS_LONG)
6540 {
6541 *((double *)target) = infinity;
6542 }
6543 else
6544 {
6545 *((float *)target) = infinity;
6546 }
6547 return TRUE;
6548 }
6549 if (trio_equal(doubleString, NAN_UPPER))
6550 {
6551 /* NaN must not have a preceeding + nor - */
6552 if (flags & FLAGS_LONGDOUBLE)
6553 {
6554 *((trio_long_double_t *)target) = trio_nan();
6555 }
6556 else if (flags & FLAGS_LONG)
6557 {
6558 *((double *)target) = trio_nan();
6559 }
6560 else
6561 {
6562 *((float *)target) = trio_nan();
6563 }
6564 return TRUE;
6565 }
6566 return FALSE;
6567
6568 case '0':
6569 doubleString[offset++] = (char)ch;
6570 self->InStream(self, &ch);
6571 if (trio_to_upper(ch) == 'X')
6572 {
6573 isHex = TRUE;
6574 doubleString[offset++] = (char)ch;
6575 self->InStream(self, &ch);
6576 }
6577 break;
6578
6579 default:
6580 break;
6581 }
6582
6583 while ((ch != EOF) && (offset - start < width))
6584 {
6585 /* Integer part */
6586 if (isHex ? isxdigit(ch) : isdigit(ch))
6587 {
6588 doubleString[offset++] = (char)ch;
6589 self->InStream(self, &ch);
6590 }
6591# if TRIO_FEATURE_QUOTE
6592 else if (flags & FLAGS_QUOTE)
6593 {
6594 /* Compare with thousands separator */
6595 for (j = 0; internalThousandSeparator[j] && self->current; j++)
6596 {
6597 if (internalThousandSeparator[j] != self->current)
6598 break;
6599
6600 self->InStream(self, &ch);
6601 }
6602 if (internalThousandSeparator[j])
6603 break; /* Mismatch */
6604 else
6605 continue; /* Match */
6606 }
6607# endif
6608 else
6609 break; /* while */
6610 }
6611 if (ch == '.')
6612 {
6613 /* Decimal part */
6614 doubleString[offset++] = (char)ch;
6615 self->InStream(self, &ch);
6616 while ((isHex ? isxdigit(ch) : isdigit(ch)) &&
6617 (offset - start < width))
6618 {
6619 doubleString[offset++] = (char)ch;
6620 self->InStream(self, &ch);
6621 }
6622 }
6623 if (isHex ? (trio_to_upper(ch) == 'P') : (trio_to_upper(ch) == 'E'))
6624 {
6625 /* Exponent */
6626 doubleString[offset++] = (char)ch;
6627 self->InStream(self, &ch);
6628 if ((ch == '+') || (ch == '-'))
6629 {
6630 doubleString[offset++] = (char)ch;
6631 self->InStream(self, &ch);
6632 }
6633 while (isdigit(ch) && (offset - start < width))
6634 {
6635 doubleString[offset++] = (char)ch;
6636 self->InStream(self, &ch);
6637 }
6638 }
6639
6640 if ((offset == start) || (*doubleString == NIL))
6641 return FALSE;
6642
6643 doubleString[offset] = 0;
6644
6645 if (flags & FLAGS_LONGDOUBLE)
6646 {
6647 *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL);
6648 }
6649 else if (flags & FLAGS_LONG)
6650 {
6651 *((double *)target) = trio_to_double(doubleString, NULL);
6652 }
6653 else
6654 {
6655 *((float *)target) = trio_to_float(doubleString, NULL);
6656 }
6657 return TRUE;
6658}
6659#endif /* TRIO_FEATURE_FLOAT */
6660
6661/*************************************************************************
6662 * TrioReadPointer
6663 */
6664TRIO_PRIVATE BOOLEAN_T
6665TrioReadPointer
6666TRIO_ARGS3((self, target, flags),
6667 trio_class_t *self,
6668 trio_pointer_t *target,
6669 trio_flags_t flags)
6670{
6671 trio_uintmax_t number;
6672 char buffer[sizeof(internalNullString)];
6673
6674 flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING);
6675
6676 if (TrioReadNumber(self,
6677 &number,
6678 flags,
6679 POINTER_WIDTH,
6680 BASE_HEX))
6681 {
6682 if (target)
6683 {
6684#if defined(TRIO_COMPILER_GCC) || defined(TRIO_COMPILER_MIPSPRO)
6685 /*
6686 * The strange assignment of number is a workaround for a compiler
6687 * warning
6688 */
6689 *target = &((char *)0)[number];
6690#else
6691 *target = (trio_pointer_t)number;
6692#endif
6693 }
6694 return TRUE;
6695 }
6696 else if (TrioReadString(self,
6697 (flags & FLAGS_IGNORE)
6698 ? NULL
6699 : buffer,
6700 0,
6701 sizeof(internalNullString) - 1))
6702 {
6703 if (trio_equal_case(buffer, internalNullString))
6704 {
6705 if (target)
6706 *target = NULL;
6707 return TRUE;
6708 }
6709 }
6710 return FALSE;
6711}
6712
6713/*************************************************************************
6714 * TrioScanProcess
6715 */
6716TRIO_PRIVATE int
6717TrioScanProcess
6718TRIO_ARGS3((data, format, parameters),
6719 trio_class_t *data,
6720 TRIO_CONST char *format,
6721 trio_parameter_t *parameters)
6722{
6723 int status;
6724 int assignment;
6725 int ch;
6726 int offset; /* Offset of format string */
6727 int i; /* Offset of current parameter */
6728 trio_flags_t flags;
6729 int width;
6730 int base;
6731 trio_pointer_t pointer;
6732
6733 /* Return on empty format string */
6734 if (format[0] == NIL)
6735 return 0;
6736
6737 status = 0;
6738 assignment = 0;
6739 i = 0;
6740 offset = 0;
6741 data->InStream(data, &ch);
6742
6743 for (;;)
6744 {
6745 /* Skip the parameter entries */
6746 while (parameters[i].type == FORMAT_PARAMETER)
6747 {
6748 assert(i <= MAX_PARAMETERS);
6749 i++;
6750 }
6751
6752 /* Compare non conversion-specifier part of format string */
6753 while (offset < parameters[i].beginOffset)
6754 {
6755 if ((CHAR_IDENTIFIER == format[offset]) &&
6756 (CHAR_IDENTIFIER == format[offset + 1]))
6757 {
6758 /* Two % in format matches one % in input stream */
6759 if (CHAR_IDENTIFIER == ch)
6760 {
6761 data->InStream(data, &ch);
6762 offset += 2;
6763 continue; /* while format chars left */
6764 }
6765 else
6766 {
6767 status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
6768 goto end;
6769 }
6770 }
6771 else /* Not an % identifier */
6772 {
6773 if (isspace((int)format[offset]))
6774 {
6775 /* Whitespaces may match any amount of whitespaces */
6776 ch = TrioSkipWhitespaces(data);
6777 }
6778 else if (ch == format[offset])
6779 {
6780 data->InStream(data, &ch);
6781 }
6782 else
6783 {
6784 status = assignment;
6785 goto end;
6786 }
6787
6788 offset++;
6789 }
6790 }
6791
6792 if (parameters[i].type == FORMAT_SENTINEL)
6793 break;
6794
6795 if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))
6796 {
6797 status = (assignment > 0) ? assignment : EOF;
6798 goto end;
6799 }
6800
6801 flags = parameters[i].flags;
6802
6803 /* Find width */
6804 width = parameters[i].width;
6805 if (flags & FLAGS_WIDTH_PARAMETER)
6806 {
6807 /* Get width from parameter list */
6808 width = (int)parameters[width].data.number.as_signed;
6809 }
6810
6811 /* Find base */
6812 if (NO_BASE != parameters[i].baseSpecifier)
6813 {
6814 /* Base from specifier has priority */
6815 base = parameters[i].baseSpecifier;
6816 }
6817 else if (flags & FLAGS_BASE_PARAMETER)
6818 {
6819 /* Get base from parameter list */
6820 base = parameters[i].base;
6821 base = (int)parameters[base].data.number.as_signed;
6822 }
6823 else
6824 {
6825 /* Use base from format string */
6826 base = parameters[i].base;
6827 }
6828
6829 switch (parameters[i].type)
6830 {
6831 case FORMAT_INT:
6832 {
6833 trio_uintmax_t number;
6834
6835 if (0 == base)
6836 base = BASE_DECIMAL;
6837
6838 if (!TrioReadNumber(data,
6839 &number,
6840 flags,
6841 width,
6842 base))
6843 {
6844 status = assignment;
6845 goto end;
6846 }
6847
6848 if (!(flags & FLAGS_IGNORE))
6849 {
6850 assignment++;
6851
6852 pointer = parameters[i].data.pointer;
6853#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
6854 if (flags & FLAGS_SIZE_T)
6855 *(size_t *)pointer = (size_t)number;
6856 else
6857#endif
6858#if TRIO_FEATURE_PTRDIFF_T
6859 if (flags & FLAGS_PTRDIFF_T)
6860 *(ptrdiff_t *)pointer = (ptrdiff_t)number;
6861 else
6862#endif
6863#if TRIO_FEATURE_INTMAX_T
6864 if (flags & FLAGS_INTMAX_T)
6865 *(trio_intmax_t *)pointer = (trio_intmax_t)number;
6866 else
6867#endif
6868 if (flags & FLAGS_QUAD)
6869 *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number;
6870 else if (flags & FLAGS_LONG)
6871 *(long int *)pointer = (long int)number;
6872 else if (flags & FLAGS_SHORT)
6873 *(short int *)pointer = (short int)number;
6874 else
6875 *(int *)pointer = (int)number;
6876 }
6877 }
6878 break; /* FORMAT_INT */
6879
6880 case FORMAT_STRING:
6881#if TRIO_FEATURE_WIDECHAR
6882 if (flags & FLAGS_WIDECHAR)
6883 {
6884 if (!TrioReadWideString(data,
6885 (flags & FLAGS_IGNORE)
6886 ? NULL
6887 : parameters[i].data.wstring,
6888 flags,
6889 width))
6890 {
6891 status = assignment;
6892 goto end;
6893 }
6894 }
6895 else
6896#endif
6897 {
6898 if (!TrioReadString(data,
6899 (flags & FLAGS_IGNORE)
6900 ? NULL
6901 : parameters[i].data.string,
6902 flags,
6903 width))
6904 {
6905 status = assignment;
6906 goto end;
6907 }
6908 }
6909 if (!(flags & FLAGS_IGNORE))
6910 assignment++;
6911 break; /* FORMAT_STRING */
6912
6913#if TRIO_FEATURE_FLOAT
6914 case FORMAT_DOUBLE:
6915 {
6916 if (flags & FLAGS_IGNORE)
6917 {
6918 pointer = NULL;
6919 }
6920 else
6921 {
6922 pointer = (flags & FLAGS_LONGDOUBLE)
6923 ? (trio_pointer_t)parameters[i].data.longdoublePointer
6924 : (trio_pointer_t)parameters[i].data.doublePointer;
6925 }
6926 if (!TrioReadDouble(data, pointer, flags, width))
6927 {
6928 status = assignment;
6929 goto end;
6930 }
6931 if (!(flags & FLAGS_IGNORE))
6932 {
6933 assignment++;
6934 }
6935 break; /* FORMAT_DOUBLE */
6936 }
6937#endif
6938
6939 case FORMAT_GROUP:
6940 {
6941 int characterclass[MAX_CHARACTER_CLASS + 1];
6942
6943 /* Skip over modifiers */
6944 while (format[offset] != SPECIFIER_GROUP)
6945 {
6946 offset++;
6947 }
6948 /* Skip over group specifier */
6949 offset++;
6950
6951 memset(characterclass, 0, sizeof(characterclass));
6952 status = TrioGetCharacterClass(format,
6953 &offset,
6954 &flags,
6955 characterclass);
6956 if (status < 0)
6957 goto end;
6958
6959 if (!TrioReadGroup(data,
6960 (flags & FLAGS_IGNORE)
6961 ? NULL
6962 : parameters[i].data.string,
6963 characterclass,
6964 flags,
6965 parameters[i].width))
6966 {
6967 status = assignment;
6968 goto end;
6969 }
6970 if (!(flags & FLAGS_IGNORE))
6971 assignment++;
6972 }
6973 break; /* FORMAT_GROUP */
6974
6975 case FORMAT_COUNT:
6976 pointer = parameters[i].data.pointer;
6977 if (NULL != pointer)
6978 {
6979 int count = data->processed;
6980 if (ch != EOF)
6981 count--; /* a character is read, but is not consumed yet */
6982#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
6983 if (flags & FLAGS_SIZE_T)
6984 *(size_t *)pointer = (size_t)count;
6985 else
6986#endif
6987#if TRIO_FEATURE_PTRDIFF_T
6988 if (flags & FLAGS_PTRDIFF_T)
6989 *(ptrdiff_t *)pointer = (ptrdiff_t)count;
6990 else
6991#endif
6992#if TRIO_FEATURE_INTMAX_T
6993 if (flags & FLAGS_INTMAX_T)
6994 *(trio_intmax_t *)pointer = (trio_intmax_t)count;
6995 else
6996#endif
6997 if (flags & FLAGS_QUAD)
6998 {
6999 *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count;
7000 }
7001 else if (flags & FLAGS_LONG)
7002 {
7003 *(long int *)pointer = (long int)count;
7004 }
7005 else if (flags & FLAGS_SHORT)
7006 {
7007 *(short int *)pointer = (short int)count;
7008 }
7009 else
7010 {
7011 *(int *)pointer = (int)count;
7012 }
7013 }
7014 break; /* FORMAT_COUNT */
7015
7016 case FORMAT_CHAR:
7017#if TRIO_FEATURE_WIDECHAR
7018 if (flags & FLAGS_WIDECHAR)
7019 {
7020 if (TrioReadWideChar(data,
7021 (flags & FLAGS_IGNORE)
7022 ? NULL
7023 : parameters[i].data.wstring,
7024 flags,
7025 (width == NO_WIDTH) ? 1 : width) == 0)
7026 {
7027 status = assignment;
7028 goto end;
7029 }
7030 }
7031 else
7032#endif
7033 {
7034 if (TrioReadChar(data,
7035 (flags & FLAGS_IGNORE)
7036 ? NULL
7037 : parameters[i].data.string,
7038 flags,
7039 (width == NO_WIDTH) ? 1 : width) == 0)
7040 {
7041 status = assignment;
7042 goto end;
7043 }
7044 }
7045 if (!(flags & FLAGS_IGNORE))
7046 assignment++;
7047 break; /* FORMAT_CHAR */
7048
7049 case FORMAT_POINTER:
7050 if (!TrioReadPointer(data,
7051 (flags & FLAGS_IGNORE)
7052 ? NULL
7053 : (trio_pointer_t *)parameters[i].data.pointer,
7054 flags))
7055 {
7056 status = assignment;
7057 goto end;
7058 }
7059 if (!(flags & FLAGS_IGNORE))
7060 assignment++;
7061 break; /* FORMAT_POINTER */
7062
7063 case FORMAT_PARAMETER:
7064 break; /* FORMAT_PARAMETER */
7065
7066 default:
7067 status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
7068 goto end;
7069 }
7070
7071 ch = data->current;
7072 offset = parameters[i].endOffset;
7073 i++;
7074 }
7075
7076 status = assignment;
7077 end:
7078 if (data->UndoStream)
7079 data->UndoStream(data);
7080 return status;
7081}
7082
7083/*************************************************************************
7084 * TrioScan
7085 */
7086TRIO_PRIVATE int
7087TrioScan
7088TRIO_ARGS7((source, sourceSize, InStream, UndoStream, format, arglist, argarray),
7089 trio_pointer_t source,
7090 size_t sourceSize,
7091 void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
7092 void (*UndoStream) TRIO_PROTO((trio_class_t *)),
7093 TRIO_CONST char *format,
7094 va_list arglist,
7095 trio_pointer_t *argarray)
7096{
7097 int status;
7098 trio_parameter_t parameters[MAX_PARAMETERS];
7099 trio_class_t data;
7100
7101 assert(VALID(InStream));
7102 assert(VALID(format));
7103
7104 memset(&data, 0, sizeof(data));
7105 data.InStream = InStream;
7106 data.UndoStream = UndoStream;
7107 data.location = (trio_pointer_t)source;
7108 data.max = sourceSize;
7109 data.error = 0;
7110
7111#if defined(USE_LOCALE)
7112 if (NULL == internalLocaleValues)
7113 {
7114 TrioSetLocale();
7115 }
7116#endif
7117
7118 status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray);
7119 if (status < 0)
7120 return status;
7121
7122 status = TrioScanProcess(&data, format, parameters);
7123 if (data.error != 0)
7124 {
7125 status = data.error;
7126 }
7127 return status;
7128}
7129
7130/*************************************************************************
7131 * TrioInStreamFile
7132 */
7133#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO
7134TRIO_PRIVATE void
7135TrioInStreamFile
7136TRIO_ARGS2((self, intPointer),
7137 trio_class_t *self,
7138 int *intPointer)
7139{
7140 FILE *file = (FILE *)self->location;
7141
7142 assert(VALID(self));
7143 assert(VALID(file));
7144
7145 self->actually.cached = 0;
7146
7147 /* The initial value of self->current is zero */
7148 if (self->current == EOF)
7149 {
7150 self->error = (ferror(file))
7151 ? TRIO_ERROR_RETURN(TRIO_ERRNO, 0)
7152 : TRIO_ERROR_RETURN(TRIO_EOF, 0);
7153 }
7154 else
7155 {
7156 self->processed++;
7157 self->actually.cached++;
7158 }
7159
7160 self->current = fgetc(file);
7161
7162 if (VALID(intPointer))
7163 {
7164 *intPointer = self->current;
7165 }
7166}
7167#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */
7168
7169/*************************************************************************
7170 * TrioUndoStreamFile
7171 */
7172#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO
7173TRIO_PRIVATE void
7174TrioUndoStreamFile
7175TRIO_ARGS1((self),
7176 trio_class_t *self)
7177{
7178 FILE *file = (FILE *)self->location;
7179
7180 assert(VALID(self));
7181 assert(VALID(file));
7182
7183 if (self->actually.cached > 0)
7184 {
7185 assert(self->actually.cached == 1);
7186
7187 self->current = ungetc(self->current, file);
7188 self->actually.cached = 0;
7189 }
7190}
7191#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */
7192
7193/*************************************************************************
7194 * TrioInStreamFileDescriptor
7195 */
7196#if TRIO_FEATURE_FD
7197TRIO_PRIVATE void
7198TrioInStreamFileDescriptor
7199TRIO_ARGS2((self, intPointer),
7200 trio_class_t *self,
7201 int *intPointer)
7202{
7203 int fd = *((int *)self->location);
7204 int size;
7205 unsigned char input;
7206
7207 assert(VALID(self));
7208
7209 self->actually.cached = 0;
7210
7211 size = read(fd, &input, sizeof(char));
7212 if (size == -1)
7213 {
7214 self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
7215 self->current = EOF;
7216 }
7217 else
7218 {
7219 self->current = (size == 0) ? EOF : input;
7220 }
7221 if (self->current != EOF)
7222 {
7223 self->actually.cached++;
7224 self->processed++;
7225 }
7226
7227 if (VALID(intPointer))
7228 {
7229 *intPointer = self->current;
7230 }
7231}
7232#endif /* TRIO_FEATURE_FD */
7233
7234/*************************************************************************
7235 * TrioInStreamCustom
7236 */
7237#if TRIO_FEATURE_CLOSURE
7238TRIO_PRIVATE void
7239TrioInStreamCustom
7240TRIO_ARGS2((self, intPointer),
7241 trio_class_t *self,
7242 int *intPointer)
7243{
7244 trio_custom_t *data;
7245
7246 assert(VALID(self));
7247 assert(VALID(self->location));
7248
7249 self->actually.cached = 0;
7250
7251 data = (trio_custom_t *)self->location;
7252
7253 self->current = (data->stream.in == NULL)
7254 ? NIL
7255 : (data->stream.in)(data->closure);
7256
7257 if (self->current == NIL)
7258 {
7259 self->current = EOF;
7260 }
7261 else
7262 {
7263 self->processed++;
7264 self->actually.cached++;
7265 }
7266
7267 if (VALID(intPointer))
7268 {
7269 *intPointer = self->current;
7270 }
7271}
7272#endif /* TRIO_FEATURE_CLOSURE */
7273
7274/*************************************************************************
7275 * TrioInStreamString
7276 */
7277TRIO_PRIVATE void
7278TrioInStreamString
7279TRIO_ARGS2((self, intPointer),
7280 trio_class_t *self,
7281 int *intPointer)
7282{
7283 unsigned char **buffer;
7284
7285 assert(VALID(self));
7286 assert(VALID(self->location));
7287
7288 self->actually.cached = 0;
7289
7290 buffer = (unsigned char **)self->location;
7291 self->current = (*buffer)[0];
7292 if (self->current == NIL)
7293 {
7294 self->current = EOF;
7295 }
7296 else
7297 {
7298 (*buffer)++;
7299 self->processed++;
7300 self->actually.cached++;
7301 }
7302
7303 if (VALID(intPointer))
7304 {
7305 *intPointer = self->current;
7306 }
7307}
7308
7309/*************************************************************************
7310 *
7311 * Formatted scanning functions
7312 *
7313 ************************************************************************/
7314
7315#if defined(TRIO_DOCUMENTATION)
7316# include "doc/doc_scanf.h"
7317#endif
7318/** @addtogroup Scanf
7319 @{
7320*/
7321
7322/*************************************************************************
7323 * scanf
7324 */
7325
7326/**
7327 Scan characters from standard input stream.
7328
7329 @param format Formatting string.
7330 @param ... Arguments.
7331 @return Number of scanned characters.
7332 */
7333#if TRIO_FEATURE_STDIO
7334TRIO_PUBLIC int
7335trio_scanf
7336TRIO_VARGS2((format, va_alist),
7337 TRIO_CONST char *format,
7338 TRIO_VA_DECL)
7339{
7340 int status;
7341 va_list args;
7342
7343 assert(VALID(format));
7344
7345 TRIO_VA_START(args, format);
7346 status = TrioScan((trio_pointer_t)stdin, 0,
7347 TrioInStreamFile,
7348 TrioUndoStreamFile,
7349 format, args, NULL);
7350 TRIO_VA_END(args);
7351 return status;
7352}
7353#endif /* TRIO_FEATURE_STDIO */
7354
7355/**
7356 Scan characters from standard input stream.
7357
7358 @param format Formatting string.
7359 @param args Arguments.
7360 @return Number of scanned characters.
7361 */
7362#if TRIO_FEATURE_STDIO
7363TRIO_PUBLIC int
7364trio_vscanf
7365TRIO_ARGS2((format, args),
7366 TRIO_CONST char *format,
7367 va_list args)
7368{
7369 assert(VALID(format));
7370
7371 return TrioScan((trio_pointer_t)stdin, 0,
7372 TrioInStreamFile,
7373 TrioUndoStreamFile,
7374 format, args, NULL);
7375}
7376#endif /* TRIO_FEATURE_STDIO */
7377
7378/**
7379 Scan characters from standard input stream.
7380
7381 @param format Formatting string.
7382 @param args Arguments.
7383 @return Number of scanned characters.
7384 */
7385#if TRIO_FEATURE_STDIO
7386TRIO_PUBLIC int
7387trio_scanfv
7388TRIO_ARGS2((format, args),
7389 TRIO_CONST char *format,
7390 trio_pointer_t *args)
7391{
7392 static va_list unused;
7393
7394 assert(VALID(format));
7395
7396 return TrioScan((trio_pointer_t)stdin, 0,
7397 TrioInStreamFile,
7398 TrioUndoStreamFile,
7399 format, unused, args);
7400}
7401#endif /* TRIO_FEATURE_STDIO */
7402
7403/*************************************************************************
7404 * fscanf
7405 */
7406
7407/**
7408 Scan characters from file.
7409
7410 @param file File pointer.
7411 @param format Formatting string.
7412 @param ... Arguments.
7413 @return Number of scanned characters.
7414 */
7415#if TRIO_FEATURE_FILE
7416TRIO_PUBLIC int
7417trio_fscanf
7418TRIO_VARGS3((file, format, va_alist),
7419 FILE *file,
7420 TRIO_CONST char *format,
7421 TRIO_VA_DECL)
7422{
7423 int status;
7424 va_list args;
7425
7426 assert(VALID(file));
7427 assert(VALID(format));
7428
7429 TRIO_VA_START(args, format);
7430 status = TrioScan((trio_pointer_t)file, 0,
7431 TrioInStreamFile,
7432 TrioUndoStreamFile,
7433 format, args, NULL);
7434 TRIO_VA_END(args);
7435 return status;
7436}
7437#endif /* TRIO_FEATURE_FILE */
7438
7439/**
7440 Scan characters from file.
7441
7442 @param file File pointer.
7443 @param format Formatting string.
7444 @param args Arguments.
7445 @return Number of scanned characters.
7446 */
7447#if TRIO_FEATURE_FILE
7448TRIO_PUBLIC int
7449trio_vfscanf
7450TRIO_ARGS3((file, format, args),
7451 FILE *file,
7452 TRIO_CONST char *format,
7453 va_list args)
7454{
7455 assert(VALID(file));
7456 assert(VALID(format));
7457
7458 return TrioScan((trio_pointer_t)file, 0,
7459 TrioInStreamFile,
7460 TrioUndoStreamFile,
7461 format, args, NULL);
7462}
7463#endif /* TRIO_FEATURE_FILE */
7464
7465/**
7466 Scan characters from file.
7467
7468 @param file File pointer.
7469 @param format Formatting string.
7470 @param args Arguments.
7471 @return Number of scanned characters.
7472 */
7473#if TRIO_FEATURE_FILE
7474TRIO_PUBLIC int
7475trio_fscanfv
7476TRIO_ARGS3((file, format, args),
7477 FILE *file,
7478 TRIO_CONST char *format,
7479 trio_pointer_t *args)
7480{
7481 static va_list unused;
7482
7483 assert(VALID(file));
7484 assert(VALID(format));
7485
7486 return TrioScan((trio_pointer_t)file, 0,
7487 TrioInStreamFile,
7488 TrioUndoStreamFile,
7489 format, unused, args);
7490}
7491#endif /* TRIO_FEATURE_FILE */
7492
7493/*************************************************************************
7494 * dscanf
7495 */
7496
7497/**
7498 Scan characters from file descriptor.
7499
7500 @param fd File descriptor.
7501 @param format Formatting string.
7502 @param ... Arguments.
7503 @return Number of scanned characters.
7504 */
7505#if TRIO_FEATURE_FD
7506TRIO_PUBLIC int
7507trio_dscanf
7508TRIO_VARGS3((fd, format, va_alist),
7509 int fd,
7510 TRIO_CONST char *format,
7511 TRIO_VA_DECL)
7512{
7513 int status;
7514 va_list args;
7515
7516 assert(VALID(format));
7517
7518 TRIO_VA_START(args, format);
7519 status = TrioScan((trio_pointer_t)&fd, 0,
7520 TrioInStreamFileDescriptor,
7521 NULL,
7522 format, args, NULL);
7523 TRIO_VA_END(args);
7524 return status;
7525}
7526#endif /* TRIO_FEATURE_FD */
7527
7528/**
7529 Scan characters from file descriptor.
7530
7531 @param fd File descriptor.
7532 @param format Formatting string.
7533 @param args Arguments.
7534 @return Number of scanned characters.
7535 */
7536#if TRIO_FEATURE_FD
7537TRIO_PUBLIC int
7538trio_vdscanf
7539TRIO_ARGS3((fd, format, args),
7540 int fd,
7541 TRIO_CONST char *format,
7542 va_list args)
7543{
7544 assert(VALID(format));
7545
7546 return TrioScan((trio_pointer_t)&fd, 0,
7547 TrioInStreamFileDescriptor,
7548 NULL,
7549 format, args, NULL);
7550}
7551#endif /* TRIO_FEATURE_FD */
7552
7553/**
7554 Scan characters from file descriptor.
7555
7556 @param fd File descriptor.
7557 @param format Formatting string.
7558 @param args Arguments.
7559 @return Number of scanned characters.
7560 */
7561#if TRIO_FEATURE_FD
7562TRIO_PUBLIC int
7563trio_dscanfv
7564TRIO_ARGS3((fd, format, args),
7565 int fd,
7566 TRIO_CONST char *format,
7567 trio_pointer_t *args)
7568{
7569 static va_list unused;
7570
7571 assert(VALID(format));
7572
7573 return TrioScan((trio_pointer_t)&fd, 0,
7574 TrioInStreamFileDescriptor,
7575 NULL,
7576 format, unused, args);
7577}
7578#endif /* TRIO_FEATURE_FD */
7579
7580/*************************************************************************
7581 * cscanf
7582 */
7583#if TRIO_FEATURE_CLOSURE
7584TRIO_PUBLIC int
7585trio_cscanf
7586TRIO_VARGS4((stream, closure, format, va_alist),
7587 trio_instream_t stream,
7588 trio_pointer_t closure,
7589 TRIO_CONST char *format,
7590 TRIO_VA_DECL)
7591{
7592 int status;
7593 va_list args;
7594 trio_custom_t data;
7595
7596 assert(VALID(stream));
7597 assert(VALID(format));
7598
7599 TRIO_VA_START(args, format);
7600 data.stream.in = stream;
7601 data.closure = closure;
7602 status = TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL);
7603 TRIO_VA_END(args);
7604 return status;
7605}
7606#endif /* TRIO_FEATURE_CLOSURE */
7607
7608#if TRIO_FEATURE_CLOSURE
7609TRIO_PUBLIC int
7610trio_vcscanf
7611TRIO_ARGS4((stream, closure, format, args),
7612 trio_instream_t stream,
7613 trio_pointer_t closure,
7614 TRIO_CONST char *format,
7615 va_list args)
7616{
7617 trio_custom_t data;
7618
7619 assert(VALID(stream));
7620 assert(VALID(format));
7621
7622 data.stream.in = stream;
7623 data.closure = closure;
7624 return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL);
7625}
7626#endif /* TRIO_FEATURE_CLOSURE */
7627
7628#if TRIO_FEATURE_CLOSURE
7629TRIO_PUBLIC int
7630trio_cscanfv
7631TRIO_ARGS4((stream, closure, format, args),
7632 trio_instream_t stream,
7633 trio_pointer_t closure,
7634 TRIO_CONST char *format,
7635 trio_pointer_t *args)
7636{
7637 static va_list unused;
7638 trio_custom_t data;
7639
7640 assert(VALID(stream));
7641 assert(VALID(format));
7642
7643 data.stream.in = stream;
7644 data.closure = closure;
7645 return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, unused, args);
7646}
7647#endif /* TRIO_FEATURE_CLOSURE */
7648
7649/*************************************************************************
7650 * sscanf
7651 */
7652
7653/**
7654 Scan characters from string.
7655
7656 @param buffer Input string.
7657 @param format Formatting string.
7658 @param ... Arguments.
7659 @return Number of scanned characters.
7660 */
7661TRIO_PUBLIC int
7662trio_sscanf
7663TRIO_VARGS3((buffer, format, va_alist),
7664 TRIO_CONST char *buffer,
7665 TRIO_CONST char *format,
7666 TRIO_VA_DECL)
7667{
7668 int status;
7669 va_list args;
7670
7671 assert(VALID(buffer));
7672 assert(VALID(format));
7673
7674 TRIO_VA_START(args, format);
7675 status = TrioScan((trio_pointer_t)&buffer, 0,
7676 TrioInStreamString,
7677 NULL,
7678 format, args, NULL);
7679 TRIO_VA_END(args);
7680 return status;
7681}
7682
7683/**
7684 Scan characters from string.
7685
7686 @param buffer Input string.
7687 @param format Formatting string.
7688 @param args Arguments.
7689 @return Number of scanned characters.
7690 */
7691TRIO_PUBLIC int
7692trio_vsscanf
7693TRIO_ARGS3((buffer, format, args),
7694 TRIO_CONST char *buffer,
7695 TRIO_CONST char *format,
7696 va_list args)
7697{
7698 assert(VALID(buffer));
7699 assert(VALID(format));
7700
7701 return TrioScan((trio_pointer_t)&buffer, 0,
7702 TrioInStreamString,
7703 NULL,
7704 format, args, NULL);
7705}
7706
7707/**
7708 Scan characters from string.
7709
7710 @param buffer Input string.
7711 @param format Formatting string.
7712 @param args Arguments.
7713 @return Number of scanned characters.
7714 */
7715TRIO_PUBLIC int
7716trio_sscanfv
7717TRIO_ARGS3((buffer, format, args),
7718 TRIO_CONST char *buffer,
7719 TRIO_CONST char *format,
7720 trio_pointer_t *args)
7721{
7722 static va_list unused;
7723
7724 assert(VALID(buffer));
7725 assert(VALID(format));
7726
7727 return TrioScan((trio_pointer_t)&buffer, 0,
7728 TrioInStreamString,
7729 NULL,
7730 format, unused, args);
7731}
7732
7733#endif /* TRIO_FEATURE_SCANF */
7734
7735/** @} End of Scanf documentation module */
7736
7737/*************************************************************************
7738 * trio_strerror
7739 */
7740TRIO_PUBLIC TRIO_CONST char *
7741trio_strerror
7742TRIO_ARGS1((errorcode),
7743 int errorcode)
7744{
7745#if TRIO_FEATURE_STRERR
7746 /* Textual versions of the error codes */
7747 switch (TRIO_ERROR_CODE(errorcode))
7748 {
7749 case TRIO_EOF:
7750 return "End of file";
7751 case TRIO_EINVAL:
7752 return "Invalid argument";
7753 case TRIO_ETOOMANY:
7754 return "Too many arguments";
7755 case TRIO_EDBLREF:
7756 return "Double reference";
7757 case TRIO_EGAP:
7758 return "Reference gap";
7759 case TRIO_ENOMEM:
7760 return "Out of memory";
7761 case TRIO_ERANGE:
7762 return "Invalid range";
7763 case TRIO_ECUSTOM:
7764 return "Custom error";
7765 default:
7766 return "Unknown";
7767 }
7768#else
7769 return "Unknown";
7770#endif
7771}
diff --git a/gs/trio/trio.h b/gs/trio/trio.h
new file mode 100644
index 000000000..58d2b69be
--- /dev/null
+++ b/gs/trio/trio.h
@@ -0,0 +1,235 @@
1/*************************************************************************
2 *
3 * $Id: trio.h,v 1.19 2009/09/13 10:12:22 breese Exp $
4 *
5 * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 *************************************************************************
17 *
18 * http://ctrio.sourceforge.net/
19 *
20 ************************************************************************/
21
22#ifndef TRIO_TRIO_H
23#define TRIO_TRIO_H
24
25#if !defined(WITHOUT_TRIO)
26
27/*
28 * Use autoconf defines if present. Packages using trio must define
29 * HAVE_CONFIG_H as a compiler option themselves.
30 */
31#if defined(HAVE_CONFIG_H)
32# include <config.h>
33#endif
34
35#include "triop.h"
36
37#include <stdio.h>
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43/*
44 * Error codes.
45 *
46 * Remember to add a textual description to trio_strerror.
47 */
48enum {
49 TRIO_EOF = 1,
50 TRIO_EINVAL = 2,
51 TRIO_ETOOMANY = 3,
52 TRIO_EDBLREF = 4,
53 TRIO_EGAP = 5,
54 TRIO_ENOMEM = 6,
55 TRIO_ERANGE = 7,
56 TRIO_ERRNO = 8,
57 TRIO_ECUSTOM = 9
58};
59
60/* Error macros */
61#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF)
62#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8)
63#define TRIO_ERROR_NAME(x) trio_strerror(x)
64
65typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int));
66typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t));
67
68TRIO_CONST char *trio_strerror TRIO_PROTO((int));
69
70/*************************************************************************
71 * Print Functions
72 */
73
74int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...));
75int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
76int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args));
77
78int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
79int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
80int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
81
82int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
83int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
84int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
85
86int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
87 TRIO_CONST char *format, ...));
88int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
89 TRIO_CONST char *format, va_list args));
90int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
91 TRIO_CONST char *format, void **args));
92
93int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...));
94int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args));
95int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args));
96
97int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
98int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
99 va_list args));
100int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
101 void **args));
102
103int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
104int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
105 va_list args));
106
107#if defined(TRIO_DEPRECATED)
108char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...));
109char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
110#endif
111
112int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...));
113int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args));
114int trio_asprintfv TRIO_PROTO((char **result, TRIO_CONST char *format, trio_pointer_t * args));
115
116/*************************************************************************
117 * Scan Functions
118 */
119int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...));
120int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args));
121int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args));
122
123int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
124int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
125int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
126
127int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
128int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
129int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
130
131int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
132 TRIO_CONST char *format, ...));
133int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
134 TRIO_CONST char *format, va_list args));
135int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
136 TRIO_CONST char *format, void **args));
137
138int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...));
139int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args));
140int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args));
141
142/*************************************************************************
143 * Locale Functions
144 */
145void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint));
146void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator));
147void trio_locale_set_grouping TRIO_PROTO((char *grouping));
148
149/*************************************************************************
150 * Renaming
151 */
152#ifdef TRIO_REPLACE_STDIO
153/* Replace the <stdio.h> functions */
154#ifndef HAVE_PRINTF
155# undef printf
156# define printf trio_printf
157#endif
158#ifndef HAVE_VPRINTF
159# undef vprintf
160# define vprintf trio_vprintf
161#endif
162#ifndef HAVE_FPRINTF
163# undef fprintf
164# define fprintf trio_fprintf
165#endif
166#ifndef HAVE_VFPRINTF
167# undef vfprintf
168# define vfprintf trio_vfprintf
169#endif
170#ifndef HAVE_SPRINTF
171# undef sprintf
172# define sprintf trio_sprintf
173#endif
174#ifndef HAVE_VSPRINTF
175# undef vsprintf
176# define vsprintf trio_vsprintf
177#endif
178#ifndef HAVE_SNPRINTF
179# undef snprintf
180# define snprintf trio_snprintf
181#endif
182#ifndef HAVE_VSNPRINTF
183# undef vsnprintf
184# define vsnprintf trio_vsnprintf
185#endif
186#ifndef HAVE_SCANF
187# undef scanf
188# define scanf trio_scanf
189#endif
190#ifndef HAVE_VSCANF
191# undef vscanf
192# define vscanf trio_vscanf
193#endif
194#ifndef HAVE_FSCANF
195# undef fscanf
196# define fscanf trio_fscanf
197#endif
198#ifndef HAVE_VFSCANF
199# undef vfscanf
200# define vfscanf trio_vfscanf
201#endif
202#ifndef HAVE_SSCANF
203# undef sscanf
204# define sscanf trio_sscanf
205#endif
206#ifndef HAVE_VSSCANF
207# undef vsscanf
208# define vsscanf trio_vsscanf
209#endif
210/* These aren't stdio functions, but we make them look similar */
211#undef dprintf
212#define dprintf trio_dprintf
213#undef vdprintf
214#define vdprintf trio_vdprintf
215#undef aprintf
216#define aprintf trio_aprintf
217#undef vaprintf
218#define vaprintf trio_vaprintf
219#undef asprintf
220#define asprintf trio_asprintf
221#undef vasprintf
222#define vasprintf trio_vasprintf
223#undef dscanf
224#define dscanf trio_dscanf
225#undef vdscanf
226#define vdscanf trio_vdscanf
227#endif
228
229#ifdef __cplusplus
230} /* extern "C" */
231#endif
232
233#endif /* WITHOUT_TRIO */
234
235#endif /* TRIO_TRIO_H */
diff --git a/gs/trio/triodef.h b/gs/trio/triodef.h
new file mode 100644
index 000000000..bf560171d
--- /dev/null
+++ b/gs/trio/triodef.h
@@ -0,0 +1,336 @@
1/*************************************************************************
2 *
3 * $Id: triodef.h,v 1.35 2009/09/20 11:37:14 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
18#ifndef TRIO_TRIODEF_H
19#define TRIO_TRIODEF_H
20
21/*************************************************************************
22 * Compiler support detection
23 */
24
25#if defined(__GNUC__)
26# define TRIO_COMPILER_GCC
27#endif
28
29#if defined(__SUNPRO_CC)
30# define TRIO_COMPILER_SUNPRO __SUNPRO_CC
31#else
32# if defined(__SUNPRO_C)
33# define TRIO_COMPILER_SUNPRO __SUNPRO_C
34# endif
35#endif
36
37#if defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__)
38# define TRIO_COMPILER_XLC
39#else
40# if defined(_AIX) && !defined(__GNUC__)
41# define TRIO_COMPILER_XLC /* Workaround for old xlc */
42# endif
43#endif
44
45#if defined(__DECC) || defined(__DECCXX)
46# define TRIO_COMPILER_DECC
47#else
48# if defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__)
49# define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */
50# endif
51#endif
52
53#if defined(__HP_aCC) || defined(__HP_cc)
54# define TRIO_COMPILER_HP
55#endif
56
57#if defined(sgi) || defined(__sgi)
58# define TRIO_COMPILER_MIPSPRO
59#endif
60
61#if defined(_MSC_VER)
62# define TRIO_COMPILER_MSVC
63#endif
64
65#if defined(__BORLANDC__)
66# define TRIO_COMPILER_BCB
67#endif
68
69/*************************************************************************
70 * Platform support detection
71 */
72
73#if defined(VMS) || defined(__VMS)
74# define TRIO_PLATFORM_VMS
75#endif
76
77#if defined(unix) || defined(__unix) || defined(__unix__)
78# define TRIO_PLATFORM_UNIX
79#endif
80
81#if defined(TRIO_COMPILER_XLC) || defined(_AIX)
82# define TRIO_PLATFORM_UNIX
83#endif
84
85#if defined(TRIO_COMPILER_DECC) || defined(__osf___)
86# if !defined(TRIO_PLATFORM_VMS)
87# define TRIO_PLATFORM_UNIX
88# endif
89#endif
90
91#if defined(__NetBSD__)
92# define TRIO_PLATFORM_UNIX
93#endif
94
95#if defined(__Lynx__)
96# define TRIO_PLATFORM_UNIX
97# define TRIO_PLATFORM_LYNX
98#endif
99
100#if defined(__APPLE__) && defined(__MACH__)
101# define TRIO_PLATFORM_UNIX
102#endif
103
104#if defined(__QNX__)
105# define TRIO_PLATFORM_UNIX
106# define TRIO_PLATFORM_QNX
107#endif
108
109#if defined(__CYGWIN__)
110# define TRIO_PLATFORM_UNIX
111#endif
112
113#if defined(AMIGA) && defined(TRIO_COMPILER_GCC)
114# define TRIO_PLATFORM_UNIX
115#endif
116
117#if defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32)
118# define TRIO_PLATFORM_WIN32
119#endif
120
121#if defined(_WIN32_WCE)
122# define TRIO_PLATFORM_WINCE
123#endif
124
125#if defined(mpeix) || defined(__mpexl)
126# define TRIO_PLATFORM_MPEIX
127#endif
128
129#if defined(_AIX)
130# define TRIO_PLATFORM_AIX
131#endif
132
133#if defined(__hpux)
134# define TRIO_PLATFORM_HPUX
135#endif
136
137#if defined(sun) || defined(__sun__)
138# if defined(__SVR4) || defined(__svr4__)
139# define TRIO_PLATFORM_SOLARIS
140# else
141# define TRIO_PLATFORM_SUNOS
142# endif
143#endif
144
145/*************************************************************************
146 * Standards support detection
147 */
148
149#if defined(__STDC__) \
150 || defined(_MSC_EXTENSIONS) \
151 || defined(TRIO_COMPILER_BCB)
152# define PREDEF_STANDARD_C89
153#endif
154#if defined(__STDC_VERSION__)
155# define PREDEF_STANDARD_C90
156#endif
157#if defined (__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199409L)
158# define PREDEF_STANDARD_C94
159#endif
160#if defined (__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L)
161# define PREDEF_STANDARD_C99
162#endif
163
164#if defined(TRIO_COMPILER_SUNPRO) && (TRIO_COMPILER_SUNPRO >= 0x420)
165# if !defined(PREDEF_STANDARD_C94)
166# define PREDEF_STANDARD_C94
167# endif
168#endif
169
170#if defined(__cplusplus)
171# define PREDEF_STANDARD_CXX
172#endif
173#if defined(__cplusplus) && __cplusplus - 0 >= 199711L
174# define PREDEF_STANDARD_CXX89
175#endif
176
177#if defined(TRIO_PLATFORM_UNIX)
178# include <unistd.h>
179#endif
180
181#if defined(_POSIX_VERSION)
182# define PREDEF_STANDARD_POSIX _POSIX_VERSION
183# if (_POSIX_VERSION >= 199506L)
184# define PREDEF_STANDARD_POSIX_1996
185# endif
186#endif
187
188#if (_XOPEN_VERSION - 0 >= 3) || defined(_XOPEN_XPG3)
189# define PREDEF_STANDARD_XPG3
190#endif
191#if (_XOPEN_VERSION - 0 >= 4) || defined(_XOPEN_XPG4)
192# define PREDEF_STANDARD_XPG4
193#endif
194#if (_XOPEN_VERSION - 0 > 4) \
195 || (defined(_XOPEN_UNIX) && (_XOPEN_VERSION - 0 == 4))
196# define PREDEF_STANDARD_UNIX95
197#endif
198#if (_XOPEN_VERSION - 0 >= 500)
199# define PREDEF_STANDARD_UNIX98
200#endif
201#if (_XOPEN_VERSION - 0 >= 600)
202# define PREDEF_STANDARD_UNIX03
203#endif
204
205/*************************************************************************
206 * Generic defines
207 */
208
209#if !defined(TRIO_PUBLIC)
210# define TRIO_PUBLIC
211#endif
212#if !defined(TRIO_PRIVATE)
213# define TRIO_PRIVATE static
214#endif
215
216#if !(defined(PREDEF_STANDARD_C89) || defined(PREDEF_STANDARD_CXX))
217# define TRIO_COMPILER_ANCIENT
218#endif
219
220#if defined(TRIO_COMPILER_ANCIENT)
221# define TRIO_CONST
222# define TRIO_VOLATILE
223# define TRIO_SIGNED
224typedef double trio_long_double_t;
225typedef char * trio_pointer_t;
226# define TRIO_SUFFIX_LONG(x) x
227# define TRIO_PROTO(x) ()
228# define TRIO_NOARGS
229# define TRIO_ARGS1(list,a1) list a1;
230# define TRIO_ARGS2(list,a1,a2) list a1; a2;
231# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3;
232# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4;
233# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5;
234# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6;
235# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) list a1; a2; a3; a4; a5; a6; a7;
236# define TRIO_VARGS2(list,a1,a2) list a1; a2
237# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3
238# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4
239# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5
240# define TRIO_VA_DECL va_dcl
241# define TRIO_VA_START(x,y) va_start(x)
242# define TRIO_VA_END(x) va_end(x)
243#else /* ANSI C */
244# define TRIO_CONST const
245# define TRIO_VOLATILE volatile
246# define TRIO_SIGNED signed
247typedef long double trio_long_double_t;
248typedef void * trio_pointer_t;
249# define TRIO_SUFFIX_LONG(x) x ## L
250# define TRIO_PROTO(x) x
251# define TRIO_NOARGS void
252# define TRIO_ARGS1(list,a1) (a1)
253# define TRIO_ARGS2(list,a1,a2) (a1,a2)
254# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3)
255# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4)
256# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5)
257# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6)
258# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) (a1,a2,a3,a4,a5,a6,a7)
259# define TRIO_VARGS2 TRIO_ARGS2
260# define TRIO_VARGS3 TRIO_ARGS3
261# define TRIO_VARGS4 TRIO_ARGS4
262# define TRIO_VARGS5 TRIO_ARGS5
263# define TRIO_VA_DECL ...
264# define TRIO_VA_START(x,y) va_start(x,y)
265# define TRIO_VA_END(x) va_end(x)
266#endif
267
268#if defined(PREDEF_STANDARD_C99) || defined(PREDEF_STANDARD_CXX)
269# define TRIO_INLINE inline
270#else
271# if defined(TRIO_COMPILER_GCC)
272# define TRIO_INLINE __inline__
273# endif
274# if defined(TRIO_COMPILER_MSVC)
275# define TRIO_INLINE _inline
276# endif
277# if defined(TRIO_COMPILER_BCB)
278# define TRIO_INLINE __inline
279# endif
280#endif
281#if !defined(TRIO_INLINE)
282# define TRIO_INLINE
283#endif
284
285/*************************************************************************
286 * Workarounds
287 */
288
289#if defined(TRIO_PLATFORM_VMS)
290/*
291 * Computations done with constants at compile time can trigger these
292 * even when compiling with IEEE enabled.
293 */
294# pragma message disable (UNDERFLOW, FLOATOVERFL)
295
296# if (__CRTL_VER < 80210001)
297/*
298 * Although the compiler supports C99 language constructs, the C
299 * run-time library does not contain all C99 functions.
300 */
301# if defined(PREDEF_STANDARD_C99)
302# undef PREDEF_STANDARD_C99
303# endif
304# endif
305#endif
306
307/*
308 * Not all preprocessors supports the LL token.
309 */
310#if defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
311#else
312# define TRIO_COMPILER_SUPPORTS_LL
313#endif
314
315#if defined(__CYGWIN__)
316/*
317 * Cygwin defines the macros for hosted C99, but does not support certain
318 * long double math functions.
319 */
320# include <cygwin/version.h>
321# define TRIO_CYGWIN_VERSION_API CYGWIN_VERSION_API_MAJOR * 1000 + \
322 CYGWIN_VERSION_API_MINOR
323/*
324 * Please change the version number below when the Cygwin API supports
325 * long double math functions (powl, fmodl, etc.)
326 */
327# if TRIO_CYGWIN_VERSION_API < 99999999
328# define TRIO_NO_FLOORL 1
329# define TRIO_NO_CEILL 1
330# define TRIO_NO_POWL 1
331# define TRIO_NO_FMODL 1
332# define TRIO_NO_LOG10L 1
333# endif
334#endif
335
336#endif /* TRIO_TRIODEF_H */
diff --git a/gs/trio/trionan.c b/gs/trio/trionan.c
new file mode 100644
index 000000000..301632257
--- /dev/null
+++ b/gs/trio/trionan.c
@@ -0,0 +1,1257 @@
1/*************************************************************************
2 *
3 * $Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************
17 *
18 * Functions to handle special quantities in floating-point numbers
19 * (that is, NaNs and infinity). They provide the capability to detect
20 * and fabricate special quantities.
21 *
22 * Although written to be as portable as possible, it can never be
23 * guaranteed to work on all platforms, as not all hardware supports
24 * special quantities.
25 *
26 * The approach used here (approximately) is to:
27 *
28 * 1. Use C99 functionality when available.
29 * 2. Use IEEE 754 bit-patterns if possible.
30 * 3. Use platform-specific techniques.
31 *
32 ************************************************************************/
33
34/*************************************************************************
35 * Include files
36 */
37#include "triodef.h"
38#include "trionan.h"
39
40#include <math.h>
41#include <string.h>
42#include <limits.h>
43#if !defined(TRIO_PLATFORM_SYMBIAN)
44# include <float.h>
45#endif
46#if defined(TRIO_PLATFORM_UNIX)
47# include <signal.h>
48#endif
49#if defined(TRIO_COMPILER_DECC)
50# include <fp_class.h>
51#endif
52#include <assert.h>
53
54#if defined(TRIO_DOCUMENTATION)
55# include "doc/doc_nan.h"
56#endif
57/** @addtogroup SpecialQuantities
58 @{
59*/
60
61/*************************************************************************
62 * Definitions
63 */
64
65#if !defined(TRIO_PUBLIC_NAN)
66# define TRIO_PUBLIC_NAN TRIO_PUBLIC
67#endif
68#if !defined(TRIO_PRIVATE_NAN)
69# define TRIO_PRIVATE_NAN TRIO_PRIVATE
70#endif
71
72#define TRIO_TRUE (1 == 1)
73#define TRIO_FALSE (0 == 1)
74
75/*
76 * We must enable IEEE floating-point on Alpha
77 */
78#if defined(__alpha) && !defined(_IEEE_FP)
79# if defined(TRIO_COMPILER_DECC)
80# if defined(TRIO_PLATFORM_VMS)
81# error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE"
82# else
83# if !defined(_CFE)
84# error "Must be compiled with option -ieee"
85# endif
86# endif
87# else
88# if defined(TRIO_COMPILER_GCC)
89# error "Must be compiled with option -mieee"
90# endif
91# endif
92#endif /* __alpha && ! _IEEE_FP */
93
94/*
95 * In ANSI/IEEE 754-1985 64-bits double format numbers have the
96 * following properties (amoungst others)
97 *
98 * o FLT_RADIX == 2: binary encoding
99 * o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used
100 * to indicate special numbers (e.g. NaN and Infinity), so the
101 * maximum exponent is 10 bits wide (2^10 == 1024).
102 * o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because
103 * numbers are normalized the initial binary 1 is represented
104 * implicitly (the so-called "hidden bit"), which leaves us with
105 * the ability to represent 53 bits wide mantissa.
106 */
107#if defined(__STDC_IEC_559__)
108# define TRIO_IEEE_754
109#else
110# if (FLT_RADIX - 0 == 2) && (DBL_MAX_EXP - 0 == 1024) && (DBL_MANT_DIG - 0 == 53)
111# define TRIO_IEEE_754
112# endif
113#endif
114
115/*
116 * Determine which fpclassify_and_sign() function to use.
117 */
118#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
119# if defined(PREDEF_STANDARD_C99) && defined(fpclassify)
120# define TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT
121# else
122# if defined(TRIO_COMPILER_DECC)
123# define TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT
124# else
125# if defined(TRIO_COMPILER_VISUALC) || defined(TRIO_COMPILER_BORLAND)
126# define TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT
127# else
128# if defined(TRIO_COMPILER_HP) && defined(FP_PLUS_NORM)
129# define TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT
130# else
131# if defined(TRIO_COMPILER_XLC) && defined(FP_PLUS_NORM)
132# define TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT
133# else
134# define TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT
135# endif
136# endif
137# endif
138# endif
139# endif
140#endif
141
142/*
143 * Determine how to generate negative zero.
144 */
145#if defined(TRIO_FUNC_NZERO)
146# if defined(TRIO_IEEE_754)
147# define TRIO_NZERO_IEEE_754
148# else
149# define TRIO_NZERO_FALLBACK
150# endif
151#endif
152
153/*
154 * Determine how to generate positive infinity.
155 */
156#if defined(TRIO_FUNC_PINF)
157# if defined(INFINITY) && defined(__STDC_IEC_559__)
158# define TRIO_PINF_C99_MACRO
159# else
160# if defined(TRIO_IEEE_754)
161# define TRIO_PINF_IEEE_754
162# else
163# define TRIO_PINF_FALLBACK
164# endif
165# endif
166#endif
167
168/*
169 * Determine how to generate NaN.
170 */
171#if defined(TRIO_FUNC_NAN)
172# if defined(PREDEF_STANDARD_C99) && !defined(TRIO_COMPILER_DECC)
173# define TRIO_NAN_C99_FUNCTION
174# else
175# if defined(NAN) && defined(__STDC_IEC_559__)
176# define TRIO_NAN_C99_MACRO
177# else
178# if defined(TRIO_IEEE_754)
179# define TRIO_NAN_IEEE_754
180# else
181# define TRIO_NAN_FALLBACK
182# endif
183# endif
184# endif
185#endif
186
187/*
188 * Resolve internal dependencies.
189 */
190#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)
191# define TRIO_FUNC_INTERNAL_ISNAN
192# define TRIO_FUNC_INTERNAL_ISINF
193# if defined(TRIO_IEEE_754)
194# define TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY
195# define TRIO_FUNC_INTERNAL_IS_NEGATIVE
196# endif
197#endif
198
199#if defined(TRIO_NZERO_IEEE_754) \
200 || defined(TRIO_PINF_IEEE_754) \
201 || defined(TRIO_NAN_IEEE_754)
202# define TRIO_FUNC_INTERNAL_MAKE_DOUBLE
203#endif
204
205#if defined(TRIO_FUNC_INTERNAL_ISNAN)
206# if defined(PREDEF_STANDARD_XPG3)
207# define TRIO_INTERNAL_ISNAN_XPG3
208# else
209# if defined(TRIO_IEEE_754)
210# define TRIO_INTERNAL_ISNAN_IEEE_754
211# else
212# define TRIO_INTERNAL_ISNAN_FALLBACK
213# endif
214# endif
215#endif
216
217#if defined(TRIO_FUNC_INTERNAL_ISINF)
218# if defined(TRIO_IEEE_754)
219# define TRIO_INTERNAL_ISINF_IEEE_754
220# else
221# define TRIO_INTERNAL_ISINF_FALLBACK
222# endif
223#endif
224
225/*************************************************************************
226 * Constants
227 */
228
229#if !defined(TRIO_EMBED_NAN)
230static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $";
231#endif
232
233#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE) \
234 || defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY) \
235 || defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
236/*
237 * Endian-agnostic indexing macro.
238 *
239 * The value of internalEndianMagic, when converted into a 64-bit
240 * integer, becomes 0x0706050403020100 (we could have used a 64-bit
241 * integer value instead of a double, but not all platforms supports
242 * that type). The value is automatically encoded with the correct
243 * endianess by the compiler, which means that we can support any
244 * kind of endianess. The individual bytes are then used as an index
245 * for the IEEE 754 bit-patterns and masks.
246 */
247#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
248static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
249#endif
250
251#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)
252/* Mask for the exponent */
253static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
254 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
255};
256
257/* Mask for the mantissa */
258static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {
259 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
260};
261#endif
262
263#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
264/* Mask for the sign bit */
265static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
266 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
267};
268#endif
269
270#if defined(TRIO_NZERO_IEEE_754)
271/* Bit-pattern for negative zero */
272static TRIO_CONST unsigned char ieee_754_negzero_array[] = {
273 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
274};
275#endif
276
277#if defined(TRIO_PINF_IEEE_754)
278/* Bit-pattern for infinity */
279static TRIO_CONST unsigned char ieee_754_infinity_array[] = {
280 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
281};
282#endif
283
284#if defined(TRIO_NAN_IEEE_754)
285/* Bit-pattern for quiet NaN */
286static TRIO_CONST unsigned char ieee_754_qnan_array[] = {
287 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
288};
289#endif
290
291
292/*************************************************************************
293 * Internal functions
294 */
295
296/*
297 * internal_make_double
298 */
299#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE)
300
301TRIO_PRIVATE_NAN double
302internal_make_double
303TRIO_ARGS1((values),
304 TRIO_CONST unsigned char *values)
305{
306 TRIO_VOLATILE double result;
307 int i;
308
309 for (i = 0; i < (int)sizeof(double); i++) {
310 ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i];
311 }
312 return result;
313}
314
315#endif
316
317/*
318 * internal_is_special_quantity
319 */
320#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)
321
322TRIO_PRIVATE_NAN int
323internal_is_special_quantity
324TRIO_ARGS2((number, has_mantissa),
325 double number,
326 int *has_mantissa)
327{
328 unsigned int i;
329 unsigned char current;
330 int is_special_quantity = TRIO_TRUE;
331
332 *has_mantissa = 0;
333
334 for (i = 0; i < (unsigned int)sizeof(double); i++) {
335 current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];
336 is_special_quantity
337 &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]);
338 *has_mantissa |= (current & ieee_754_mantissa_mask[i]);
339 }
340 return is_special_quantity;
341}
342
343#endif
344
345/*
346 * internal_is_negative
347 */
348#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
349
350TRIO_PRIVATE_NAN int
351internal_is_negative
352TRIO_ARGS1((number),
353 double number)
354{
355 unsigned int i;
356 int is_negative = TRIO_FALSE;
357
358 for (i = 0; i < (unsigned int)sizeof(double); i++) {
359 is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]
360 & ieee_754_sign_mask[i]);
361 }
362 return is_negative;
363}
364
365#endif
366
367#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)
368
369TRIO_PRIVATE_NAN TRIO_INLINE int
370c99_fpclassify_and_signbit
371TRIO_ARGS2((number, is_negative),
372 double number,
373 int *is_negative)
374{
375 *is_negative = signbit(number);
376 switch (fpclassify(number)) {
377 case FP_NAN:
378 return TRIO_FP_NAN;
379 case FP_INFINITE:
380 return TRIO_FP_INFINITE;
381 case FP_SUBNORMAL:
382 return TRIO_FP_SUBNORMAL;
383 case FP_ZERO:
384 return TRIO_FP_ZERO;
385 default:
386 return TRIO_FP_NORMAL;
387 }
388}
389
390#endif /* TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT */
391
392#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)
393
394TRIO_PRIVATE_NAN TRIO_INLINE int
395decc_fpclassify_and_signbit
396TRIO_ARGS2((number, is_negative),
397 double number,
398 int *is_negative)
399{
400 switch (fp_class(number)) {
401 case FP_QNAN:
402 case FP_SNAN:
403 *is_negative = TRIO_FALSE; /* NaN has no sign */
404 return TRIO_FP_NAN;
405 case FP_POS_INF:
406 *is_negative = TRIO_FALSE;
407 return TRIO_FP_INFINITE;
408 case FP_NEG_INF:
409 *is_negative = TRIO_TRUE;
410 return TRIO_FP_INFINITE;
411 case FP_POS_DENORM:
412 *is_negative = TRIO_FALSE;
413 return TRIO_FP_SUBNORMAL;
414 case FP_NEG_DENORM:
415 *is_negative = TRIO_TRUE;
416 return TRIO_FP_SUBNORMAL;
417 case FP_POS_ZERO:
418 *is_negative = TRIO_FALSE;
419 return TRIO_FP_ZERO;
420 case FP_NEG_ZERO:
421 *is_negative = TRIO_TRUE;
422 return TRIO_FP_ZERO;
423 case FP_POS_NORM:
424 *is_negative = TRIO_FALSE;
425 return TRIO_FP_NORMAL;
426 case FP_NEG_NORM:
427 *is_negative = TRIO_TRUE;
428 return TRIO_FP_NORMAL;
429 default:
430 *is_negative = (number < 0.0);
431 return TRIO_FP_NORMAL;
432 }
433}
434
435#endif /* TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT */
436
437#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)
438
439TRIO_PRIVATE_NAN int
440ms_fpclassify_and_signbit
441TRIO_ARGS2((number, is_negative),
442 double number,
443 int *is_negative)
444{
445 int result;
446# if defined(TRIO_COMPILER_BORLAND)
447 /*
448 * The floating-point precision may be changed by the Borland _fpclass()
449 * function, so we have to save and restore the floating-point control mask.
450 */
451 unsigned int mask;
452 /* Remember the old mask */
453 mask = _control87(0, 0);
454# endif
455
456 switch (_fpclass(number)) {
457 case _FPCLASS_QNAN:
458 case _FPCLASS_SNAN:
459 *is_negative = TRIO_FALSE; /* NaN has no sign */
460 result = TRIO_FP_NAN;
461 break;
462 case _FPCLASS_PINF:
463 *is_negative = TRIO_FALSE;
464 result = TRIO_FP_INFINITE;
465 break;
466 case _FPCLASS_NINF:
467 *is_negative = TRIO_TRUE;
468 result = TRIO_FP_INFINITE;
469 break;
470 case _FPCLASS_PD:
471 *is_negative = TRIO_FALSE;
472 result = TRIO_FP_SUBNORMAL;
473 break;
474 case _FPCLASS_ND:
475 *is_negative = TRIO_TRUE;
476 result = TRIO_FP_SUBNORMAL;
477 break;
478 case _FPCLASS_PZ:
479 *is_negative = TRIO_FALSE;
480 result = TRIO_FP_ZERO;
481 break;
482 case _FPCLASS_NZ:
483 *is_negative = TRIO_TRUE;
484 result = TRIO_FP_ZERO;
485 break;
486 case _FPCLASS_PN:
487 *is_negative = TRIO_FALSE;
488 result = TRIO_FP_NORMAL;
489 break;
490 case _FPCLASS_NN:
491 *is_negative = TRIO_TRUE;
492 result = TRIO_FP_NORMAL;
493 break;
494 default:
495 *is_negative = (number < 0.0);
496 result = TRIO_FP_NORMAL;
497 break;
498 }
499
500# if defined(TRIO_COMPILER_BORLAND)
501 /* Restore the old precision */
502 (void)_control87(mask, MCW_PC);
503# endif
504
505 return result;
506}
507
508#endif /* TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT */
509
510#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)
511
512TRIO_PRIVATE_NAN TRIO_INLINE int
513hp_fpclassify_and_signbit
514TRIO_ARGS2((number, is_negative),
515 double number,
516 int *is_negative)
517{
518 /*
519 * HP-UX 9.x and 10.x have an fpclassify() function, that is different
520 * from the C99 fpclassify() macro supported on HP-UX 11.x.
521 */
522 switch (fpclassify(number)) {
523 case FP_QNAN:
524 case FP_SNAN:
525 *is_negative = TRIO_FALSE; /* NaN has no sign */
526 return TRIO_FP_NAN;
527 case FP_PLUS_INF:
528 *is_negative = TRIO_FALSE;
529 return TRIO_FP_INFINITE;
530 case FP_MINUS_INF:
531 *is_negative = TRIO_TRUE;
532 return TRIO_FP_INFINITE;
533 case FP_PLUS_DENORM:
534 *is_negative = TRIO_FALSE;
535 return TRIO_FP_SUBNORMAL;
536 case FP_MINUS_DENORM:
537 *is_negative = TRIO_TRUE;
538 return TRIO_FP_SUBNORMAL;
539 case FP_PLUS_ZERO:
540 *is_negative = TRIO_FALSE;
541 return TRIO_FP_ZERO;
542 case FP_MINUS_ZERO:
543 *is_negative = TRIO_TRUE;
544 return TRIO_FP_ZERO;
545 case FP_PLUS_NORM:
546 *is_negative = TRIO_FALSE;
547 return TRIO_FP_NORMAL;
548 case FP_MINUS_NORM:
549 *is_negative = TRIO_TRUE;
550 return TRIO_FP_NORMAL;
551 default:
552 *is_negative = (number < 0.0);
553 return TRIO_FP_NORMAL;
554 }
555}
556
557#endif /* TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT */
558
559#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)
560
561TRIO_PRIVATE_NAN TRIO_INLINE int
562xlc_fpclassify_and_signbit
563TRIO_ARGS2((number, is_negative),
564 double number,
565 int *is_negative)
566{
567 /*
568 * AIX has class() for C, and _class() for C++
569 */
570# if defined(__cplusplus)
571# define AIX_CLASS(n) _class(n)
572# else
573# define AIX_CLASS(n) class(n)
574# endif
575
576 switch (AIX_CLASS(number)) {
577 case FP_QNAN:
578 case FP_SNAN:
579 *is_negative = TRIO_FALSE; /* NaN has no sign */
580 return TRIO_FP_NAN;
581 case FP_PLUS_INF:
582 *is_negative = TRIO_FALSE;
583 return TRIO_FP_INFINITE;
584 case FP_MINUS_INF:
585 *is_negative = TRIO_TRUE;
586 return TRIO_FP_INFINITE;
587 case FP_PLUS_DENORM:
588 *is_negative = TRIO_FALSE;
589 return TRIO_FP_SUBNORMAL;
590 case FP_MINUS_DENORM:
591 *is_negative = TRIO_TRUE;
592 return TRIO_FP_SUBNORMAL;
593 case FP_PLUS_ZERO:
594 *is_negative = TRIO_FALSE;
595 return TRIO_FP_ZERO;
596 case FP_MINUS_ZERO:
597 *is_negative = TRIO_TRUE;
598 return TRIO_FP_ZERO;
599 case FP_PLUS_NORM:
600 *is_negative = TRIO_FALSE;
601 return TRIO_FP_NORMAL;
602 case FP_MINUS_NORM:
603 *is_negative = TRIO_TRUE;
604 return TRIO_FP_NORMAL;
605 default:
606 *is_negative = (number < 0.0);
607 return TRIO_FP_NORMAL;
608 }
609}
610
611#endif /* TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT */
612
613#if defined(TRIO_FUNC_INTERNAL_ISNAN)
614
615TRIO_PRIVATE_NAN TRIO_INLINE int
616internal_isnan
617TRIO_ARGS1((number),
618 double number)
619{
620# if defined(TRIO_INTERNAL_ISNAN_XPG3) || defined(TRIO_PLATFORM_SYMBIAN)
621 /*
622 * XPG3 defines isnan() as a function.
623 */
624 return isnan(number);
625
626# endif
627
628# if defined(TRIO_INTERNAL_ISNAN_IEEE_754)
629
630 /*
631 * Examine IEEE 754 bit-pattern. A NaN must have a special exponent
632 * pattern, and a non-empty mantissa.
633 */
634 int has_mantissa;
635 int is_special_quantity;
636
637 is_special_quantity = internal_is_special_quantity(number, &has_mantissa);
638
639 return (is_special_quantity && has_mantissa);
640
641# endif
642
643# if defined(TRIO_INTERNAL_ISNAN_FALLBACK)
644
645 /*
646 * Fallback solution
647 */
648 int status;
649 double integral, fraction;
650
651# if defined(TRIO_PLATFORM_UNIX)
652 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
653# endif
654
655 status = (/*
656 * NaN is the only number which does not compare to itself
657 */
658 ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) ||
659 /*
660 * Fallback solution if NaN compares to NaN
661 */
662 ((number != 0.0) &&
663 (fraction = modf(number, &integral),
664 integral == fraction)));
665
666# if defined(TRIO_PLATFORM_UNIX)
667 signal(SIGFPE, signal_handler);
668# endif
669
670 return status;
671
672# endif
673}
674
675#endif /* TRIO_FUNC_INTERNAL_ISNAN */
676
677#if defined(TRIO_FUNC_INTERNAL_ISINF)
678
679TRIO_PRIVATE_NAN TRIO_INLINE int
680internal_isinf
681TRIO_ARGS1((number),
682 double number)
683{
684# if defined(TRIO_PLATFORM_SYMBIAN)
685
686 return isinf(number);
687
688# endif
689
690# if defined(TRIO_INTERNAL_ISINF_IEEE_754)
691 /*
692 * Examine IEEE 754 bit-pattern. Infinity must have a special exponent
693 * pattern, and an empty mantissa.
694 */
695 int has_mantissa;
696 int is_special_quantity;
697
698 is_special_quantity = internal_is_special_quantity(number, &has_mantissa);
699
700 return (is_special_quantity && !has_mantissa)
701 ? ((number < 0.0) ? -1 : 1)
702 : 0;
703
704# endif
705
706# if defined(TRIO_INTERNAL_ISINF_FALLBACK)
707
708 /*
709 * Fallback solution.
710 */
711 int status;
712
713# if defined(TRIO_PLATFORM_UNIX)
714 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
715# endif
716
717 double infinity = trio_pinf();
718
719 status = ((number == infinity)
720 ? 1
721 : ((number == -infinity) ? -1 : 0));
722
723# if defined(TRIO_PLATFORM_UNIX)
724 signal(SIGFPE, signal_handler);
725# endif
726
727 return status;
728
729# endif
730}
731
732#endif /* TRIO_FUNC_INTERNAL_ISINF */
733
734/*************************************************************************
735 * Public functions
736 */
737
738#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
739
740TRIO_PUBLIC_NAN int
741trio_fpclassify_and_signbit
742TRIO_ARGS2((number, is_negative),
743 double number,
744 int *is_negative)
745{
746 /* The TRIO_FUNC_xxx_FPCLASSIFY_AND_SIGNBIT macros are mutually exclusive */
747
748#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)
749
750 return c99_fpclassify_and_signbit(number, is_negative);
751
752#endif
753
754#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)
755
756 return decc_fpclassify_and_signbit(number, is_negative);
757
758#endif
759
760#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)
761
762 return ms_fpclassify_and_signbit(number, is_negative);
763
764#endif
765
766#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)
767
768 return hp_fpclassify_and_signbit(number, is_negative);
769
770#endif
771
772#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)
773
774 return xlc_fpclassify_and_signbit(number, is_negative);
775
776#endif
777
778#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)
779
780 /*
781 * Fallback solution.
782 */
783 int rc;
784
785 if (number == 0.0) {
786 /*
787 * In IEEE 754 the sign of zero is ignored in comparisons, so we
788 * have to handle this as a special case by examining the sign bit
789 * directly.
790 */
791# if defined(TRIO_IEEE_754)
792 *is_negative = internal_is_negative(number);
793# else
794 *is_negative = TRIO_FALSE; /* FIXME */
795# endif
796 return TRIO_FP_ZERO;
797 }
798 if (internal_isnan(number)) {
799 *is_negative = TRIO_FALSE;
800 return TRIO_FP_NAN;
801 }
802 rc = internal_isinf(number);
803 if (rc != 0) {
804 *is_negative = (rc == -1);
805 return TRIO_FP_INFINITE;
806 }
807 if ((number > 0.0) && (number < DBL_MIN)) {
808 *is_negative = TRIO_FALSE;
809 return TRIO_FP_SUBNORMAL;
810 }
811 if ((number < 0.0) && (number > -DBL_MIN)) {
812 *is_negative = TRIO_TRUE;
813 return TRIO_FP_SUBNORMAL;
814 }
815 *is_negative = (number < 0.0);
816 return TRIO_FP_NORMAL;
817
818#endif
819}
820
821#endif
822
823/**
824 Check for NaN.
825
826 @param number An arbitrary floating-point number.
827 @return Boolean value indicating whether or not the number is a NaN.
828*/
829#if defined(TRIO_FUNC_ISNAN)
830
831TRIO_PUBLIC_NAN int
832trio_isnan
833TRIO_ARGS1((number),
834 double number)
835{
836 int dummy;
837
838 return (trio_fpclassify_and_signbit(number, &dummy) == TRIO_FP_NAN);
839}
840
841#endif
842
843/**
844 Check for infinity.
845
846 @param number An arbitrary floating-point number.
847 @return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
848*/
849#if defined(TRIO_FUNC_ISINF)
850
851TRIO_PUBLIC_NAN int
852trio_isinf
853TRIO_ARGS1((number),
854 double number)
855{
856 int is_negative;
857
858 if (trio_fpclassify_and_signbit(number, &is_negative) == TRIO_FP_INFINITE)
859 {
860 return (is_negative) ? -1 : 1;
861 }
862 else
863 {
864 return 0;
865 }
866}
867
868#endif
869
870/**
871 Check for finity.
872
873 @param number An arbitrary floating-point number.
874 @return Boolean value indicating whether or not the number is a finite.
875*/
876#if defined(TRIO_FUNC_ISFINITE)
877
878TRIO_PUBLIC_NAN int
879trio_isfinite
880TRIO_ARGS1((number),
881 double number)
882{
883 int dummy;
884
885 switch (trio_fpclassify_and_signbit(number, &dummy))
886 {
887 case TRIO_FP_INFINITE:
888 case TRIO_FP_NAN:
889 return 0;
890 default:
891 return 1;
892 }
893}
894
895#endif
896
897/**
898 Examine the sign of a number.
899
900 @param number An arbitrary floating-point number.
901 @return Boolean value indicating whether or not the number has the
902 sign bit set (i.e. is negative).
903*/
904#if defined(TRIO_FUNC_SIGNBIT)
905
906TRIO_PUBLIC_NAN int
907trio_signbit
908TRIO_ARGS1((number),
909 double number)
910{
911 int is_negative;
912
913 (void)trio_fpclassify_and_signbit(number, &is_negative);
914 return is_negative;
915}
916
917#endif
918
919/**
920 Examine the class of a number.
921
922 @param number An arbitrary floating-point number.
923 @return Enumerable value indicating the class of @p number
924*/
925#if defined(TRIO_FUNC_FPCLASSIFY)
926
927TRIO_PUBLIC_NAN int
928trio_fpclassify
929TRIO_ARGS1((number),
930 double number)
931{
932 int dummy;
933
934 return trio_fpclassify_and_signbit(number, &dummy);
935}
936
937#endif
938
939/**
940 Generate negative zero.
941
942 @return Floating-point representation of negative zero.
943*/
944#if defined(TRIO_FUNC_NZERO)
945
946TRIO_PUBLIC_NAN double
947trio_nzero(TRIO_NOARGS)
948{
949# if defined(TRIO_NZERO_IEEE_754)
950
951 return internal_make_double(ieee_754_negzero_array);
952
953# endif
954
955# if defined(TRIO_NZERO_FALLBACK)
956
957 TRIO_VOLATILE double zero = 0.0;
958
959 return -zero;
960
961# endif
962}
963
964#endif
965
966/**
967 Generate positive infinity.
968
969 @return Floating-point representation of positive infinity.
970*/
971#if defined(TRIO_FUNC_PINF)
972
973TRIO_PUBLIC_NAN double
974trio_pinf(TRIO_NOARGS)
975{
976 /* Cache the result */
977 static double pinf_value = 0.0;
978
979 if (pinf_value == 0.0) {
980
981# if defined(TRIO_PINF_C99_MACRO)
982
983 pinf_value = (double)INFINITY;
984
985# endif
986
987# if defined(TRIO_PINF_IEEE_754)
988
989 pinf_value = internal_make_double(ieee_754_infinity_array);
990
991# endif
992
993# if defined(TRIO_PINF_FALLBACK)
994 /*
995 * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used
996 * as infinity. Otherwise we have to resort to an overflow
997 * operation to generate infinity.
998 */
999# if defined(TRIO_PLATFORM_UNIX)
1000 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
1001# endif
1002
1003 pinf_value = HUGE_VAL;
1004 if (HUGE_VAL == DBL_MAX) {
1005 /* Force overflow */
1006 pinf_value += HUGE_VAL;
1007 }
1008
1009# if defined(TRIO_PLATFORM_UNIX)
1010 signal(SIGFPE, signal_handler);
1011# endif
1012
1013# endif
1014 }
1015 return pinf_value;
1016}
1017
1018#endif
1019
1020/**
1021 Generate negative infinity.
1022
1023 @return Floating-point value of negative infinity.
1024*/
1025#if defined(TRIO_FUNC_NINF)
1026
1027TRIO_PUBLIC_NAN double
1028trio_ninf(TRIO_NOARGS)
1029{
1030 static double ninf_value = 0.0;
1031
1032 if (ninf_value == 0.0) {
1033 /*
1034 * Negative infinity is calculated by negating positive infinity,
1035 * which can be done because it is legal to do calculations on
1036 * infinity (for example, 1 / infinity == 0).
1037 */
1038 ninf_value = -trio_pinf();
1039 }
1040 return ninf_value;
1041}
1042
1043#endif
1044
1045/**
1046 Generate NaN.
1047
1048 @return Floating-point representation of NaN.
1049*/
1050#if defined(TRIO_FUNC_NAN)
1051
1052TRIO_PUBLIC_NAN double
1053trio_nan(TRIO_NOARGS)
1054{
1055 /* Cache the result */
1056 static double nan_value = 0.0;
1057
1058 if (nan_value == 0.0) {
1059
1060# if defined(TRIO_NAN_C99_FUNCTION) || defined(TRIO_PLATFORM_SYMBIAN)
1061
1062 nan_value = nan("");
1063
1064# endif
1065
1066# if defined(TRIO_NAN_C99_MACRO)
1067
1068 nan_value = (double)NAN;
1069
1070# endif
1071
1072# if defined(TRIO_NAN_IEEE_754)
1073
1074 nan_value = internal_make_double(ieee_754_qnan_array);
1075
1076# endif
1077
1078# if defined(TRIO_NAN_FALLBACK)
1079 /*
1080 * There are several ways to generate NaN. The one used here is
1081 * to divide infinity by infinity. I would have preferred to add
1082 * negative infinity to positive infinity, but that yields wrong
1083 * result (infinity) on FreeBSD.
1084 *
1085 * This may fail if the hardware does not support NaN, or if
1086 * the Invalid Operation floating-point exception is unmasked.
1087 */
1088# if defined(TRIO_PLATFORM_UNIX)
1089 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
1090# endif
1091
1092 nan_value = trio_pinf() / trio_pinf();
1093
1094# if defined(TRIO_PLATFORM_UNIX)
1095 signal(SIGFPE, signal_handler);
1096# endif
1097
1098# endif
1099 }
1100 return nan_value;
1101}
1102
1103#endif
1104
1105/** @} SpecialQuantities */
1106
1107/*************************************************************************
1108 * For test purposes.
1109 *
1110 * Add the following compiler option to include this test code.
1111 *
1112 * Unix : -DSTANDALONE
1113 * VMS : /DEFINE=(STANDALONE)
1114 */
1115#if defined(STANDALONE)
1116# include <stdio.h>
1117
1118static TRIO_CONST char *
1119getClassification
1120TRIO_ARGS1((type),
1121 int type)
1122{
1123 switch (type) {
1124 case TRIO_FP_INFINITE:
1125 return "FP_INFINITE";
1126 case TRIO_FP_NAN:
1127 return "FP_NAN";
1128 case TRIO_FP_NORMAL:
1129 return "FP_NORMAL";
1130 case TRIO_FP_SUBNORMAL:
1131 return "FP_SUBNORMAL";
1132 case TRIO_FP_ZERO:
1133 return "FP_ZERO";
1134 default:
1135 return "FP_UNKNOWN";
1136 }
1137}
1138
1139static void
1140print_class
1141TRIO_ARGS2((prefix, number),
1142 TRIO_CONST char *prefix,
1143 double number)
1144{
1145 printf("%-6s: %s %-15s %g\n",
1146 prefix,
1147 trio_signbit(number) ? "-" : "+",
1148 getClassification(trio_fpclassify(number)),
1149 number);
1150}
1151
1152int main(TRIO_NOARGS)
1153{
1154 double my_nan;
1155 double my_pinf;
1156 double my_ninf;
1157# if defined(TRIO_PLATFORM_UNIX)
1158 void (*signal_handler) TRIO_PROTO((int));
1159# endif
1160
1161 my_nan = trio_nan();
1162 my_pinf = trio_pinf();
1163 my_ninf = trio_ninf();
1164
1165 print_class("Nan", my_nan);
1166 print_class("PInf", my_pinf);
1167 print_class("NInf", my_ninf);
1168 print_class("PZero", 0.0);
1169 print_class("NZero", -0.0);
1170 print_class("PNorm", 1.0);
1171 print_class("NNorm", -1.0);
1172 print_class("PSub", 1.01e-307 - 1.00e-307);
1173 print_class("NSub", 1.00e-307 - 1.01e-307);
1174
1175 printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1176 my_nan,
1177 ((unsigned char *)&my_nan)[0],
1178 ((unsigned char *)&my_nan)[1],
1179 ((unsigned char *)&my_nan)[2],
1180 ((unsigned char *)&my_nan)[3],
1181 ((unsigned char *)&my_nan)[4],
1182 ((unsigned char *)&my_nan)[5],
1183 ((unsigned char *)&my_nan)[6],
1184 ((unsigned char *)&my_nan)[7],
1185 trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));
1186 printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1187 my_pinf,
1188 ((unsigned char *)&my_pinf)[0],
1189 ((unsigned char *)&my_pinf)[1],
1190 ((unsigned char *)&my_pinf)[2],
1191 ((unsigned char *)&my_pinf)[3],
1192 ((unsigned char *)&my_pinf)[4],
1193 ((unsigned char *)&my_pinf)[5],
1194 ((unsigned char *)&my_pinf)[6],
1195 ((unsigned char *)&my_pinf)[7],
1196 trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));
1197 printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1198 my_ninf,
1199 ((unsigned char *)&my_ninf)[0],
1200 ((unsigned char *)&my_ninf)[1],
1201 ((unsigned char *)&my_ninf)[2],
1202 ((unsigned char *)&my_ninf)[3],
1203 ((unsigned char *)&my_ninf)[4],
1204 ((unsigned char *)&my_ninf)[5],
1205 ((unsigned char *)&my_ninf)[6],
1206 ((unsigned char *)&my_ninf)[7],
1207 trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));
1208
1209# if defined(TRIO_PLATFORM_UNIX)
1210 signal_handler = signal(SIGFPE, SIG_IGN);
1211# endif
1212
1213 my_pinf = DBL_MAX + DBL_MAX;
1214 my_ninf = -my_pinf;
1215 my_nan = my_pinf / my_pinf;
1216
1217# if defined(TRIO_PLATFORM_UNIX)
1218 signal(SIGFPE, signal_handler);
1219# endif
1220
1221 printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1222 my_nan,
1223 ((unsigned char *)&my_nan)[0],
1224 ((unsigned char *)&my_nan)[1],
1225 ((unsigned char *)&my_nan)[2],
1226 ((unsigned char *)&my_nan)[3],
1227 ((unsigned char *)&my_nan)[4],
1228 ((unsigned char *)&my_nan)[5],
1229 ((unsigned char *)&my_nan)[6],
1230 ((unsigned char *)&my_nan)[7],
1231 trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));
1232 printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1233 my_pinf,
1234 ((unsigned char *)&my_pinf)[0],
1235 ((unsigned char *)&my_pinf)[1],
1236 ((unsigned char *)&my_pinf)[2],
1237 ((unsigned char *)&my_pinf)[3],
1238 ((unsigned char *)&my_pinf)[4],
1239 ((unsigned char *)&my_pinf)[5],
1240 ((unsigned char *)&my_pinf)[6],
1241 ((unsigned char *)&my_pinf)[7],
1242 trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));
1243 printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1244 my_ninf,
1245 ((unsigned char *)&my_ninf)[0],
1246 ((unsigned char *)&my_ninf)[1],
1247 ((unsigned char *)&my_ninf)[2],
1248 ((unsigned char *)&my_ninf)[3],
1249 ((unsigned char *)&my_ninf)[4],
1250 ((unsigned char *)&my_ninf)[5],
1251 ((unsigned char *)&my_ninf)[6],
1252 ((unsigned char *)&my_ninf)[7],
1253 trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));
1254
1255 return 0;
1256}
1257#endif
diff --git a/gs/trio/trionan.h b/gs/trio/trionan.h
new file mode 100644
index 000000000..a38b1cc26
--- /dev/null
+++ b/gs/trio/trionan.h
@@ -0,0 +1,183 @@
1/*************************************************************************
2 *
3 * $Id: trionan.h,v 1.9 2005/03/27 18:52:45 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
18#ifndef TRIO_TRIONAN_H
19#define TRIO_TRIONAN_H
20
21#include "triodef.h"
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27#if !defined(TRIO_PUBLIC_NAN)
28# if !defined(TRIO_PUBLIC)
29# define TRIO_PUBLIC
30# endif
31# define TRIO_PUBLIC_NAN TRIO_PUBLIC
32#endif
33
34enum {
35 TRIO_FP_INFINITE,
36 TRIO_FP_NAN,
37 TRIO_FP_NORMAL,
38 TRIO_FP_SUBNORMAL,
39 TRIO_FP_ZERO
40};
41
42/*************************************************************************
43 * Dependencies
44 */
45
46#if defined(TRIO_EMBED_NAN)
47
48/*
49 * The application that trionan is embedded in must define which functions
50 * it uses.
51 *
52 * The following resolves internal dependencies.
53 */
54
55# if defined(TRIO_FUNC_ISNAN) \
56 || defined(TRIO_FUNC_ISINF)
57# if !defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
58# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT
59# endif
60# endif
61
62# if defined(TRIO_FUNC_NAN)
63# if !defined(TRIO_FUNC_PINF)
64# define TRIO_FUNC_PINF
65# endif
66# endif
67
68# if defined(TRIO_FUNC_NINF)
69# if !defined(TRIO_FUNC_PINF)
70# define TRIO_FUNC_PINF
71# endif
72# endif
73
74#else
75
76/*
77 * When trionan is not embedded all all functions are defined.
78 */
79
80# define TRIO_FUNC_NAN
81# define TRIO_FUNC_PINF
82# define TRIO_FUNC_NINF
83# define TRIO_FUNC_NZERO
84# define TRIO_FUNC_ISNAN
85# define TRIO_FUNC_ISINF
86# define TRIO_FUNC_ISFINITE
87# define TRIO_FUNC_SIGNBIT
88# define TRIO_FUNC_FPCLASSIFY
89# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT
90
91#endif
92
93/*************************************************************************
94 * Functions
95 */
96
97/*
98 * Return NaN (Not-a-Number).
99 */
100#if defined(TRIO_FUNC_NAN)
101TRIO_PUBLIC_NAN double
102trio_nan
103TRIO_PROTO((void));
104#endif
105
106/*
107 * Return positive infinity.
108 */
109#if defined(TRIO_FUNC_PINF)
110TRIO_PUBLIC_NAN double
111trio_pinf
112TRIO_PROTO((void));
113#endif
114
115/*
116 * Return negative infinity.
117 */
118#if defined(TRIO_FUNC_NINF)
119TRIO_PUBLIC_NAN double
120trio_ninf
121TRIO_PROTO((void));
122#endif
123
124/*
125 * Return negative zero.
126 */
127#if defined(TRIO_FUNC_NZERO)
128TRIO_PUBLIC_NAN double
129trio_nzero
130TRIO_PROTO((TRIO_NOARGS));
131#endif
132
133/*
134 * If number is a NaN return non-zero, otherwise return zero.
135 */
136#if defined(TRIO_FUNC_ISNAN)
137TRIO_PUBLIC_NAN int
138trio_isnan
139TRIO_PROTO((double number));
140#endif
141
142/*
143 * If number is positive infinity return 1, if number is negative
144 * infinity return -1, otherwise return 0.
145 */
146#if defined(TRIO_FUNC_ISINF)
147TRIO_PUBLIC_NAN int
148trio_isinf
149TRIO_PROTO((double number));
150#endif
151
152/*
153 * If number is finite return non-zero, otherwise return zero.
154 */
155#if defined(TRIO_FUNC_ISFINITE)
156TRIO_PUBLIC_NAN int
157trio_isfinite
158TRIO_PROTO((double number));
159#endif
160
161#if defined(TRIO_FUNC_SIGNBIT)
162TRIO_PUBLIC_NAN int
163trio_signbit
164TRIO_PROTO((double number));
165#endif
166
167#if defined(TRIO_FUNC_FPCLASSIFY)
168TRIO_PUBLIC_NAN int
169trio_fpclassify
170TRIO_PROTO((double number));
171#endif
172
173#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
174TRIO_PUBLIC_NAN int
175trio_fpclassify_and_signbit
176TRIO_PROTO((double number, int *is_negative));
177#endif
178
179#ifdef __cplusplus
180}
181#endif
182
183#endif /* TRIO_TRIONAN_H */
diff --git a/gs/trio/triop.h b/gs/trio/triop.h
new file mode 100644
index 000000000..fecc37bd3
--- /dev/null
+++ b/gs/trio/triop.h
@@ -0,0 +1,472 @@
1/*************************************************************************
2 *
3 * $Id: triop.h,v 1.18 2009/07/05 10:14:07 breese Exp $
4 *
5 * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************
17 *
18 * Private functions, types, etc. used for callback functions.
19 *
20 * The ref pointer is an opaque type and should remain as such.
21 * Private data must only be accessible through the getter and
22 * setter functions.
23 *
24 ************************************************************************/
25
26#ifndef TRIO_TRIOP_H
27#define TRIO_TRIOP_H
28
29#include "triodef.h"
30
31#include <stdlib.h>
32#if defined(TRIO_COMPILER_ANCIENT)
33# include <varargs.h>
34#else
35# include <stdarg.h>
36#endif
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42/*************************************************************************
43 * Supported standards
44 */
45
46/*
47 * TRIO_C99 (=0 or =1)
48 *
49 * Define this to 0 to disable C99 format specifier extensions, or
50 * define to 1 to enable them. The format specifiers that are
51 * disabled by this switch are labelled with [C99] in the format
52 * specifier documentation.
53 */
54#if !defined(TRIO_C99)
55# define TRIO_C99 1
56#endif
57
58/*
59 * TRIO_BSD (=0 or =1)
60 *
61 * Define this to 0 to disable BSD format specifier extensions, or
62 * define to 1 to enable them. The format specifiers that are
63 * disabled by this switch are labelled with [BSD] in the format
64 * specifier documentation.
65 */
66#if !defined(TRIO_BSD)
67# define TRIO_BSD 1
68#endif
69
70/*
71 * TRIO_GNU (=0 or =1)
72 *
73 * Define this to 0 to disable GNU format specifier extensions, or
74 * define to 1 to enable them. The format specifiers that are
75 * disabled by this switch are labelled with [GNU] in the format
76 * specifier documentation.
77 */
78#if !defined(TRIO_GNU)
79# define TRIO_GNU 1
80#endif
81
82/*
83 * TRIO_MISC (=0 or =1)
84 *
85 * Define this to 0 to disable miscellaneous format specifier
86 * extensions, or define to 1 to enable them. The format specifiers
87 * that are disabled by this switch are labelled with [MISC] in the
88 * format specifier documentation.
89 */
90#if !defined(TRIO_MISC)
91# define TRIO_MISC 1
92#endif
93
94/*
95 * TRIO_UNIX98 (=0 or =1)
96 *
97 * Define this to 0 to disable UNIX98 format specifier extensions,
98 * or define to 1 to enable them. The format specifiers that are
99 * disabled by this switch are labelled with [UNIX98] in the format
100 * specifier documentation.
101 */
102#if !defined(TRIO_UNIX98)
103# define TRIO_UNIX98 1
104#endif
105
106/*
107 * TRIO_MICROSOFT (=0 or =1)
108 *
109 * Define this to 0 to disable Microsoft Visual C format specifier
110 * extensions, or define to 1 to enable them. The format specifiers
111 * that are disabled by this switch are labelled with [MSVC] in the
112 * format specifier documentation.
113 */
114#if !defined(TRIO_MICROSOFT)
115# define TRIO_MICROSOFT 1
116#endif
117
118/*
119 * TRIO_EXTENSION (=0 or =1)
120 *
121 * Define this to 0 to disable Trio-specific extensions, or define
122 * to 1 to enable them. This has two effects: it controls whether
123 * or not the Trio user-defined formating mechanism
124 * (trio_register() etc) is supported, and it enables or disables
125 * Trio's own format specifier extensions. The format specifiers
126 * that are disabled by this switch are labelled with [TRIO] in
127 * the format specifier documentation.
128 */
129#if !defined(TRIO_EXTENSION)
130# define TRIO_EXTENSION 1
131#endif
132
133/*
134 * TRIO_DEPRECATED (=0 or =1)
135 *
136 * Define this to 0 to disable deprecated functionality, or define
137 * to 1 to enable them.
138 */
139#if !defined(TRIO_DEPRECATED)
140# define TRIO_DEPRECATED 1
141#endif
142
143/*************************************************************************
144 * Features
145 */
146
147#if defined(TRIO_SNPRINTF_ONLY)
148# define TRIO_FEATURE_SCANF 0
149# define TRIO_FEATURE_FILE 0
150# define TRIO_FEATURE_STDIO 0
151# define TRIO_FEATURE_FD 0
152# define TRIO_FEATURE_DYNAMICSTRING 0
153# define TRIO_FEATURE_CLOSURE 0
154# define TRIO_FEATURE_STRERR 0
155# define TRIO_FEATURE_LOCALE 0
156# define TRIO_EMBED_NAN 1
157# define TRIO_EMBED_STRING 1
158#endif
159
160/*
161 * TRIO_FEATURE_SCANF (=0 or =1)
162 *
163 * Define this to 0 to disable all the scanf() variants, or define to 1
164 * to enable them.
165 */
166#if !defined(TRIO_FEATURE_SCANF)
167# define TRIO_FEATURE_SCANF 1
168#endif
169
170/*
171 * TRIO_FEATURE_FILE (=0 or =1)
172 *
173 * Define this to 0 to disable compilation of the trio_fprintf() and
174 * trio_fscanf() family of functions, or define to 1 to enable them.
175 *
176 * This may be useful on an embedded platform with no filesystem.
177 * Note that trio_printf() uses fwrite to write to stdout, so if you
178 * do not have an implementation of fwrite() at all then you must also
179 * define TRIO_FEATURE_STDIO to 0.
180 */
181#if !defined(TRIO_FEATURE_FILE)
182# define TRIO_FEATURE_FILE 1
183#endif
184
185/*
186 * TRIO_FEATURE_STDIO (=0 or =1)
187 *
188 * Define this to 0 to disable compilation of the trio_printf() and
189 * trio_scanf() family of functions, or define to 1 to enable them.
190 *
191 * This may be useful on an embedded platform with no standard I/O.
192 */
193#if !defined(TRIO_FEATURE_STDIO)
194# define TRIO_FEATURE_STDIO 1
195#endif
196
197/*
198 * TRIO_FEATURE_FD (=0 or =1)
199 *
200 * Define this to 0 to disable compilation of the trio_dprintf() and
201 * trio_dscanf() family of functions, or define to 1 to enable them.
202 *
203 * This may be useful on an embedded platform with no filesystem, or on
204 * a platform that supports file I/O using FILE* but not using raw file
205 * descriptors.
206 */
207#if !defined(TRIO_FEATURE_FD)
208# define TRIO_FEATURE_FD 1
209#endif
210
211/*
212 * TRIO_FEATURE_DYNAMICSTRING (=0 or =1)
213 *
214 * Define this to 0 to disable compilation of the trio_aprintf()
215 * family of functions, or define to 1 to enable them.
216 *
217 * If you define both this and TRIO_MINIMAL to 0, then Trio will never
218 * call malloc or free.
219 */
220#if !defined(TRIO_FEATURE_DYNAMICSTRING)
221# define TRIO_FEATURE_DYNAMICSTRING 1
222#endif
223
224/*
225 * TRIO_FEATURE_CLOSURE (=0 or =1)
226 *
227 * Define this to 0 to disable compilation of the trio_cprintf() and
228 * trio_cscanf() family of functions, or define to 1 to enable them.
229 *
230 * These functions are rarely needed. This saves a (small) amount of code.
231 */
232#if !defined(TRIO_FEATURE_CLOSURE)
233# define TRIO_FEATURE_CLOSURE 1
234#endif
235
236/*
237 * TRIO_FEATURE_ERRORCODE (=0 or =1)
238 *
239 * Define this to 0 to return -1 from the print and scan function on
240 * error, or define to 1 to return a negative number with debugging
241 * information as part of the return code.
242 *
243 * If enabled, the return code will be a negative number, which encodes
244 * an error code and an error location. These can be decoded with the
245 * TRIO_ERROR_CODE and TRIO_ERROR_POSITION macros.
246 */
247#if defined(TRIO_ERRORS)
248# define TRIO_FEATURE_ERRORCODE TRIO_ERRORS
249#endif
250#if !defined(TRIO_FEATURE_ERRORCODE)
251# define TRIO_FEATURE_ERRORCODE 1
252#endif
253
254/*
255 * TRIO_FEATURE_STRERR (=0 or =1)
256 *
257 * Define this to 0 if you do not use trio_strerror(), or define to 1 if
258 * you do use it.
259 *
260 * This saves a (small) amount of code.
261 */
262#if !defined(TRIO_FEATURE_STRERR)
263# define TRIO_FEATURE_STRERR 1
264#endif
265
266/*
267 * TRIO_FEATURE_FLOAT (=0 or =1)
268 *
269 * Define this to 0 to disable all floating-point support, or define
270 * to 1 to enable it.
271 *
272 * This is useful in restricted embedded platforms that do not support
273 * floating-point. Obviously you cannot use floating-point format
274 * specifiers if you define this.
275 *
276 * Do not compile trionan.c if you disable this.
277 */
278#if !defined(TRIO_FEATURE_FLOAT)
279# define TRIO_FEATURE_FLOAT 1
280#endif
281
282/*
283 * TRIO_FEATURE_LOCALE (=0 or =1)
284 *
285 * Define this to 0 to disable customized locale support, or define
286 * to 1 to enable it.
287 *
288 * This saves a (small) amount of code.
289 */
290#if !defined(TRIO_FEATURE_LOCALE)
291# define TRIO_FEATURE_LOCALE 1
292#endif
293
294/*
295 * TRIO_MINIMAL
296 *
297 * Define this to disable building the public trionan.h and triostr.h.
298 * If you define this, then you must not compile trionan.c and triostr.c
299 * separately.
300 */
301#if defined(TRIO_MINIMAL)
302# if !defined(TRIO_EMBED_NAN)
303# define TRIO_EMBED_NAN
304# endif
305# if !defined(TRIO_EMBED_STRING)
306# define TRIO_EMBED_STRING
307# endif
308#endif
309
310/* Does not work yet. Do not enable */
311#ifndef TRIO_FEATURE_WIDECHAR
312# define TRIO_FEATURE_WIDECHAR 0
313#endif
314
315/*************************************************************************
316 * Mapping standards to internal features
317 */
318
319#if !defined(TRIO_FEATURE_HEXFLOAT)
320# define TRIO_FEATURE_HEXFLOAT (TRIO_C99 && TRIO_FEATURE_FLOAT)
321#endif
322
323#if !defined(TRIO_FEATURE_LONGDOUBLE)
324# define TRIO_FEATURE_LONGDOUBLE TRIO_FEATURE_FLOAT
325#endif
326
327#if !defined(TRIO_FEATURE_ERRNO)
328# define TRIO_FEATURE_ERRNO TRIO_GNU
329#endif
330
331#if !defined(TRIO_FEATURE_QUAD)
332# define TRIO_FEATURE_QUAD (TRIO_BSD || TRIO_GNU)
333#endif
334
335#if !defined(TRIO_FEATURE_SIZE_T)
336# define TRIO_FEATURE_SIZE_T TRIO_C99
337#endif
338
339#if !defined(TRIO_FEATURE_SIZE_T_UPPER)
340# define TRIO_FEATURE_SIZE_T_UPPER TRIO_GNU
341#endif
342
343#if !defined(TRIO_FEATURE_PTRDIFF_T)
344# define TRIO_FEATURE_PTRDIFF_T TRIO_C99
345#endif
346
347#if !defined(TRIO_FEATURE_INTMAX_T)
348# define TRIO_FEATURE_INTMAX_T TRIO_C99
349#endif
350
351#if !defined(TRIO_FEATURE_FIXED_SIZE)
352# define TRIO_FEATURE_FIXED_SIZE TRIO_MICROSOFT
353#endif
354
355#if !defined(TRIO_FEATURE_POSITIONAL)
356# define TRIO_FEATURE_POSITIONAL TRIO_UNIX98
357#endif
358
359#if !defined(TRIO_FEATURE_USER_DEFINED)
360# define TRIO_FEATURE_USER_DEFINED TRIO_EXTENSION
361#endif
362
363#if !defined(TRIO_FEATURE_BINARY)
364# define TRIO_FEATURE_BINARY TRIO_EXTENSION
365#endif
366
367#if !defined(TRIO_FEATURE_QUOTE)
368# define TRIO_FEATURE_QUOTE TRIO_EXTENSION
369#endif
370
371#if !defined(TRIO_FEATURE_STICKY)
372# define TRIO_FEATURE_STICKY TRIO_EXTENSION
373#endif
374
375#if !defined(TRIO_FEATURE_VARSIZE)
376# define TRIO_FEATURE_VARSIZE TRIO_EXTENSION
377#endif
378
379#if !defined(TRIO_FEATURE_ROUNDING)
380# define TRIO_FEATURE_ROUNDING TRIO_EXTENSION
381#endif
382
383/*************************************************************************
384 * Memory handling
385 */
386#ifndef TRIO_MALLOC
387# define TRIO_MALLOC(n) malloc(n)
388#endif
389#ifndef TRIO_REALLOC
390# define TRIO_REALLOC(x,n) realloc((x),(n))
391#endif
392#ifndef TRIO_FREE
393# define TRIO_FREE(x) free(x)
394#endif
395
396
397/*************************************************************************
398 * User-defined specifiers
399 */
400
401typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t));
402
403trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name));
404void trio_unregister TRIO_PROTO((trio_pointer_t handle));
405
406TRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref));
407TRIO_CONST trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref));
408
409/* Modifiers */
410int trio_get_width TRIO_PROTO((trio_pointer_t ref));
411void trio_set_width TRIO_PROTO((trio_pointer_t ref, int width));
412int trio_get_precision TRIO_PROTO((trio_pointer_t ref));
413void trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision));
414int trio_get_base TRIO_PROTO((trio_pointer_t ref));
415void trio_set_base TRIO_PROTO((trio_pointer_t ref, int base));
416int trio_get_padding TRIO_PROTO((trio_pointer_t ref));
417void trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding));
418int trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */
419void trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort));
420int trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */
421void trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short));
422int trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */
423void trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long));
424int trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */
425void trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong));
426int trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */
427void trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble));
428int trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */
429void trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative));
430int trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */
431void trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned));
432int trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /* (space) */
433void trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space));
434int trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */
435void trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign));
436#if TRIO_FEATURE_QUOTE
437int trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */
438void trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote));
439#endif
440int trio_get_upper TRIO_PROTO((trio_pointer_t ref));
441void trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper));
442#if TRIO_FEATURE_INTMAX_T
443int trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */
444void trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest));
445#endif
446#if TRIO_FEATURE_PTRDIFF_T
447int trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */
448void trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff));
449#endif
450#if TRIO_FEATURE_SIZE_T
451int trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */
452void trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size));
453#endif
454
455/* Printing */
456int trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...));
457int trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args));
458int trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args));
459
460void trio_print_int TRIO_PROTO((trio_pointer_t ref, int number));
461void trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number));
462/* void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */
463/* void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */
464void trio_print_double TRIO_PROTO((trio_pointer_t ref, double number));
465void trio_print_string TRIO_PROTO((trio_pointer_t ref, TRIO_CONST char *string));
466void trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer));
467
468#ifdef __cplusplus
469} /* extern "C" */
470#endif
471
472#endif /* TRIO_TRIOP_H */
diff --git a/gs/trio/triostr.c b/gs/trio/triostr.c
new file mode 100644
index 000000000..5721b7cb0
--- /dev/null
+++ b/gs/trio/triostr.c
@@ -0,0 +1,2385 @@
1/*************************************************************************
2 *
3 * $Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
18/*************************************************************************
19 * Include files
20 */
21
22#if defined(HAVE_CONFIG_H)
23# include <config.h>
24#endif
25#include <assert.h>
26#include <stdlib.h>
27#include <string.h>
28#include <ctype.h>
29#include "triodef.h"
30#include "triostr.h"
31#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
32# define USE_MATH
33#endif
34#if defined(USE_MATH)
35# include <math.h>
36#endif
37
38/*************************************************************************
39 * Definitions
40 */
41
42#if !defined(TRIO_PUBLIC_STRING)
43# define TRIO_PUBLIC_STRING TRIO_PUBLIC
44#endif
45#if !defined(TRIO_PRIVATE_STRING)
46# define TRIO_PRIVATE_STRING TRIO_PRIVATE
47#endif
48
49#if !defined(NULL)
50# define NULL 0
51#endif
52#if !defined(NIL)
53# define NIL ((char)0)
54#endif
55#if !defined(FALSE)
56# define FALSE (1 == 0)
57# define TRUE (! FALSE)
58#endif
59#if !defined(BOOLEAN_T)
60# define BOOLEAN_T int
61#endif
62
63#if defined(USE_MATH)
64# if defined(PREDEF_STANDARD_C99)
65# if defined(TRIO_COMPILER_DECC)
66# if (TRIO_COMPILER_DECC - 0 > 80000000)
67/*
68 * The OSF/1 runtime that comes with the DECC compiler does not support
69 * hexfloats conversion.
70 */
71# define USE_STRTOD
72# define USE_STRTOF
73# endif
74# else
75# define USE_STRTOD
76# define USE_STRTOF
77# endif
78# else
79# if defined(TRIO_COMPILER_VISUALC)
80# define USE_STRTOD
81# endif
82#endif
83#endif
84
85#if defined(TRIO_PLATFORM_UNIX)
86# if defined(PREDEF_STANDARD_UNIX95)
87# define USE_STRCASECMP
88# define USE_STRNCASECMP
89# endif
90# if defined(TRIO_PLATFORM_SUNOS)
91# define USE_SYS_ERRLIST
92# else
93# define USE_STRERROR
94# endif
95# if defined(TRIO_PLATFORM_QNX)
96# define strcasecmp(x,y) stricmp(x,y)
97# define strncasecmp(x,y,n) strnicmp(x,y,n)
98# endif
99#endif
100
101#if defined(TRIO_PLATFORM_WIN32)
102# define USE_STRCASECMP
103# if defined(TRIO_PLATFORM_WINCE)
104# define strcasecmp(x,y) _stricmp(x,y)
105# else
106# define strcasecmp(x,y) strcmpi(x,y)
107# endif
108#endif
109
110#if !defined(HAVE_CONFIG_H)
111# if !(defined(TRIO_PLATFORM_SUNOS))
112# define HAVE_TOLOWER
113# define HAVE_TOUPPER
114# endif
115#endif
116
117#if defined(USE_MATH) && !defined(TRIO_NO_POWL)
118# if !defined(HAVE_POWL)
119# if defined(PREDEF_STANDARD_C99) \
120 || defined(PREDEF_STANDARD_UNIX03)
121# define HAVE_POWL
122# else
123# if defined(TRIO_COMPILER_VISUALC)
124# if defined(powl)
125# define HAVE_POWL
126# endif
127# endif
128# endif
129# endif
130#endif
131
132#if defined(HAVE_POWL)
133# define trio_powl(x,y) powl((x),(y))
134#else
135# define trio_powl(x,y) pow((double)(x),(double)(y))
136#endif
137
138#if defined(TRIO_FUNC_TO_UPPER) \
139 || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \
140 || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \
141 || defined(TRIO_FUNC_MATCH) \
142 || defined(TRIO_FUNC_TO_LONG_DOUBLE) \
143 || defined(TRIO_FUNC_UPPER)
144# define TRIO_FUNC_INTERNAL_TO_UPPER
145#endif
146
147/*************************************************************************
148 * Structures
149 */
150
151struct _trio_string_t
152{
153 char *content;
154 size_t length;
155 size_t allocated;
156};
157
158/*************************************************************************
159 * Constants
160 */
161
162#if !defined(TRIO_EMBED_STRING)
163static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $";
164#endif
165
166/*************************************************************************
167 * Static String Functions
168 */
169
170#if defined(TRIO_DOCUMENTATION)
171# include "doc/doc_static.h"
172#endif
173/** @addtogroup StaticStrings
174 @{
175*/
176
177/*
178 * internal_duplicate_max
179 */
180#if defined(TRIO_FUNC_DUPLICATE) \
181 || defined(TRIO_FUNC_DUPLICATE_MAX) \
182 || defined(TRIO_FUNC_STRING_DUPLICATE) \
183 || defined(TRIO_FUNC_XSTRING_DUPLICATE)
184
185TRIO_PRIVATE_STRING char *
186internal_duplicate_max
187TRIO_ARGS2((source, size),
188 TRIO_CONST char *source,
189 size_t size)
190{
191 char *target;
192
193 assert(source);
194
195 /* Make room for string plus a terminating zero */
196 size++;
197 target = trio_create(size);
198 if (target)
199 {
200 trio_copy_max(target, size, source);
201 }
202 return target;
203}
204
205#endif
206
207/*
208 * internal_string_alloc
209 */
210#if defined(TRIO_FUNC_STRING_CREATE) \
211 || defined(TRIO_FUNC_STRING_DUPLICATE) \
212 || defined(TRIO_FUNC_XSTRING_DUPLICATE)
213
214TRIO_PRIVATE_STRING trio_string_t *
215internal_string_alloc(TRIO_NOARGS)
216{
217 trio_string_t *self;
218
219 self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
220 if (self)
221 {
222 self->content = NULL;
223 self->length = 0;
224 self->allocated = 0;
225 }
226 return self;
227}
228
229#endif
230
231/*
232 * internal_string_grow
233 *
234 * The size of the string will be increased by 'delta' characters. If
235 * 'delta' is zero, the size will be doubled.
236 */
237#if defined(TRIO_FUNC_STRING_CREATE) \
238 || defined(TRIO_FUNC_STRING_APPEND) \
239 || defined(TRIO_FUNC_XSTRING_APPEND) \
240 || defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
241
242TRIO_PRIVATE_STRING BOOLEAN_T
243internal_string_grow
244TRIO_ARGS2((self, delta),
245 trio_string_t *self,
246 size_t delta)
247{
248 BOOLEAN_T status = FALSE;
249 char *new_content;
250 size_t new_size;
251
252 new_size = (delta == 0)
253 ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
254 : self->allocated + delta;
255
256 new_content = (char *)TRIO_REALLOC(self->content, new_size);
257 if (new_content)
258 {
259 self->content = new_content;
260 self->allocated = new_size;
261 status = TRUE;
262 }
263 return status;
264}
265
266#endif
267
268/*
269 * internal_string_grow_to
270 *
271 * The size of the string will be increased to 'length' plus one characters.
272 * If 'length' is less than the original size, the original size will be
273 * used (that is, the size of the string is never decreased).
274 */
275#if defined(TRIO_FUNC_STRING_APPEND) \
276 || defined(TRIO_FUNC_XSTRING_APPEND) \
277 || defined(TRIO_FUNC_XSTRING_APPEND_MAX)
278
279TRIO_PRIVATE_STRING BOOLEAN_T
280internal_string_grow_to
281TRIO_ARGS2((self, length),
282 trio_string_t *self,
283 size_t length)
284{
285 length++; /* Room for terminating zero */
286 return (self->allocated < length)
287 ? internal_string_grow(self, length - self->allocated)
288 : TRUE;
289}
290
291#endif
292
293#if defined(TRIO_FUNC_INTERNAL_TO_UPPER)
294
295TRIO_PRIVATE_STRING TRIO_INLINE int
296internal_to_upper
297TRIO_ARGS1((source),
298 int source)
299{
300# if defined(HAVE_TOUPPER)
301
302 return toupper(source);
303
304# else
305
306 /* Does not handle locales or non-contiguous alphabetic characters */
307 return ((source >= (int)'a') && (source <= (int)'z'))
308 ? source - 'a' + 'A'
309 : source;
310
311# endif
312}
313
314#endif
315
316
317/**
318 Create new string.
319
320 @param size Size of new string.
321 @return Pointer to string, or NULL if allocation failed.
322*/
323#if defined(TRIO_FUNC_CREATE)
324
325TRIO_PUBLIC_STRING char *
326trio_create
327TRIO_ARGS1((size),
328 size_t size)
329{
330 return (char *)TRIO_MALLOC(size);
331}
332
333#endif
334
335/**
336 Destroy string.
337
338 @param string String to be freed.
339*/
340#if defined(TRIO_FUNC_DESTROY)
341
342TRIO_PUBLIC_STRING void
343trio_destroy
344TRIO_ARGS1((string),
345 char *string)
346{
347 if (string)
348 {
349 TRIO_FREE(string);
350 }
351}
352
353#endif
354
355/**
356 Count the number of characters in a string.
357
358 @param string String to measure.
359 @return Number of characters in @p string.
360*/
361#if defined(TRIO_FUNC_LENGTH)
362
363TRIO_PUBLIC_STRING size_t
364trio_length
365TRIO_ARGS1((string),
366 TRIO_CONST char *string)
367{
368 return strlen(string);
369}
370
371#endif
372
373/**
374 Count at most @p max characters in a string.
375
376 @param string String to measure.
377 @param max Maximum number of characters to count.
378 @return The maximum value of @p max and number of characters in @p string.
379*/
380#if defined(TRIO_FUNC_LENGTH_MAX)
381
382TRIO_PUBLIC_STRING size_t
383trio_length_max
384TRIO_ARGS2((string, max),
385 TRIO_CONST char *string,
386 size_t max)
387{
388 size_t i;
389
390 for (i = 0; i < max; ++i)
391 {
392 if (string[i] == 0)
393 break;
394 }
395 return i;
396}
397
398#endif
399
400/**
401 Append @p source at the end of @p target.
402
403 @param target Target string.
404 @param source Source string.
405 @return Boolean value indicating success or failure.
406
407 @pre @p target must point to a memory chunk with sufficient room to
408 contain the @p target string and @p source string.
409 @pre No boundary checking is performed, so insufficient memory will
410 result in a buffer overrun.
411 @post @p target will be zero terminated.
412*/
413#if defined(TRIO_FUNC_APPEND)
414
415TRIO_PUBLIC_STRING int
416trio_append
417TRIO_ARGS2((target, source),
418 char *target,
419 TRIO_CONST char *source)
420{
421 assert(target);
422 assert(source);
423
424 return (strcat(target, source) != NULL);
425}
426
427#endif
428
429/**
430 Append at most @p max characters from @p source to @p target.
431
432 @param target Target string.
433 @param max Maximum number of characters to append.
434 @param source Source string.
435 @return Boolean value indicating success or failure.
436
437 @pre @p target must point to a memory chuck with sufficient room to
438 contain the @p target string and the @p source string (at most @p max
439 characters).
440 @pre No boundary checking is performed, so insufficient memory will
441 result in a buffer overrun.
442 @post @p target will be zero terminated.
443*/
444#if defined(TRIO_FUNC_APPEND_MAX)
445
446TRIO_PUBLIC_STRING int
447trio_append_max
448TRIO_ARGS3((target, max, source),
449 char *target,
450 size_t max,
451 TRIO_CONST char *source)
452{
453 size_t length;
454
455 assert(target);
456 assert(source);
457
458 length = trio_length(target);
459
460 if (max > length)
461 {
462 strncat(target, source, max - length - 1);
463 }
464 return TRUE;
465}
466
467#endif
468
469/**
470 Determine if a string contains a substring.
471
472 @param string String to be searched.
473 @param substring String to be found.
474 @return Boolean value indicating success or failure.
475*/
476#if defined(TRIO_FUNC_CONTAINS)
477
478TRIO_PUBLIC_STRING int
479trio_contains
480TRIO_ARGS2((string, substring),
481 TRIO_CONST char *string,
482 TRIO_CONST char *substring)
483{
484 assert(string);
485 assert(substring);
486
487 return (0 != strstr(string, substring));
488}
489
490#endif
491
492/**
493 Copy @p source to @p target.
494
495 @param target Target string.
496 @param source Source string.
497 @return Boolean value indicating success or failure.
498
499 @pre @p target must point to a memory chunk with sufficient room to
500 contain the @p source string.
501 @pre No boundary checking is performed, so insufficient memory will
502 result in a buffer overrun.
503 @post @p target will be zero terminated.
504*/
505#if defined(TRIO_FUNC_COPY)
506
507TRIO_PUBLIC_STRING int
508trio_copy
509TRIO_ARGS2((target, source),
510 char *target,
511 TRIO_CONST char *source)
512{
513 assert(target);
514 assert(source);
515
516 (void)strcpy(target, source);
517 return TRUE;
518}
519
520#endif
521
522/**
523 Copy at most @p max - 1 characters from @p source to @p target.
524
525 @param target Target string.
526 @param max Maximum number of characters to append (one of which is
527 a NUL terminator). In other words @p source must point to at least
528 @p max - 1 bytes, but @p target must point to at least @p max
529 bytes.
530 @param source Source string.
531 @return Boolean value indicating success or failure.
532
533 @pre @p target must point to a memory chunk with sufficient room to
534 contain the @p source string and a NUL terminator (at most @p max
535 bytes total).
536 @pre No boundary checking is performed, so insufficient memory will
537 result in a buffer overrun.
538 @post @p target will be zero terminated.
539*/
540#if defined(TRIO_FUNC_COPY_MAX)
541
542TRIO_PUBLIC_STRING int
543trio_copy_max
544TRIO_ARGS3((target, max, source),
545 char *target,
546 size_t max,
547 TRIO_CONST char *source)
548{
549 assert(target);
550 assert(source);
551 assert(max > 0); /* Includes != 0 */
552
553 (void)strncpy(target, source, max - 1);
554 target[max - 1] = (char)0;
555 return TRUE;
556}
557
558#endif
559
560/**
561 Duplicate @p source.
562
563 @param source Source string.
564 @return A copy of the @p source string.
565
566 @post @p target will be zero terminated.
567*/
568#if defined(TRIO_FUNC_DUPLICATE)
569
570TRIO_PUBLIC_STRING char *
571trio_duplicate
572TRIO_ARGS1((source),
573 TRIO_CONST char *source)
574{
575 return internal_duplicate_max(source, trio_length(source));
576}
577
578#endif
579
580/**
581 Duplicate at most @p max characters of @p source.
582
583 @param source Source string.
584 @param max Maximum number of characters to duplicate.
585 @return A copy of the @p source string.
586
587 @post @p target will be zero terminated.
588*/
589#if defined(TRIO_FUNC_DUPLICATE_MAX)
590
591TRIO_PUBLIC_STRING char *
592trio_duplicate_max
593TRIO_ARGS2((source, max),
594 TRIO_CONST char *source,
595 size_t max)
596{
597 size_t length;
598
599 assert(source);
600 assert(max > 0);
601
602 length = trio_length(source);
603 if (length > max)
604 {
605 length = max;
606 }
607 return internal_duplicate_max(source, length);
608}
609
610#endif
611
612/**
613 Compare if two strings are equal.
614
615 @param first First string.
616 @param second Second string.
617 @return Boolean indicating whether the two strings are equal or not.
618
619 Case-insensitive comparison.
620*/
621#if defined(TRIO_FUNC_EQUAL)
622
623TRIO_PUBLIC_STRING int
624trio_equal
625TRIO_ARGS2((first, second),
626 TRIO_CONST char *first,
627 TRIO_CONST char *second)
628{
629 assert(first);
630 assert(second);
631
632 if ((first != NULL) && (second != NULL))
633 {
634# if defined(USE_STRCASECMP)
635 return (0 == strcasecmp(first, second));
636# else
637 while ((*first != NIL) && (*second != NIL))
638 {
639 if (internal_to_upper(*first) != internal_to_upper(*second))
640 {
641 break;
642 }
643 first++;
644 second++;
645 }
646 return ((*first == NIL) && (*second == NIL));
647# endif
648 }
649 return FALSE;
650}
651
652#endif
653
654/**
655 Compare if two strings are equal.
656
657 @param first First string.
658 @param second Second string.
659 @return Boolean indicating whether the two strings are equal or not.
660
661 Case-sensitive comparison.
662*/
663#if defined(TRIO_FUNC_EQUAL_CASE)
664
665TRIO_PUBLIC_STRING int
666trio_equal_case
667TRIO_ARGS2((first, second),
668 TRIO_CONST char *first,
669 TRIO_CONST char *second)
670{
671 assert(first);
672 assert(second);
673
674 if ((first != NULL) && (second != NULL))
675 {
676 return (0 == strcmp(first, second));
677 }
678 return FALSE;
679}
680
681#endif
682
683/**
684 Compare if two strings up until the first @p max characters are equal.
685
686 @param first First string.
687 @param max Maximum number of characters to compare.
688 @param second Second string.
689 @return Boolean indicating whether the two strings are equal or not.
690
691 Case-sensitive comparison.
692*/
693#if defined(TRIO_FUNC_EQUAL_CASE_MAX)
694
695TRIO_PUBLIC_STRING int
696trio_equal_case_max
697TRIO_ARGS3((first, max, second),
698 TRIO_CONST char *first,
699 size_t max,
700 TRIO_CONST char *second)
701{
702 assert(first);
703 assert(second);
704
705 if ((first != NULL) && (second != NULL))
706 {
707 return (0 == strncmp(first, second, max));
708 }
709 return FALSE;
710}
711
712#endif
713
714/**
715 Compare if two strings are equal.
716
717 @param first First string.
718 @param second Second string.
719 @return Boolean indicating whether the two strings are equal or not.
720
721 Collating characters are considered equal.
722*/
723#if defined(TRIO_FUNC_EQUAL_LOCALE)
724
725TRIO_PUBLIC_STRING int
726trio_equal_locale
727TRIO_ARGS2((first, second),
728 TRIO_CONST char *first,
729 TRIO_CONST char *second)
730{
731 assert(first);
732 assert(second);
733
734# if defined(LC_COLLATE)
735 return (strcoll(first, second) == 0);
736# else
737 return trio_equal(first, second);
738# endif
739}
740
741#endif
742
743/**
744 Compare if two strings up until the first @p max characters are equal.
745
746 @param first First string.
747 @param max Maximum number of characters to compare.
748 @param second Second string.
749 @return Boolean indicating whether the two strings are equal or not.
750
751 Case-insensitive comparison.
752*/
753#if defined(TRIO_FUNC_EQUAL_MAX)
754
755TRIO_PUBLIC_STRING int
756trio_equal_max
757TRIO_ARGS3((first, max, second),
758 TRIO_CONST char *first,
759 size_t max,
760 TRIO_CONST char *second)
761{
762 assert(first);
763 assert(second);
764
765 if ((first != NULL) && (second != NULL))
766 {
767# if defined(USE_STRNCASECMP)
768 return (0 == strncasecmp(first, second, max));
769# else
770 /* Not adequately tested yet */
771 size_t cnt = 0;
772 while ((*first != NIL) && (*second != NIL) && (cnt <= max))
773 {
774 if (internal_to_upper(*first) != internal_to_upper(*second))
775 {
776 break;
777 }
778 first++;
779 second++;
780 cnt++;
781 }
782 return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
783# endif
784 }
785 return FALSE;
786}
787
788#endif
789
790/**
791 Provide a textual description of an error code (errno).
792
793 @param error_number Error number.
794 @return Textual description of @p error_number.
795*/
796#if defined(TRIO_FUNC_ERROR)
797
798TRIO_PUBLIC_STRING TRIO_CONST char *
799trio_error
800TRIO_ARGS1((error_number),
801 int error_number)
802{
803# if defined(USE_STRERROR)
804
805 return strerror(error_number);
806
807# else
808# if defined(USE_SYS_ERRLIST)
809
810 extern char *sys_errlist[];
811 extern int sys_nerr;
812
813 return ((error_number < 0) || (error_number >= sys_nerr))
814 ? "unknown"
815 : sys_errlist[error_number];
816
817# else
818
819 return "unknown";
820
821# endif
822# endif
823}
824
825#endif
826
827/**
828 Format the date/time according to @p format.
829
830 @param target Target string.
831 @param max Maximum number of characters to format.
832 @param format Formatting string.
833 @param datetime Date/time structure.
834 @return Number of formatted characters.
835
836 The formatting string accepts the same specifiers as the standard C
837 function strftime.
838*/
839#if defined(TRIO_FUNC_FORMAT_DATE_MAX)
840
841TRIO_PUBLIC_STRING size_t
842trio_format_date_max
843TRIO_ARGS4((target, max, format, datetime),
844 char *target,
845 size_t max,
846 TRIO_CONST char *format,
847 TRIO_CONST struct tm *datetime)
848{
849 assert(target);
850 assert(format);
851 assert(datetime);
852 assert(max > 0);
853
854 return strftime(target, max, format, datetime);
855}
856
857#endif
858
859/**
860 Calculate a hash value for a string.
861
862 @param string String to be calculated on.
863 @param type Hash function.
864 @return Calculated hash value.
865
866 @p type can be one of the following
867 @li @c TRIO_HASH_PLAIN Plain hash function.
868*/
869#if defined(TRIO_FUNC_HASH)
870
871TRIO_PUBLIC_STRING unsigned long
872trio_hash
873TRIO_ARGS2((string, type),
874 TRIO_CONST char *string,
875 int type)
876{
877 unsigned long value = 0L;
878 char ch;
879
880 assert(string);
881
882 switch (type)
883 {
884 case TRIO_HASH_PLAIN:
885 while ( (ch = *string++) != NIL )
886 {
887 value *= 31;
888 value += (unsigned long)ch;
889 }
890 break;
891 default:
892 assert(FALSE);
893 break;
894 }
895 return value;
896}
897
898#endif
899
900/**
901 Find first occurrence of a character in a string.
902
903 @param string String to be searched.
904 @param character Character to be found.
905 @return A pointer to the found character, or NULL if character was not found.
906 */
907#if defined(TRIO_FUNC_INDEX)
908
909TRIO_PUBLIC_STRING char *
910trio_index
911TRIO_ARGS2((string, character),
912 TRIO_CONST char *string,
913 int character)
914{
915 assert(string);
916
917 return strchr(string, character);
918}
919
920#endif
921
922/**
923 Find last occurrence of a character in a string.
924
925 @param string String to be searched.
926 @param character Character to be found.
927 @return A pointer to the found character, or NULL if character was not found.
928 */
929#if defined(TRIO_FUNC_INDEX_LAST)
930
931TRIO_PUBLIC_STRING char *
932trio_index_last
933TRIO_ARGS2((string, character),
934 TRIO_CONST char *string,
935 int character)
936{
937 assert(string);
938
939 return strchr(string, character);
940}
941
942#endif
943
944/**
945 Convert the alphabetic letters in the string to lower-case.
946
947 @param target String to be converted.
948 @return Number of processed characters (converted or not).
949*/
950#if defined(TRIO_FUNC_LOWER)
951
952TRIO_PUBLIC_STRING int
953trio_lower
954TRIO_ARGS1((target),
955 char *target)
956{
957 assert(target);
958
959 return trio_span_function(target, target, trio_to_lower);
960}
961
962#endif
963
964/**
965 Compare two strings using wildcards.
966
967 @param string String to be searched.
968 @param pattern Pattern, including wildcards, to search for.
969 @return Boolean value indicating success or failure.
970
971 Case-insensitive comparison.
972
973 The following wildcards can be used
974 @li @c * Match any number of characters.
975 @li @c ? Match a single character.
976*/
977#if defined(TRIO_FUNC_MATCH)
978
979TRIO_PUBLIC_STRING int
980trio_match
981TRIO_ARGS2((string, pattern),
982 TRIO_CONST char *string,
983 TRIO_CONST char *pattern)
984{
985 assert(string);
986 assert(pattern);
987
988 for (; ('*' != *pattern); ++pattern, ++string)
989 {
990 if (NIL == *string)
991 {
992 return (NIL == *pattern);
993 }
994 if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern))
995 && ('?' != *pattern))
996 {
997 return FALSE;
998 }
999 }
1000 /* two-line patch to prevent *too* much recursiveness: */
1001 while ('*' == pattern[1])
1002 pattern++;
1003
1004 do
1005 {
1006 if ( trio_match(string, &pattern[1]) )
1007 {
1008 return TRUE;
1009 }
1010 }
1011 while (*string++);
1012
1013 return FALSE;
1014}
1015
1016#endif
1017
1018/**
1019 Compare two strings using wildcards.
1020
1021 @param string String to be searched.
1022 @param pattern Pattern, including wildcards, to search for.
1023 @return Boolean value indicating success or failure.
1024
1025 Case-sensitive comparison.
1026
1027 The following wildcards can be used
1028 @li @c * Match any number of characters.
1029 @li @c ? Match a single character.
1030*/
1031#if defined(TRIO_FUNC_MATCH_CASE)
1032
1033TRIO_PUBLIC_STRING int
1034trio_match_case
1035TRIO_ARGS2((string, pattern),
1036 TRIO_CONST char *string,
1037 TRIO_CONST char *pattern)
1038{
1039 assert(string);
1040 assert(pattern);
1041
1042 for (; ('*' != *pattern); ++pattern, ++string)
1043 {
1044 if (NIL == *string)
1045 {
1046 return (NIL == *pattern);
1047 }
1048 if ((*string != *pattern)
1049 && ('?' != *pattern))
1050 {
1051 return FALSE;
1052 }
1053 }
1054 /* two-line patch to prevent *too* much recursiveness: */
1055 while ('*' == pattern[1])
1056 pattern++;
1057
1058 do
1059 {
1060 if ( trio_match_case(string, &pattern[1]) )
1061 {
1062 return TRUE;
1063 }
1064 }
1065 while (*string++);
1066
1067 return FALSE;
1068}
1069
1070#endif
1071
1072/**
1073 Execute a function on each character in string.
1074
1075 @param target Target string.
1076 @param source Source string.
1077 @param Function Function to be executed.
1078 @return Number of processed characters.
1079*/
1080#if defined(TRIO_FUNC_SPAN_FUNCTION)
1081
1082TRIO_PUBLIC_STRING size_t
1083trio_span_function
1084TRIO_ARGS3((target, source, Function),
1085 char *target,
1086 TRIO_CONST char *source,
1087 int (*Function) TRIO_PROTO((int)))
1088{
1089 size_t count = 0;
1090
1091 assert(target);
1092 assert(source);
1093 assert(Function);
1094
1095 while (*source != NIL)
1096 {
1097 *target++ = Function(*source++);
1098 count++;
1099 }
1100 return count;
1101}
1102
1103#endif
1104
1105/**
1106 Search for a substring in a string.
1107
1108 @param string String to be searched.
1109 @param substring String to be found.
1110 @return Pointer to first occurrence of @p substring in @p string, or NULL
1111 if no match was found.
1112*/
1113#if defined(TRIO_FUNC_SUBSTRING)
1114
1115TRIO_PUBLIC_STRING char *
1116trio_substring
1117TRIO_ARGS2((string, substring),
1118 TRIO_CONST char *string,
1119 TRIO_CONST char *substring)
1120{
1121 assert(string);
1122 assert(substring);
1123
1124 return strstr(string, substring);
1125}
1126
1127#endif
1128
1129/**
1130 Search for a substring in the first @p max characters of a string.
1131
1132 @param string String to be searched.
1133 @param max Maximum characters to be searched.
1134 @param substring String to be found.
1135 @return Pointer to first occurrence of @p substring in @p string, or NULL
1136 if no match was found.
1137*/
1138#if defined(TRIO_FUNC_SUBSTRING_MAX)
1139
1140TRIO_PUBLIC_STRING char *
1141trio_substring_max
1142TRIO_ARGS3((string, max, substring),
1143 TRIO_CONST char *string,
1144 size_t max,
1145 TRIO_CONST char *substring)
1146{
1147 size_t count;
1148 size_t size;
1149 char *result = NULL;
1150
1151 assert(string);
1152 assert(substring);
1153
1154 size = trio_length(substring);
1155 if (size <= max)
1156 {
1157 for (count = 0; count <= max - size; count++)
1158 {
1159 if (trio_equal_max(substring, size, &string[count]))
1160 {
1161 result = (char *)&string[count];
1162 break;
1163 }
1164 }
1165 }
1166 return result;
1167}
1168
1169#endif
1170
1171/**
1172 Tokenize string.
1173
1174 @param string String to be tokenized.
1175 @param delimiters String containing list of delimiting characters.
1176 @return Start of new token.
1177
1178 @warning @p string will be destroyed.
1179*/
1180#if defined(TRIO_FUNC_TOKENIZE)
1181
1182TRIO_PUBLIC_STRING char *
1183trio_tokenize
1184TRIO_ARGS2((string, delimiters),
1185 char *string,
1186 TRIO_CONST char *delimiters)
1187{
1188 assert(delimiters);
1189
1190 return strtok(string, delimiters);
1191}
1192
1193#endif
1194
1195/**
1196 Convert string to floating-point number.
1197
1198 @param source String to be converted.
1199 @param endp Pointer to end of the converted string.
1200 @return A floating-point number.
1201
1202 The following Extended Backus-Naur form is used
1203 @verbatim
1204 double ::= [ <sign> ]
1205 ( <number> |
1206 <number> <decimal_point> <number> |
1207 <decimal_point> <number> )
1208 [ <exponential> [ <sign> ] <number> ]
1209 number ::= 1*( <digit> )
1210 digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
1211 exponential ::= ( 'e' | 'E' )
1212 sign ::= ( '-' | '+' )
1213 decimal_point ::= '.'
1214 @endverbatim
1215*/
1216#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
1217
1218/* FIXME: Add EBNF for hex-floats */
1219TRIO_PUBLIC_STRING trio_long_double_t
1220trio_to_long_double
1221TRIO_ARGS2((source, endp),
1222 TRIO_CONST char *source,
1223 char **endp)
1224{
1225# if defined(USE_STRTOLD)
1226 return strtold(source, endp);
1227# else
1228 int isNegative = FALSE;
1229 int isExponentNegative = FALSE;
1230 trio_long_double_t integer = 0.0;
1231 trio_long_double_t fraction = 0.0;
1232 unsigned long exponent = 0;
1233 trio_long_double_t base;
1234 trio_long_double_t fracdiv = 1.0;
1235 trio_long_double_t value = 0.0;
1236
1237 /* First try hex-floats */
1238 if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
1239 {
1240 base = 16.0;
1241 source += 2;
1242 while (isxdigit((int)*source))
1243 {
1244 integer *= base;
1245 integer += (isdigit((int)*source)
1246 ? (*source - '0')
1247 : 10 + (internal_to_upper((int)*source) - 'A'));
1248 source++;
1249 }
1250 if (*source == '.')
1251 {
1252 source++;
1253 while (isxdigit((int)*source))
1254 {
1255 fracdiv /= base;
1256 fraction += fracdiv * (isdigit((int)*source)
1257 ? (*source - '0')
1258 : 10 + (internal_to_upper((int)*source) - 'A'));
1259 source++;
1260 }
1261 if ((*source == 'p') || (*source == 'P'))
1262 {
1263 source++;
1264 if ((*source == '+') || (*source == '-'))
1265 {
1266 isExponentNegative = (*source == '-');
1267 source++;
1268 }
1269 while (isdigit((int)*source))
1270 {
1271 exponent *= 10;
1272 exponent += (*source - '0');
1273 source++;
1274 }
1275 }
1276 }
1277 /* For later use with exponent */
1278 base = 2.0;
1279 }
1280 else /* Then try normal decimal floats */
1281 {
1282 base = 10.0;
1283 isNegative = (*source == '-');
1284 /* Skip sign */
1285 if ((*source == '+') || (*source == '-'))
1286 source++;
1287
1288 /* Integer part */
1289 while (isdigit((int)*source))
1290 {
1291 integer *= base;
1292 integer += (*source - '0');
1293 source++;
1294 }
1295
1296 if (*source == '.')
1297 {
1298 source++; /* skip decimal point */
1299 while (isdigit((int)*source))
1300 {
1301 fracdiv /= base;
1302 fraction += (*source - '0') * fracdiv;
1303 source++;
1304 }
1305 }
1306 if ((*source == 'e')
1307 || (*source == 'E')
1308# if TRIO_MICROSOFT
1309 || (*source == 'd')
1310 || (*source == 'D')
1311# endif
1312 )
1313 {
1314 source++; /* Skip exponential indicator */
1315 isExponentNegative = (*source == '-');
1316 if ((*source == '+') || (*source == '-'))
1317 source++;
1318 while (isdigit((int)*source))
1319 {
1320 exponent *= (int)base;
1321 exponent += (*source - '0');
1322 source++;
1323 }
1324 }
1325 }
1326
1327 value = integer + fraction;
1328 if (exponent != 0)
1329 {
1330 if (isExponentNegative)
1331 value /= trio_powl(base, (trio_long_double_t)exponent);
1332 else
1333 value *= trio_powl(base, (trio_long_double_t)exponent);
1334 }
1335 if (isNegative)
1336 value = -value;
1337
1338 if (endp)
1339 *endp = (char *)source;
1340 return value;
1341# endif
1342}
1343
1344#endif
1345
1346/**
1347 Convert string to floating-point number.
1348
1349 @param source String to be converted.
1350 @param endp Pointer to end of the converted string.
1351 @return A floating-point number.
1352
1353 See @ref trio_to_long_double.
1354*/
1355#if defined(TRIO_FUNC_TO_DOUBLE)
1356
1357TRIO_PUBLIC_STRING double
1358trio_to_double
1359TRIO_ARGS2((source, endp),
1360 TRIO_CONST char *source,
1361 char **endp)
1362{
1363#if defined(USE_STRTOD)
1364 return strtod(source, endp);
1365#else
1366 return (double)trio_to_long_double(source, endp);
1367#endif
1368}
1369
1370#endif
1371
1372/**
1373 Convert string to floating-point number.
1374
1375 @param source String to be converted.
1376 @param endp Pointer to end of the converted string.
1377 @return A floating-point number.
1378
1379 See @ref trio_to_long_double.
1380*/
1381#if defined(TRIO_FUNC_TO_FLOAT)
1382
1383TRIO_PUBLIC_STRING float
1384trio_to_float
1385TRIO_ARGS2((source, endp),
1386 TRIO_CONST char *source,
1387 char **endp)
1388{
1389# if defined(USE_STRTOF)
1390 return strtof(source, endp);
1391# else
1392 return (float)trio_to_long_double(source, endp);
1393# endif
1394}
1395
1396#endif
1397
1398/**
1399 Convert string to signed integer.
1400
1401 @param string String to be converted.
1402 @param endp Pointer to end of converted string.
1403 @param base Radix number of number.
1404*/
1405#if defined(TRIO_FUNC_TO_LONG)
1406
1407TRIO_PUBLIC_STRING long
1408trio_to_long
1409TRIO_ARGS3((string, endp, base),
1410 TRIO_CONST char *string,
1411 char **endp,
1412 int base)
1413{
1414 assert(string);
1415 assert((base >= 2) && (base <= 36));
1416
1417 return strtol(string, endp, base);
1418}
1419
1420#endif
1421
1422/**
1423 Convert one alphabetic letter to lower-case.
1424
1425 @param source The letter to be converted.
1426 @return The converted letter.
1427*/
1428#if defined(TRIO_FUNC_TO_LOWER)
1429
1430TRIO_PUBLIC_STRING int
1431trio_to_lower
1432TRIO_ARGS1((source),
1433 int source)
1434{
1435# if defined(HAVE_TOLOWER)
1436
1437 return tolower(source);
1438
1439# else
1440
1441 /* Does not handle locales or non-contiguous alphabetic characters */
1442 return ((source >= (int)'A') && (source <= (int)'Z'))
1443 ? source - 'A' + 'a'
1444 : source;
1445
1446# endif
1447}
1448
1449#endif
1450
1451/**
1452 Convert string to unsigned integer.
1453
1454 @param string String to be converted.
1455 @param endp Pointer to end of converted string.
1456 @param base Radix number of number.
1457*/
1458#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
1459
1460TRIO_PUBLIC_STRING unsigned long
1461trio_to_unsigned_long
1462TRIO_ARGS3((string, endp, base),
1463 TRIO_CONST char *string,
1464 char **endp,
1465 int base)
1466{
1467 assert(string);
1468 assert((base >= 2) && (base <= 36));
1469
1470 return strtoul(string, endp, base);
1471}
1472
1473#endif
1474
1475/**
1476 Convert one alphabetic letter to upper-case.
1477
1478 @param source The letter to be converted.
1479 @return The converted letter.
1480*/
1481#if defined(TRIO_FUNC_TO_UPPER)
1482
1483TRIO_PUBLIC_STRING int
1484trio_to_upper
1485TRIO_ARGS1((source),
1486 int source)
1487{
1488 return internal_to_upper(source);
1489}
1490
1491#endif
1492
1493/**
1494 Convert the alphabetic letters in the string to upper-case.
1495
1496 @param target The string to be converted.
1497 @return The number of processed characters (converted or not).
1498*/
1499#if defined(TRIO_FUNC_UPPER)
1500
1501TRIO_PUBLIC_STRING int
1502trio_upper
1503TRIO_ARGS1((target),
1504 char *target)
1505{
1506 assert(target);
1507
1508 return trio_span_function(target, target, internal_to_upper);
1509}
1510
1511#endif
1512
1513/** @} End of StaticStrings */
1514
1515
1516/*************************************************************************
1517 * Dynamic String Functions
1518 */
1519
1520#if defined(TRIO_DOCUMENTATION)
1521# include "doc/doc_dynamic.h"
1522#endif
1523/** @addtogroup DynamicStrings
1524 @{
1525*/
1526
1527/**
1528 Create a new dynamic string.
1529
1530 @param initial_size Initial size of the buffer.
1531 @return Newly allocated dynamic string, or NULL if memory allocation failed.
1532*/
1533#if defined(TRIO_FUNC_STRING_CREATE)
1534
1535TRIO_PUBLIC_STRING trio_string_t *
1536trio_string_create
1537TRIO_ARGS1((initial_size),
1538 int initial_size)
1539{
1540 trio_string_t *self;
1541
1542 self = internal_string_alloc();
1543 if (self)
1544 {
1545 if (internal_string_grow(self,
1546 (size_t)((initial_size > 0) ? initial_size : 1)))
1547 {
1548 self->content[0] = (char)0;
1549 self->allocated = initial_size;
1550 }
1551 else
1552 {
1553 trio_string_destroy(self);
1554 self = NULL;
1555 }
1556 }
1557 return self;
1558}
1559
1560#endif
1561
1562/**
1563 Deallocate the dynamic string and its contents.
1564
1565 @param self Dynamic string
1566*/
1567#if defined(TRIO_FUNC_STRING_DESTROY)
1568
1569TRIO_PUBLIC_STRING void
1570trio_string_destroy
1571TRIO_ARGS1((self),
1572 trio_string_t *self)
1573{
1574 assert(self);
1575
1576 if (self)
1577 {
1578 trio_destroy(self->content);
1579 TRIO_FREE(self);
1580 }
1581}
1582
1583#endif
1584
1585/**
1586 Get a pointer to the content.
1587
1588 @param self Dynamic string.
1589 @param offset Offset into content.
1590 @return Pointer to the content.
1591
1592 @p Offset can be zero, positive, or negative. If @p offset is zero,
1593 then the start of the content will be returned. If @p offset is positive,
1594 then a pointer to @p offset number of characters from the beginning of the
1595 content is returned. If @p offset is negative, then a pointer to @p offset
1596 number of characters from the ending of the string, starting at the
1597 terminating zero, is returned.
1598*/
1599#if defined(TRIO_FUNC_STRING_GET)
1600
1601TRIO_PUBLIC_STRING char *
1602trio_string_get
1603TRIO_ARGS2((self, offset),
1604 trio_string_t *self,
1605 int offset)
1606{
1607 char *result = NULL;
1608
1609 assert(self);
1610
1611 if (self->content != NULL)
1612 {
1613 if (self->length == 0)
1614 {
1615 (void)trio_string_length(self);
1616 }
1617 if (offset >= 0)
1618 {
1619 if (offset > (int)self->length)
1620 {
1621 offset = self->length;
1622 }
1623 }
1624 else
1625 {
1626 offset += self->length + 1;
1627 if (offset < 0)
1628 {
1629 offset = 0;
1630 }
1631 }
1632 result = &(self->content[offset]);
1633 }
1634 return result;
1635}
1636
1637#endif
1638
1639/**
1640 Extract the content.
1641
1642 @param self Dynamic String
1643 @return Content of dynamic string.
1644
1645 The content is removed from the dynamic string. This enables destruction
1646 of the dynamic string without deallocation of the content.
1647*/
1648#if defined(TRIO_FUNC_STRING_EXTRACT)
1649
1650TRIO_PUBLIC_STRING char *
1651trio_string_extract
1652TRIO_ARGS1((self),
1653 trio_string_t *self)
1654{
1655 char *result;
1656
1657 assert(self);
1658
1659 result = self->content;
1660 /* FIXME: Allocate new empty buffer? */
1661 self->content = NULL;
1662 self->length = self->allocated = 0;
1663 return result;
1664}
1665
1666#endif
1667
1668/**
1669 Set the content of the dynamic string.
1670
1671 @param self Dynamic String
1672 @param buffer The new content.
1673
1674 Sets the content of the dynamic string to a copy @p buffer.
1675 An existing content will be deallocated first, if necessary.
1676
1677 @remark
1678 This function will make a copy of @p buffer.
1679 You are responsible for deallocating @p buffer yourself.
1680*/
1681#if defined(TRIO_FUNC_XSTRING_SET)
1682
1683TRIO_PUBLIC_STRING void
1684trio_xstring_set
1685TRIO_ARGS2((self, buffer),
1686 trio_string_t *self,
1687 char *buffer)
1688{
1689 assert(self);
1690
1691 trio_destroy(self->content);
1692 self->content = trio_duplicate(buffer);
1693}
1694
1695#endif
1696
1697/*
1698 * trio_string_size
1699 */
1700#if defined(TRIO_FUNC_STRING_SIZE)
1701
1702TRIO_PUBLIC_STRING int
1703trio_string_size
1704TRIO_ARGS1((self),
1705 trio_string_t *self)
1706{
1707 assert(self);
1708
1709 return self->allocated;
1710}
1711
1712#endif
1713
1714/*
1715 * trio_string_terminate
1716 */
1717#if defined(TRIO_FUNC_STRING_TERMINATE)
1718
1719TRIO_PUBLIC_STRING void
1720trio_string_terminate
1721TRIO_ARGS1((self),
1722 trio_string_t *self)
1723{
1724 trio_xstring_append_char(self, 0);
1725}
1726
1727#endif
1728
1729/**
1730 Append the second string to the first.
1731
1732 @param self Dynamic string to be modified.
1733 @param other Dynamic string to copy from.
1734 @return Boolean value indicating success or failure.
1735*/
1736#if defined(TRIO_FUNC_STRING_APPEND)
1737
1738TRIO_PUBLIC_STRING int
1739trio_string_append
1740TRIO_ARGS2((self, other),
1741 trio_string_t *self,
1742 trio_string_t *other)
1743{
1744 size_t length;
1745
1746 assert(self);
1747 assert(other);
1748
1749 length = self->length + other->length;
1750 if (!internal_string_grow_to(self, length))
1751 goto error;
1752 trio_copy(&self->content[self->length], other->content);
1753 self->length = length;
1754 return TRUE;
1755
1756 error:
1757 return FALSE;
1758}
1759
1760#endif
1761
1762
1763/*
1764 * trio_xstring_append
1765 */
1766#if defined(TRIO_FUNC_XSTRING_APPEND)
1767
1768TRIO_PUBLIC_STRING int
1769trio_xstring_append
1770TRIO_ARGS2((self, other),
1771 trio_string_t *self,
1772 TRIO_CONST char *other)
1773{
1774 size_t length;
1775
1776 assert(self);
1777 assert(other);
1778
1779 length = self->length + trio_length(other);
1780 if (!internal_string_grow_to(self, length))
1781 goto error;
1782 trio_copy(&self->content[self->length], other);
1783 self->length = length;
1784 return TRUE;
1785
1786 error:
1787 return FALSE;
1788}
1789
1790#endif
1791
1792/*
1793 * trio_xstring_append_char
1794 */
1795#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
1796
1797TRIO_PUBLIC_STRING int
1798trio_xstring_append_char
1799TRIO_ARGS2((self, character),
1800 trio_string_t *self,
1801 char character)
1802{
1803 assert(self);
1804
1805 if ((int)self->length >= trio_string_size(self))
1806 {
1807 if (!internal_string_grow(self, 0))
1808 goto error;
1809 }
1810 self->content[self->length] = character;
1811 self->length++;
1812 return TRUE;
1813
1814 error:
1815 return FALSE;
1816}
1817
1818#endif
1819
1820/*
1821 * trio_xstring_append_max
1822 */
1823#if defined(TRIO_FUNC_XSTRING_APPEND_MAX)
1824
1825TRIO_PUBLIC_STRING int
1826trio_xstring_append_max
1827TRIO_ARGS3((self, other, max),
1828 trio_string_t *self,
1829 TRIO_CONST char *other,
1830 size_t max)
1831{
1832 size_t length;
1833
1834 assert(self);
1835 assert(other);
1836
1837 length = self->length + trio_length_max(other, max);
1838 if (!internal_string_grow_to(self, length))
1839 goto error;
1840
1841 /*
1842 * Pass max + 1 since trio_copy_max copies one character less than
1843 * this from the source to make room for a terminating zero.
1844 */
1845 trio_copy_max(&self->content[self->length], max + 1, other);
1846 self->length = length;
1847 return TRUE;
1848
1849 error:
1850 return FALSE;
1851}
1852
1853#endif
1854
1855/**
1856 Search for the first occurrence of second parameter in the first.
1857
1858 @param self Dynamic string to be modified.
1859 @param other Dynamic string to copy from.
1860 @return Boolean value indicating success or failure.
1861*/
1862#if defined(TRIO_FUNC_STRING_CONTAINS)
1863
1864TRIO_PUBLIC_STRING int
1865trio_string_contains
1866TRIO_ARGS2((self, other),
1867 trio_string_t *self,
1868 trio_string_t *other)
1869{
1870 assert(self);
1871 assert(other);
1872
1873 return trio_contains(self->content, other->content);
1874}
1875
1876#endif
1877
1878/*
1879 * trio_xstring_contains
1880 */
1881#if defined(TRIO_FUNC_XSTRING_CONTAINS)
1882
1883TRIO_PUBLIC_STRING int
1884trio_xstring_contains
1885TRIO_ARGS2((self, other),
1886 trio_string_t *self,
1887 TRIO_CONST char *other)
1888{
1889 assert(self);
1890 assert(other);
1891
1892 return trio_contains(self->content, other);
1893}
1894
1895#endif
1896
1897/*
1898 * trio_string_copy
1899 */
1900#if defined(TRIO_FUNC_STRING_COPY)
1901
1902TRIO_PUBLIC_STRING int
1903trio_string_copy
1904TRIO_ARGS2((self, other),
1905 trio_string_t *self,
1906 trio_string_t *other)
1907{
1908 assert(self);
1909 assert(other);
1910
1911 self->length = 0;
1912 return trio_string_append(self, other);
1913}
1914
1915#endif
1916
1917
1918/*
1919 * trio_xstring_copy
1920 */
1921#if defined(TRIO_FUNC_XSTRING_COPY)
1922
1923TRIO_PUBLIC_STRING int
1924trio_xstring_copy
1925TRIO_ARGS2((self, other),
1926 trio_string_t *self,
1927 TRIO_CONST char *other)
1928{
1929 assert(self);
1930 assert(other);
1931
1932 self->length = 0;
1933 return trio_xstring_append(self, other);
1934}
1935
1936#endif
1937
1938/*
1939 * trio_string_duplicate
1940 */
1941#if defined(TRIO_FUNC_STRING_DUPLICATE)
1942
1943TRIO_PUBLIC_STRING trio_string_t *
1944trio_string_duplicate
1945TRIO_ARGS1((other),
1946 trio_string_t *other)
1947{
1948 trio_string_t *self;
1949
1950 assert(other);
1951
1952 self = internal_string_alloc();
1953 if (self)
1954 {
1955 self->content = internal_duplicate_max(other->content, other->length);
1956 if (self->content)
1957 {
1958 self->length = other->length;
1959 self->allocated = self->length + 1;
1960 }
1961 else
1962 {
1963 self->length = self->allocated = 0;
1964 }
1965 }
1966 return self;
1967}
1968
1969#endif
1970
1971/*
1972 * trio_xstring_duplicate
1973 */
1974#if defined(TRIO_FUNC_XSTRING_DUPLICATE)
1975
1976TRIO_PUBLIC_STRING trio_string_t *
1977trio_xstring_duplicate
1978TRIO_ARGS1((other),
1979 TRIO_CONST char *other)
1980{
1981 trio_string_t *self;
1982
1983 assert(other);
1984
1985 self = internal_string_alloc();
1986 if (self)
1987 {
1988 self->content = internal_duplicate_max(other, trio_length(other));
1989 if (self->content)
1990 {
1991 self->length = trio_length(self->content);
1992 self->allocated = self->length + 1;
1993 }
1994 else
1995 {
1996 self->length = self->allocated = 0;
1997 }
1998 }
1999 return self;
2000}
2001
2002#endif
2003
2004/*
2005 * trio_string_equal
2006 */
2007#if defined(TRIO_FUNC_STRING_EQUAL)
2008
2009TRIO_PUBLIC_STRING int
2010trio_string_equal
2011TRIO_ARGS2((self, other),
2012 trio_string_t *self,
2013 trio_string_t *other)
2014{
2015 assert(self);
2016 assert(other);
2017
2018 return trio_equal(self->content, other->content);
2019}
2020
2021#endif
2022
2023
2024/*
2025 * trio_xstring_equal
2026 */
2027#if defined(TRIO_FUNC_XSTRING_EQUAL)
2028
2029TRIO_PUBLIC_STRING int
2030trio_xstring_equal
2031TRIO_ARGS2((self, other),
2032 trio_string_t *self,
2033 TRIO_CONST char *other)
2034{
2035 assert(self);
2036 assert(other);
2037
2038 return trio_equal(self->content, other);
2039}
2040
2041#endif
2042
2043/*
2044 * trio_string_equal_max
2045 */
2046#if defined(TRIO_FUNC_STRING_EQUAL_MAX)
2047
2048TRIO_PUBLIC_STRING int
2049trio_string_equal_max
2050TRIO_ARGS3((self, max, other),
2051 trio_string_t *self,
2052 size_t max,
2053 trio_string_t *other)
2054{
2055 assert(self);
2056 assert(other);
2057
2058 return trio_equal_max(self->content, max, other->content);
2059}
2060#endif
2061
2062/*
2063 * trio_xstring_equal_max
2064 */
2065#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
2066
2067TRIO_PUBLIC_STRING int
2068trio_xstring_equal_max
2069TRIO_ARGS3((self, max, other),
2070 trio_string_t *self,
2071 size_t max,
2072 TRIO_CONST char *other)
2073{
2074 assert(self);
2075 assert(other);
2076
2077 return trio_equal_max(self->content, max, other);
2078}
2079
2080#endif
2081
2082/*
2083 * trio_string_equal_case
2084 */
2085#if defined(TRIO_FUNC_STRING_EQUAL_CASE)
2086
2087TRIO_PUBLIC_STRING int
2088trio_string_equal_case
2089TRIO_ARGS2((self, other),
2090 trio_string_t *self,
2091 trio_string_t *other)
2092{
2093 assert(self);
2094 assert(other);
2095
2096 return trio_equal_case(self->content, other->content);
2097}
2098
2099#endif
2100
2101/*
2102 * trio_xstring_equal_case
2103 */
2104#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
2105
2106TRIO_PUBLIC_STRING int
2107trio_xstring_equal_case
2108TRIO_ARGS2((self, other),
2109 trio_string_t *self,
2110 TRIO_CONST char *other)
2111{
2112 assert(self);
2113 assert(other);
2114
2115 return trio_equal_case(self->content, other);
2116}
2117
2118#endif
2119
2120/*
2121 * trio_string_equal_case_max
2122 */
2123#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
2124
2125TRIO_PUBLIC_STRING int
2126trio_string_equal_case_max
2127TRIO_ARGS3((self, max, other),
2128 trio_string_t *self,
2129 size_t max,
2130 trio_string_t *other)
2131{
2132 assert(self);
2133 assert(other);
2134
2135 return trio_equal_case_max(self->content, max, other->content);
2136}
2137
2138#endif
2139
2140/*
2141 * trio_xstring_equal_case_max
2142 */
2143#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
2144
2145TRIO_PUBLIC_STRING int
2146trio_xstring_equal_case_max
2147TRIO_ARGS3((self, max, other),
2148 trio_string_t *self,
2149 size_t max,
2150 TRIO_CONST char *other)
2151{
2152 assert(self);
2153 assert(other);
2154
2155 return trio_equal_case_max(self->content, max, other);
2156}
2157
2158#endif
2159
2160/*
2161 * trio_string_format_data_max
2162 */
2163#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
2164
2165TRIO_PUBLIC_STRING size_t
2166trio_string_format_date_max
2167TRIO_ARGS4((self, max, format, datetime),
2168 trio_string_t *self,
2169 size_t max,
2170 TRIO_CONST char *format,
2171 TRIO_CONST struct tm *datetime)
2172{
2173 assert(self);
2174
2175 return trio_format_date_max(self->content, max, format, datetime);
2176}
2177
2178#endif
2179
2180/*
2181 * trio_string_index
2182 */
2183#if defined(TRIO_FUNC_STRING_INDEX)
2184
2185TRIO_PUBLIC_STRING char *
2186trio_string_index
2187TRIO_ARGS2((self, character),
2188 trio_string_t *self,
2189 int character)
2190{
2191 assert(self);
2192
2193 return trio_index(self->content, character);
2194}
2195
2196#endif
2197
2198/*
2199 * trio_string_index_last
2200 */
2201#if defined(TRIO_FUNC_STRING_INDEX_LAST)
2202
2203TRIO_PUBLIC_STRING char *
2204trio_string_index_last
2205TRIO_ARGS2((self, character),
2206 trio_string_t *self,
2207 int character)
2208{
2209 assert(self);
2210
2211 return trio_index_last(self->content, character);
2212}
2213
2214#endif
2215
2216/*
2217 * trio_string_length
2218 */
2219#if defined(TRIO_FUNC_STRING_LENGTH)
2220
2221TRIO_PUBLIC_STRING int
2222trio_string_length
2223TRIO_ARGS1((self),
2224 trio_string_t *self)
2225{
2226 assert(self);
2227
2228 if (self->length == 0)
2229 {
2230 self->length = trio_length(self->content);
2231 }
2232 return self->length;
2233}
2234
2235#endif
2236
2237/*
2238 * trio_string_lower
2239 */
2240#if defined(TRIO_FUNC_STRING_LOWER)
2241
2242TRIO_PUBLIC_STRING int
2243trio_string_lower
2244TRIO_ARGS1((self),
2245 trio_string_t *self)
2246{
2247 assert(self);
2248
2249 return trio_lower(self->content);
2250}
2251
2252#endif
2253
2254/*
2255 * trio_string_match
2256 */
2257#if defined(TRIO_FUNC_STRING_MATCH)
2258
2259TRIO_PUBLIC_STRING int
2260trio_string_match
2261TRIO_ARGS2((self, other),
2262 trio_string_t *self,
2263 trio_string_t *other)
2264{
2265 assert(self);
2266 assert(other);
2267
2268 return trio_match(self->content, other->content);
2269}
2270
2271#endif
2272
2273/*
2274 * trio_xstring_match
2275 */
2276#if defined(TRIO_FUNC_XSTRING_MATCH)
2277
2278TRIO_PUBLIC_STRING int
2279trio_xstring_match
2280TRIO_ARGS2((self, other),
2281 trio_string_t *self,
2282 TRIO_CONST char *other)
2283{
2284 assert(self);
2285 assert(other);
2286
2287 return trio_match(self->content, other);
2288}
2289
2290#endif
2291
2292/*
2293 * trio_string_match_case
2294 */
2295#if defined(TRIO_FUNC_STRING_MATCH_CASE)
2296
2297TRIO_PUBLIC_STRING int
2298trio_string_match_case
2299TRIO_ARGS2((self, other),
2300 trio_string_t *self,
2301 trio_string_t *other)
2302{
2303 assert(self);
2304 assert(other);
2305
2306 return trio_match_case(self->content, other->content);
2307}
2308
2309#endif
2310
2311/*
2312 * trio_xstring_match_case
2313 */
2314#if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
2315
2316TRIO_PUBLIC_STRING int
2317trio_xstring_match_case
2318TRIO_ARGS2((self, other),
2319 trio_string_t *self,
2320 TRIO_CONST char *other)
2321{
2322 assert(self);
2323 assert(other);
2324
2325 return trio_match_case(self->content, other);
2326}
2327
2328#endif
2329
2330/*
2331 * trio_string_substring
2332 */
2333#if defined(TRIO_FUNC_STRING_SUBSTRING)
2334
2335TRIO_PUBLIC_STRING char *
2336trio_string_substring
2337TRIO_ARGS2((self, other),
2338 trio_string_t *self,
2339 trio_string_t *other)
2340{
2341 assert(self);
2342 assert(other);
2343
2344 return trio_substring(self->content, other->content);
2345}
2346
2347#endif
2348
2349/*
2350 * trio_xstring_substring
2351 */
2352#if defined(TRIO_FUNC_XSTRING_SUBSTRING)
2353
2354TRIO_PUBLIC_STRING char *
2355trio_xstring_substring
2356TRIO_ARGS2((self, other),
2357 trio_string_t *self,
2358 TRIO_CONST char *other)
2359{
2360 assert(self);
2361 assert(other);
2362
2363 return trio_substring(self->content, other);
2364}
2365
2366#endif
2367
2368/*
2369 * trio_string_upper
2370 */
2371#if defined(TRIO_FUNC_STRING_UPPER)
2372
2373TRIO_PUBLIC_STRING int
2374trio_string_upper
2375TRIO_ARGS1((self),
2376 trio_string_t *self)
2377{
2378 assert(self);
2379
2380 return trio_upper(self->content);
2381}
2382
2383#endif
2384
2385/** @} End of DynamicStrings */
diff --git a/gs/trio/triostr.h b/gs/trio/triostr.h
new file mode 100644
index 000000000..847fb7232
--- /dev/null
+++ b/gs/trio/triostr.h
@@ -0,0 +1,681 @@
1/*************************************************************************
2 *
3 * $Id: triostr.h,v 1.18 2010/01/26 13:02:02 breese Exp $
4 *
5 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
18#ifndef TRIO_TRIOSTR_H
19#define TRIO_TRIOSTR_H
20
21/*
22 * Documentation is located in triostr.c
23 */
24
25#include <assert.h>
26#include <stdlib.h>
27#include <string.h>
28#include <time.h>
29#include "triodef.h"
30#include "triop.h"
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36enum {
37 TRIO_HASH_NONE = 0,
38 TRIO_HASH_PLAIN,
39 TRIO_HASH_TWOSIGNED
40};
41
42#if !defined(TRIO_PUBLIC_STRING)
43# if !defined(TRIO_PUBLIC)
44# define TRIO_PUBLIC
45# endif
46# define TRIO_PUBLIC_STRING TRIO_PUBLIC
47#endif
48
49/*************************************************************************
50 * Dependencies
51 */
52
53#if defined(TRIO_EMBED_STRING)
54
55/*
56 * The application that triostr is embedded in must define which functions
57 * it uses.
58 *
59 * The following resolves internal dependencies.
60 */
61
62# if defined(TRIO_FUNC_XSTRING_SET)
63# if !defined(TRIO_FUNC_DUPLICATE)
64# define TRIO_FUNC_DUPLICATE
65# endif
66# endif
67
68# if defined(TRIO_FUNC_DUPLICATE) \
69 || defined(TRIO_FUNC_DUPLICATE_MAX) \
70 || defined(TRIO_FUNC_STRING_DUPLICATE) \
71 || defined(TRIO_FUNC_XSTRING_DUPLICATE)
72# if !defined(TRIO_FUNC_CREATE)
73# define TRIO_FUNC_CREATE
74# endif
75# if !defined(TRIO_FUNC_COPY_MAX)
76# define TRIO_FUNC_COPY_MAX
77# endif
78# endif
79
80# if defined(TRIO_FUNC_STRING_CREATE)
81# if !defined(TRIO_FUNC_STRING_DESTROY)
82# define TRIO_FUNC_STRING_DESTROY
83# endif
84# endif
85
86# if defined(TRIO_FUNC_STRING_DESTROY) \
87 || defined(TRIO_FUNC_XSTRING_SET)
88# if !defined(TRIO_FUNC_DESTROY)
89# define TRIO_FUNC_DESTROY
90# endif
91# endif
92
93# if defined(TRIO_FUNC_EQUAL_LOCALE) \
94 || defined(TRIO_FUNC_STRING_EQUAL) \
95 || defined(TRIO_FUNC_XSTRING_EQUAL)
96# if !defined(TRIO_FUNC_EQUAL)
97# define TRIO_FUNC_EQUAL
98# endif
99# endif
100
101# if defined(TRIO_FUNC_EQUAL_CASE) \
102 || defined(TRIO_FUNC_STRING_EQUAL_CASE) \
103 || defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
104# if !defined(TRIO_FUNC_EQUAL_CASE)
105# define TRIO_FUNC_EQUAL_CASE
106# endif
107# endif
108
109# if defined(TRIO_FUNC_SUBSTRING_MAX) \
110 || defined(TRIO_FUNC_STRING_EQUAL_MAX) \
111 || defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
112# if !defined(TRIO_FUNC_EQUAL_MAX)
113# define TRIO_FUNC_EQUAL_MAX
114# endif
115# endif
116
117# if defined(TRIO_FUNC_TO_DOUBLE) \
118 || defined(TRIO_FUNC_TO_FLOAT)
119# if !defined(TRIO_FUNC_TO_LONG_DOUBLE)
120# define TRIO_FUNC_TO_LONG_DOUBLE
121# endif
122# endif
123
124# if defined(TRIO_FUNC_STRING_TERMINATE)
125# if !defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
126# define TRIO_FUNC_XSTRING_APPEND_CHAR
127# endif
128# endif
129
130# if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
131# if !defined(TRIO_FUNC_STRING_SIZE)
132# define TRIO_FUNC_STRING_SIZE
133# endif
134# endif
135
136#else
137
138/*
139 * When triostr is not embedded all functions are defined.
140 */
141
142# define TRIO_FUNC_APPEND
143# define TRIO_FUNC_APPEND_MAX
144# define TRIO_FUNC_CONTAINS
145# define TRIO_FUNC_COPY
146# define TRIO_FUNC_COPY_MAX
147# define TRIO_FUNC_CREATE
148# define TRIO_FUNC_DESTROY
149# define TRIO_FUNC_DUPLICATE
150# define TRIO_FUNC_DUPLICATE_MAX
151# define TRIO_FUNC_EQUAL
152# define TRIO_FUNC_EQUAL_CASE
153# define TRIO_FUNC_EQUAL_CASE_MAX
154# define TRIO_FUNC_EQUAL_LOCALE
155# define TRIO_FUNC_EQUAL_MAX
156# define TRIO_FUNC_ERROR
157# if !defined(TRIO_PLATFORM_WINCE)
158# define TRIO_FUNC_FORMAT_DATE_MAX
159# endif
160# define TRIO_FUNC_HASH
161# define TRIO_FUNC_INDEX
162# define TRIO_FUNC_INDEX_LAST
163# define TRIO_FUNC_LENGTH
164# define TRIO_FUNC_LENGTH_MAX
165# define TRIO_FUNC_LOWER
166# define TRIO_FUNC_MATCH
167# define TRIO_FUNC_MATCH_CASE
168# define TRIO_FUNC_SPAN_FUNCTION
169# define TRIO_FUNC_SUBSTRING
170# define TRIO_FUNC_SUBSTRING_MAX
171# define TRIO_FUNC_TO_DOUBLE
172# define TRIO_FUNC_TO_FLOAT
173# define TRIO_FUNC_TO_LONG
174# define TRIO_FUNC_TO_LONG_DOUBLE
175# define TRIO_FUNC_TO_LOWER
176# define TRIO_FUNC_TO_UNSIGNED_LONG
177# define TRIO_FUNC_TO_UPPER
178# define TRIO_FUNC_TOKENIZE
179# define TRIO_FUNC_UPPER
180
181# define TRIO_FUNC_STRING_APPEND
182# define TRIO_FUNC_STRING_CONTAINS
183# define TRIO_FUNC_STRING_COPY
184# define TRIO_FUNC_STRING_CREATE
185# define TRIO_FUNC_STRING_DESTROY
186# define TRIO_FUNC_STRING_DUPLICATE
187# define TRIO_FUNC_STRING_EQUAL
188# define TRIO_FUNC_STRING_EQUAL_CASE
189# define TRIO_FUNC_STRING_EQUAL_CASE_MAX
190# define TRIO_FUNC_STRING_EQUAL_MAX
191# define TRIO_FUNC_STRING_EXTRACT
192# if !defined(TRIO_PLATFORM_WINCE)
193# define TRIO_FUNC_STRING_FORMAT_DATE_MAX
194# endif
195# define TRIO_FUNC_STRING_GET
196# define TRIO_FUNC_STRING_INDEX
197# define TRIO_FUNC_STRING_INDEX_LAST
198# define TRIO_FUNC_STRING_LENGTH
199# define TRIO_FUNC_STRING_LOWER
200# define TRIO_FUNC_STRING_MATCH
201# define TRIO_FUNC_STRING_MATCH_CASE
202# define TRIO_FUNC_STRING_SIZE
203# define TRIO_FUNC_STRING_SUBSTRING
204# define TRIO_FUNC_STRING_TERMINATE
205# define TRIO_FUNC_STRING_UPPER
206
207# define TRIO_FUNC_XSTRING_APPEND
208# define TRIO_FUNC_XSTRING_APPEND_CHAR
209# define TRIO_FUNC_XSTRING_APPEND_MAX
210# define TRIO_FUNC_XSTRING_CONTAINS
211# define TRIO_FUNC_XSTRING_COPY
212# define TRIO_FUNC_XSTRING_DUPLICATE
213# define TRIO_FUNC_XSTRING_EQUAL
214# define TRIO_FUNC_XSTRING_EQUAL_CASE
215# define TRIO_FUNC_XSTRING_EQUAL_CASE_MAX
216# define TRIO_FUNC_XSTRING_EQUAL_MAX
217# define TRIO_FUNC_XSTRING_MATCH
218# define TRIO_FUNC_XSTRING_MATCH_CASE
219# define TRIO_FUNC_XSTRING_SET
220# define TRIO_FUNC_XSTRING_SUBSTRING
221
222#endif
223
224
225/*************************************************************************
226 * String functions
227 */
228
229#if defined(TRIO_FUNC_APPEND)
230TRIO_PUBLIC_STRING int
231trio_append
232TRIO_PROTO((char *target, TRIO_CONST char *source));
233#endif
234
235#if defined(TRIO_FUNC_APPEND_MAX)
236TRIO_PUBLIC_STRING int
237trio_append_max
238TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source));
239#endif
240
241#if defined(TRIO_FUNC_CONTAINS)
242TRIO_PUBLIC_STRING int
243trio_contains
244TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring));
245#endif
246
247#if defined(TRIO_FUNC_COPY)
248TRIO_PUBLIC_STRING int
249trio_copy
250TRIO_PROTO((char *target, TRIO_CONST char *source));
251#endif
252
253#if defined(TRIO_FUNC_COPY_MAX)
254TRIO_PUBLIC_STRING int
255trio_copy_max
256TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source));
257#endif
258
259#if defined(TRIO_FUNC_CREATE)
260TRIO_PUBLIC_STRING char *
261trio_create
262TRIO_PROTO((size_t size));
263#endif
264
265#if defined(TRIO_FUNC_DESTROY)
266TRIO_PUBLIC_STRING void
267trio_destroy
268TRIO_PROTO((char *string));
269#endif
270
271#if defined(TRIO_FUNC_DUPLICATE)
272TRIO_PUBLIC_STRING char *
273trio_duplicate
274TRIO_PROTO((TRIO_CONST char *source));
275#endif
276
277#if defined(TRIO_FUNC_DUPLICATE_MAX)
278TRIO_PUBLIC_STRING char *
279trio_duplicate_max
280TRIO_PROTO((TRIO_CONST char *source, size_t max));
281#endif
282
283#if defined(TRIO_FUNC_EQUAL)
284TRIO_PUBLIC_STRING int
285trio_equal
286TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));
287#endif
288
289#if defined(TRIO_FUNC_EQUAL_CASE)
290TRIO_PUBLIC_STRING int
291trio_equal_case
292TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));
293#endif
294
295#if defined(TRIO_FUNC_EQUAL_CASE_MAX)
296TRIO_PUBLIC_STRING int
297trio_equal_case_max
298TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second));
299#endif
300
301#if defined(TRIO_FUNC_EQUAL_LOCALE)
302TRIO_PUBLIC_STRING int
303trio_equal_locale
304TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));
305#endif
306
307#if defined(TRIO_FUNC_EQUAL_MAX)
308TRIO_PUBLIC_STRING int
309trio_equal_max
310TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second));
311#endif
312
313#if defined(TRIO_FUNC_ERROR)
314TRIO_PUBLIC_STRING TRIO_CONST char *
315trio_error
316TRIO_PROTO((int));
317#endif
318
319#if defined(TRIO_FUNC_FORMAT_DATE_MAX)
320TRIO_PUBLIC_STRING size_t
321trio_format_date_max
322TRIO_PROTO((char *target, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime));
323#endif
324
325#if defined(TRIO_FUNC_HASH)
326TRIO_PUBLIC_STRING unsigned long
327trio_hash
328TRIO_PROTO((TRIO_CONST char *string, int type));
329#endif
330
331#if defined(TRIO_FUNC_INDEX)
332TRIO_PUBLIC_STRING char *
333trio_index
334TRIO_PROTO((TRIO_CONST char *string, int character));
335#endif
336
337#if defined(TRIO_FUNC_INDEX_LAST)
338TRIO_PUBLIC_STRING char *
339trio_index_last
340TRIO_PROTO((TRIO_CONST char *string, int character));
341#endif
342
343#if defined(TRIO_FUNC_LENGTH)
344TRIO_PUBLIC_STRING size_t
345trio_length
346TRIO_PROTO((TRIO_CONST char *string));
347#endif
348
349#if defined(TRIO_FUNC_LENGTH_MAX)
350TRIO_PUBLIC_STRING size_t
351trio_length_max
352TRIO_PROTO((TRIO_CONST char *string, size_t max));
353#endif
354
355#if defined(TRIO_FUNC_LOWER)
356TRIO_PUBLIC_STRING int
357trio_lower
358TRIO_PROTO((char *target));
359#endif
360
361#if defined(TRIO_FUNC_MATCH)
362TRIO_PUBLIC_STRING int
363trio_match
364TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern));
365#endif
366
367#if defined(TRIO_FUNC_MATCH_CASE)
368TRIO_PUBLIC_STRING int
369trio_match_case
370TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern));
371#endif
372
373#if defined(TRIO_FUNC_SPAN_FUNCTION)
374TRIO_PUBLIC_STRING size_t
375trio_span_function
376TRIO_PROTO((char *target, TRIO_CONST char *source, int (*Function) TRIO_PROTO((int))));
377#endif
378
379#if defined(TRIO_FUNC_SUBSTRING)
380TRIO_PUBLIC_STRING char *
381trio_substring
382TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring));
383#endif
384
385#if defined(TRIO_FUNC_SUBSTRING_MAX)
386TRIO_PUBLIC_STRING char *
387trio_substring_max
388TRIO_PROTO((TRIO_CONST char *string, size_t max, TRIO_CONST char *substring));
389#endif
390
391#if defined(TRIO_FUNC_TO_DOUBLE)
392TRIO_PUBLIC_STRING double
393trio_to_double
394TRIO_PROTO((TRIO_CONST char *source, char **endp));
395#endif
396
397#if defined(TRIO_FUNC_TO_FLOAT)
398TRIO_PUBLIC_STRING float
399trio_to_float
400TRIO_PROTO((TRIO_CONST char *source, char **endp));
401#endif
402
403#if defined(TRIO_FUNC_TO_LONG)
404TRIO_PUBLIC_STRING long
405trio_to_long
406TRIO_PROTO((TRIO_CONST char *source, char **endp, int base));
407#endif
408
409#if defined(TRIO_FUNC_TO_LOWER)
410TRIO_PUBLIC_STRING int
411trio_to_lower
412TRIO_PROTO((int source));
413#endif
414
415#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
416TRIO_PUBLIC_STRING trio_long_double_t
417trio_to_long_double
418TRIO_PROTO((TRIO_CONST char *source, char **endp));
419#endif
420
421#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
422TRIO_PUBLIC_STRING unsigned long
423trio_to_unsigned_long
424TRIO_PROTO((TRIO_CONST char *source, char **endp, int base));
425#endif
426
427#if defined(TRIO_FUNC_TO_UPPER)
428TRIO_PUBLIC_STRING int
429trio_to_upper
430TRIO_PROTO((int source));
431#endif
432
433#if defined(TRIO_FUNC_TOKENIZE)
434TRIO_PUBLIC_STRING char *
435trio_tokenize
436TRIO_PROTO((char *string, TRIO_CONST char *delimiters));
437#endif
438
439#if defined(TRIO_FUNC_UPPER)
440TRIO_PUBLIC_STRING int
441trio_upper
442TRIO_PROTO((char *target));
443#endif
444
445/*************************************************************************
446 * Dynamic string functions
447 */
448
449/*
450 * Opaque type for dynamic strings
451 */
452
453typedef struct _trio_string_t trio_string_t;
454
455#if defined(TRIO_FUNC_STRING_APPEND)
456TRIO_PUBLIC_STRING int
457trio_string_append
458TRIO_PROTO((trio_string_t *self, trio_string_t *other));
459#endif
460
461#if defined(TRIO_FUNC_STRING_CONTAINS)
462TRIO_PUBLIC_STRING int
463trio_string_contains
464TRIO_PROTO((trio_string_t *self, trio_string_t *other));
465#endif
466
467#if defined(TRIO_FUNC_STRING_COPY)
468TRIO_PUBLIC_STRING int
469trio_string_copy
470TRIO_PROTO((trio_string_t *self, trio_string_t *other));
471#endif
472
473#if defined(TRIO_FUNC_STRING_CREATE)
474TRIO_PUBLIC_STRING trio_string_t *
475trio_string_create
476TRIO_PROTO((int initial_size));
477#endif
478
479#if defined(TRIO_FUNC_STRING_DESTROY)
480TRIO_PUBLIC_STRING void
481trio_string_destroy
482TRIO_PROTO((trio_string_t *self));
483#endif
484
485#if defined(TRIO_FUNC_STRING_DUPLICATE)
486TRIO_PUBLIC_STRING trio_string_t *
487trio_string_duplicate
488TRIO_PROTO((trio_string_t *other));
489#endif
490
491#if defined(TRIO_FUNC_STRING_EQUAL)
492TRIO_PUBLIC_STRING int
493trio_string_equal
494TRIO_PROTO((trio_string_t *self, trio_string_t *other));
495#endif
496
497#if defined(TRIO_FUNC_STRING_EQUAL_MAX)
498TRIO_PUBLIC_STRING int
499trio_string_equal_max
500TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second));
501#endif
502
503#if defined(TRIO_FUNC_STRING_EQUAL_CASE)
504TRIO_PUBLIC_STRING int
505trio_string_equal_case
506TRIO_PROTO((trio_string_t *self, trio_string_t *other));
507#endif
508
509#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
510TRIO_PUBLIC_STRING int
511trio_string_equal_case_max
512TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other));
513#endif
514
515#if defined(TRIO_FUNC_STRING_EXTRACT)
516TRIO_PUBLIC_STRING char *
517trio_string_extract
518TRIO_PROTO((trio_string_t *self));
519#endif
520
521#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
522TRIO_PUBLIC_STRING size_t
523trio_string_format_date_max
524TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime));
525#endif
526
527#if defined(TRIO_FUNC_STRING_GET)
528TRIO_PUBLIC_STRING char *
529trio_string_get
530TRIO_PROTO((trio_string_t *self, int offset));
531#endif
532
533#if defined(TRIO_FUNC_STRING_INDEX)
534TRIO_PUBLIC_STRING char *
535trio_string_index
536TRIO_PROTO((trio_string_t *self, int character));
537#endif
538
539#if defined(TRIO_FUNC_STRING_INDEX_LAST)
540TRIO_PUBLIC_STRING char *
541trio_string_index_last
542TRIO_PROTO((trio_string_t *self, int character));
543#endif
544
545#if defined(TRIO_FUNC_STRING_LENGTH)
546TRIO_PUBLIC_STRING int
547trio_string_length
548TRIO_PROTO((trio_string_t *self));
549#endif
550
551#if defined(TRIO_FUNC_STRING_LOWER)
552TRIO_PUBLIC_STRING int
553trio_string_lower
554TRIO_PROTO((trio_string_t *self));
555#endif
556
557#if defined(TRIO_FUNC_STRING_MATCH)
558TRIO_PUBLIC_STRING int
559trio_string_match
560TRIO_PROTO((trio_string_t *self, trio_string_t *other));
561#endif
562
563#if defined(TRIO_FUNC_STRING_MATCH_CASE)
564TRIO_PUBLIC_STRING int
565trio_string_match_case
566TRIO_PROTO((trio_string_t *self, trio_string_t *other));
567#endif
568
569#if defined(TRIO_FUNC_STRING_SIZE)
570TRIO_PUBLIC_STRING int
571trio_string_size
572TRIO_PROTO((trio_string_t *self));
573#endif
574
575#if defined(TRIO_FUNC_STRING_SUBSTRING)
576TRIO_PUBLIC_STRING char *
577trio_string_substring
578TRIO_PROTO((trio_string_t *self, trio_string_t *other));
579#endif
580
581#if defined(TRIO_FUNC_STRING_TERMINATE)
582TRIO_PUBLIC_STRING void
583trio_string_terminate
584TRIO_PROTO((trio_string_t *self));
585#endif
586
587#if defined(TRIO_FUNC_STRING_UPPER)
588TRIO_PUBLIC_STRING int
589trio_string_upper
590TRIO_PROTO((trio_string_t *self));
591#endif
592
593#if defined(TRIO_FUNC_XSTRING_APPEND)
594TRIO_PUBLIC_STRING int
595trio_xstring_append
596TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
597#endif
598
599#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
600TRIO_PUBLIC_STRING int
601trio_xstring_append_char
602TRIO_PROTO((trio_string_t *self, char character));
603#endif
604
605#if defined(TRIO_FUNC_XSTRING_APPEND_MAX)
606TRIO_PUBLIC_STRING int
607trio_xstring_append_max
608TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other, size_t max));
609#endif
610
611#if defined(TRIO_FUNC_XSTRING_CONTAINS)
612TRIO_PUBLIC_STRING int
613trio_xstring_contains
614TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
615#endif
616
617#if defined(TRIO_FUNC_XSTRING_COPY)
618TRIO_PUBLIC_STRING int
619trio_xstring_copy
620TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
621#endif
622
623#if defined(TRIO_FUNC_XSTRING_DUPLICATE)
624TRIO_PUBLIC_STRING trio_string_t *
625trio_xstring_duplicate
626TRIO_PROTO((TRIO_CONST char *other));
627#endif
628
629#if defined(TRIO_FUNC_XSTRING_EQUAL)
630TRIO_PUBLIC_STRING int
631trio_xstring_equal
632TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
633#endif
634
635#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
636TRIO_PUBLIC_STRING int
637trio_xstring_equal_max
638TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other));
639#endif
640
641#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
642TRIO_PUBLIC_STRING int
643trio_xstring_equal_case
644TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
645#endif
646
647#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
648TRIO_PUBLIC_STRING int
649trio_xstring_equal_case_max
650TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other));
651#endif
652
653#if defined(TRIO_FUNC_XSTRING_MATCH)
654TRIO_PUBLIC_STRING int
655trio_xstring_match
656TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
657#endif
658
659#if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
660TRIO_PUBLIC_STRING int
661trio_xstring_match_case
662TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
663#endif
664
665#if defined(TRIO_FUNC_XSTRING_SET)
666TRIO_PUBLIC_STRING void
667trio_xstring_set
668TRIO_PROTO((trio_string_t *self, char *buffer));
669#endif
670
671#if defined(TRIO_FUNC_XSTRING_SUBSTRING)
672TRIO_PUBLIC_STRING char *
673trio_xstring_substring
674TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
675#endif
676
677#ifdef __cplusplus
678}
679#endif
680
681#endif /* TRIO_TRIOSTR_H */
diff --git a/main/pcl6_gcc.mak b/main/pcl6_gcc.mak
index 99051a02c..1ef764360 100644
--- a/main/pcl6_gcc.mak
+++ b/main/pcl6_gcc.mak
@@ -80,6 +80,9 @@ TIFFSRCDIR?=../gs/tiff
80TIFFCONFDIR?=../tiff-config 80TIFFCONFDIR?=../tiff-config
81TIFFPLATFORM?=unix 81TIFFPLATFORM?=unix
82 82
83# specify the location of the trio source
84TRIOSRCDIR=../gs/trio
85
83# ridiculousness, not worth documenting. 86# ridiculousness, not worth documenting.
84AK?= 87AK?=
85 88
diff --git a/main/pcl6_msvc.mak b/main/pcl6_msvc.mak
index 447d81bab..19ccdb424 100644
--- a/main/pcl6_msvc.mak
+++ b/main/pcl6_msvc.mak
@@ -185,6 +185,10 @@ TIFFCONFIG_SUFFIX=.vc
185TIFFPLATFORM=win32 185TIFFPLATFORM=win32
186!endif 186!endif
187 187
188!ifndef TRIOSRCDIR
189TRIOSRCDIR=..\gs\trio
190!endif
191
188# specify if banding should be memory or file based, and choose a 192# specify if banding should be memory or file based, and choose a
189# compression method 193# compression method
190!ifndef BAND_LIST_STORAGE 194!ifndef BAND_LIST_STORAGE
diff --git a/pcl/pcfontpg.c b/pcl/pcfontpg.c
index b0084f839..4cc261f18 100644
--- a/pcl/pcfontpg.c
+++ b/pcl/pcfontpg.c
@@ -72,7 +72,7 @@ process_font(pcl_state_t * pcs, pl_font_t * fp)
72 72
73 /* reset to default font and print the select font string and pjl number */ 73 /* reset to default font and print the select font string and pjl number */
74 /* create the string command for font selection */ 74 /* create the string command for font selection */
75 sprintf(buff, "<esc>(%u<esc>(s%dp%uv%us%db%dT\n", 75 gs_sprintf(buff, "<esc>(%u<esc>(s%dp%uv%us%db%dT\n",
76 pfp->symbol_set, (pfp->proportional_spacing ? 1 : 0), 76 pfp->symbol_set, (pfp->proportional_spacing ? 1 : 0),
77 pfp->height_4ths / 10, pfp->style, pfp->stroke_weight, 77 pfp->height_4ths / 10, pfp->style, pfp->stroke_weight,
78 pfp->typeface_family); 78 pfp->typeface_family);
@@ -87,7 +87,7 @@ process_font(pcl_state_t * pcs, pl_font_t * fp)
87 87
88 pcl_set_cap_x(pcs, (coord) (pcs->margins.right / (16.0 / 15.0)), 88 pcl_set_cap_x(pcs, (coord) (pcs->margins.right / (16.0 / 15.0)),
89 false, false); 89 false, false);
90 sprintf(buff, "%d", fp->params.pjl_font_number); 90 gs_sprintf(buff, "%d", fp->params.pjl_font_number);
91 91
92 code = pcl_text((byte *) buff, strlen(buff), pcs, false); 92 code = pcl_text((byte *) buff, strlen(buff), pcs, false);
93 if (code < 0) 93 if (code < 0)
diff --git a/pcl/pcht.c b/pcl/pcht.c
index a1c2034d4..9b1e96468 100644
--- a/pcl/pcht.c
+++ b/pcl/pcht.c
@@ -1512,7 +1512,7 @@ pcl_ht_init_render_methods(pcl_state_t * pcs, gs_memory_t * pmem)
1512 if ((pcs->rendering_info[i].flags & HT_FIXED) != 0) 1512 if ((pcs->rendering_info[i].flags & HT_FIXED) != 0)
1513 continue; 1513 continue;
1514 gs_c_param_list_write(&list, pmem); 1514 gs_c_param_list_write(&list, pmem);
1515 sprintf(nbuff, "Dither_%d", i); 1515 gs_sprintf(nbuff, "Dither_%d", i);
1516 if ((param_request((gs_param_list *) & list, nbuff) >= 0) && 1516 if ((param_request((gs_param_list *) & list, nbuff) >= 0) &&
1517 (gs_getdeviceparams(pcur_dev, (gs_param_list *) & list) >= 0)) { 1517 (gs_getdeviceparams(pcur_dev, (gs_param_list *) & list) >= 0)) {
1518 gs_param_dict dict; 1518 gs_param_dict dict;
diff --git a/pcl/pcstatus.c b/pcl/pcstatus.c
index 52ac35a34..a43c8b43b 100644
--- a/pcl/pcstatus.c
+++ b/pcl/pcstatus.c
@@ -76,7 +76,7 @@ stprintf(stream * s, const char *fmt, ...)
76 char buf[1024]; 76 char buf[1024];
77 77
78 va_start(args, fmt); 78 va_start(args, fmt);
79 count = vsprintf(buf, fmt, args); 79 count = gs_vsprintf(buf, fmt, args);
80 sputs(s, (const byte *)buf, count, &count); 80 sputs(s, (const byte *)buf, count, &count);
81} 81}
82 82
@@ -137,7 +137,7 @@ status_print_idlist(stream * s, const ushort * idlist, int nid,
137 137
138 n = idlist[i] >> 6; 138 n = idlist[i] >> 6;
139 l = (idlist[i] & 077) + 'A' - 1; 139 l = (idlist[i] & 077) + 'A' - 1;
140 sprintf(idstr, "%d%c", n, l); 140 gs_sprintf(idstr, "%d%c", n, l);
141 status_put_id(s, title, idstr); 141 status_put_id(s, title, idstr);
142 } 142 }
143 status_end_id_list(s); 143 status_end_id_list(s);
@@ -373,7 +373,7 @@ status_macros(stream * s, pcl_state_t * pcs, pcl_data_storage_t storage)
373 if (((pcl_macro_t *) value)->storage & storage) { 373 if (((pcl_macro_t *) value)->storage & storage) {
374 char id_string[6]; 374 char id_string[6];
375 375
376 sprintf(id_string, "%u", (key.data[0] << 8) + key.data[1]); 376 gs_sprintf(id_string, "%u", (key.data[0] << 8) + key.data[1]);
377 status_put_id(s, "IDLIST", id_string); 377 status_put_id(s, "IDLIST", id_string);
378 } 378 }
379 status_end_id_list(s); 379 status_end_id_list(s);
@@ -395,7 +395,7 @@ status_patterns(stream * s, pcl_state_t * pcs, pcl_data_storage_t storage)
395 if ((pptrn != 0) && (pcs->pattern_type == pcl_pattern_user_defined)) { 395 if ((pptrn != 0) && (pcs->pattern_type == pcl_pattern_user_defined)) {
396 char id_string[6]; 396 char id_string[6];
397 397
398 sprintf(id_string, "%u", id); 398 gs_sprintf(id_string, "%u", id);
399 status_put_id(s, "IDLIST", id_string); 399 status_put_id(s, "IDLIST", id_string);
400 } 400 }
401 } else { 401 } else {
@@ -407,7 +407,7 @@ status_patterns(stream * s, pcl_state_t * pcs, pcl_data_storage_t storage)
407 if (pptrn != 0) { 407 if (pptrn != 0) {
408 char id_string[6]; 408 char id_string[6];
409 409
410 sprintf(id_string, "%u", id); 410 gs_sprintf(id_string, "%u", id);
411 status_put_id(s, "IDLIST", id_string); 411 status_put_id(s, "IDLIST", id_string);
412 } 412 }
413 } 413 }
diff --git a/pl/dwimg.c b/pl/dwimg.c
index 0c260a9fb..8decdb1b3 100644
--- a/pl/dwimg.c
+++ b/pl/dwimg.c
@@ -1531,7 +1531,7 @@ WndImg2Proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1531 { /* Save the text window size */ 1531 { /* Save the text window size */
1532 char winposbuf[64]; 1532 char winposbuf[64];
1533 1533
1534 sprintf(winposbuf, "%d %d %d %d", img->x, img->y, 1534 gs_sprintf(winposbuf, "%d %d %d %d", img->x, img->y,
1535 img->cx, img->cy); 1535 img->cx, img->cy);
1536 win_set_reg_value((img->device != NULL ? "Image" : "Tracer"), 1536 win_set_reg_value((img->device != NULL ? "Image" : "Tracer"),
1537 winposbuf); 1537 winposbuf);
diff --git a/pl/dwmainc.c b/pl/dwmainc.c
index f8637fe70..727282d7f 100644
--- a/pl/dwmainc.c
+++ b/pl/dwmainc.c
@@ -400,7 +400,7 @@ main_utf8(int argc, char *argv[])
400 HDC hdc = GetDC(NULL); /* get hdc for desktop */ 400 HDC hdc = GetDC(NULL); /* get hdc for desktop */
401 int depth = 401 int depth =
402 GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL); 402 GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
403 sprintf(ddpi, "-dDisplayResolution=%d", 403 gs_sprintf(ddpi, "-dDisplayResolution=%d",
404 GetDeviceCaps(hdc, LOGPIXELSY)); 404 GetDeviceCaps(hdc, LOGPIXELSY));
405 ReleaseDC(NULL, hdc); 405 ReleaseDC(NULL, hdc);
406 if (depth == 32) 406 if (depth == 32)
@@ -419,7 +419,7 @@ main_utf8(int argc, char *argv[])
419 else if (depth >= 4) 419 else if (depth >= 4)
420 format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | 420 format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE |
421 DISPLAY_DEPTH_4 | DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST; 421 DISPLAY_DEPTH_4 | DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST;
422 sprintf(dformat, "-dDisplayFormat=%d", format); 422 gs_sprintf(dformat, "-dDisplayFormat=%d", format);
423 nargc = argc + 2; 423 nargc = argc + 2;
424 nargv = (char **)malloc((nargc + 1) * sizeof(char *)); 424 nargv = (char **)malloc((nargc + 1) * sizeof(char *));
425 nargv[0] = argv[0]; 425 nargv[0] = argv[0];
diff --git a/pl/pjparse.c b/pl/pjparse.c
index 491bd44cd..b95caaded 100644
--- a/pl/pjparse.c
+++ b/pl/pjparse.c
@@ -284,7 +284,7 @@ pjl_side_effects(pjl_parser_state_t * pst, char *variable, char *value,
284 int formlines = pjl_calc_formlines_new_page_size(page_length); 284 int formlines = pjl_calc_formlines_new_page_size(page_length);
285 pjl_envir_var_t var; 285 pjl_envir_var_t var;
286 286
287 sprintf(var.value, "%d", formlines); 287 gs_sprintf(var.value, "%d", formlines);
288 pjl_set(pst, (char *)"FORMLINES", var.value, defaults); 288 pjl_set(pst, (char *)"FORMLINES", var.value, defaults);
289 } 289 }
290 /* fill in other side effects here */ 290 /* fill in other side effects here */
diff --git a/pl/plmain.c b/pl/plmain.c
index 3588b679e..d0993e27c 100644
--- a/pl/plmain.c
+++ b/pl/plmain.c
@@ -602,7 +602,7 @@ pl_main_universe_init(pl_main_universe_t * universe, /* universe to init */
602 universe->pdl_instance_array[index] = universe->curr_instance; 602 universe->pdl_instance_array[index] = universe->curr_instance;
603 if (code < 0) { 603 if (code < 0) {
604 if (err_str) 604 if (err_str)
605 sprintf(err_str, "Unable to create %s interpreter.\n", 605 gs_sprintf(err_str, "Unable to create %s interpreter.\n",
606 pl_characteristics(pdl_implementation[index])-> 606 pl_characteristics(pdl_implementation[index])->
607 language); 607 language);
608 goto pmui_err; 608 goto pmui_err;
@@ -617,7 +617,7 @@ pl_main_universe_init(pl_main_universe_t * universe, /* universe to init */
617 inst) < 0 617 inst) < 0
618 || pl_get_device_memory(instance, &inst->device_memory) < 0) { 618 || pl_get_device_memory(instance, &inst->device_memory) < 0) {
619 if (err_str) 619 if (err_str)
620 sprintf(err_str, "Unable to init %s interpreter.\n", 620 gs_sprintf(err_str, "Unable to init %s interpreter.\n",
621 pl_characteristics(pdl_implementation[index])-> 621 pl_characteristics(pdl_implementation[index])->
622 language); 622 language);
623 goto pmui_err; 623 goto pmui_err;
@@ -650,7 +650,7 @@ pl_main_universe_dnit(pl_main_universe_t * universe, /* universe to dnit */
650 if (universe->curr_instance 650 if (universe->curr_instance
651 && pl_remove_device(universe->curr_instance) < 0) { 651 && pl_remove_device(universe->curr_instance) < 0) {
652 if (err_str) 652 if (err_str)
653 sprintf(err_str, "Unable to close out PDL instance.\n"); 653 gs_sprintf(err_str, "Unable to close out PDL instance.\n");
654 return -1; 654 return -1;
655 } 655 }
656 656
@@ -666,7 +666,7 @@ pl_main_universe_dnit(pl_main_universe_t * universe, /* universe to dnit */
666 && pl_deallocate_interp(universe->pdl_interp_array[index]) < 666 && pl_deallocate_interp(universe->pdl_interp_array[index]) <
667 0)) { 667 0)) {
668 if (err_str) 668 if (err_str)
669 sprintf(err_str, "Unable to close out %s instance.\n", 669 gs_sprintf(err_str, "Unable to close out %s instance.\n",
670 pl_characteristics(universe-> 670 pl_characteristics(universe->
671 pdl_implementation[index])-> 671 pdl_implementation[index])->
672 language); 672 language);
@@ -1488,7 +1488,7 @@ pl_post_finish_page(pl_interp_instance_t * interp, void *closure)
1488 if (pti->pause) { 1488 if (pti->pause) {
1489 char strbuf[256]; 1489 char strbuf[256];
1490 1490
1491 sprintf(strbuf, "End of page %d, press <enter> to continue.\n", 1491 gs_sprintf(strbuf, "End of page %d, press <enter> to continue.\n",
1492 pti->page_count); 1492 pti->page_count);
1493 pl_log_string(pti->memory, strbuf, 1); 1493 pl_log_string(pti->memory, strbuf, 1);
1494 } else if (gs_debug_c(':')) 1494 } else if (gs_debug_c(':'))
diff --git a/pxl/pxerrors.c b/pxl/pxerrors.c
index 17152a2eb..9dd7ac406 100644
--- a/pxl/pxerrors.c
+++ b/pxl/pxerrors.c
@@ -166,7 +166,7 @@ px_error_message_line(char message[px_max_error_line + 1], int N,
166 166
167 switch (N) { 167 switch (N) {
168 case 1: 168 case 1:
169 sprintf(message, " Subsystem: %s\n", subsystem); 169 gs_sprintf(message, " Subsystem: %s\n", subsystem);
170 break; 170 break;
171 case 2: 171 case 2:
172 strcpy(message, " Error: "); 172 strcpy(message, " Error: ");
@@ -186,10 +186,10 @@ px_error_message_line(char message[px_max_error_line + 1], int N,
186 } 186 }
187 strcat(end, "\n"); 187 strcat(end, "\n");
188 } else if (code >= px_error_first && code < px_error_next) 188 } else if (code >= px_error_first && code < px_error_next)
189 sprintf(end, "%s\n", 189 gs_sprintf(end, "%s\n",
190 px_error_names[code - px_error_first]); 190 px_error_names[code - px_error_first]);
191 else 191 else
192 sprintf(end, "Internal error 0x%x\n", code); 192 gs_sprintf(end, "Internal error 0x%x\n", code);
193 } 193 }
194 break; 194 break;
195 case 3: 195 case 3:
@@ -203,19 +203,19 @@ px_error_message_line(char message[px_max_error_line + 1], int N,
203 if (last_operator >= 0x40 && last_operator < 0xc0 && 203 if (last_operator >= 0x40 && last_operator < 0xc0 &&
204 (oname = 204 (oname =
205 px_operator_names[last_operator - 0x40]) != 0) 205 px_operator_names[last_operator - 0x40]) != 0)
206 sprintf(end, "%s\n", oname); 206 gs_sprintf(end, "%s\n", oname);
207 else 207 else
208 sprintf(end, "0x%02x\n", last_operator); 208 gs_sprintf(end, "0x%02x\n", last_operator);
209 } 209 }
210 break; 210 break;
211 case 4: 211 case 4:
212 strcpy(message, " Position: "); 212 strcpy(message, " Position: ");
213 end = message + strlen(message); 213 end = message + strlen(message);
214 if (st->parent_operator_count) 214 if (st->parent_operator_count)
215 sprintf(end, "%ld;%ld\n", st->parent_operator_count, 215 gs_sprintf(end, "%ld;%ld\n", st->parent_operator_count,
216 st->operator_count); 216 st->operator_count);
217 else 217 else
218 sprintf(end, "%ld\n", st->operator_count); 218 gs_sprintf(end, "%ld\n", st->operator_count);
219 break; 219 break;
220 default: 220 default:
221 return -1; 221 return -1;
diff --git a/pxl/pxfont.c b/pxl/pxfont.c
index 8af33fdb9..a73e1907b 100644
--- a/pxl/pxfont.c
+++ b/pxl/pxfont.c
@@ -514,7 +514,7 @@ pxSetFont(px_args_t * par, px_state_t * pxs)
514 { 514 {
515 char setstr[26]; /* 64-bit value plus message */ 515 char setstr[26]; /* 64-bit value plus message */
516 516
517 sprintf(setstr, " : %d", symbol_set); 517 gs_sprintf(setstr, " : %d", symbol_set);
518 strncat(pxs->error_line, setstr, 518 strncat(pxs->error_line, setstr,
519 px_max_error_line - strlen(pxs->error_line)); 519 px_max_error_line - strlen(pxs->error_line));
520 pxs->error_line[px_max_error_line] = 0; 520 pxs->error_line[px_max_error_line] = 0;
diff --git a/pxl/pxpthr.c b/pxl/pxpthr.c
index 50324f109..3aae63f92 100644
--- a/pxl/pxpthr.c
+++ b/pxl/pxpthr.c
@@ -151,7 +151,7 @@ pxPassthrough_init(px_state_t * pxs)
151 stream_cursor_read r; 151 stream_cursor_read r;
152 152
153 ret = 153 ret =
154 sprintf(buf, 154 gs_sprintf(buf,
155 "@PJL SET PAPERLENGTH = %d\n@PJL SET PAPERWIDTH = %d\n", 155 "@PJL SET PAPERLENGTH = %d\n@PJL SET PAPERWIDTH = %d\n",
156 (int)(pxs->media_dims.y * 10 + .5), 156 (int)(pxs->media_dims.y * 10 + .5),
157 (int)(pxs->media_dims.x * 10 + .5)); 157 (int)(pxs->media_dims.x * 10 + .5));
diff --git a/svg/svg_msvc.mak b/svg/svg_msvc.mak
index 58709ea11..d80fdc0fa 100644
--- a/svg/svg_msvc.mak
+++ b/svg/svg_msvc.mak
@@ -115,6 +115,10 @@ TIFFCONFIG_SUFFIX=.vc
115TIFFPLATFORM=win32 115TIFFPLATFORM=win32
116!endif 116!endif
117 117
118!ifndef TRIOSRCDIR
119TRIOSRCDIR=..\gs\trio
120!endif
121
118# PLPLATFORM indicates should be set to 'ps' for language switch 122# PLPLATFORM indicates should be set to 'ps' for language switch
119# builds and null otherwise. 123# builds and null otherwise.
120!ifndef PLPLATFORM 124!ifndef PLPLATFORM
diff --git a/xps/xps_msvc.mak b/xps/xps_msvc.mak
index 9701070b5..ffb8889f8 100644
--- a/xps/xps_msvc.mak
+++ b/xps/xps_msvc.mak
@@ -169,6 +169,10 @@ SHARE_JPEGXR=0
169JPEGXR_CFLAGS=/TP /DNDEBUG 169JPEGXR_CFLAGS=/TP /DNDEBUG
170!endif 170!endif
171 171
172!ifndef TRIOSRCDIR
173TRIOSRCDIR=..\gs\trio
174!endif
175
172# PLPLATFORM indicates should be set to 'ps' for language switch 176# PLPLATFORM indicates should be set to 'ps' for language switch
173# builds and null otherwise. 177# builds and null otherwise.
174!ifndef PLPLATFORM 178!ifndef PLPLATFORM
diff --git a/xps/xpsttf.c b/xps/xpsttf.c
index 7d3bd21e0..380b4dd84 100644
--- a/xps/xpsttf.c
+++ b/xps/xpsttf.c
@@ -180,7 +180,7 @@ xps_true_callback_glyph_name(gs_font *pfont, gs_glyph glyph, gs_const_string *ps
180 { 180 {
181 /* Invent a name if we don't know the table format. */ 181 /* Invent a name if we don't know the table format. */
182 char buf[32]; 182 char buf[32];
183 sprintf(buf, "glyph%d", (int)glyph); 183 gs_sprintf(buf, "glyph%d", (int)glyph);
184 pstr->data = (byte*)buf; 184 pstr->data = (byte*)buf;
185 pstr->size = strlen((char*)pstr->data); 185 pstr->size = strlen((char*)pstr->data);
186 return 0; 186 return 0;
diff --git a/xps/xpszip.c b/xps/xpszip.c
index aeaaa9daf..52b89ad89 100644
--- a/xps/xpszip.c
+++ b/xps/xpszip.c
@@ -304,11 +304,11 @@ xps_read_zip_part(xps_context_t *ctx, char *partname)
304 size = 0; 304 size = 0;
305 while (1) 305 while (1)
306 { 306 {
307 sprintf(buf, "%s/[%d].piece", name, count); 307 gs_sprintf(buf, "%s/[%d].piece", name, count);
308 ent = xps_find_zip_entry(ctx, buf); 308 ent = xps_find_zip_entry(ctx, buf);
309 if (!ent) 309 if (!ent)
310 { 310 {
311 sprintf(buf, "%s/[%d].last.piece", name, count); 311 gs_sprintf(buf, "%s/[%d].last.piece", name, count);
312 ent = xps_find_zip_entry(ctx, buf); 312 ent = xps_find_zip_entry(ctx, buf);
313 } 313 }
314 if (!ent) 314 if (!ent)
@@ -325,9 +325,9 @@ xps_read_zip_part(xps_context_t *ctx, char *partname)
325 for (i = 0; i < count; i++) 325 for (i = 0; i < count; i++)
326 { 326 {
327 if (i < count - 1) 327 if (i < count - 1)
328 sprintf(buf, "%s/[%d].piece", name, i); 328 gs_sprintf(buf, "%s/[%d].piece", name, i);
329 else 329 else
330 sprintf(buf, "%s/[%d].last.piece", name, i); 330 gs_sprintf(buf, "%s/[%d].last.piece", name, i);
331 ent = xps_find_zip_entry(ctx, buf); 331 ent = xps_find_zip_entry(ctx, buf);
332 xps_read_zip_entry(ctx, ent, part->data + offset); 332 xps_read_zip_entry(ctx, ent, part->data + offset);
333 offset += ent->usize; 333 offset += ent->usize;
@@ -371,11 +371,11 @@ xps_read_dir_part(xps_context_t *ctx, char *name)
371 size = 0; 371 size = 0;
372 while (1) 372 while (1)
373 { 373 {
374 sprintf(buf, "%s%s/[%d].piece", ctx->directory, name, count); 374 gs_sprintf(buf, "%s%s/[%d].piece", ctx->directory, name, count);
375 file = gp_fopen(buf, "rb"); 375 file = gp_fopen(buf, "rb");
376 if (!file) 376 if (!file)
377 { 377 {
378 sprintf(buf, "%s%s/[%d].last.piece", ctx->directory, name, count); 378 gs_sprintf(buf, "%s%s/[%d].last.piece", ctx->directory, name, count);
379 file = gp_fopen(buf, "rb"); 379 file = gp_fopen(buf, "rb");
380 } 380 }
381 if (!file) 381 if (!file)
@@ -394,9 +394,9 @@ xps_read_dir_part(xps_context_t *ctx, char *name)
394 for (i = 0; i < count; i++) 394 for (i = 0; i < count; i++)
395 { 395 {
396 if (i < count - 1) 396 if (i < count - 1)
397 sprintf(buf, "%s%s/[%d].piece", ctx->directory, name, i); 397 gs_sprintf(buf, "%s%s/[%d].piece", ctx->directory, name, i);
398 else 398 else
399 sprintf(buf, "%s%s/[%d].last.piece", ctx->directory, name, i); 399 gs_sprintf(buf, "%s%s/[%d].last.piece", ctx->directory, name, i);
400 file = gp_fopen(buf, "rb"); 400 file = gp_fopen(buf, "rb");
401 n = fread(part->data + offset, 1, size - offset, file); 401 n = fread(part->data + offset, 1, size - offset, file);
402 offset += n; 402 offset += n;