1 /* __gmp_doprnt_integer -- integer style formatted output. 2 3 THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST 4 CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN 5 FUTURE GNU MP RELEASES. 6 7 Copyright 2001 Free Software Foundation, Inc. 8 9 This file is part of the GNU MP Library. 10 11 The GNU MP Library is free software; you can redistribute it and/or modify 12 it under the terms of the GNU Lesser General Public License as published by 13 the Free Software Foundation; either version 3 of the License, or (at your 14 option) any later version. 15 16 The GNU MP Library is distributed in the hope that it will be useful, but 17 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 19 License for more details. 20 21 You should have received a copy of the GNU Lesser General Public License 22 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ 23 24 #include "config.h" 25 26 #if HAVE_STDARG 27 #include <stdarg.h> /* for va_list and hence doprnt_funs_t */ 28 #else 29 #include <varargs.h> 30 #endif 31 32 #include <string.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 36 #include "gmp.h" 37 #include "gmp-impl.h" 38 39 40 int 41 __gmp_doprnt_integer (const struct doprnt_funs_t *funs, 42 void *data, 43 const struct doprnt_params_t *p, 44 const char *s) 45 { 46 int retval = 0; 47 int slen, justlen, showbaselen, sign, signlen, slashlen, zeros; 48 int justify, den_showbaselen; 49 const char *slash, *showbase; 50 51 /* '+' or ' ' if wanted, and don't already have '-' */ 52 sign = p->sign; 53 if (s[0] == '-') 54 { 55 sign = s[0]; 56 s++; 57 } 58 signlen = (sign != '\0'); 59 60 /* if the precision was explicitly 0, print nothing for a 0 value */ 61 if (*s == '0' && p->prec == 0) 62 s++; 63 64 slen = strlen (s); 65 slash = strchr (s, '/'); 66 67 showbase = NULL; 68 showbaselen = 0; 69 70 if (p->showbase != DOPRNT_SHOWBASE_NO) 71 { 72 switch (p->base) { 73 case 16: showbase = "0x"; showbaselen = 2; break; 74 case -16: showbase = "0X"; showbaselen = 2; break; 75 case 8: showbase = "0"; showbaselen = 1; break; 76 } 77 } 78 79 den_showbaselen = showbaselen; 80 if (slash == NULL 81 || (p->showbase == DOPRNT_SHOWBASE_NONZERO && slash[1] == '0')) 82 den_showbaselen = 0; 83 84 if (p->showbase == DOPRNT_SHOWBASE_NONZERO && s[0] == '0') 85 showbaselen = 0; 86 87 /* the influence of p->prec on mpq is currently undefined */ 88 zeros = MAX (0, p->prec - slen); 89 90 /* space left over after actual output length */ 91 justlen = p->width 92 - (strlen(s) + signlen + showbaselen + den_showbaselen + zeros); 93 94 justify = p->justify; 95 if (justlen <= 0) /* no justifying if exceed width */ 96 justify = DOPRNT_JUSTIFY_NONE; 97 98 if (justify == DOPRNT_JUSTIFY_RIGHT) /* pad right */ 99 DOPRNT_REPS (p->fill, justlen); 100 101 DOPRNT_REPS_MAYBE (sign, signlen); /* sign */ 102 103 DOPRNT_MEMORY_MAYBE (showbase, showbaselen); /* base */ 104 105 DOPRNT_REPS_MAYBE ('0', zeros); /* zeros */ 106 107 if (justify == DOPRNT_JUSTIFY_INTERNAL) /* pad internal */ 108 DOPRNT_REPS (p->fill, justlen); 109 110 /* if there's a showbase on the denominator, then print the numerator 111 separately so it can be inserted */ 112 if (den_showbaselen != 0) 113 { 114 ASSERT (slash != NULL); 115 slashlen = slash+1 - s; 116 DOPRNT_MEMORY (s, slashlen); /* numerator and slash */ 117 slen -= slashlen; 118 s += slashlen; 119 DOPRNT_MEMORY (showbase, den_showbaselen); 120 } 121 122 DOPRNT_MEMORY (s, slen); /* number, or denominator */ 123 124 if (justify == DOPRNT_JUSTIFY_LEFT) /* pad left */ 125 DOPRNT_REPS (p->fill, justlen); 126 127 done: 128 return retval; 129 130 error: 131 retval = -1; 132 goto done; 133 } 134