doprnti.c revision 1.1.1.1
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 7Copyright 2001 Free Software Foundation, Inc. 8 9This file is part of the GNU MP Library. 10 11The GNU MP Library is free software; you can redistribute it and/or modify 12it under the terms of the GNU Lesser General Public License as published by 13the Free Software Foundation; either version 3 of the License, or (at your 14option) any later version. 15 16The GNU MP Library is distributed in the hope that it will be useful, but 17WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 19License for more details. 20 21You should have received a copy of the GNU Lesser General Public License 22along 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 40int 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