2840001 #include <stdint.h>
2840002 #include <stdbool.h>
2840003 #include <stdlib.h>
2840004 #include <string.h>
2840005 #include <stdio.h>
2840006 //----------------------------------------------------------------------
2840007 static size_t uimaxtoa (uintmax_t integer, char *buffer, int base,
2840008 int uppercase, size_t size);
2840009 static size_t imaxtoa (intmax_t integer, char *buffer, int base,
2840010 int uppercase, size_t size);
2840011 static size_t simaxtoa (intmax_t integer, char *buffer, int base,
2840012 int uppercase, size_t size);
2840013 static size_t uimaxtoa_fill (uintmax_t integer, char *buffer, int base,
2840014 int uppercase, int width, int filler,
2840015 int max);
2840016 static size_t imaxtoa_fill (intmax_t integer, char *buffer, int base,
2840017 int uppercase, int width, int filler,
2840018 int max);
2840019 static size_t simaxtoa_fill (intmax_t integer, char *buffer, int base,
2840020 int uppercase, int width, int filler,
2840021 int max);
2840022 static size_t strtostr_fill (char *string, char *buffer, int width,
2840023 int filler, int max);
2840024 //----------------------------------------------------------------------
2840025 int
2840026 vsnprintf (char *restrict string, size_t size,
2840027 const char *restrict format, va_list ap)
2840028 {
2840029 //
2840030 // We produce at most `size-1' characters, + '\0'.
2840031 // `size' is used also as the max size for internal
2840032 // strings, but only if it is not too big.
2840033 //
2840034 int f = 0;
2840035 int s = 0;
2840036 int remain = size - 1;
2840037 //
2840038 bool specifier = 0;
2840039 bool specifier_flags = 0;
2840040 bool specifier_width = 0;
2840041 bool specifier_precision = 0;
2840042 bool specifier_type = 0;
2840043 //
2840044 bool flag_plus = 0;
2840045 bool flag_minus = 0;
2840046 bool flag_space = 0;
2840047 bool flag_alternate = 0;
2840048 bool flag_zero = 0;
2840049 //
2840050 int alignment;
2840051 int filler;
2840052 //
2840053 intmax_t value_i;
2840054 uintmax_t value_ui;
2840055 char *value_cp;
2840056 //
2840057 size_t width;
2840058 size_t precision;
2840059 #define str_size BUFSIZ/2
2840060 char width_string[str_size];
2840061 char precision_string[str_size];
2840062 int w;
2840063 int p;
2840064 //
2840065 width_string[0] = '\0';
2840066 precision_string[0] = '\0';
2840067 //
2840068 while (format[f] != 0 && s < (size - 1))
2840069 {
2840070 if (!specifier)
2840071 {
2840072 //------------------- The context is not inside a specifier.
2840073 if (format[f] != '%')
2840074 {
2840075 string[s] = format[f];
2840076 s++;
2840077 remain--;
2840078 f++;
2840079 continue;
2840080 }
2840081 if (format[f] == '%' && format[f+1] == '%')
2840082 {
2840083 string[s] = '%';
2840084 f++;
2840085 f++;
2840086 s++;
2840087 remain--;
2840088 continue;
2840089 }
2840090 if (format[f] == '%')
2840091 {
2840092 f++;
2840093 specifier = 1;
2840094 specifier_flags = 1;
2840095 continue;
2840096 }
2840097 }
2840098 //
2840099 if (specifier && specifier_flags)
2840100 {
2840101 //------------------- The context is inside specifier flags.
2840102 if (format[f] == '+')
2840103 {
2840104 flag_plus = 1;
2840105 f++;
2840106 continue;
2840107 }
2840108 else if (format[f] == '-')
2840109 {
2840110 flag_minus = 1;
2840111 f++;
2840112 continue;
2840113 }
2840114 else if (format[f] == ' ')
2840115 {
2840116 flag_space = 1;
2840117 f++;
2840118 continue;
2840119 }
2840120 else if (format[f] == '#')
2840121 {
2840122 flag_alternate = 1;
2840123 f++;
2840124 continue;
2840125 }
2840126 else if (format[f] == '0')
2840127 {
2840128 flag_zero = 1;
2840129 f++;
2840130 continue;
2840131 }
2840132 else
2840133 {
2840134 specifier_flags = 0;
2840135 specifier_width = 1;
2840136 }
2840137 }
2840138 //
2840139 if (specifier && specifier_width)
2840140 {
2840141 //------------------- The context is inside specifier width.
2840142 for (w = 0; format[f] >= '0' && format[f] <= '9'
2840143 && w < str_size; w++)
2840144 {
2840145 width_string[w] = format[f];
2840146 f++;
2840147 }
2840148 width_string[w] = '\0';
2840149
2840150 specifier_width = 0;
2840151
2840152 if (format[f] == '.')
2840153 {
2840154 specifier_precision = 1;
2840155 f++;
2840156 }
2840157 else
2840158 {
2840159 specifier_precision = 0;
2840160 specifier_type = 1;
2840161 }
2840162 }
2840163 //
2840164 if (specifier && specifier_precision)
2840165 {
2840166 //--------------- The context is inside specifier precision.
2840167 for (p = 0; format[f] >= '0' && format[f] <= '9'
2840168 && p < str_size; p++)
2840169 {
2840170 precision_string[p] = format[f];
2840171 p++;
2840172 }
2840173 precision_string[p] = '\0';
2840174
2840175 specifier_precision = 0;
2840176 specifier_type = 1;
2840177 }
2840178 //
2840179 if (specifier && specifier_type)
2840180 {
2840181 //-------------------- The context is inside specifier type.
2840182 width = atoi (width_string);
2840183 precision = atoi (precision_string);
2840184 filler = ' ';
2840185 if (flag_zero) filler = '0';
2840186 if (flag_space) filler = ' ';
2840187 alignment = width;
2840188 if (flag_minus)
2840189 {
2840190 alignment = -alignment;
2840191 filler = ' '; // The filler character cannot
2840192 // be zero, so it is black.
2840193 }
2840194 //
2840195 if (format[f] == 'h' && format[f+1] == 'h')
2840196 {
2840197 if (format[f+2] == 'd' || format[f+2] == 'i')
2840198 {
2840199 //---------------------------- signed char, base 10.
2840200 value_i = va_arg (ap, int);
2840201 if (flag_plus)
2840202 {
2840203 s += simaxtoa_fill (value_i, &string[s], 10, 0,
2840204 alignment, filler, remain);
2840205 }
2840206 else
2840207 {
2840208 s += imaxtoa_fill (value_i, &string[s], 10, 0,
2840209 alignment, filler, remain);
2840210 }
2840211 f += 3;
2840212 }
2840213 else if (format[f+2] == 'u')
2840214 {
2840215 //-------------------------- unsigned char, base 10.
2840216 value_ui = va_arg (ap, unsigned int);
2840217 s += uimaxtoa_fill (value_ui, &string[s], 10, 0,
2840218 alignment, filler, remain);
2840219 f += 3;
2840220 }
2840221 else if (format[f+2] == 'o')
2840222 {
2840223 //--------------------------- unsigned char, base 8.
2840224 value_ui = va_arg (ap, unsigned int);
2840225 s += uimaxtoa_fill (value_ui, &string[s], 8, 0,
2840226 alignment, filler, remain);
2840227 f += 3;
2840228 }
2840229 else if (format[f+2] == 'x')
2840230 {
2840231 //-------------------------- unsigned char, base 16.
2840232 value_ui = va_arg (ap, unsigned int);
2840233 s += uimaxtoa_fill (value_ui, &string[s], 16, 0,
2840234 alignment, filler, remain);
2840235 f += 3;
2840236 }
2840237 else if (format[f+2] == 'X')
2840238 {
2840239 //-------------------------- unsigned char, base 16.
2840240 value_ui = va_arg (ap, unsigned int);
2840241 s += uimaxtoa_fill (value_ui, &string[s], 16, 1,
2840242 alignment, filler, remain);
2840243 f += 3;
2840244 }
2840245 else
2840246 {
2840247 //---------------- unsupported or unknown specifier.
2840248 f += 2;
2840249 }
2840250 }
2840251 else if (format[f] == 'h')
2840252 {
2840253 if (format[f+1] == 'd' || format[f+1] == 'i')
2840254 {
2840255 //------------------------------ short int, base 10.
2840256 value_i = va_arg (ap, int);
2840257 if (flag_plus)
2840258 {
2840259 s += simaxtoa_fill (value_i, &string[s], 10, 0,
2840260 alignment, filler, remain);
2840261 }
2840262 else
2840263 {
2840264 s += imaxtoa_fill (value_i, &string[s], 10, 0,
2840265 alignment, filler, remain);
2840266 }
2840267 f += 2;
2840268 }
2840269 else if (format[f+1] == 'u')
2840270 {
2840271 //--------------------- unsigned short int, base 10.
2840272 value_ui = va_arg (ap, unsigned int);
2840273 s += uimaxtoa_fill (value_ui, &string[s], 10, 0,
2840274 alignment, filler, remain);
2840275 f += 2;
2840276 }
2840277 else if (format[f+1] == 'o')
2840278 {
2840279 //---------------------- unsigned short int, base 8.
2840280 value_ui = va_arg (ap, unsigned int);
2840281 s += uimaxtoa_fill (value_ui, &string[s], 8, 0,
2840282 alignment, filler, remain);
2840283 f += 2;
2840284 }
2840285 else if (format[f+1] == 'x')
2840286 {
2840287 //--------------------- unsigned short int, base 16.
2840288 value_ui = va_arg (ap, unsigned int);
2840289 s += uimaxtoa_fill (value_ui, &string[s], 16, 0,
2840290 alignment, filler, remain);
2840291 f += 2;
2840292 }
2840293 else if (format[f+1] == 'X')
2840294 {
2840295 //--------------------- unsigned short int, base 16.
2840296 value_ui = va_arg (ap, unsigned int);
2840297 s += uimaxtoa_fill (value_ui, &string[s], 16, 1,
2840298 alignment, filler, remain);
2840299 f += 2;
2840300 }
2840301 else
2840302 {
2840303 //---------------- unsupported or unknown specifier.
2840304 f += 1;
2840305 }
2840306 }
2840307
2840308 //------------------------------------------------------
2840309 // There is no `long long int'.
2840310 //------------------------------------------------------
2840311
2840312 else if (format[f] == 'l')
2840313 {
2840314 if (format[f+1] == 'd' || format[f+1] == 'i')
2840315 {
2840316 //-------------------------------- long int base 10.
2840317 value_i = va_arg (ap, long int);
2840318 if (flag_plus)
2840319 {
2840320 s += simaxtoa_fill (value_i, &string[s], 10, 0,
2840321 alignment, filler, remain);
2840322 }
2840323 else
2840324 {
2840325 s += imaxtoa_fill (value_i, &string[s], 10, 0,
2840326 alignment, filler, remain);
2840327 }
2840328 f += 2;
2840329 }
2840330 else if (format[f+1] == 'u')
2840331 {
2840332 //----------------------- Unsigned long int base 10.
2840333 value_ui = va_arg (ap, unsigned long int);
2840334 s += uimaxtoa_fill (value_ui, &string[s], 10, 0,
2840335 alignment, filler, remain);
2840336 f += 2;
2840337 }
2840338 else if (format[f+1] == 'o')
2840339 {
2840340 //------------------------ Unsigned long int base 8.
2840341 value_ui = va_arg (ap, unsigned long int);
2840342 s += uimaxtoa_fill (value_ui, &string[s], 8, 0,
2840343 alignment, filler, remain);
2840344 f += 2;
2840345 }
2840346 else if (format[f+1] == 'x')
2840347 {
2840348 //----------------------- Unsigned long int base 16.
2840349 value_ui = va_arg (ap, unsigned long int);
2840350 s += uimaxtoa_fill (value_ui, &string[s], 16, 0,
2840351 alignment, filler, remain);
2840352 f += 2;
2840353 }
2840354 else if (format[f+1] == 'X')
2840355 {
2840356 //----------------------- Unsigned long int base 16.
2840357 value_ui = va_arg (ap, unsigned long int);
2840358 s += uimaxtoa_fill (value_ui, &string[s], 16, 1,
2840359 alignment, filler, remain);
2840360 f += 2;
2840361 }
2840362 else
2840363 {
2840364 //---------------- unsupported or unknown specifier.
2840365 f += 1;
2840366 }
2840367 }
2840368 else if (format[f] == 'j')
2840369 {
2840370 if (format[f+1] == 'd' || format[f+1] == 'i')
2840371 {
2840372 //-------------------------------- intmax_t base 10.
2840373 value_i = va_arg (ap, intmax_t);
2840374 if (flag_plus)
2840375 {
2840376 s += simaxtoa_fill (value_i, &string[s], 10, 0,
2840377 alignment, filler, remain);
2840378 }
2840379 else
2840380 {
2840381 s += imaxtoa_fill (value_i, &string[s], 10, 0,
2840382 alignment, filler, remain);
2840383 }
2840384 f += 2;
2840385 }
2840386 else if (format[f+1] == 'u')
2840387 {
2840388 //------------------------------- uintmax_t base 10.
2840389 value_ui = va_arg (ap, uintmax_t);
2840390 s += uimaxtoa_fill (value_ui, &string[s], 10, 0,
2840391 alignment, filler, remain);
2840392 f += 2;
2840393 }
2840394 else if (format[f+1] == 'o')
2840395 {
2840396 //-------------------------------- uintmax_t base 8.
2840397 value_ui = va_arg (ap, uintmax_t);
2840398 s += uimaxtoa_fill (value_ui, &string[s], 8, 0,
2840399 alignment, filler, remain);
2840400 f += 2;
2840401 }
2840402 else if (format[f+1] == 'x')
2840403 {
2840404 //------------------------------- uintmax_t base 16.
2840405 value_ui = va_arg (ap, uintmax_t);
2840406 s += uimaxtoa_fill (value_ui, &string[s], 16, 0,
2840407 alignment, filler, remain);
2840408 f += 2;
2840409 }
2840410 else if (format[f+1] == 'X')
2840411 {
2840412 //------------------------------- uintmax_t base 16.
2840413 value_ui = va_arg (ap, uintmax_t);
2840414 s += uimaxtoa_fill (value_ui, &string[s], 16, 1,
2840415 alignment, filler, remain);
2840416 f += 2;
2840417 }
2840418 else
2840419 {
2840420 //---------------- unsupported or unknown specifier.
2840421 f += 1;
2840422 }
2840423 }
2840424 else if (format[f] == 'z')
2840425 {
2840426 if (format[f+1] == 'd'
2840427 || format[f+1] == 'i'
2840428 || format[f+1] == 'i')
2840429 {
2840430 //---------------------------------- size_t base 10.
2840431 value_ui = va_arg (ap, unsigned long int);
2840432 s += uimaxtoa_fill (value_ui, &string[s], 10, 0,
2840433 alignment, filler, remain);
2840434 f += 2;
2840435 }
2840436 else if (format[f+1] == 'o')
2840437 {
2840438 //----------------------------------- size_t base 8.
2840439 value_ui = va_arg (ap, unsigned long int);
2840440 s += uimaxtoa_fill (value_ui, &string[s], 8, 0,
2840441 alignment, filler, remain);
2840442 f += 2;
2840443 }
2840444 else if (format[f+1] == 'x')
2840445 {
2840446 //---------------------------------- size_t base 16.
2840447 value_ui = va_arg (ap, unsigned long int);
2840448 s += uimaxtoa_fill (value_ui, &string[s], 16, 0,
2840449 alignment, filler, remain);
2840450 f += 2;
2840451 }
2840452 else if (format[f+1] == 'X')
2840453 {
2840454 //---------------------------------- size_t base 16.
2840455 value_ui = va_arg (ap, unsigned long int);
2840456 s += uimaxtoa_fill (value_ui, &string[s], 16, 1,
2840457 alignment, filler, remain);
2840458 f += 2;
2840459 }
2840460 else
2840461 {
2840462 //---------------- unsupported or unknown specifier.
2840463 f += 1;
2840464 }
2840465 }
2840466 else if (format[f] == 't')
2840467 {
2840468 if (format[f+1] == 'd' || format[f+1] == 'i')
2840469 {
2840470 //------------------------------- ptrdiff_t base 10.
2840471 value_i = va_arg (ap, long int);
2840472 if (flag_plus)
2840473 {
2840474 s += simaxtoa_fill (value_i, &string[s], 10, 0,
2840475 alignment, filler, remain);
2840476 }
2840477 else
2840478 {
2840479 s += imaxtoa_fill (value_i, &string[s], 10, 0,
2840480 alignment, filler, remain);
2840481 }
2840482 f += 2;
2840483 }
2840484 else if (format[f+1] == 'u')
2840485 {
2840486 //----------------- ptrdiff_t base 10, without sign.
2840487 value_ui = va_arg (ap, unsigned long int);
2840488 s += uimaxtoa_fill (value_ui, &string[s], 10, 0,
2840489 alignment, filler, remain);
2840490 f += 2;
2840491 }
2840492 else if (format[f+1] == 'o')
2840493 {
2840494 //------------------ ptrdiff_t base 8, without sign.
2840495 value_ui = va_arg (ap, unsigned long int);
2840496 s += uimaxtoa_fill (value_ui, &string[s], 8, 0,
2840497 alignment, filler, remain);
2840498 f += 2;
2840499 }
2840500 else if (format[f+1] == 'x')
2840501 {
2840502 //----------------- ptrdiff_t base 16, without sign.
2840503 value_ui = va_arg (ap, unsigned long int);
2840504 s += uimaxtoa_fill (value_ui, &string[s], 16, 0,
2840505 alignment, filler, remain);
2840506 f += 2;
2840507 }
2840508 else if (format[f+1] == 'X')
2840509 {
2840510 //----------------- ptrdiff_t base 16, without sign.
2840511 value_ui = va_arg (ap, unsigned long int);
2840512 s += uimaxtoa_fill (value_ui, &string[s], 16, 1,
2840513 alignment, filler, remain);
2840514 f += 2;
2840515 }
2840516 else
2840517 {
2840518 //---------------- unsupported or unknown specifier.
2840519 f += 1;
2840520 }
2840521 }
2840522 if (format[f] == 'd' || format[f] == 'i')
2840523 {
2840524 //----------------------------------------- int base 10.
2840525 value_i = va_arg (ap, int);
2840526 if (flag_plus)
2840527 {
2840528 s += simaxtoa_fill (value_i, &string[s], 10, 0,
2840529 alignment, filler, remain);
2840530 }
2840531 else
2840532 {
2840533 s += imaxtoa_fill (value_i, &string[s], 10, 0,
2840534 alignment, filler, remain);
2840535 }
2840536 f += 1;
2840537 }
2840538 else if (format[f] == 'u')
2840539 {
2840540 //-------------------------------- unsigned int base 10.
2840541 value_ui = va_arg (ap, unsigned int);
2840542 s += uimaxtoa_fill (value_ui, &string[s], 10, 0,
2840543 alignment, filler, remain);
2840544 f += 1;
2840545 }
2840546 else if (format[f] == 'o')
2840547 {
2840548 //--------------------------------- unsigned int base 8.
2840549 value_ui = va_arg (ap, unsigned int);
2840550 s += uimaxtoa_fill (value_ui, &string[s], 8, 0,
2840551 alignment, filler, remain);
2840552 f += 1;
2840553 }
2840554 else if (format[f] == 'x')
2840555 {
2840556 //-------------------------------- unsigned int base 16.
2840557 value_ui = va_arg (ap, unsigned int);
2840558 s += uimaxtoa_fill (value_ui, &string[s], 16, 0,
2840559 alignment, filler, remain);
2840560 f += 1;
2840561 }
2840562 else if (format[f] == 'X')
2840563 {
2840564 //-------------------------------- unsigned int base 16.
2840565 value_ui = va_arg (ap, unsigned int);
2840566 s += uimaxtoa_fill (value_ui, &string[s], 16, 1,
2840567 alignment, filler, remain);
2840568 f += 1;
2840569 }
2840570 else if (format[f] == 'c')
2840571 {
2840572 //--------------------------------------- unsigned char.
2840573 value_ui = va_arg (ap, unsigned int);
2840574 string[s] = (char) value_ui;
2840575 s += 1;
2840576 f += 1;
2840577 }
2840578 else if (format[f] == 's')
2840579 {
2840580 //---------------------------------------------- string.
2840581 value_cp = va_arg (ap, char *);
2840582 filler = ' ';
2840583
2840584 s += strtostr_fill (value_cp, &string[s], alignment,
2840585 filler, remain);
2840586 f += 1;
2840587 }
2840588 else
2840589 {
2840590 //-------------------- unsupported or unknown specifier.
2840591 ;
2840592 }
2840593 //----------------------------------------------------------
2840594 // End of specifier.
2840595 //----------------------------------------------------------
2840596 width_string[0] = '\0';
2840597 precision_string[0] = '\0';
2840598
2840599 specifier = 0;
2840600 specifier_flags = 0;
2840601 specifier_width = 0;
2840602 specifier_precision = 0;
2840603 specifier_type = 0;
2840604
2840605 flag_plus = 0;
2840606 flag_minus = 0;
2840607 flag_space = 0;
2840608 flag_alternate = 0;
2840609 flag_zero = 0;
2840610 }
2840611 }
2840612 string[s] = '\0';
2840613 return s;
2840614 }
2840615 //----------------------------------------------------------------------
2840616 // Static functions.
2840617 //----------------------------------------------------------------------
2840618 static size_t
2840619 uimaxtoa (uintmax_t integer, char *buffer, int base, int uppercase,
2840620 size_t size)
2840621 {
2840622 //------------------------------------------------------------------
2840623 // Convert a maximum rank integer into a string.
2840624 //------------------------------------------------------------------
2840625
2840626 uintmax_t integer_copy = integer;
2840627 size_t digits;
2840628 int b;
2840629 unsigned char remainder;
2840630
2840631 for (digits = 0; integer_copy > 0; digits++)
2840632 {
2840633 integer_copy = integer_copy / base;
2840634 }
2840635
2840636 if (buffer == NULL && integer == 0) return 1;
2840637 if (buffer == NULL && integer > 0) return digits;
2840638
2840639 if (integer == 0)
2840640 {
2840641 buffer[0] = '0';
2840642 buffer[1] = '\0';
2840643 return 1;
2840644 }
2840645 //
2840646 // Fix the maximum number of digits.
2840647 //
2840648 if (size > 0 && digits > size) digits = size;
2840649 //
2840650 *(buffer + digits) = '\0'; // End of string.
2840651
2840652 for (b = digits - 1; integer != 0 && b >= 0; b--)
2840653 {
2840654 remainder = integer % base;
2840655 integer = integer / base;
2840656
2840657 if (remainder <= 9)
2840658 {
2840659 *(buffer + b) = remainder + '0';
2840660 }
2840661 else
2840662 {
2840663 if (uppercase)
2840664 {
2840665 *(buffer + b) = remainder - 10 + 'A';
2840666 }
2840667 else
2840668 {
2840669 *(buffer + b) = remainder - 10 + 'a';
2840670 }
2840671 }
2840672 }
2840673 return digits;
2840674 }
2840675 //----------------------------------------------------------------------
2840676 static size_t
2840677 imaxtoa (intmax_t integer, char *buffer, int base, int uppercase,
2840678 size_t size)
2840679 {
2840680 //------------------------------------------------------------------
2840681 // Convert a maximum rank integer with sign into a string.
2840682 //------------------------------------------------------------------
2840683
2840684 if (integer >= 0)
2840685 {
2840686 return uimaxtoa (integer, buffer, base, uppercase, size);
2840687 }
2840688 //
2840689 // At this point, there is a negative number, less than zero.
2840690 //
2840691 if (buffer == NULL)
2840692 {
2840693 return uimaxtoa (-integer, NULL, base, uppercase, size) + 1;
2840694 }
2840695
2840696 *buffer = '-'; // The minus sign is needed at the beginning.
2840697 if (size == 1)
2840698 {
2840699 *(buffer + 1) = '\0';
2840700 return 1;
2840701 }
2840702 else
2840703 {
2840704 return uimaxtoa (-integer, buffer+1, base, uppercase, size-1)
2840705 + 1;
2840706 }
2840707 }
2840708 //----------------------------------------------------------------------
2840709 static size_t
2840710 simaxtoa (intmax_t integer, char *buffer, int base, int uppercase,
2840711 size_t size)
2840712 {
2840713 //------------------------------------------------------------------
2840714 // Convert a maximum rank integer with sign into a string, placing
2840715 // the sign also if it is positive.
2840716 //------------------------------------------------------------------
2840717
2840718 if (buffer == NULL && integer >= 0)
2840719 {
2840720 return uimaxtoa (integer, NULL, base, uppercase, size) + 1;
2840721 }
2840722
2840723 if (buffer == NULL && integer < 0)
2840724 {
2840725 return uimaxtoa (-integer, NULL, base, uppercase, size) + 1;
2840726 }
2840727 //
2840728 // At this point, `buffer' is different from NULL.
2840729 //
2840730 if (integer >= 0)
2840731 {
2840732 *buffer = '+';
2840733 }
2840734 else
2840735 {
2840736 *buffer = '-';
2840737 }
2840738
2840739 if (size == 1)
2840740 {
2840741 *(buffer + 1) = '\0';
2840742 return 1;
2840743 }
2840744
2840745 if (integer >= 0)
2840746 {
2840747 return uimaxtoa (integer, buffer+1, base, uppercase, size-1)
2840748 + 1;
2840749 }
2840750 else
2840751 {
2840752 return uimaxtoa (-integer, buffer+1, base, uppercase, size-1)
2840753 + 1;
2840754 }
2840755 }
2840756 //----------------------------------------------------------------------
2840757 static size_t
2840758 uimaxtoa_fill (uintmax_t integer, char *buffer, int base,
2840759 int uppercase, int width, int filler, int max)
2840760 {
2840761 //------------------------------------------------------------------
2840762 // Convert a maximum rank integer without sign into a string,
2840763 // takeing care of the alignment.
2840764 //------------------------------------------------------------------
2840765
2840766 size_t size_i;
2840767 size_t size_f;
2840768
2840769 if (max < 0) return 0; // «max» deve essere un valore positivo.
2840770
2840771 size_i = uimaxtoa (integer, NULL, base, uppercase, 0);
2840772
2840773 if (width > 0 && max > 0 && width > max) width = max;
2840774 if (width < 0 && -max < 0 && width < -max) width = -max;
2840775
2840776 if (size_i > abs (width))
2840777 {
2840778 return uimaxtoa (integer, buffer, base, uppercase, abs (width));
2840779 }
2840780
2840781 if (width == 0 && max > 0)
2840782 {
2840783 return uimaxtoa (integer, buffer, base, uppercase, max);
2840784 }
2840785
2840786 if (width == 0)
2840787 {
2840788 return uimaxtoa (integer, buffer, base, uppercase, abs (width));
2840789 }
2840790 //
2840791 // size_i <= abs (width).
2840792 //
2840793 size_f = abs (width) - size_i;
2840794
2840795 if (width < 0)
2840796 {
2840797 // Left alignment.
2840798 uimaxtoa (integer, buffer, base, uppercase, 0);
2840799 memset (buffer + size_i, filler, size_f);
2840800 }
2840801 else
2840802 {
2840803 // Right alignment.
2840804 memset (buffer, filler, size_f);
2840805 uimaxtoa (integer, buffer + size_f, base, uppercase, 0);
2840806 }
2840807 *(buffer + abs (width)) = '\0';
2840808
2840809 return abs (width);
2840810 }
2840811 //----------------------------------------------------------------------
2840812 static size_t
2840813 imaxtoa_fill (intmax_t integer, char *buffer, int base,
2840814 int uppercase, int width, int filler, int max)
2840815 {
2840816 //------------------------------------------------------------------
2840817 // Convert a maximum rank integer with sign into a string,
2840818 // takeing care of the alignment.
2840819 //------------------------------------------------------------------
2840820
2840821 size_t size_i;
2840822 size_t size_f;
2840823
2840824 if (max < 0) return 0; // `max' must be a positive value.
2840825
2840826 size_i = imaxtoa (integer, NULL, base, uppercase, 0);
2840827
2840828 if (width > 0 && max > 0 && width > max) width = max;
2840829 if (width < 0 && -max < 0 && width < -max) width = -max;
2840830
2840831 if (size_i > abs (width))
2840832 {
2840833 return imaxtoa (integer, buffer, base, uppercase, abs (width));
2840834 }
2840835
2840836 if (width == 0 && max > 0)
2840837 {
2840838 return imaxtoa (integer, buffer, base, uppercase, max);
2840839 }
2840840
2840841 if (width == 0)
2840842 {
2840843 return imaxtoa (integer, buffer, base, uppercase, abs (width));
2840844 }
2840845
2840846 // size_i <= abs (width).
2840847
2840848 size_f = abs (width) - size_i;
2840849
2840850 if (width < 0)
2840851 {
2840852 // Left alignment.
2840853 imaxtoa (integer, buffer, base, uppercase, 0);
2840854 memset (buffer + size_i, filler, size_f);
2840855 }
2840856 else
2840857 {
2840858 // Right alignment.
2840859 memset (buffer, filler, size_f);
2840860 imaxtoa (integer, buffer + size_f, base, uppercase, 0);
2840861 }
2840862 *(buffer + abs (width)) = '\0';
2840863
2840864 return abs (width);
2840865 }
2840866 //----------------------------------------------------------------------
2840867 static size_t
2840868 simaxtoa_fill (intmax_t integer, char *buffer, int base,
2840869 int uppercase, int width, int filler, int max)
2840870 {
2840871 //------------------------------------------------------------------
2840872 // Convert a maximum rank integer with sign into a string,
2840873 // placing the sign also if it is positive and takeing care of the
2840874 // alignment.
2840875 //------------------------------------------------------------------
2840876
2840877 size_t size_i;
2840878 size_t size_f;
2840879
2840880 if (max < 0) return 0; // `max' must be a positive value.
2840881
2840882 size_i = simaxtoa (integer, NULL, base, uppercase, 0);
2840883
2840884 if (width > 0 && max > 0 && width > max) width = max;
2840885 if (width < 0 && -max < 0 && width < -max) width = -max;
2840886
2840887 if (size_i > abs (width))
2840888 {
2840889 return simaxtoa (integer, buffer, base, uppercase, abs (width));
2840890 }
2840891
2840892 if (width == 0 && max > 0)
2840893 {
2840894 return simaxtoa (integer, buffer, base, uppercase, max);
2840895 }
2840896
2840897 if (width == 0)
2840898 {
2840899 return simaxtoa (integer, buffer, base, uppercase, abs (width));
2840900 }
2840901 //
2840902 // size_i <= abs (width).
2840903 //
2840904 size_f = abs (width) - size_i;
2840905
2840906 if (width < 0)
2840907 {
2840908 // Left alignment.
2840909 simaxtoa (integer, buffer, base, uppercase, 0);
2840910 memset (buffer + size_i, filler, size_f);
2840911 }
2840912 else
2840913 {
2840914 // Right alignment.
2840915 memset (buffer, filler, size_f);
2840916 simaxtoa (integer, buffer + size_f, base, uppercase, 0);
2840917 }
2840918 *(buffer + abs (width)) = '\0';
2840919
2840920 return abs (width);
2840921 }
2840922 //----------------------------------------------------------------------
2840923 static size_t
2840924 strtostr_fill (char *string, char *buffer, int width, int filler,
2840925 int max)
2840926 {
2840927 //------------------------------------------------------------------
2840928 // Transfer a string with care for the alignment.
2840929 //------------------------------------------------------------------
2840930
2840931 size_t size_s;
2840932 size_t size_f;
2840933
2840934 if (max < 0) return 0; // `max' must be a positive value.
2840935
2840936 size_s = strlen (string);
2840937
2840938 if (width > 0 && max > 0 && width > max) width = max;
2840939 if (width < 0 && -max < 0 && width < -max) width = -max;
2840940
2840941 if (width != 0 && size_s > abs (width))
2840942 {
2840943 memcpy (buffer, string, abs (width));
2840944 buffer[width] = '\0';
2840945 return width;
2840946 }
2840947
2840948 if (width == 0 && max > 0 && size_s > max)
2840949 {
2840950 memcpy (buffer, string, max);
2840951 buffer[max] = '\0';
2840952 return max;
2840953 }
2840954
2840955 if (width == 0 && max > 0 && size_s < max)
2840956 {
2840957 memcpy (buffer, string, size_s);
2840958 buffer[size_s] = '\0';
2840959 return size_s;
2840960 }
2840961 //
2840962 // width =! 0
2840963 // size_s <= abs (width)
2840964 //
2840965 size_f = abs (width) - size_s;
2840966
2840967 if (width < 0)
2840968 {
2840969 // Right alignment.
2840970 memset (buffer, filler, size_f);
2840971 strncpy (buffer+size_f, string, size_s);
2840972 }
2840973 else
2840974 {
2840975 // Left alignment.
2840976 strncpy (buffer, string, size_s);
2840977 memset (buffer+size_s, filler, size_f);
2840978 }
2840979 *(buffer + abs (width)) = '\0';
2840980
2840981 return abs (width);
2840982 }
2840983
2840984
|