Changeset f2b8cdc in mainline
- Timestamp:
- 2009-04-04T22:04:28Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b27eb71
- Parents:
- 4527fb5
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/string.h
r4527fb5 rf2b8cdc 65 65 66 66 extern wchar_t str_decode(const char *str, size_t *offset, size_t sz); 67 extern int chr_encode( constwchar_t ch, char *str, size_t *offset, size_t sz);67 extern int chr_encode(wchar_t ch, char *str, size_t *offset, size_t sz); 68 68 69 69 extern size_t str_size(const char *str); … … 79 79 extern count_t wstr_nlength(const wchar_t *str, size_t size); 80 80 81 extern bool ascii_check( constwchar_t ch);82 extern bool chr_check( constwchar_t ch);81 extern bool ascii_check(wchar_t ch); 82 extern bool chr_check(wchar_t ch); 83 83 84 84 extern int str_cmp(const char *s1, const char *s2); -
kernel/generic/src/lib/string.c
r4527fb5 rf2b8cdc 207 207 * code was invalid. 208 208 */ 209 int chr_encode( constwchar_t ch, char *str, size_t *offset, size_t size)209 int chr_encode(wchar_t ch, char *str, size_t *offset, size_t size) 210 210 { 211 211 if (*offset >= size) … … 423 423 * 424 424 */ 425 bool ascii_check( constwchar_t ch)425 bool ascii_check(wchar_t ch) 426 426 { 427 427 if ((ch >= 0) && (ch <= 127)) … … 436 436 * 437 437 */ 438 bool chr_check( constwchar_t ch)438 bool chr_check(wchar_t ch) 439 439 { 440 440 if ((ch >= 0) && (ch <= 1114111)) -
uspace/lib/libc/arch/amd64/include/types.h
r4527fb5 rf2b8cdc 48 48 typedef unsigned long long int uint64_t; 49 49 50 typedef int64_t ssize_t; 51 typedef uint64_t size_t; 52 typedef uint64_t count_t; 53 typedef uint64_t index_t; 54 50 55 typedef uint64_t uintptr_t; 51 56 -
uspace/lib/libc/arch/arm32/include/types.h
r4527fb5 rf2b8cdc 49 49 typedef unsigned long long int uint64_t; 50 50 51 typedef int32_t ssize_t; 52 typedef uint32_t size_t; 53 typedef uint32_t count_t; 54 typedef uint32_t index_t; 55 51 56 typedef uint32_t uintptr_t; 52 57 -
uspace/lib/libc/arch/ia32/include/types.h
r4527fb5 rf2b8cdc 48 48 typedef unsigned long long int uint64_t; 49 49 50 typedef int32_t ssize_t; 51 typedef uint32_t size_t; 52 typedef uint32_t count_t; 53 typedef uint32_t index_t; 54 50 55 typedef uint32_t uintptr_t; 51 56 -
uspace/lib/libc/arch/ia64/include/types.h
r4527fb5 rf2b8cdc 48 48 typedef unsigned long int uint64_t; 49 49 50 typedef int64_t ssize_t; 51 typedef uint64_t size_t; 52 typedef uint64_t count_t; 53 typedef uint64_t index_t; 54 50 55 typedef uint64_t uintptr_t; 51 56 -
uspace/lib/libc/arch/mips32/include/types.h
r4527fb5 rf2b8cdc 49 49 typedef unsigned long long int uint64_t; 50 50 51 typedef int32_t ssize_t; 52 typedef uint32_t size_t; 53 typedef uint32_t count_t; 54 typedef uint32_t index_t; 55 51 56 typedef uint32_t uintptr_t; 52 57 -
uspace/lib/libc/arch/ppc32/include/types.h
r4527fb5 rf2b8cdc 48 48 typedef unsigned long long int uint64_t; 49 49 50 typedef int32_t ssize_t; 51 typedef uint32_t size_t; 52 typedef uint32_t count_t; 53 typedef uint32_t index_t; 54 50 55 typedef uint32_t uintptr_t; 51 56 -
uspace/lib/libc/arch/sparc64/include/types.h
r4527fb5 rf2b8cdc 48 48 typedef unsigned long int uint64_t; 49 49 50 typedef int64_t ssize_t; 51 typedef uint64_t size_t; 52 typedef uint64_t count_t; 53 typedef uint64_t index_t; 54 50 55 typedef uint64_t uintptr_t; 51 56 -
uspace/lib/libc/generic/io/fprintf.c
r4527fb5 rf2b8cdc 39 39 #include <io/printf_core.h> 40 40 41 static int vfprintf_ write(const char *s, size_t count, void *f)41 static int vfprintf_str_write(const char *s, size_t size, void *f) 42 42 { 43 return fwrite(s, 1, count, (FILE *) f); 43 /* FIXME: Should return number of characters? */ 44 return fwrite(s, 1, size, (FILE *) f); 45 } 46 47 static int vfprintf_wstr_write(const char *s, size_t size, void *f) 48 { 49 /* TODO */ 50 return size; 44 51 } 45 52 … … 47 54 { 48 55 struct printf_spec ps = { 49 (int (*)(void *, size_t, void *)) vfprintf_write, 56 vfprintf_str_write, 57 vfprintf_wstr_write, 50 58 (void *) f 51 59 }; -
uspace/lib/libc/generic/io/printf_core.c
r4527fb5 rf2b8cdc 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 3 * Copyright (c) 2006 Josef Cejka 4 * Copyright (c) 2009 Martin Decky 4 5 * All rights reserved. 5 6 * … … 28 29 */ 29 30 30 /** @addtogroup libc31 /** @addtogroup generic 31 32 * @{ 32 33 */ 33 34 /** 34 35 * @file 35 * @brief 36 * @brief Printing functions. 36 37 */ 37 38 … … 42 43 #include <string.h> 43 44 44 #define __PRINTF_FLAG_PREFIX 0x00000001 /**< show prefixes 0x or 0*/ 45 #define __PRINTF_FLAG_SIGNED 0x00000002 /**< signed / unsigned number */ 46 #define __PRINTF_FLAG_ZEROPADDED 0x00000004 /**< print leading zeroes */ 47 #define __PRINTF_FLAG_LEFTALIGNED 0x00000010 /**< align to left */ 48 #define __PRINTF_FLAG_SHOWPLUS 0x00000020 /**< always show + sign */ 49 #define __PRINTF_FLAG_SPACESIGN 0x00000040 /**< print space instead of plus */ 50 #define __PRINTF_FLAG_BIGCHARS 0x00000080 /**< show big characters */ 51 #define __PRINTF_FLAG_NEGATIVE 0x00000100 /**< number has - sign */ 52 53 #define PRINT_NUMBER_BUFFER_SIZE (64+5) /**< Buffer big enought for 64 bit number 54 * printed in base 2, sign, prefix and 55 * 0 to terminate string.. (last one is only for better testing 56 * end of buffer by zero-filling subroutine) 57 */ 45 /** show prefixes 0x or 0 */ 46 #define __PRINTF_FLAG_PREFIX 0x00000001 47 /** signed / unsigned number */ 48 #define __PRINTF_FLAG_SIGNED 0x00000002 49 /** print leading zeroes */ 50 #define __PRINTF_FLAG_ZEROPADDED 0x00000004 51 /** align to left */ 52 #define __PRINTF_FLAG_LEFTALIGNED 0x00000010 53 /** always show + sign */ 54 #define __PRINTF_FLAG_SHOWPLUS 0x00000020 55 /** print space instead of plus */ 56 #define __PRINTF_FLAG_SPACESIGN 0x00000040 57 /** show big characters */ 58 #define __PRINTF_FLAG_BIGCHARS 0x00000080 59 /** number has - sign */ 60 #define __PRINTF_FLAG_NEGATIVE 0x00000100 61 62 /** 63 * Buffer big enough for 64-bit number printed in base 2, sign, prefix and 0 64 * to terminate string... (last one is only for better testing end of buffer by 65 * zero-filling subroutine) 66 */ 67 #define PRINT_NUMBER_BUFFER_SIZE (64 + 5) 68 58 69 /** Enumeration of possible arguments types. 59 70 */ … … 64 75 PrintfQualifierLong, 65 76 PrintfQualifierLongLong, 66 PrintfQualifierSizeT,67 77 PrintfQualifierPointer 68 78 } qualifier_t; 69 79 70 static char digits_small[] = "0123456789abcdef"; /**< Small hexadecimal characters */ 71 static char digits_big[] = "0123456789ABCDEF"; /**< Big hexadecimal characters */ 72 73 /** Print count chars from buffer without adding newline 74 * @param buf Buffer with size at least count bytes - NULL pointer NOT allowed! 75 * @param count 76 * @param ps output method and its data 77 * @return number of printed characters 78 */ 79 static int printf_putnchars(const char * buf, size_t count, 80 struct printf_spec *ps) 81 { 82 return ps->write((void *)buf, count, ps->data); 83 } 84 85 /** Print string without added newline 86 * @param str string to print 87 * @param ps write function specification and support data 88 * @return number of printed characters 89 */ 90 static int printf_putstr(const char * str, struct printf_spec *ps) 91 { 92 size_t count; 93 80 static char nullstr[] = "(NULL)"; 81 static char digits_small[] = "0123456789abcdef"; 82 static char digits_big[] = "0123456789ABCDEF"; 83 static char invalch = U_SPECIAL; 84 85 /** Print one or more characters without adding newline. 86 * 87 * @param buf Buffer holding characters with size of 88 * at least size bytes. NULL is not allowed! 89 * @param size Size of the buffer in bytes. 90 * @param ps Output method and its data. 91 * 92 * @return Number of characters printed. 93 * 94 */ 95 static int printf_putnchars(const char *buf, size_t size, 96 printf_spec_t *ps) 97 { 98 return ps->str_write((void *) buf, size, ps->data); 99 } 100 101 /** Print one or more wide characters without adding newline. 102 * 103 * @param buf Buffer holding wide characters with size of 104 * at least size bytes. NULL is not allowed! 105 * @param size Size of the buffer in bytes. 106 * @param ps Output method and its data. 107 * 108 * @return Number of wide characters printed. 109 * 110 */ 111 static int printf_wputnchars(const wchar_t *buf, size_t size, 112 printf_spec_t *ps) 113 { 114 return ps->wstr_write((void *) buf, size, ps->data); 115 } 116 117 /** Print string without adding a newline. 118 * 119 * @param str String to print. 120 * @param ps Write function specification and support data. 121 * 122 * @return Number of characters printed. 123 * 124 */ 125 static int printf_putstr(const char *str, printf_spec_t *ps) 126 { 94 127 if (str == NULL) 95 return printf_putnchars("(NULL)", 6, ps); 96 97 count = strlen(str); 98 99 return ps->write((void *) str, count, ps->data); 100 } 101 102 /** Print one character to output 103 * @param c one character 104 * @param ps output method 105 * @return number of printed characters 106 */ 107 static int printf_putchar(int c, struct printf_spec *ps) 108 { 109 unsigned char ch = c; 110 111 return ps->write((void *) &ch, 1, ps->data); 112 } 113 114 /** Print one formatted character 115 * @param c character to print 116 * @param width 117 * @param flags 118 * @return number of printed characters 119 */ 120 static int print_char(char c, int width, uint64_t flags, struct printf_spec *ps) 121 { 122 int counter = 0; 123 128 return printf_putnchars(nullstr, str_size(nullstr), ps); 129 130 return ps->str_write((void *) str, str_size(str), ps->data); 131 } 132 133 /** Print one ASCII character. 134 * 135 * @param c ASCII character to be printed. 136 * @param ps Output method. 137 * 138 * @return Number of characters printed. 139 * 140 */ 141 static int printf_putchar(const char ch, printf_spec_t *ps) 142 { 143 if (!ascii_check(ch)) 144 return ps->str_write((void *) &invalch, 1, ps->data); 145 146 return ps->str_write(&ch, 1, ps->data); 147 } 148 149 /** Print one wide character. 150 * 151 * @param c Wide character to be printed. 152 * @param ps Output method. 153 * 154 * @return Number of characters printed. 155 * 156 */ 157 static int printf_putwchar(const wchar_t ch, printf_spec_t *ps) 158 { 159 if (!chr_check(ch)) 160 return ps->str_write((void *) &invalch, 1, ps->data); 161 162 return ps->wstr_write(&ch, sizeof(wchar_t), ps->data); 163 } 164 165 /** Print one formatted ASCII character. 166 * 167 * @param ch Character to print. 168 * @param width Width modifier. 169 * @param flags Flags that change the way the character is printed. 170 * 171 * @return Number of characters printed, negative value on failure. 172 * 173 */ 174 static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps) 175 { 176 count_t counter = 0; 124 177 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 178 while (--width > 0) { 179 /* 180 * One space is consumed by the character itself, hence 181 * the predecrement. 182 */ 183 if (printf_putchar(' ', ps) > 0) 184 counter++; 185 } 186 } 187 188 if (printf_putchar(ch, ps) > 0) 189 counter++; 190 191 while (--width > 0) { 125 192 /* 126 * One space is consumed by the character itself, hence the127 * predecrement.193 * One space is consumed by the character itself, hence 194 * the predecrement. 128 195 */ 196 if (printf_putchar(' ', ps) > 0) 197 counter++; 198 } 199 200 return (int) (counter + 1); 201 } 202 203 /** Print one formatted wide character. 204 * 205 * @param ch Character to print. 206 * @param width Width modifier. 207 * @param flags Flags that change the way the character is printed. 208 * 209 * @return Number of characters printed, negative value on failure. 210 * 211 */ 212 static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps) 213 { 214 count_t counter = 0; 215 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 129 216 while (--width > 0) { 130 if (printf_putchar(' ', ps) > 0) 131 ++counter; 132 } 133 } 134 135 if (printf_putchar(c, ps) > 0) 217 /* 218 * One space is consumed by the character itself, hence 219 * the predecrement. 220 */ 221 if (printf_putchar(' ', ps) > 0) 222 counter++; 223 } 224 } 225 226 if (printf_putwchar(ch, ps) > 0) 136 227 counter++; 137 /* 138 * One space is consumed by the character itself, hence the 139 * predecrement. 140 */ 228 141 229 while (--width > 0) { 230 /* 231 * One space is consumed by the character itself, hence 232 * the predecrement. 233 */ 142 234 if (printf_putchar(' ', ps) > 0) 143 ++counter; 144 } 145 146 return ++counter; 147 } 148 149 /** Print one string 150 * @param s string 151 * @param width 152 * @param precision 153 * @param flags 154 * @return number of printed characters 155 */ 156 static int print_string(char *s, int width, int precision, uint64_t flags, 157 struct printf_spec *ps) 158 { 159 int counter = 0; 160 size_t size; 235 counter++; 236 } 237 238 return (int) (counter + 1); 239 } 240 241 /** Print string. 242 * 243 * @param str String to be printed. 244 * @param width Width modifier. 245 * @param precision Precision modifier. 246 * @param flags Flags that modify the way the string is printed. 247 * 248 * @return Number of characters printed, negative value on failure. 249 */ 250 static int print_str(char *str, int width, unsigned int precision, 251 uint32_t flags, printf_spec_t *ps) 252 { 253 if (str == NULL) 254 return printf_putstr(nullstr, ps); 255 256 /* Print leading spaces. */ 257 count_t strw = str_length(str); 258 if (precision == 0) 259 precision = strw; 260 261 /* Left padding */ 262 count_t counter = 0; 263 width -= precision; 264 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 265 while (width-- > 0) { 266 if (printf_putchar(' ', ps) == 1) 267 counter++; 268 } 269 } 270 271 /* Part of @a str fitting into the alloted space. */ 161 272 int retval; 162 163 if (s == NULL) { 164 return printf_putstr("(NULL)", ps); 165 } 166 167 size = strlen(s); 168 169 /* print leading spaces */ 170 171 if (precision == 0) 172 precision = size; 173 273 size_t size = str_lsize(str, precision); 274 if ((retval = printf_putnchars(str, size, ps)) < 0) 275 return -counter; 276 277 counter += retval; 278 279 /* Right padding */ 280 while (width-- > 0) { 281 if (printf_putchar(' ', ps) == 1) 282 counter++; 283 } 284 285 return ((int) counter); 286 287 } 288 289 /** Print wide string. 290 * 291 * @param str Wide string to be printed. 292 * @param width Width modifier. 293 * @param precision Precision modifier. 294 * @param flags Flags that modify the way the string is printed. 295 * 296 * @return Number of wide characters printed, negative value on failure. 297 */ 298 static int print_wstr(wchar_t *str, int width, unsigned int precision, 299 uint32_t flags, printf_spec_t *ps) 300 { 301 if (str == NULL) 302 return printf_putstr(nullstr, ps); 303 304 /* Print leading spaces. */ 305 size_t strw = wstr_length(str); 306 if (precision == 0) 307 precision = strw; 308 309 /* Left padding */ 310 count_t counter = 0; 174 311 width -= precision; 175 176 312 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 177 while (width-- > 0) { 178 if (printf_putchar(' ', ps) == 1) 313 while (width-- > 0) { 314 if (printf_putchar(' ', ps) == 1) 179 315 counter++; 180 316 } 181 317 } 182 318 183 if ((retval = printf_putnchars(s, size < precision ? size : precision, 184 ps)) < 0) { 319 /* Part of @a wstr fitting into the alloted space. */ 320 int retval; 321 size_t size = wstr_lsize(str, precision); 322 if ((retval = printf_wputnchars(str, size, ps)) < 0) 185 323 return -counter; 186 } 187 188 counter += retval; 189 324 325 counter += retval; 326 327 /* Right padding */ 190 328 while (width-- > 0) { 191 if (printf_putchar(' ', ps) == 1) 192 ++counter; 193 } 194 195 return counter; 196 } 197 198 199 /** Print number in given base 200 * 201 * Print significant digits of a number in given 202 * base. 203 * 204 * @param num Number to print. 205 * @param width 206 * @param precision 207 * @param base Base to print the number in (should 208 * be in range 2 .. 16). 209 * @param flags output modifiers 210 * @return number of printed characters 329 if (printf_putchar(' ', ps) == 1) 330 counter++; 331 } 332 333 return ((int) counter); 334 } 335 336 /** Print a number in a given base. 337 * 338 * Print significant digits of a number in given base. 339 * 340 * @param num Number to print. 341 * @param width Width modifier. 342 * @param precision Precision modifier. 343 * @param base Base to print the number in (must be between 2 and 16). 344 * @param flags Flags that modify the way the number is printed. 345 * 346 * @return Number of characters printed. 211 347 * 212 348 */ 213 349 static int print_number(uint64_t num, int width, int precision, int base, 214 uint 64_t flags, struct printf_spec*ps)215 { 216 char *digits = digits_small;217 char d[PRINT_NUMBER_BUFFER_SIZE]; /* this is good enough even for218 * base == 2, prefix and sign */219 char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];220 int size = 0; /* size of number with all prefixes and signs */221 int number_size; /* size of plain number */222 char sgn;223 int retval;224 int counter = 0;225 226 i f (flags & __PRINTF_FLAG_BIGCHARS)227 digits = digits_big;228 229 *ptr-- = 0; /* Put zero at end of string */230 350 uint32_t flags, printf_spec_t *ps) 351 { 352 char *digits; 353 if (flags & __PRINTF_FLAG_BIGCHARS) 354 digits = digits_big; 355 else 356 digits = digits_small; 357 358 char data[PRINT_NUMBER_BUFFER_SIZE]; 359 char *ptr = &data[PRINT_NUMBER_BUFFER_SIZE - 1]; 360 361 /* Size of number with all prefixes and signs */ 362 int size = 0; 363 364 /* Put zero at end of string */ 365 *ptr-- = 0; 366 231 367 if (num == 0) { 232 368 *ptr-- = '0'; … … 239 375 } 240 376 241 number_size = size; 242 377 /* Size of plain number */ 378 int number_size = size; 379 243 380 /* 244 * Collect sum of all prefixes/signs/... to calculate padding and245 * leading zeroes 381 * Collect the sum of all prefixes/signs/etc. to calculate padding and 382 * leading zeroes. 246 383 */ 247 384 if (flags & __PRINTF_FLAG_PREFIX) { 248 385 switch(base) { 249 case 2: /* Binary formating is not standard, but usefull */ 386 case 2: 387 /* Binary formating is not standard, but usefull */ 250 388 size += 2; 251 389 break; … … 258 396 } 259 397 } 260 261 sgn = 0;398 399 char sgn = 0; 262 400 if (flags & __PRINTF_FLAG_SIGNED) { 263 401 if (flags & __PRINTF_FLAG_NEGATIVE) { … … 272 410 } 273 411 } 274 275 if (flags & __PRINTF_FLAG_LEFTALIGNED) {412 413 if (flags & __PRINTF_FLAG_LEFTALIGNED) 276 414 flags &= ~__PRINTF_FLAG_ZEROPADDED; 277 } 278 415 279 416 /* 280 * If number is leftaligned or precision is specified then zeropadding281 * is ignored.417 * If the number is left-aligned or precision is specified then 418 * padding with zeros is ignored. 282 419 */ 283 420 if (flags & __PRINTF_FLAG_ZEROPADDED) { 284 if ((precision == 0) && (width > size)) {421 if ((precision == 0) && (width > size)) 285 422 precision = width - size + number_size; 286 } 287 } 288 289 /* print leading spaces */ 290 291 /* We must print whole number not only a part. */ 292 if (number_size > precision) 423 } 424 425 /* Print leading spaces */ 426 if (number_size > precision) { 427 /* Print the whole number, not only a part */ 293 428 precision = number_size; 294 429 } 430 295 431 width -= precision + size - number_size; 432 count_t counter = 0; 296 433 297 434 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 298 while (width-- > 0) { 299 if (printf_putchar(' ', ps) == 1) 435 while (width-- > 0) { 436 if (printf_putchar(' ', ps) == 1) 300 437 counter++; 301 438 } 302 439 } 303 440 304 /* print sign */441 /* Print sign */ 305 442 if (sgn) { 306 443 if (printf_putchar(sgn, ps) == 1) … … 308 445 } 309 446 310 /* print prefix */ 311 447 /* Print prefix */ 312 448 if (flags & __PRINTF_FLAG_PREFIX) { 313 449 switch(base) { 314 case 2: /* Binary formating is not standard, but usefull */ 450 case 2: 451 /* Binary formating is not standard, but usefull */ 315 452 if (printf_putchar('0', ps) == 1) 316 453 counter++; … … 340 477 } 341 478 } 342 343 /* print leading zeroes */479 480 /* Print leading zeroes */ 344 481 precision -= number_size; 345 while (precision-- > 0) { 482 while (precision-- > 0) { 346 483 if (printf_putchar('0', ps) == 1) 347 484 counter++; 348 485 } 349 350 351 /* print number itself */ 352 353 if ((retval = printf_putstr(++ptr, ps)) > 0) { 486 487 /* Print the number itself */ 488 int retval; 489 if ((retval = printf_putstr(++ptr, ps)) > 0) 354 490 counter += retval; 355 } 356 357 /* print ending spaces */ 358 359 while (width-- > 0) { 360 if (printf_putchar(' ', ps) == 1) 491 492 /* Print tailing spaces */ 493 494 while (width-- > 0) { 495 if (printf_putchar(' ', ps) == 1) 361 496 counter++; 362 497 } 363 364 return counter; 365 } 366 498 499 return ((int) counter); 500 } 367 501 368 502 /** Print formatted string. … … 370 504 * Print string formatted according to the fmt parameter and variadic arguments. 371 505 * Each formatting directive must have the following form: 372 * 373 * 506 * 507 * \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION 374 508 * 375 509 * FLAGS:@n 376 * - "#" Force to print prefix.377 * For conversion \%o the prefix is 0, for %x and \%X prefixes are 0x and378 * 0X and for conversion \%b theprefix is 0b.379 * 380 * - "-"Align to left.381 * 382 * - "+"Print positive sign just as negative.383 * 384 * - " "If the printed number is positive and "+" flag is not set,385 * 386 * 387 * - "0"Print 0 as padding instead of spaces. Zeroes are placed between388 * 389 * 390 * 510 * - "#" Force to print prefix. For \%o conversion, the prefix is 0, for 511 * \%x and \%X prefixes are 0x and 0X and for conversion \%b the 512 * prefix is 0b. 513 * 514 * - "-" Align to left. 515 * 516 * - "+" Print positive sign just as negative. 517 * 518 * - " " If the printed number is positive and "+" flag is not set, 519 * print space in place of sign. 520 * 521 * - "0" Print 0 as padding instead of spaces. Zeroes are placed between 522 * sign and the rest of the number. This flag is ignored if "-" 523 * flag is specified. 524 * 391 525 * WIDTH:@n 392 * - Specify minimal width of printed argument. If it is bigger, width is 393 * ignored. If width is specified with a "*" character instead of number, 394 * width is taken from parameter list. And integer parameter is expected 395 * before parameter for processed conversion specification. If this value 396 * is negative its absolute value is taken and the "-" flag is set. 526 * - Specify the minimal width of a printed argument. If it is bigger, 527 * width is ignored. If width is specified with a "*" character instead of 528 * number, width is taken from parameter list. And integer parameter is 529 * expected before parameter for processed conversion specification. If 530 * this value is negative its absolute value is taken and the "-" flag is 531 * set. 397 532 * 398 533 * PRECISION:@n 399 * 400 * Smaller numbers are printed with leading zeroes. Bigger numbers are401 * not affected. Strings with more than precision characters are cut off.402 * Just as with width, an "*" can be used used instead of a number. An403 * integer value is then expected in parameters. When both width and404 * precision are specified using "*", the first parameter is used for405 * width and thesecond one for precision.406 * 534 * - Value precision. For numbers it specifies minimum valid numbers. 535 * Smaller numbers are printed with leading zeroes. Bigger numbers are not 536 * affected. Strings with more than precision characters are cut off. Just 537 * as with width, an "*" can be used used instead of a number. An integer 538 * value is then expected in parameters. When both width and precision are 539 * specified using "*", the first parameter is used for width and the 540 * second one for precision. 541 * 407 542 * TYPE:@n 408 * - "hh"Signed or unsigned char.@n409 * - "h" Signed or usigned short.@n410 * - "" Signed or usigned int (default value).@n411 * - "l" Signed or usigned long int.@n412 * - "ll" Signed or usigned long long int.@n413 * - "z" Type size_t.@n414 * 415 * 543 * - "hh" Signed or unsigned char.@n 544 * - "h" Signed or unsigned short.@n 545 * - "" Signed or unsigned int (default value).@n 546 * - "l" Signed or unsigned long int.@n 547 * If conversion is "c", the character is wchar_t (wide character).@n 548 * If conversion is "s", the string is wchar_t * (wide string).@n 549 * - "ll" Signed or unsigned long long int.@n 550 * 416 551 * CONVERSION:@n 417 * - % Print percentile character itself. 418 * 419 * - c Print single character. 420 * 421 * - s Print zero terminated string. If a NULL value is passed as 422 * value, "(NULL)" is printed instead. 423 * 424 * - P, p Print value of a pointer. Void * value is expected and it is 425 * printed in hexadecimal notation with prefix (as with '\%#X' or 426 * '\%#x' for 32bit or '\%#X' or '\%#x' for 64bit long pointers). 427 * 428 * - b Print value as unsigned binary number. Prefix is not printed by 429 * default. (Nonstandard extension.) 430 * 431 * - o Print value as unsigned octal number. Prefix is not printed by 432 * default. 433 * 434 * - d, i Print signed decimal number. There is no difference between d 435 * and i conversion. 436 * 437 * - u Print unsigned decimal number. 438 * 439 * - X, x Print hexadecimal number with upper- or lower-case. Prefix is 440 * not printed by default. 441 * 442 * All other characters from fmt except the formatting directives are printed in 552 * - % Print percentile character itself. 553 * 554 * - c Print single character. The character is expected to be plain 555 * ASCII (e.g. only values 0 .. 127 are valid).@n 556 * If type is "l", then the character is expected to be wide character 557 * (e.g. values 0 .. 0x10ffff are valid). 558 * 559 * - s Print zero terminated string. If a NULL value is passed as 560 * value, "(NULL)" is printed instead.@n 561 * If type is "l", then the string is expected to be wide string. 562 * 563 * - P, p Print value of a pointer. Void * value is expected and it is 564 * printed in hexadecimal notation with prefix (as with \%#X / \%#x 565 * for 32-bit or \%#X / \%#x for 64-bit long pointers). 566 * 567 * - b Print value as unsigned binary number. Prefix is not printed by 568 * default. (Nonstandard extension.) 569 * 570 * - o Print value as unsigned octal number. Prefix is not printed by 571 * default. 572 * 573 * - d, i Print signed decimal number. There is no difference between d 574 * and i conversion. 575 * 576 * - u Print unsigned decimal number. 577 * 578 * - X, x Print hexadecimal number with upper- or lower-case. Prefix is 579 * not printed by default. 580 * 581 * All other characters from fmt except the formatting directives are printed 443 582 * verbatim. 444 583 * 445 * @param fmt Formatting NULL terminated string. 446 * @return Number of printed characters or negative value on failure. 447 */ 448 int printf_core(const char *fmt, struct printf_spec *ps, va_list ap) 449 { 450 /* i is the index of the currently processed char from fmt */ 451 int i = 0; 452 /* j is the index to the first not printed nonformating character */ 453 int j = 0; 454 455 int end; 456 int counter; /* counter of printed characters */ 457 int retval; /* used to store return values from called functions */ 458 char c; 459 qualifier_t qualifier; /* type of argument */ 460 int base; /* base in which will be a numeric parameter printed */ 461 uint64_t number; /* argument value */ 462 size_t size; /* byte size of integer parameter */ 463 int width, precision; 464 uint64_t flags; 465 466 counter = 0; 467 468 while ((c = fmt[i])) { 469 /* control character */ 470 if (c == '%' ) { 471 /* print common characters if any processed */ 584 * @param fmt Format NULL-terminated string. 585 * 586 * @return Number of characters printed, negative value on failure. 587 * 588 */ 589 int printf_core(const char *fmt, printf_spec_t *ps, va_list ap) 590 { 591 size_t i; /* Index of the currently processed character from fmt */ 592 size_t nxt = 0; /* Index of the next character from fmt */ 593 size_t j = 0; /* Index to the first not printed nonformating character */ 594 595 count_t counter = 0; /* Number of characters printed */ 596 int retval; /* Return values from nested functions */ 597 598 while (true) { 599 i = nxt; 600 wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 601 602 if (uc == 0) 603 break; 604 605 /* Control character */ 606 if (uc == '%') { 607 /* Print common characters if any processed */ 472 608 if (i > j) { 473 if ((retval = printf_putnchars(&fmt[j], 474 (size_t)(i - j), ps)) < 0) { /* error */ 475 goto minus_out; 609 if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) { 610 /* Error */ 611 counter = -counter; 612 goto out; 476 613 } 477 614 counter += retval; 478 615 } 479 616 480 617 j = i; 481 /* parse modifiers */ 482 flags = 0; 483 end = 0; 618 619 /* Parse modifiers */ 620 uint32_t flags = 0; 621 bool end = false; 484 622 485 623 do { 486 ++i; 487 switch (c = fmt[i]) { 624 i = nxt; 625 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 626 switch (uc) { 488 627 case '#': 489 628 flags |= __PRINTF_FLAG_PREFIX; … … 502 641 break; 503 642 default: 504 end = 1; 505 }; 506 507 } while (end == 0); 508 509 /* width & '*' operator */ 510 width = 0; 511 if (isdigit(fmt[i])) { 512 while (isdigit(fmt[i])) { 643 end = true; 644 }; 645 } while (!end); 646 647 /* Width & '*' operator */ 648 int width = 0; 649 if (isdigit(uc)) { 650 while (true) { 513 651 width *= 10; 514 width += fmt[i++] - '0'; 652 width += uc - '0'; 653 654 i = nxt; 655 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 656 if (uc == 0) 657 break; 658 if (!isdigit(uc)) 659 break; 515 660 } 516 } else if (fmt[i] == '*') { 517 /* get width value from argument list*/ 518 i++; 519 width = (int)va_arg(ap, int); 661 } else if (uc == '*') { 662 /* Get width value from argument list */ 663 i = nxt; 664 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 665 width = (int) va_arg(ap, int); 520 666 if (width < 0) { 521 /* negative width sets '-' flag */667 /* Negative width sets '-' flag */ 522 668 width *= -1; 523 669 flags |= __PRINTF_FLAG_LEFTALIGNED; … … 525 671 } 526 672 527 /* precision and '*' operator */ 528 precision = 0; 529 if (fmt[i] == '.') { 530 ++i; 531 if (isdigit(fmt[i])) { 532 while (isdigit(fmt[i])) { 673 /* Precision and '*' operator */ 674 int precision = 0; 675 if (uc == '.') { 676 i = nxt; 677 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 678 if (isdigit(uc)) { 679 while (true) { 533 680 precision *= 10; 534 precision += fmt[i++] - '0'; 681 precision += uc - '0'; 682 683 i = nxt; 684 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 685 if (uc == 0) 686 break; 687 if (!isdigit(uc)) 688 break; 535 689 } 536 } else if (fmt[i] == '*') { 537 /* get precision value from argument */ 538 i++; 539 precision = (int)va_arg(ap, int); 690 } else if (uc == '*') { 691 /* Get precision value from the argument list */ 692 i = nxt; 693 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 694 precision = (int) va_arg(ap, int); 540 695 if (precision < 0) { 541 /* negative precision ignored*/696 /* Ignore negative precision */ 542 697 precision = 0; 543 698 } 544 699 } 545 700 } 546 547 switch (fmt[i++]) { 548 /** @todo unimplemented qualifiers: 549 * t ptrdiff_t - ISO C 99 701 702 qualifier_t qualifier; 703 704 switch (uc) { 705 /** @todo Unimplemented qualifiers: 706 * t ptrdiff_t - ISO C 99 550 707 */ 551 case 'h': /* char or short */ 708 case 'h': 709 /* Char or short */ 552 710 qualifier = PrintfQualifierShort; 553 if (fmt[i] == 'h') { 554 i++; 711 i = nxt; 712 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 713 if (uc == 'h') { 714 i = nxt; 715 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 555 716 qualifier = PrintfQualifierByte; 556 717 } 557 718 break; 558 case 'l': /* long or long long*/ 719 case 'l': 720 /* Long or long long */ 559 721 qualifier = PrintfQualifierLong; 560 if (fmt[i] == 'l') { 561 i++; 722 i = nxt; 723 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 724 if (uc == 'l') { 725 i = nxt; 726 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 562 727 qualifier = PrintfQualifierLongLong; 563 728 } 564 729 break; 565 case 'z': /* size_t */566 qualifier = PrintfQualifierSizeT;567 break;568 730 default: 569 /* set default type */731 /* Default type */ 570 732 qualifier = PrintfQualifierInt; 571 --i; 572 } 573 574 base = 10; 575 576 switch (c = fmt[i]) { 577 733 } 734 735 unsigned int base = 10; 736 737 switch (uc) { 578 738 /* 579 739 * String and character conversions. 580 740 */ 581 741 case 's': 582 if ((retval = print_string(va_arg(ap, char*), 583 width, precision, flags, ps)) < 0) { 584 goto minus_out; 742 if (qualifier == PrintfQualifierLong) 743 retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps); 744 else 745 retval = print_str(va_arg(ap, char *), width, precision, flags, ps); 746 747 if (retval < 0) { 748 counter = -counter; 749 goto out; 585 750 } 586 751 587 752 counter += retval; 588 j = i + 1;753 j = nxt; 589 754 goto next_char; 590 755 case 'c': 591 c = va_arg(ap, unsigned int); 592 retval = print_char(c, width, flags, ps); 756 if (qualifier == PrintfQualifierLong) 757 retval = print_wchar(va_arg(ap, wchar_t), width, flags, ps); 758 else 759 retval = print_char(va_arg(ap, unsigned int), width, flags, ps); 760 593 761 if (retval < 0) { 594 goto minus_out; 595 } 596 762 counter = -counter; 763 goto out; 764 }; 765 597 766 counter += retval; 598 j = i + 1;767 j = nxt; 599 768 goto next_char; 600 601 /* 769 770 /* 602 771 * Integer values 603 772 */ 604 case 'P': /* pointer */ 605 flags |= __PRINTF_FLAG_BIGCHARS; 773 case 'P': 774 /* Pointer */ 775 flags |= __PRINTF_FLAG_BIGCHARS; 606 776 case 'p': 607 777 flags |= __PRINTF_FLAG_PREFIX; 608 778 base = 16; 609 779 qualifier = PrintfQualifierPointer; 610 break; 611 case 'b': 780 break; 781 case 'b': 612 782 base = 2; 613 783 break; … … 617 787 case 'd': 618 788 case 'i': 619 flags |= __PRINTF_FLAG_SIGNED; 789 flags |= __PRINTF_FLAG_SIGNED; 620 790 case 'u': 621 791 break; … … 625 795 base = 16; 626 796 break; 627 /* percentile itself */ 628 case '%': 797 798 /* Percentile itself */ 799 case '%': 629 800 j = i; 630 801 goto next_char; 802 631 803 /* 632 804 * Bad formatting. … … 634 806 default: 635 807 /* 636 * Unknown format. Now, j is the index of '%', 637 * so we will print the whole bad format 638 * sequence. 808 * Unknown format. Now, j is the index of '%' 809 * so we will print whole bad format sequence. 639 810 */ 640 goto next_char; 641 } 642 643 811 goto next_char; 812 } 813 644 814 /* Print integers */ 815 size_t size; 816 uint64_t number; 645 817 switch (qualifier) { 646 818 case PrintfQualifierByte: 647 819 size = sizeof(unsigned char); 648 number = (uint64_t) va_arg(ap, unsigned int);820 number = (uint64_t) va_arg(ap, unsigned int); 649 821 break; 650 822 case PrintfQualifierShort: 651 823 size = sizeof(unsigned short); 652 number = (uint64_t) va_arg(ap, unsigned int);824 number = (uint64_t) va_arg(ap, unsigned int); 653 825 break; 654 826 case PrintfQualifierInt: 655 827 size = sizeof(unsigned int); 656 number = (uint64_t) va_arg(ap, unsigned int);828 number = (uint64_t) va_arg(ap, unsigned int); 657 829 break; 658 830 case PrintfQualifierLong: 659 831 size = sizeof(unsigned long); 660 number = (uint64_t) va_arg(ap, unsigned long);832 number = (uint64_t) va_arg(ap, unsigned long); 661 833 break; 662 834 case PrintfQualifierLongLong: 663 835 size = sizeof(unsigned long long); 664 number = (uint64_t)va_arg(ap, 665 unsigned long long); 836 number = (uint64_t) va_arg(ap, unsigned long long); 666 837 break; 667 838 case PrintfQualifierPointer: 668 839 size = sizeof(void *); 669 number = (uint64_t)(unsigned long)va_arg(ap, 670 void *); 671 break; 672 case PrintfQualifierSizeT: 673 size = sizeof(size_t); 674 number = (uint64_t)va_arg(ap, size_t); 675 break; 676 default: /* Unknown qualifier */ 677 goto minus_out; 678 840 number = (uint64_t) (unsigned long) va_arg(ap, void *); 841 break; 842 default: 843 /* Unknown qualifier */ 844 counter = -counter; 845 goto out; 679 846 } 680 847 … … 682 849 if (number & (0x1 << (size * 8 - 1))) { 683 850 flags |= __PRINTF_FLAG_NEGATIVE; 684 851 685 852 if (size == sizeof(uint64_t)) { 686 number = -((int64_t) number);853 number = -((int64_t) number); 687 854 } else { 688 855 number = ~number; … … 694 861 } 695 862 } 696 863 697 864 if ((retval = print_number(number, width, precision, 698 base, flags, ps)) < 0 ) { 699 goto minus_out; 700 } 701 865 base, flags, ps)) < 0) { 866 counter = -counter; 867 goto out; 868 } 869 702 870 counter += retval; 703 j = i + 1;704 } 871 j = nxt; 872 } 705 873 next_char: 706 707 ++i; 874 ; 708 875 } 709 876 710 877 if (i > j) { 711 retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps); 712 if (retval < 0) { /* error */ 713 goto minus_out; 878 if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) { 879 /* Error */ 880 counter = -counter; 881 goto out; 714 882 } 715 883 counter += retval; 716 884 } 717 885 718 return counter; 719 minus_out: 720 return -counter; 886 out: 887 return ((int) counter); 721 888 } 722 889 -
uspace/lib/libc/generic/io/vprintf.c
r4527fb5 rf2b8cdc 42 42 static atomic_t printf_futex = FUTEX_INITIALIZER; 43 43 44 static int vprintf_ write(const char *str, size_t count, void *unused)44 static int vprintf_str_write(const char *str, size_t size, void *data) 45 45 { 46 return write_stdout(str, count); 46 size_t offset = 0; 47 size_t prev; 48 count_t chars = 0; 49 50 while (offset < size) { 51 prev = offset; 52 str_decode(str, &offset, size); 53 write_stdout(str + prev, offset - prev); 54 chars++; 55 } 56 57 return chars; 47 58 } 59 60 static int vprintf_wstr_write(const wchar_t *str, size_t size, void *data) 61 { 62 size_t offset = 0; 63 size_t boff; 64 count_t chars = 0; 65 char buf[4]; 66 67 while (offset < size) { 68 boff = 0; 69 chr_encode(str[chars], buf, &boff, 4); 70 write_stdout(buf, boff); 71 chars++; 72 offset += sizeof(wchar_t); 73 } 74 75 return chars; 76 } 77 48 78 49 79 /** Print formatted text. … … 55 85 { 56 86 struct printf_spec ps = { 57 (int (*)(void *, size_t, void *)) vprintf_write, 87 vprintf_str_write, 88 vprintf_wstr_write, 58 89 NULL 59 90 }; -
uspace/lib/libc/generic/io/vsnprintf.c
r4527fb5 rf2b8cdc 37 37 #include <string.h> 38 38 #include <io/printf_core.h> 39 #include <errno.h> 39 40 40 struct vsnprintf_data{41 size_t size; /* total space for string*/42 size_t len; /* count of currently used characters */43 char * string; /* destination string*/44 } ;41 typedef struct { 42 size_t size; /* Total size of the buffer (in bytes) */ 43 size_t len; /* Number of already used bytes */ 44 char *dst; /* Destination */ 45 } vsnprintf_data_t; 45 46 46 47 /** Write string to given buffer. 47 * Write at most data->size characters including trailing zero. According to C9948 * has snprintf to return number of characters that would have been written if49 * enough space had been available. Hence the return value is not number of50 * really printed characters but size of input string. Number of really used51 * characters is stored in data->len.52 48 * 53 * @param str Source string to print. 54 * @param count Size of the source string. 55 * @param data Structure with destination string, counter of used space 56 * and total string size. 57 * @return Number of characters to print (not characters really 58 * printed!) 49 * Write at most data->size plain characters including trailing zero. 50 * According to C99, snprintf() has to return number of characters that 51 * would have been written if enough space had been available. Hence 52 * the return value is not the number of actually printed characters 53 * but size of the input string. 54 * 55 * @param str Source string to print. 56 * @param size Number of plain characters in str. 57 * @param data Structure describing destination string, counter 58 * of used space and total string size. 59 * 60 * @return Number of characters to print (not characters actually 61 * printed). 62 * 59 63 */ 60 static int 61 vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) 64 static int vsnprintf_str_write(const char *str, size_t size, vsnprintf_data_t *data) 62 65 { 63 size_t i; 64 i = data->size - data->len; 65 66 if (i == 0) { 67 return count; 66 size_t left = data->size - data->len; 67 68 if (left == 0) 69 return ((int) size); 70 71 if (left == 1) { 72 /* We have only one free byte left in buffer 73 * -> store trailing zero 74 */ 75 data->dst[data->size - 1] = 0; 76 data->len = data->size; 77 return ((int) size); 68 78 } 69 79 70 if ( i == 1) {71 /* 72 * We have only one free byte left in buffer => write there73 * trailing zero.80 if (left <= size) { 81 /* We do not have enough space for the whole string 82 * with the trailing zero => print only a part 83 * of string 74 84 */ 75 data->string[data->size - 1] = 0; 76 data->len = data->size; 77 return count; 85 index_t index = 0; 86 87 while (index < size) { 88 wchar_t uc = str_decode(str, &index, size); 89 90 if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK) 91 break; 92 } 93 94 /* Put trailing zero at end, but not count it 95 * into data->len so it could be rewritten next time 96 */ 97 data->dst[data->len] = 0; 98 99 return ((int) size); 78 100 } 79 101 80 if (i <= count) { 81 /* 82 * We have not enought space for whole string with the trailing 83 * zero => print only a part of string. 84 */ 85 memcpy((void *)(data->string + data->len), (void *)str, i - 1); 86 data->string[data->size - 1] = 0; 87 data->len = data->size; 88 return count; 102 /* Buffer is big enought to print the whole string */ 103 memcpy((void *)(data->dst + data->len), (void *) str, size); 104 data->len += size; 105 106 /* Put trailing zero at end, but not count it 107 * into data->len so it could be rewritten next time 108 */ 109 data->dst[data->len] = 0; 110 111 return ((int) size); 112 } 113 114 /** Write wide string to given buffer. 115 * 116 * Write at most data->size plain characters including trailing zero. 117 * According to C99, snprintf() has to return number of characters that 118 * would have been written if enough space had been available. Hence 119 * the return value is not the number of actually printed characters 120 * but size of the input string. 121 * 122 * @param str Source wide string to print. 123 * @param size Number of bytes in str. 124 * @param data Structure describing destination string, counter 125 * of used space and total string size. 126 * 127 * @return Number of wide characters to print (not characters actually 128 * printed). 129 * 130 */ 131 static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data) 132 { 133 index_t index = 0; 134 135 while (index < (size / sizeof(wchar_t))) { 136 size_t left = data->size - data->len; 137 138 if (left == 0) 139 return ((int) size); 140 141 if (left == 1) { 142 /* We have only one free byte left in buffer 143 * -> store trailing zero 144 */ 145 data->dst[data->size - 1] = 0; 146 data->len = data->size; 147 return ((int) size); 148 } 149 150 if (chr_encode(str[index], data->dst, &data->len, data->size - 1) != EOK) 151 break; 152 153 index++; 89 154 } 90 155 91 /* Buffer is big enought to print whole string */ 92 memcpy((void *)(data->string + data->len), (void *)str, count); 93 data->len += count; 94 /* 95 * Put trailing zero at end, but not count it into data->len so it could 96 * be rewritten next time. 156 /* Put trailing zero at end, but not count it 157 * into data->len so it could be rewritten next time 97 158 */ 98 data-> string[data->len] = 0;99 100 return count;159 data->dst[data->len] = 0; 160 161 return ((int) size); 101 162 } 102 163 103 /** Print formatted to the given buffer with limited size.104 * @param str Buffer.105 * @param size Bffer size.106 * @param fmt Format string.107 * \see For more details about format string see printf_core.108 */109 164 int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) 110 165 { 111 struct vsnprintf_data data = {size, 0, str}; 112 struct printf_spec ps = { 113 (int(*)(void *, size_t, void *)) vsnprintf_write, 166 vsnprintf_data_t data = { 167 size, 168 0, 169 str 170 }; 171 printf_spec_t ps = { 172 (int(*) (const char *, size_t, void *)) vsnprintf_str_write, 173 (int(*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write, 114 174 &data 115 175 }; 116 117 /* 118 * Print 0 at end of string - fix the case that nothing will be printed. 119 */ 176 177 /* Print 0 at end of string - fix the case that nothing will be printed */ 120 178 if (size > 0) 121 179 str[0] = 0; -
uspace/lib/libc/generic/string.c
r4527fb5 rf2b8cdc 40 40 #include <malloc.h> 41 41 #include <errno.h> 42 #include <align.h> 42 43 #include <string.h> 43 44 … … 193 194 } 194 195 196 /** Get size of string. 197 * 198 * Get the number of bytes which are used by the string @a str (excluding the 199 * NULL-terminator). 200 * 201 * @param str String to consider. 202 * 203 * @return Number of bytes used by the string 204 * 205 */ 206 size_t str_size(const char *str) 207 { 208 size_t size = 0; 209 210 while (*str++ != 0) 211 size++; 212 213 return size; 214 } 215 216 /** Get size of wide string. 217 * 218 * Get the number of bytes which are used by the wide string @a str (excluding the 219 * NULL-terminator). 220 * 221 * @param str Wide string to consider. 222 * 223 * @return Number of bytes used by the wide string 224 * 225 */ 226 size_t wstr_size(const wchar_t *str) 227 { 228 return (wstr_length(str) * sizeof(wchar_t)); 229 } 230 231 /** Get size of string with length limit. 232 * 233 * Get the number of bytes which are used by up to @a max_len first 234 * characters in the string @a str. If @a max_len is greater than 235 * the length of @a str, the entire string is measured (excluding the 236 * NULL-terminator). 237 * 238 * @param str String to consider. 239 * @param max_len Maximum number of characters to measure. 240 * 241 * @return Number of bytes used by the characters. 242 * 243 */ 244 size_t str_lsize(const char *str, count_t max_len) 245 { 246 count_t len = 0; 247 size_t offset = 0; 248 249 while (len < max_len) { 250 if (str_decode(str, &offset, STR_NO_LIMIT) == 0) 251 break; 252 253 len++; 254 } 255 256 return offset; 257 } 258 259 /** Get size of wide string with length limit. 260 * 261 * Get the number of bytes which are used by up to @a max_len first 262 * wide characters in the wide string @a str. If @a max_len is greater than 263 * the length of @a str, the entire wide string is measured (excluding the 264 * NULL-terminator). 265 * 266 * @param str Wide string to consider. 267 * @param max_len Maximum number of wide characters to measure. 268 * 269 * @return Number of bytes used by the wide characters. 270 * 271 */ 272 size_t wstr_lsize(const wchar_t *str, count_t max_len) 273 { 274 return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t)); 275 } 276 277 /** Get number of characters in a string. 278 * 279 * @param str NULL-terminated string. 280 * 281 * @return Number of characters in string. 282 * 283 */ 284 count_t str_length(const char *str) 285 { 286 count_t len = 0; 287 size_t offset = 0; 288 289 while (str_decode(str, &offset, STR_NO_LIMIT) != 0) 290 len++; 291 292 return len; 293 } 294 295 /** Get number of characters in a wide string. 296 * 297 * @param str NULL-terminated wide string. 298 * 299 * @return Number of characters in @a str. 300 * 301 */ 302 count_t wstr_length(const wchar_t *wstr) 303 { 304 count_t len = 0; 305 306 while (*wstr++ != 0) 307 len++; 308 309 return len; 310 } 311 312 /** Get number of characters in a string with size limit. 313 * 314 * @param str NULL-terminated string. 315 * @param size Maximum number of bytes to consider. 316 * 317 * @return Number of characters in string. 318 * 319 */ 320 count_t str_nlength(const char *str, size_t size) 321 { 322 count_t len = 0; 323 size_t offset = 0; 324 325 while (str_decode(str, &offset, size) != 0) 326 len++; 327 328 return len; 329 } 330 331 /** Get number of characters in a string with size limit. 332 * 333 * @param str NULL-terminated string. 334 * @param size Maximum number of bytes to consider. 335 * 336 * @return Number of characters in string. 337 * 338 */ 339 count_t wstr_nlength(const wchar_t *str, size_t size) 340 { 341 count_t len = 0; 342 count_t limit = ALIGN_DOWN(size, sizeof(wchar_t)); 343 count_t offset = 0; 344 345 while ((offset < limit) && (*str++ != 0)) { 346 len++; 347 offset += sizeof(wchar_t); 348 } 349 350 return len; 351 } 352 353 /** Check whether character is plain ASCII. 354 * 355 * @return True if character is plain ASCII. 356 * 357 */ 358 bool ascii_check(wchar_t ch) 359 { 360 if ((ch >= 0) && (ch <= 127)) 361 return true; 362 363 return false; 364 } 365 195 366 /** Check whether character is valid 196 367 * … … 198 369 * 199 370 */ 200 bool chr_check( constwchar_t ch)371 bool chr_check(wchar_t ch) 201 372 { 202 373 if ((ch >= 0) && (ch <= 1114111)) … … 204 375 205 376 return false; 377 } 378 379 /** Compare two NULL terminated strings. 380 * 381 * Do a char-by-char comparison of two NULL-terminated strings. 382 * The strings are considered equal iff they consist of the same 383 * characters on the minimum of their lengths. 384 * 385 * @param s1 First string to compare. 386 * @param s2 Second string to compare. 387 * 388 * @return 0 if the strings are equal, -1 if first is smaller, 389 * 1 if second smaller. 390 * 391 */ 392 int str_cmp(const char *s1, const char *s2) 393 { 394 wchar_t c1 = 0; 395 wchar_t c2 = 0; 396 397 size_t off1 = 0; 398 size_t off2 = 0; 399 400 while (true) { 401 c1 = str_decode(s1, &off1, STR_NO_LIMIT); 402 c2 = str_decode(s2, &off2, STR_NO_LIMIT); 403 404 if (c1 < c2) 405 return -1; 406 407 if (c1 > c2) 408 return 1; 409 410 if (c1 == 0 || c2 == 0) 411 break; 412 } 413 414 return 0; 415 } 416 417 /** Compare two NULL terminated strings with length limit. 418 * 419 * Do a char-by-char comparison of two NULL-terminated strings. 420 * The strings are considered equal iff they consist of the same 421 * characters on the minimum of their lengths and the length limit. 422 * 423 * @param s1 First string to compare. 424 * @param s2 Second string to compare. 425 * @param max_len Maximum number of characters to consider. 426 * 427 * @return 0 if the strings are equal, -1 if first is smaller, 428 * 1 if second smaller. 429 * 430 */ 431 int str_lcmp(const char *s1, const char *s2, count_t max_len) 432 { 433 wchar_t c1 = 0; 434 wchar_t c2 = 0; 435 436 size_t off1 = 0; 437 size_t off2 = 0; 438 439 count_t len = 0; 440 441 while (true) { 442 if (len >= max_len) 443 break; 444 445 c1 = str_decode(s1, &off1, STR_NO_LIMIT); 446 c2 = str_decode(s2, &off2, STR_NO_LIMIT); 447 448 if (c1 < c2) 449 return -1; 450 451 if (c1 > c2) 452 return 1; 453 454 if (c1 == 0 || c2 == 0) 455 break; 456 457 ++len; 458 } 459 460 return 0; 461 462 } 463 464 /** Copy NULL-terminated string. 465 * 466 * Copy source string @a src to destination buffer @a dst. 467 * No more than @a size bytes are written. NULL-terminator is always 468 * written after the last succesfully copied character (i.e. if the 469 * destination buffer is has at least 1 byte, it will be always 470 * NULL-terminated). 471 * 472 * @param src Source string. 473 * @param dst Destination buffer. 474 * @param count Size of the destination buffer. 475 * 476 */ 477 void str_ncpy(char *dst, const char *src, size_t size) 478 { 479 /* No space for the NULL-terminator in the buffer */ 480 if (size == 0) 481 return; 482 483 wchar_t ch; 484 size_t str_off = 0; 485 size_t dst_off = 0; 486 487 while ((ch = str_decode(src, &str_off, STR_NO_LIMIT)) != 0) { 488 if (chr_encode(ch, dst, &dst_off, size) != EOK) 489 break; 490 } 491 492 if (dst_off >= size) 493 dst[size - 1] = 0; 494 else 495 dst[dst_off] = 0; 496 } 497 498 /** Copy NULL-terminated wide string to string 499 * 500 * Copy source wide string @a src to destination buffer @a dst. 501 * No more than @a size bytes are written. NULL-terminator is always 502 * written after the last succesfully copied character (i.e. if the 503 * destination buffer is has at least 1 byte, it will be always 504 * NULL-terminated). 505 * 506 * @param src Source wide string. 507 * @param dst Destination buffer. 508 * @param count Size of the destination buffer. 509 * 510 */ 511 void wstr_nstr(char *dst, const wchar_t *src, size_t size) 512 { 513 /* No space for the NULL-terminator in the buffer */ 514 if (size == 0) 515 return; 516 517 wchar_t ch; 518 count_t src_idx = 0; 519 size_t dst_off = 0; 520 521 while ((ch = src[src_idx++]) != 0) { 522 if (chr_encode(ch, dst, &dst_off, size) != EOK) 523 break; 524 } 525 526 if (dst_off >= size) 527 dst[size - 1] = 0; 528 else 529 dst[dst_off] = 0; 530 } 531 532 /** Find first occurence of character in string. 533 * 534 * @param str String to search. 535 * @param ch Character to look for. 536 * 537 * @return Pointer to character in @a str or NULL if not found. 538 * 539 */ 540 const char *str_chr(const char *str, wchar_t ch) 541 { 542 wchar_t acc; 543 size_t off = 0; 544 545 while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { 546 if (acc == ch) 547 return (str + off); 548 } 549 550 return NULL; 551 } 552 553 /** Insert a wide character into a wide string. 554 * 555 * Insert a wide character into a wide string at position 556 * @a pos. The characters after the position are shifted. 557 * 558 * @param str String to insert to. 559 * @param ch Character to insert to. 560 * @param pos Character index where to insert. 561 @ @param max_pos Characters in the buffer. 562 * 563 * @return True if the insertion was sucessful, false if the position 564 * is out of bounds. 565 * 566 */ 567 bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos) 568 { 569 count_t len = wstr_length(str); 570 571 if ((pos > len) || (pos + 1 > max_pos)) 572 return false; 573 574 count_t i; 575 for (i = len; i + 1 > pos; i--) 576 str[i + 1] = str[i]; 577 578 str[pos] = ch; 579 580 return true; 581 } 582 583 /** Remove a wide character from a wide string. 584 * 585 * Remove a wide character from a wide string at position 586 * @a pos. The characters after the position are shifted. 587 * 588 * @param str String to remove from. 589 * @param pos Character index to remove. 590 * 591 * @return True if the removal was sucessful, false if the position 592 * is out of bounds. 593 * 594 */ 595 bool wstr_remove(wchar_t *str, count_t pos) 596 { 597 count_t len = wstr_length(str); 598 599 if (pos >= len) 600 return false; 601 602 count_t i; 603 for (i = pos + 1; i <= len; i++) 604 str[i - 1] = str[i]; 605 606 return true; 206 607 } 207 608 -
uspace/lib/libc/include/io/printf_core.h
r4527fb5 rf2b8cdc 40 40 41 41 /** Structure for specifying output methods for different printf clones. */ 42 struct printf_spec { 43 /* Output function, returns count of printed characters or EOF */ 44 int (*write)(void *, size_t, void *); 45 /* Support data - output stream specification, its state, locks,... */ 42 typedef struct printf_spec { 43 /* String output function, returns number of printed characters or EOF */ 44 int (*str_write)(const char *, size_t, void *); 45 46 /* Wide string output function, returns number of printed characters or EOF */ 47 int (*wstr_write)(const wchar_t *, size_t, void *); 48 49 /* User data - output stream specification, state, locks, etc. */ 46 50 void *data; 51 } printf_spec_t; 47 52 48 }; 49 50 int printf_core(const char *fmt, struct printf_spec *ps ,va_list ap); 53 int printf_core(const char *fmt, printf_spec_t *ps, va_list ap); 51 54 52 55 #endif -
uspace/lib/libc/include/string.h
r4527fb5 rf2b8cdc 42 42 #define U_SPECIAL '?' 43 43 44 /**< No size limit constant */ 45 #define STR_NO_LIMIT ((size_t) -1) 46 47 /**< Maximum size of a string containing cnt characters */ 48 #define STR_BOUNDS(cnt) (cnt << 2) 49 44 50 extern wchar_t str_decode(const char *str, size_t *offset, size_t sz); 45 51 extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz); 46 52 47 extern bool chr_check(const wchar_t ch); 53 extern size_t str_size(const char *str); 54 extern size_t wstr_size(const wchar_t *str); 55 56 extern size_t str_lsize(const char *str, count_t max_len); 57 extern size_t wstr_lsize(const wchar_t *str, count_t max_len); 58 59 extern count_t str_length(const char *str); 60 extern count_t wstr_length(const wchar_t *wstr); 61 62 extern count_t str_nlength(const char *str, size_t size); 63 extern count_t wstr_nlength(const wchar_t *str, size_t size); 64 65 extern bool ascii_check(wchar_t ch); 66 extern bool chr_check(wchar_t ch); 67 68 extern int str_cmp(const char *s1, const char *s2); 69 extern int str_lcmp(const char *s1, const char *s2, count_t max_len); 70 71 extern void str_ncpy(char *dst, const char *src, size_t size); 72 extern void wstr_nstr(char *dst, const wchar_t *src, size_t size); 73 74 extern const char *str_chr(const char *str, wchar_t ch); 75 76 extern bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos); 77 extern bool wstr_remove(wchar_t *str, count_t pos); 78 79 /* 80 * TODO: Get rid of this. 81 */ 48 82 49 83 extern int strcmp(const char *, const char *); -
uspace/lib/libc/include/sys/types.h
r4527fb5 rf2b8cdc 38 38 #include <libarch/types.h> 39 39 40 typedef unsigned long size_t;41 typedef signed long ssize_t;42 40 typedef long off_t; 43 41 typedef int mode_t;
Note:
See TracChangeset
for help on using the changeset viewer.