Changeset 6c69d19 in mainline for uspace/lib/posix
- Timestamp:
- 2011-07-25T20:34:17Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 00c2de63, c936c7f
- Parents:
- 5889fc74 (diff), d542aad (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib/posix
- Files:
-
- 47 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/posix/Makefile
r5889fc74 r6c69d19 63 63 $(INCLUDE_LIBC): ../c/include 64 64 ln -s -f -n $^ $@ 65 -
uspace/lib/posix/assert.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Program assertion. 33 33 */ 34 34 … … 52 52 /** @} 53 53 */ 54 -
uspace/lib/posix/ctype.c
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Character classification. 34 34 */ 35 35 … … 43 43 * Checks whether character is a hexadecimal digit. 44 44 * 45 * @param c 46 * @return 45 * @param c Character to inspect. 46 * @return Non-zero if character match the definition, zero otherwise. 47 47 */ 48 48 int posix_isxdigit(int c) … … 56 56 * Checks whether character is a word separator. 57 57 * 58 * @param c 59 * @return 58 * @param c Character to inspect. 59 * @return Non-zero if character match the definition, zero otherwise. 60 60 */ 61 61 int posix_isblank(int c) … … 67 67 * Checks whether character is a control character. 68 68 * 69 * @param c 70 * @return 69 * @param c Character to inspect. 70 * @return Non-zero if character match the definition, zero otherwise. 71 71 */ 72 72 int posix_iscntrl(int c) … … 78 78 * Checks whether character is any printing character except space. 79 79 * 80 * @param c 81 * @return 80 * @param c Character to inspect. 81 * @return Non-zero if character match the definition, zero otherwise. 82 82 */ 83 83 int posix_isgraph(int c) … … 89 89 * Checks whether character is a printing character. 90 90 * 91 * @param c 92 * @return 91 * @param c Character to inspect. 92 * @return Non-zero if character match the definition, zero otherwise. 93 93 */ 94 94 int posix_isprint(int c) … … 100 100 * Checks whether character is a punctuation. 101 101 * 102 * @param c 103 * @return 102 * @param c Character to inspect. 103 * @return Non-zero if character match the definition, zero otherwise. 104 104 */ 105 105 int posix_ispunct(int c) 106 106 { 107 return !isspace(c) && !isalnum(c) ;107 return !isspace(c) && !isalnum(c) && posix_isprint(c); 108 108 } 109 109 … … 111 111 * Checks whether character is ASCII. (obsolete) 112 112 * 113 * @param c 114 * @return 113 * @param c Character to inspect. 114 * @return Non-zero if character match the definition, zero otherwise. 115 115 */ 116 116 extern int posix_isascii(int c) … … 122 122 * Converts argument to a 7-bit ASCII character. (obsolete) 123 123 * 124 * @param c 125 * @return 124 * @param c Character to convert. 125 * @return Coverted character. 126 126 */ 127 127 extern int posix_toascii(int c) -
uspace/lib/posix/ctype.h
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Character classification. 34 34 */ 35 35 -
uspace/lib/posix/errno.c
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file System error numbers. 33 33 */ 34 34 … … 51 51 /** @} 52 52 */ 53 -
uspace/lib/posix/errno.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file System error numbers. 33 33 */ 34 34 … … 325 325 /** @} 326 326 */ 327 -
uspace/lib/posix/fcntl.c
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file File control. 33 33 */ 34 34 -
uspace/lib/posix/fcntl.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file File control. 33 33 */ 34 34 -
uspace/lib/posix/float.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Floating type support. 33 33 */ 34 34 -
uspace/lib/posix/fnmatch.c
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Filename-matching. 33 33 */ 34 34 … … 45 45 #include "internal/common.h" 46 46 #include "fnmatch.h" 47 48 // TODO: documentation 47 49 48 50 #define INVALID_PATTERN -1 … … 169 171 }; 170 172 173 /** 174 * 175 * @param key 176 * @param elem 177 * @return 178 */ 171 179 static int _class_compare(const void *key, const void *elem) 172 180 { … … 175 183 } 176 184 185 /** 186 * 187 * @param cname 188 * @param c 189 * @return 190 */ 177 191 static bool _is_in_class (const char *cname, int c) 178 192 { … … 191 205 } 192 206 207 /** 208 * 209 * @param pattern 210 * @param str 211 * @param flags 212 * @return 213 */ 193 214 static int _match_char_class(const char **pattern, const char *str, int flags) 194 215 { … … 204 225 /************** END CHARACTER CLASSES ****************/ 205 226 227 /** 228 * 229 * @param pattern 230 * @param flags 231 * @return 232 */ 206 233 static _coll_elm_t _next_coll_elm(const char **pattern, int flags) 207 234 { … … 240 267 241 268 /** 242 * 269 * 270 * @param pattern 271 * @param str 272 * @param flags 273 * @return 243 274 */ 244 275 static int _match_bracket_expr(const char **pattern, const char *str, int flags) … … 327 358 328 359 /** 329 * 360 * 361 * @param pattern 362 * @param string 363 * @param flags 364 * @return 330 365 */ 331 366 static bool _partial_match(const char **pattern, const char **string, int flags) … … 421 456 } 422 457 458 /** 459 * 460 * @param pattern 461 * @param string 462 * @param flags 463 * @return 464 */ 423 465 static bool _full_match(const char *pattern, const char *string, int flags) 424 466 { … … 476 518 } 477 519 520 /** 521 * 522 * @param s 523 * @return 524 */ 478 525 static char *_casefold(const char *s) 479 526 { … … 506 553 507 554 if ((flags & FNM_CASEFOLD) != 0) { 508 free((char *) pattern); 509 free((char *) string); 555 if (pattern) { 556 free((char *) pattern); 557 } 558 if (string) { 559 free((char *) string); 560 } 510 561 } 511 562 … … 604 655 /** @} 605 656 */ 606 -
uspace/lib/posix/fnmatch.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Filename-matching. 33 33 */ 34 34 … … 36 36 #define POSIX_FNMATCH_H_ 37 37 38 /* Error Values .*/38 /* Error Values */ 39 39 #undef FNM_NOMATCH 40 40 #define FNM_NOMATCH 1 … … 66 66 /** @} 67 67 */ 68 -
uspace/lib/posix/internal/common.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Helper definitions common for all libposix files. 33 33 */ 34 34 -
uspace/lib/posix/inttypes.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Fixed size integer types. 33 33 */ 34 34 … … 39 39 #include "libc/inttypes.h" 40 40 41 extern posix_intmax_t posix_strtoimax(const char *restrict nptr, 42 char **restrict endptr, int base); 43 extern posix_uintmax_t posix_strtoumax(const char *restrict nptr, 44 char **restrict endptr, int base); 45 46 #ifndef LIBPOSIX_INTERNAL 47 #define strtoimax posix_strtoimax 48 #define strtoumax posix_strtoumax 49 #endif 50 41 51 #endif /* POSIX_INTTYPES_H_ */ 42 52 -
uspace/lib/posix/iso646.h
r5889fc74 r6c69d19 1 /* 2 * Copyright (c) 2011 Jiri Zarevucky 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * - The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 1 28 2 29 /** @addtogroup libposix 3 30 * @{ 4 31 */ 5 /** @file 32 /** @file Alternative spellings. 6 33 */ 7 34 … … 25 52 /** @} 26 53 */ 27 -
uspace/lib/posix/limits.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Implementation-defined limit constants. 33 33 */ 34 34 -
uspace/lib/posix/locale.c
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Locale-specific definitions. 33 33 */ 34 34 … … 41 41 #include "limits.h" 42 42 #include "string.h" 43 44 // TODO: documentation 43 45 44 46 struct __posix_locale { … … 73 75 }; 74 76 77 /** 78 * 79 * @param category 80 * @param locale 81 * @return 82 */ 75 83 char *posix_setlocale(int category, const char *locale) 76 84 { … … 83 91 } 84 92 93 /** 94 * 95 * @return 96 */ 85 97 struct posix_lconv *posix_localeconv(void) 86 98 { … … 89 101 } 90 102 103 /** 104 * 105 * @param locobj 106 * @return 107 */ 91 108 posix_locale_t posix_duplocale(posix_locale_t locobj) 92 109 { … … 104 121 } 105 122 123 /** 124 * 125 * @param locobj 126 */ 106 127 void posix_freelocale(posix_locale_t locobj) 107 128 { 108 free(locobj); 129 if (locobj) { 130 free(locobj); 131 } 109 132 } 110 133 134 /** 135 * 136 * @param category_mask 137 * @param locale 138 * @param base 139 * @return 140 */ 111 141 posix_locale_t posix_newlocale(int category_mask, const char *locale, 112 142 posix_locale_t base) … … 129 159 } 130 160 131 posix_locale_t posix_uselocale (posix_locale_t newloc) 161 /** 162 * 163 * @param newloc 164 * @return 165 */ 166 posix_locale_t posix_uselocale(posix_locale_t newloc) 132 167 { 133 168 // TODO -
uspace/lib/posix/locale.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Locale-specific definitions. 33 33 */ 34 34 35 35 #ifndef POSIX_LOCALE_H_ 36 36 #define POSIX_LOCALE_H_ 37 38 // TODO: documentation 37 39 38 40 #ifndef NULL … … 83 85 84 86 struct posix_lconv { 85 char 86 char 87 char 88 char 89 char 90 char 91 char 92 char 93 char 94 char 95 char 96 char 97 char 98 char 99 char 100 char 101 char 102 char 103 char 104 char 105 char 106 char 107 char 108 char 87 char *currency_symbol; 88 char *decimal_point; 89 char frac_digits; 90 char *grouping; 91 char *int_curr_symbol; 92 char int_frac_digits; 93 char int_n_cs_precedes; 94 char int_n_sep_by_space; 95 char int_n_sign_posn; 96 char int_p_cs_precedes; 97 char int_p_sep_by_space; 98 char int_p_sign_posn; 99 char *mon_decimal_point; 100 char *mon_grouping; 101 char *mon_thousands_sep; 102 char *negative_sign; 103 char n_cs_precedes; 104 char n_sep_by_space; 105 char n_sign_posn; 106 char *positive_sign; 107 char p_cs_precedes; 108 char p_sep_by_space; 109 char p_sign_posn; 110 char *thousands_sep; 109 111 }; 110 112 … … 117 119 extern posix_locale_t posix_newlocale(int category_mask, const char *locale, 118 120 posix_locale_t base); 119 extern posix_locale_t posix_uselocale 121 extern posix_locale_t posix_uselocale(posix_locale_t newloc); 120 122 121 123 #ifndef LIBPOSIX_INTERNAL … … 131 133 #endif 132 134 133 134 135 #endif /* POSIX_LOCALE_H_ */ 135 136 -
uspace/lib/posix/math.c
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Mathematical operations. 33 33 */ 34 34 -
uspace/lib/posix/math.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Mathematical operations. 33 33 */ 34 34 -
uspace/lib/posix/pwd.c
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Password handling. 33 33 */ 34 34 35 35 #define LIBPOSIX_INTERNAL 36 36 37 #include "pwd.h" 37 38 #include "string.h" 38 39 #include "errno.h" 39 40 41 // TODO: documentation 40 42 41 43 static bool entry_read = false; … … 53 55 * Since HelenOS doesn't have user accounts, this always returns 54 56 * the same made-up entry. 57 * 58 * @return 55 59 */ 56 60 struct posix_passwd *posix_getpwent(void) … … 178 182 /** @} 179 183 */ 180 -
uspace/lib/posix/pwd.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Password handling. 33 33 */ 34 34 35 35 #ifndef POSIX_PWD_H_ 36 36 #define POSIX_PWD_H_ 37 38 // TODO: documentation 37 39 38 40 #include "sys/types.h" … … 76 78 /** @} 77 79 */ 78 -
uspace/lib/posix/signal.c
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Signal handling. 33 33 */ 34 34 … … 45 45 #include "libc/task.h" 46 46 47 // TODO: documentation 48 47 49 /* Used to serialize signal handling. */ 48 50 static FIBRIL_MUTEX_INITIALIZE(_signal_mutex); … … 63 65 }; 64 66 67 /** 68 * 69 * @param signo 70 */ 65 71 void __posix_default_signal_handler(int signo) 66 72 { … … 118 124 } 119 125 126 /** 127 * 128 * @param signo 129 */ 120 130 void __posix_hold_signal_handler(int signo) 121 131 { … … 123 133 } 124 134 135 /** 136 * 137 * @param signo 138 */ 125 139 void __posix_ignore_signal_handler(int signo) 126 140 { … … 128 142 } 129 143 130 144 /** 145 * 146 * @param set 147 * @return 148 */ 131 149 int posix_sigemptyset(posix_sigset_t *set) 132 150 { … … 137 155 } 138 156 157 /** 158 * 159 * @param set 160 * @return 161 */ 139 162 int posix_sigfillset(posix_sigset_t *set) 140 163 { … … 145 168 } 146 169 170 /** 171 * 172 * @param set 173 * @param signo 174 * @return 175 */ 147 176 int posix_sigaddset(posix_sigset_t *set, int signo) 148 177 { … … 153 182 } 154 183 184 /** 185 * 186 * @param set 187 * @param signo 188 * @return 189 */ 155 190 int posix_sigdelset(posix_sigset_t *set, int signo) 156 191 { … … 161 196 } 162 197 198 /** 199 * 200 * @param set 201 * @param signo 202 * @return 203 */ 163 204 int posix_sigismember(const posix_sigset_t *set, int signo) 164 205 { … … 168 209 } 169 210 211 /** 212 * 213 * @param sig 214 * @param act 215 * @param oact 216 */ 170 217 static void _sigaction_unsafe(int sig, const struct posix_sigaction *restrict act, 171 218 struct posix_sigaction *restrict oact) … … 182 229 } 183 230 231 /** 232 * 233 * @param sig 234 * @param act 235 * @param oact 236 * @return 237 */ 184 238 int posix_sigaction(int sig, const struct posix_sigaction *restrict act, 185 239 struct posix_sigaction *restrict oact) … … 206 260 } 207 261 262 /** 263 * 264 * @param sig 265 * @param func 266 * @return 267 */ 208 268 void (*posix_signal(int sig, void (*func)(int)))(int) 209 269 { … … 222 282 } 223 283 284 /** 285 * 286 * @param signo 287 * @param siginfo 288 * @return 289 */ 224 290 static int _raise_sigaction(int signo, posix_siginfo_t *siginfo) 225 291 { … … 259 325 } 260 326 327 /** 328 * 329 * @param sig 330 * @return 331 */ 261 332 int posix_raise(int sig) 262 333 { … … 273 344 } 274 345 346 /** 347 * 348 * @param pid 349 * @param signo 350 * @return 351 */ 275 352 int posix_kill(posix_pid_t pid, int signo) 276 353 { … … 303 380 } 304 381 382 /** 383 * 384 * @param pid 385 * @param sig 386 * @return 387 */ 305 388 int posix_killpg(posix_pid_t pid, int sig) 306 389 { … … 309 392 } 310 393 394 /** 395 * 396 * @param pinfo 397 * @param message 398 */ 311 399 void posix_psiginfo(const posix_siginfo_t *pinfo, const char *message) 312 400 { … … 316 404 } 317 405 406 /** 407 * 408 * @param signum 409 * @param message 410 */ 318 411 void posix_psignal(int signum, const char *message) 319 412 { … … 326 419 } 327 420 421 /** 422 * 423 * @param how 424 * @param set 425 * @param oset 426 * @return 427 */ 328 428 int posix_thread_sigmask(int how, const posix_sigset_t *restrict set, 329 429 posix_sigset_t *restrict oset) … … 358 458 } 359 459 460 /** 461 * 462 * @param how 463 * @param set 464 * @param oset 465 * @return 466 */ 360 467 int posix_sigprocmask(int how, const posix_sigset_t *restrict set, 361 468 posix_sigset_t *restrict oset) … … 371 478 /** @} 372 479 */ 373 -
uspace/lib/posix/signal.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Signal handling. 33 33 */ 34 34 35 35 #ifndef POSIX_SIGNAL_H_ 36 36 #define POSIX_SIGNAL_H_ 37 38 // TODO: documentation 37 39 38 40 #include "libc/errno.h" … … 107 109 posix_mcontext_t uc_mcontext; 108 110 } posix_ucontext_t; 109 110 111 111 112 /* Values of posix_sigevent::sigev_notify */ … … 154 155 #define SIGSTKSZ 0 155 156 156 /* full POSIX set */157 /* Full POSIX set */ 157 158 enum { 158 159 /* Termination Signals */ … … 214 215 215 216 /* Values for sigaction field si_code. */ 216 217 217 enum { 218 218 SI_USER, … … 287 287 #define sigevent posix_sigevent 288 288 #endif 289 #define sigaction posix_sigaction290 289 #define mcontext_t posix_mcontext_t 291 290 #define ucontext_t posix_ucontext_t 292 291 #define stack_t posix_stack_t 293 292 #define siginfo_t posix_siginfo_t 293 294 #define sigaction posix_sigaction 294 295 295 296 #define signal posix_signal -
uspace/lib/posix/stdbool.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Boolean type and values. 33 33 */ 34 34 … … 50 50 51 51 #endif /* POSIX_STDBOOL_H_ */ 52 -
uspace/lib/posix/stddef.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Standard type definitions. 33 33 */ 34 34 -
uspace/lib/posix/stdint.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Integer types. 33 33 */ 34 34 … … 88 88 #define AOFF64_MIN UINT64_MIN 89 89 90 #undef INTMAX_MIN 91 #undef INTMAX_MAX 92 #define INTMAX_MIN INT64_MIN 93 #define INTMAX_MAX INT64_MAX 94 95 #undef UINTMAX_MIN 96 #undef UINTMAX_MAX 97 #define UINTMAX_MIN UINT64_MIN 98 #define UINTMAX_MAX UINT64_MAX 99 90 100 #include "libc/sys/types.h" 91 101 -
uspace/lib/posix/stdio.c
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Standard buffered input/output. 34 34 */ 35 35 … … 355 355 { 356 356 off64_t ret = ftell(stream); 357 if (ret == -1) { 358 return errno; 359 } 360 pos->offset = ret; 361 return 0; 357 if (ret != -1) { 358 pos->offset = ret; 359 return 0; 360 } else { 361 return -1; 362 } 362 363 } 363 364 -
uspace/lib/posix/stdio.h
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Standard buffered input/output. 34 34 */ 35 35 -
uspace/lib/posix/stdio/scanf.c
r5889fc74 r6c69d19 303 303 self->fetched = 0; 304 304 self->cursor = NULL; 305 free(self->window); 306 self->window = NULL; 305 if (self->window) { 306 free(self->window); 307 self->window = NULL; 308 } 307 309 self->window_size = 0; 308 310 self->state = _PROV_CONSTRUCTED; … … 653 655 /* Update the cursor so it can be returned to the provider. */ 654 656 cur_borrowed += cur_updated - cur_limited; 655 if (width != -1 ) {657 if (width != -1 && cur_limited != NULL) { 656 658 /* Deallocate duplicated part of the cursor view. */ 657 659 free(cur_limited); … … 833 835 /* Update the cursor so it can be returned to the provider. */ 834 836 cur_borrowed += cur_updated - cur_limited; 835 if (width != -1 ) {837 if (width != -1 && cur_limited != NULL) { 836 838 /* Deallocate duplicated part of the cursor view. */ 837 839 free(cur_limited); -
uspace/lib/posix/stdlib.c
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Standard library definitions. 34 34 */ 35 35 … … 40 40 41 41 #include "errno.h" 42 #include "limits.h" 42 43 43 44 #include "libc/sort.h" … … 59 60 60 61 /** 62 * Integer absolute value. 61 63 * 62 64 * @param i Input value. … … 69 71 70 72 /** 73 * Long integer absolute value. 71 74 * 72 75 * @param i Input value. … … 79 82 80 83 /** 84 * Long long integer absolute value. 81 85 * 82 86 * @param i Input value. … … 88 92 } 89 93 94 /** 95 * Compute the quotient and remainder of an integer division. 96 * 97 * @param numer Numerator. 98 * @param denom Denominator. 99 * @return Quotient and remainder packed into structure. 100 */ 90 101 posix_div_t posix_div(int numer, int denom) 91 102 { … … 93 104 } 94 105 106 /** 107 * Compute the quotient and remainder of a long integer division. 108 * 109 * @param numer Numerator. 110 * @param denom Denominator. 111 * @return Quotient and remainder packed into structure. 112 */ 95 113 posix_ldiv_t posix_ldiv(long numer, long denom) 96 114 { … … 98 116 } 99 117 118 /** 119 * Compute the quotient and remainder of a long long integer division. 120 * 121 * @param numer Numerator. 122 * @param denom Denominator. 123 * @return Quotient and remainder packed into structure. 124 */ 100 125 posix_lldiv_t posix_lldiv(long long numer, long long denom) 101 126 { … … 109 134 * @param elem2 Second element to compare. 110 135 * @param compare Comparison function without userdata parameter. 111 *112 136 * @return Relative ordering of the elements. 113 137 */ … … 115 139 { 116 140 int (*compare)(const void *, const void *) = userdata; 117 return compare(elem1, elem2); 141 int ret = compare(elem1, elem2); 142 143 /* Native qsort internals expect this. */ 144 if (ret < 0) { 145 return -1; 146 } else if (ret > 0) { 147 return 1; 148 } else { 149 return 0; 150 } 118 151 } 119 152 … … 121 154 * Array sorting utilizing the quicksort algorithm. 122 155 * 123 * @param array 124 * @param count 125 * @param size 126 * @param compare 156 * @param array Array of elements to sort. 157 * @param count Number of elements in the array. 158 * @param size Width of each element. 159 * @param compare Decides relative ordering of two elements. 127 160 */ 128 161 void posix_qsort(void *array, size_t count, size_t size, … … 171 204 /** 172 205 * Retrieve a value of the given environment variable. 206 * 173 207 * Since HelenOS doesn't support env variables at the moment, 174 208 * this function always returns NULL. 175 209 * 176 * @param name 177 * @return Always NULL.210 * @param name Name of the variable. 211 * @return Value of the variable or NULL if such variable does not exist. 178 212 */ 179 213 char *posix_getenv(const char *name) … … 195 229 196 230 /** 197 * 198 * @param string String to be passed to a command interpreter. 199 * @return 231 * Issue a command. 232 * 233 * @param string String to be passed to a command interpreter or NULL. 234 * @return Termination status of the command if the command is not NULL, 235 * otherwise indicate whether there is a command interpreter (non-zero) 236 * or not (zero). 200 237 */ 201 238 int posix_system(const char *string) { … … 205 242 206 243 /** 207 * 208 * @param name 209 * @param resolved 210 * @return 211 */ 212 char *posix_realpath(const char *name, char *resolved) 244 * Resolve absolute pathname. 245 * 246 * @param name Pathname to be resolved. 247 * @param resolved Either buffer for the resolved absolute pathname or NULL. 248 * @return On success, either resolved (if it was not NULL) or pointer to the 249 * newly allocated buffer containing the absolute pathname (if resolved was 250 * NULL). Otherwise NULL. 251 * 252 */ 253 char *posix_realpath(const char *restrict name, char *restrict resolved) 213 254 { 214 255 #ifndef PATH_MAX … … 254 295 * its native representation. See posix_strtold(). 255 296 * 256 * @param nptr 257 * @return 297 * @param nptr String representation of a floating-point number. 298 * @return Double-precision number resulting from the string conversion. 258 299 */ 259 300 double posix_atof(const char *nptr) … … 266 307 * its native representation. See posix_strtold(). 267 308 * 268 * @param nptr 269 * @param endptr 270 * @return 309 * @param nptr String representation of a floating-point number. 310 * @param endptr Pointer to the final part of the string which 311 * was not used for conversion. 312 * @return Single-precision number resulting from the string conversion. 271 313 */ 272 314 float posix_strtof(const char *restrict nptr, char **restrict endptr) … … 279 321 * its native representation. See posix_strtold(). 280 322 * 281 * @param nptr 282 * @param endptr 283 * @return 323 * @param nptr String representation of a floating-point number. 324 * @param endptr Pointer to the final part of the string which 325 * was not used for conversion. 326 * @return Double-precision number resulting from the string conversion. 284 327 */ 285 328 double posix_strtod(const char *restrict nptr, char **restrict endptr) … … 289 332 290 333 /** 291 * 292 * @param size 293 * @return 334 * Allocate memory chunk. 335 * 336 * @param size Size of the chunk to allocate. 337 * @return Either pointer to the allocated chunk or NULL if not possible. 294 338 */ 295 339 void *posix_malloc(size_t size) … … 299 343 300 344 /** 301 * 302 * @param nelem 303 * @param elsize 304 * @return 345 * Allocate memory for an array of elements. 346 * 347 * @param nelem Number of elements in the array. 348 * @param elsize Size of each element. 349 * @return Either pointer to the allocated array or NULL if not possible. 305 350 */ 306 351 void *posix_calloc(size_t nelem, size_t elsize) … … 310 355 311 356 /** 312 * 313 * @param ptr 314 * @param size 315 * @return 357 * Reallocate memory chunk to a new size. 358 * 359 * @param ptr Memory chunk to reallocate. Might be NULL. 360 * @param size Size of the reallocated chunk. Might be zero. 361 * @return Either NULL or the pointer to the newly reallocated chunk. 316 362 */ 317 363 void *posix_realloc(void *ptr, size_t size) 318 364 { 319 return realloc(ptr, size); 320 } 321 322 /** 323 * 324 * @param ptr 365 if (ptr != NULL && size == 0) { 366 /* Native realloc does not handle this special case. */ 367 free(ptr); 368 return NULL; 369 } else { 370 return realloc(ptr, size); 371 } 372 } 373 374 /** 375 * Free allocated memory chunk. 376 * 377 * @param ptr Memory chunk to be freed. 325 378 */ 326 379 void posix_free(void *ptr) 327 380 { 328 free(ptr); 381 if (ptr) { 382 free(ptr); 383 } 329 384 } 330 385 … … 341 396 342 397 /** 343 * Should read system load statistics. Not supported. Always returns -1. 344 * 345 * @param loadavg 346 * @param nelem 347 * @return 398 * Get system load average statistics. 399 * 400 * Not supported. Always returns -1. 401 * 402 * @param loadavg Array where the load averages shall be placed. 403 * @param nelem Maximum number of elements to be placed into the array. 404 * @return Number of elements placed into the array on success, -1 otherwise. 348 405 */ 349 406 int bsd_getloadavg(double loadavg[], int nelem) -
uspace/lib/posix/stdlib.h
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Standard library definitions. 34 34 */ 35 35 … … 56 56 extern long long posix_llabs(long long i); 57 57 58 /* Integer division */58 /* Integer Division */ 59 59 60 60 typedef struct { … … 80 80 size_t nmemb, size_t size, int (*compar)(const void *, const void *)); 81 81 82 83 82 /* Environment Access */ 84 83 extern char *posix_getenv(const char *name); 85 84 extern int posix_putenv(char *string); 86 87 85 extern int posix_system(const char *string); 88 89 86 90 87 /* Symbolic Links */ … … 101 98 extern long int posix_atol(const char *nptr); 102 99 extern long long int posix_atoll(const char *nptr); 103 104 100 extern long int posix_strtol(const char *restrict nptr, 105 101 char **restrict endptr, int base); … … 110 106 extern unsigned long long int posix_strtoull( 111 107 const char *restrict nptr, char **restrict endptr, int base); 112 113 108 114 109 /* Memory Allocation */ -
uspace/lib/posix/stdlib/strtol.c
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Backend for integer conversions. 33 33 */ 34 34 … … 38 38 #include "../stdlib.h" 39 39 40 #include "../limits.h"41 40 #include "../ctype.h" 42 41 #include "../errno.h" 43 44 // TODO: documentation 45 42 #include "../inttypes.h" 43 #include "../limits.h" 44 45 #define intmax_t posix_intmax_t 46 #define uintmax_t posix_uintmax_t 47 48 /** 49 * Decides whether a digit belongs to a particular base. 50 * 51 * @param c Character representation of the digit. 52 * @param base Base against which the digit shall be tested. 53 * @return True if the digit belongs to the base, false otherwise. 54 */ 46 55 static inline bool is_digit_in_base(int c, int base) 47 56 { … … 54 63 } 55 64 56 static inline int get_digit_in_base(int c, int base) 65 /** 66 * Derive a digit from its character representation. 67 * 68 * @param c Character representation of the digit. 69 * @return Digit value represented by an integer. 70 */ 71 static inline int digit_value(int c) 57 72 { 58 73 if (c <= '9') { … … 63 78 } 64 79 65 static inline unsigned long long internal_strtol( 80 /** 81 * Generic function for parsing an integer from it's string representation. 82 * Different variants differ in lower and upper bounds. 83 * The parsed string returned by this function is always positive, sign 84 * information is provided via a dedicated parameter. 85 * 86 * @param nptr Input string. 87 * @param endptr If non-NULL, *endptr is set to the position of the first 88 * unrecognized character. If no digit has been parsed, value of 89 * nptr is stored there (regardless of any skipped characters at the 90 * beginning). 91 * @param base Expected base of the string representation. If 0, base is 92 * determined to be decimal, octal or hexadecimal using the same rules 93 * as C syntax. Otherwise, value must be between 2 and 36, inclusive. 94 * @param min_value Lower bound for the resulting conversion. 95 * @param max_value Upper bound for the resulting conversion. 96 * @param out_negative Either NULL for unsigned conversion or a pointer to the 97 * bool variable into which shall be placed the negativity of the resulting 98 * converted value. 99 * @return The absolute value of the parsed value, or the closest in-range value 100 * if the parsed value is out of range. If the input is invalid, zero is 101 * returned and errno is set to EINVAL. 102 */ 103 static inline uintmax_t internal_strtol( 66 104 const char *restrict nptr, char **restrict endptr, int base, 67 const long long min_value, const unsigned long longmax_value,105 const intmax_t min_value, const uintmax_t max_value, 68 106 bool *restrict out_negative) 69 107 { … … 78 116 } 79 117 80 unsigned long long real_max_value = max_value; 118 /* The maximal absolute value that can be returned in this run. 119 * Depends on sign. 120 */ 121 uintmax_t real_max_value = max_value; 81 122 82 123 /* Current index in the input string. */ 83 int i = 0;124 size_t i = 0; 84 125 bool negative = false; 85 126 … … 93 134 case '-': 94 135 negative = true; 95 real_max_value = -min_value; 136 137 /* The strange computation is are there to avoid a corner case 138 * where -min_value can't be represented in intmax_t. 139 * (I'm not exactly sure what the semantics are in such a 140 * case, but this should be safe for any case.) 141 */ 142 real_max_value = (min_value == 0) 143 ? 0 144 :(((uintmax_t) -(min_value + 1)) + 1); 145 96 146 /* fallthrough */ 97 147 case '+': … … 104 154 if (nptr[i] == '0') { 105 155 if (tolower(nptr[i + 1]) == 'x') { 156 /* 0x... is hex. */ 106 157 base = 16; 107 158 i += 2; 108 159 } else { 160 /* 0... is octal. */ 109 161 base = 8; 110 162 } 111 163 } else { 164 /* Anything else is decimal by default. */ 112 165 base = 10; 113 166 } 114 167 break; 115 168 case 16: 169 /* Allow hex number to be prefixed with "0x". */ 116 170 if (nptr[i] == '0' && tolower(nptr[i + 1]) == 'x') { 117 171 i += 2; … … 133 187 * of overflow. 134 188 */ 135 u nsigned long longmax_safe_value = (real_max_value - base + 1) / base;136 137 u nsigned long longresult = 0;189 uintmax_t max_safe_value = (real_max_value - base + 1) / base; 190 191 uintmax_t result = 0; 138 192 139 193 if (real_max_value == 0) { … … 145 199 if (nptr[i] != '0') { 146 200 errno = ERANGE; 147 result = max_value;201 result = 0; 148 202 } 149 203 i++; … … 152 206 153 207 while (is_digit_in_base(nptr[i], base)) { 154 int digit = get_digit_in_base(nptr[i], base);208 int digit = digit_value(nptr[i]); 155 209 156 210 if (result > max_safe_value) { 157 211 /* corner case, check for overflow */ 158 212 159 unsigned long long 160 boundary = (real_max_value - digit) / base; 213 uintmax_t boundary = (real_max_value - digit) / base; 161 214 162 215 if (result > boundary) { 163 216 /* overflow */ 164 217 errno = ERANGE; 165 result = max_value;218 result = real_max_value; 166 219 break; 167 220 } … … 188 241 } 189 242 243 /** 244 * Convert a string to an integer. 245 * 246 * @param nptr Input string. 247 * @return Result of the conversion. 248 */ 190 249 int posix_atoi(const char *nptr) 191 250 { 192 251 bool neg = false; 193 u nsigned long longresult =252 uintmax_t result = 194 253 internal_strtol(nptr, NULL, 10, INT_MIN, INT_MAX, &neg); 195 254 196 return (int) (neg ? -result : result); 197 } 198 255 return (neg ? ((int) -result) : (int) result); 256 } 257 258 /** 259 * Convert a string to a long integer. 260 * 261 * @param nptr Input string. 262 * @return Result of the conversion. 263 */ 199 264 long posix_atol(const char *nptr) 200 265 { 201 266 bool neg = false; 202 u nsigned long longresult =267 uintmax_t result = 203 268 internal_strtol(nptr, NULL, 10, LONG_MIN, LONG_MAX, &neg); 204 269 205 return (long) (neg ? -result : result); 206 } 207 270 return (neg ? ((long) -result) : (long) result); 271 } 272 273 /** 274 * Convert a string to a long long integer. 275 * 276 * @param nptr Input string. 277 * @return Result of the conversion. 278 */ 208 279 long long posix_atoll(const char *nptr) 209 280 { 210 281 bool neg = false; 211 u nsigned long longresult =282 uintmax_t result = 212 283 internal_strtol(nptr, NULL, 10, LLONG_MIN, LLONG_MAX, &neg); 213 284 214 return (long long) (neg ? -result : result); 215 } 216 285 return (neg ? ((long long) -result) : (long long) result); 286 } 287 288 /** 289 * Convert a string to a long integer. 290 * 291 * @param nptr Input string. 292 * @param endptr Pointer to the final part of the string which 293 * was not used for conversion. 294 * @param base Expected base of the string representation. 295 * @return Result of the conversion. 296 */ 217 297 long posix_strtol(const char *restrict nptr, char **restrict endptr, int base) 218 298 { 219 299 bool neg = false; 220 u nsigned long longresult =300 uintmax_t result = 221 301 internal_strtol(nptr, endptr, base, LONG_MIN, LONG_MAX, &neg); 222 302 223 return (long) (neg ? -result : result); 224 } 225 303 return (neg ? ((long) -result) : ((long) result)); 304 } 305 306 /** 307 * Convert a string to a long long integer. 308 * 309 * @param nptr Input string. 310 * @param endptr Pointer to the final part of the string which 311 * was not used for conversion. 312 * @param base Expected base of the string representation. 313 * @return Result of the conversion. 314 */ 226 315 long long posix_strtoll( 227 316 const char *restrict nptr, char **restrict endptr, int base) 228 317 { 229 318 bool neg = false; 230 u nsigned long longresult =319 uintmax_t result = 231 320 internal_strtol(nptr, endptr, base, LLONG_MIN, LLONG_MAX, &neg); 232 321 233 return (long long) (neg ? -result : result); 234 } 235 322 return (neg ? ((long long) -result) : (long long) result); 323 } 324 325 /** 326 * Convert a string to a largest signed integer type. 327 * 328 * @param nptr Input string. 329 * @param endptr Pointer to the final part of the string which 330 * was not used for conversion. 331 * @param base Expected base of the string representation. 332 * @return Result of the conversion. 333 */ 334 intmax_t posix_strtoimax( 335 const char *restrict nptr, char **restrict endptr, int base) 336 { 337 bool neg = false; 338 uintmax_t result = 339 internal_strtol(nptr, endptr, base, INTMAX_MIN, INTMAX_MAX, &neg); 340 341 return (neg ? ((intmax_t) -result) : (intmax_t) result); 342 } 343 344 /** 345 * Convert a string to an unsigned long integer. 346 * 347 * @param nptr Input string. 348 * @param endptr Pointer to the final part of the string which 349 * was not used for conversion. 350 * @param base Expected base of the string representation. 351 * @return Result of the conversion. 352 */ 236 353 unsigned long posix_strtoul( 237 354 const char *restrict nptr, char **restrict endptr, int base) 238 355 { 239 u nsigned long longresult =356 uintmax_t result = 240 357 internal_strtol(nptr, endptr, base, 0, ULONG_MAX, NULL); 241 358 … … 243 360 } 244 361 362 /** 363 * Convert a string to an unsigned long long integer. 364 * 365 * @param nptr Input string. 366 * @param endptr Pointer to the final part of the string which 367 * was not used for conversion. 368 * @param base Expected base of the string representation. 369 * @return Result of the conversion. 370 */ 245 371 unsigned long long posix_strtoull( 246 372 const char *restrict nptr, char **restrict endptr, int base) 247 373 { 248 return internal_strtol(nptr, endptr, base, 0, ULLONG_MAX, NULL); 249 } 250 374 uintmax_t result = 375 internal_strtol(nptr, endptr, base, 0, ULLONG_MAX, NULL); 376 377 return (unsigned long long) result; 378 } 379 380 /** 381 * Convert a string to a largest unsigned integer type. 382 * 383 * @param nptr Input string. 384 * @param endptr Pointer to the final part of the string which 385 * was not used for conversion. 386 * @param base Expected base of the string representation. 387 * @return Result of the conversion. 388 */ 389 uintmax_t posix_strtoumax( 390 const char *restrict nptr, char **restrict endptr, int base) 391 { 392 uintmax_t result = 393 internal_strtol(nptr, endptr, base, 0, UINTMAX_MAX, NULL); 394 395 return result; 396 } 251 397 252 398 /** @} 253 399 */ 254 -
uspace/lib/posix/stdlib/strtold.c
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Backend for floating point conversions. 33 33 */ 34 34 … … 46 46 #include "../strings.h" 47 47 #include "../errno.h" 48 #include "../limits.h" 49 50 // FIXME: #include <float.h> 48 51 49 52 #ifndef HUGE_VALL … … 52 55 53 56 #ifndef abs 54 #define abs(x) ((x < 0) ? -x : x) 55 #endif 56 57 // TODO: clean up, documentation 58 59 // FIXME: ensure it builds and works on all platforms 60 61 const int max_small_pow5 = 15; 62 63 /* The value at index i is approximately 5**i. */ 64 long double small_pow5[] = { 65 0x1P0, 66 0x5P0, 67 0x19P0, 68 0x7dP0, 69 0x271P0, 70 0xc35P0, 71 0x3d09P0, 72 0x1312dP0, 73 0x5f5e1P0, 74 0x1dcd65P0, 75 0x9502f9P0, 76 0x2e90eddP0, 77 0xe8d4a51P0, 78 0x48c27395P0, 79 0x16bcc41e9P0, 80 0x71afd498dP0 57 #define abs(x) (((x) < 0) ? -(x) : (x)) 58 #endif 59 60 /* If the constants are not defined, use double precision as default. */ 61 #ifndef LDBL_MANT_DIG 62 #define LDBL_MANT_DIG 53 63 #endif 64 #ifndef LDBL_MAX_EXP 65 #define LDBL_MAX_EXP 1024 66 #endif 67 #ifndef LDBL_MIN_EXP 68 #define LDBL_MIN_EXP (-1021) 69 #endif 70 #ifndef LDBL_DIG 71 #define LDBL_DIG 15 72 #endif 73 #ifndef LDBL_MIN 74 #define LDBL_MIN 2.2250738585072014E-308 75 #endif 76 77 /* power functions ************************************************************/ 78 79 #if LDBL_MAX_EXP >= 16384 80 const int MAX_POW5 = 12; 81 #else 82 const int MAX_POW5 = 8; 83 #endif 84 85 /* The value at index i is approximately 5**(2**i). */ 86 long double pow5[] = { 87 0x5p0l, 88 0x19p0l, 89 0x271p0l, 90 0x5F5E1p0l, 91 0x2386F26FC1p0l, 92 0x4EE2D6D415B85ACEF81p0l, 93 0x184F03E93FF9F4DAA797ED6E38ED6p36l, 94 0x127748F9301D319BF8CDE66D86D62p185l, 95 0x154FDD7F73BF3BD1BBB77203731FDp482l, 96 #if LDBL_MAX_EXP >= 16384 97 0x1C633415D4C1D238D98CAB8A978A0p1076l, 98 0x192ECEB0D02EA182ECA1A7A51E316p2265l, 99 0x13D1676BB8A7ABBC94E9A519C6535p4643l, 100 0x188C0A40514412F3592982A7F0094p9398l, 101 #endif 81 102 }; 82 103 83 /* The value at index i is approximately 5**(2**i). */ 84 long double large_pow5[] = { 85 0x5P0l, 86 0x19P0l, 87 0x271P0l, 88 0x5f5e1P0l, 89 0x2386f26fc1P0l, 90 0x4ee2d6d415b85acef81P0l, 91 0x184f03e93ff9f4daa797ed6e38ed64bf6a1f01P0l, 92 0x24ee91f2603a6337f19bccdb0dac404dc08d3cff5ecP128l, 93 0x553f75fdcefcef46eeddcP512l, 94 0x1c633415d4c1d238d98cab8a978a0b1f138cb07303P1024l, 95 0x325d9d61a05d4305d9434f4a3c62d433949ae6209d492P2200l, 96 0x9e8b3b5dc53d5de4a74d28ce329ace526a3197bbebe3034f77154ce2bcba1964P4500l, 97 0x6230290145104bcd64a60a9fc025254932bb0fd922271133eeae7P9300l 98 }; 104 #if LDBL_MAX_EXP >= 16384 105 const int MAX_POW2 = 15; 106 #else 107 const int MAX_POW2 = 9; 108 #endif 99 109 100 110 /* Powers of two. */ … … 110 120 0x1P256l, 111 121 0x1P512l, 122 #if LDBL_MAX_EXP >= 16384 112 123 0x1P1024l, 113 124 0x1P2048l, 114 125 0x1P4096l, 115 0x1P8192l 126 0x1P8192l, 127 #endif 116 128 }; 117 129 118 static inline bool out_of_range(long double num)119 {120 return num == 0.0l || num == HUGE_VALL;121 }122 123 130 /** 124 131 * Multiplies a number by a power of five. 125 * The result is not exact and may not be the best possible approximation. 126 * 127 * @param base Number to be multiplied. 128 * @param exponent Base 5 exponent. 129 * @return base multiplied by 5**exponent 130 */ 131 static long double mul_pow5(long double base, int exponent) 132 { 133 if (out_of_range(base)) { 134 return base; 135 } 136 137 if (abs(exponent) >> 13 != 0) { 132 * The result may be inexact and may not be the best possible approximation. 133 * 134 * @param mant Number to be multiplied. 135 * @param exp Base 5 exponent. 136 * @return mant multiplied by 5**exp 137 */ 138 static long double mul_pow5(long double mant, int exp) 139 { 140 if (mant == 0.0l || mant == HUGE_VALL) { 141 return mant; 142 } 143 144 if (abs(exp) >> (MAX_POW5 + 1) != 0) { 145 /* Too large exponent. */ 138 146 errno = ERANGE; 139 return exponent < 0 ? 0.0l : HUGE_VALL; 140 } 141 142 if (exponent < 0) { 143 exponent = -exponent; 144 base /= small_pow5[exponent & 0xF]; 145 for (int i = 4; i < 13; ++i) { 146 if (((exponent >> i) & 1) != 0) { 147 base /= large_pow5[i]; 148 if (out_of_range(base)) { 147 return exp < 0 ? LDBL_MIN : HUGE_VALL; 148 } 149 150 if (exp < 0) { 151 exp = abs(exp); 152 for (int bit = 0; bit <= MAX_POW5; ++bit) { 153 /* Multiply by powers of five bit-by-bit. */ 154 if (((exp >> bit) & 1) != 0) { 155 mant /= pow5[bit]; 156 if (mant == 0.0l) { 157 /* Underflow. */ 158 mant = LDBL_MIN; 149 159 errno = ERANGE; 150 160 break; … … 153 163 } 154 164 } else { 155 base *= small_pow5[exponent & 0xF]; 156 for (int i = 4; i < 13; ++i) { 157 if (((exponent >> i) & 1) != 0) { 158 base *= large_pow5[i]; 159 if (out_of_range(base)) { 165 for (int bit = 0; bit <= MAX_POW5; ++bit) { 166 /* Multiply by powers of five bit-by-bit. */ 167 if (((exp >> bit) & 1) != 0) { 168 mant *= pow5[bit]; 169 if (mant == HUGE_VALL) { 170 /* Overflow. */ 160 171 errno = ERANGE; 161 172 break; … … 165 176 } 166 177 167 return base;168 } 169 170 /** 171 * Multiplies a number by a power of two. 172 * 173 * @param baseNumber to be multiplied.174 * @param exp onentBase 2 exponent.175 * @return base multiplied by 2**exponent176 */ 177 static long double mul_pow2(long double base, int exponent)178 { 179 if ( out_of_range(base)) {180 return base;181 } 182 183 if ( abs(exponent) >> 14 != 0) {178 return mant; 179 } 180 181 /** 182 * Multiplies a number by a power of two. This is always exact. 183 * 184 * @param mant Number to be multiplied. 185 * @param exp Base 2 exponent. 186 * @return mant multiplied by 2**exp. 187 */ 188 static long double mul_pow2(long double mant, int exp) 189 { 190 if (mant == 0.0l || mant == HUGE_VALL) { 191 return mant; 192 } 193 194 if (exp > LDBL_MAX_EXP || exp < LDBL_MIN_EXP) { 184 195 errno = ERANGE; 185 return exponent < 0 ? 0.0l : HUGE_VALL; 186 } 187 188 if (exponent < 0) { 189 exponent = -exponent; 190 for (int i = 0; i < 14; ++i) { 191 if (((exponent >> i) & 1) != 0) { 192 base /= pow2[i]; 193 if (out_of_range(base)) { 196 return exp < 0 ? LDBL_MIN : HUGE_VALL; 197 } 198 199 if (exp < 0) { 200 exp = abs(exp); 201 for (int i = 0; i <= MAX_POW2; ++i) { 202 if (((exp >> i) & 1) != 0) { 203 mant /= pow2[i]; 204 if (mant == 0.0l) { 205 mant = LDBL_MIN; 194 206 errno = ERANGE; 195 207 break; … … 198 210 } 199 211 } else { 200 for (int i = 0; i < 14; ++i) {201 if (((exp onent>> i) & 1) != 0) {202 base*= pow2[i];203 if ( out_of_range(base)) {212 for (int i = 0; i <= MAX_POW2; ++i) { 213 if (((exp >> i) & 1) != 0) { 214 mant *= pow2[i]; 215 if (mant == HUGE_VALL) { 204 216 errno = ERANGE; 205 217 break; … … 209 221 } 210 222 211 return base; 212 } 213 214 223 return mant; 224 } 225 226 /* end power functions ********************************************************/ 227 228 229 230 /** 231 * Convert decimal string representation of the floating point number. 232 * Function expects the string pointer to be already pointed at the first 233 * digit (i.e. leading optional sign was already consumed by the caller). 234 * 235 * @param sptr Pointer to the storage of the string pointer. Upon successful 236 * conversion, the string pointer is updated to point to the first 237 * unrecognized character. 238 * @return An approximate representation of the input floating-point number. 239 */ 215 240 static long double parse_decimal(const char **sptr) 216 241 { 217 // TODO: Use strtol(), at least for exponent. 242 assert(sptr != NULL); 243 assert (*sptr != NULL); 218 244 219 245 const int DEC_BASE = 10; 220 246 const char DECIMAL_POINT = '.'; 221 247 const char EXPONENT_MARK = 'e'; 222 /* The highest amount of digits that can be safely parsed 223 * before an overflow occurs. 224 */ 225 const int PARSE_DECIMAL_DIGS = 19; 226 227 /* significand */ 228 uint64_t significand = 0; 229 230 /* position in the input string */ 231 int i = 0; 248 249 const char *str = *sptr; 250 long double significand = 0; 251 long exponent = 0; 232 252 233 253 /* number of digits parsed so far */ 234 254 int parsed_digits = 0; 235 236 int exponent = 0; 237 238 const char *str = *sptr; 239 240 /* digits before decimal point */ 241 while (isdigit(str[i])) { 242 if (parsed_digits == 0 && str[i] == '0') { 255 bool after_decimal = false; 256 257 while (isdigit(*str) || (!after_decimal && *str == DECIMAL_POINT)) { 258 if (*str == DECIMAL_POINT) { 259 after_decimal = true; 260 str++; 261 continue; 262 } 263 264 if (parsed_digits == 0 && *str == '0') { 243 265 /* Nothing, just skip leading zeros. */ 244 } else if (parsed_digits < PARSE_DECIMAL_DIGS) { 245 significand *= DEC_BASE; 246 significand += str[i] - '0'; 266 } else if (parsed_digits < LDBL_DIG) { 267 significand = significand * DEC_BASE + (*str - '0'); 247 268 parsed_digits++; 248 269 } else { … … 250 271 } 251 272 252 i++; 253 } 254 255 if (str[i] == DECIMAL_POINT) { 256 i++; 257 258 /* digits after decimal point */ 259 while (isdigit(str[i])) { 260 if (parsed_digits == 0 && str[i] == '0') { 261 /* Skip leading zeros and decrement exponent. */ 262 exponent--; 263 } else if (parsed_digits < PARSE_DECIMAL_DIGS) { 264 significand *= DEC_BASE; 265 significand += str[i] - '0'; 266 exponent--; 267 parsed_digits++; 268 } else { 269 /* ignore */ 270 } 271 272 i++; 273 } 273 if (after_decimal) { 274 /* Decrement exponent if we are parsing the fractional part. */ 275 exponent--; 276 } 277 278 str++; 274 279 } 275 280 276 281 /* exponent */ 277 if (tolower(str[i]) == EXPONENT_MARK) { 278 i++; 279 280 bool negative = false; 281 int exp = 0; 282 283 switch (str[i]) { 284 case '-': 285 negative = true; 286 /* fallthrough */ 287 case '+': 288 i++; 289 } 290 291 while (isdigit(str[i])) { 292 if (exp < 65536) { 293 exp *= DEC_BASE; 294 exp += str[i] - '0'; 295 } 296 297 i++; 298 } 299 300 if (negative) { 301 exp = -exp; 302 } 303 304 exponent += exp; 305 } 306 307 long double result = (long double) significand; 308 result = mul_pow5(result, exponent); 309 if (result != HUGE_VALL) { 310 result = mul_pow2(result, exponent); 311 } 312 313 *sptr = &str[i]; 314 return result; 315 } 316 282 if (tolower(*str) == EXPONENT_MARK) { 283 str++; 284 285 /* Returns MIN/MAX value on error, which is ok. */ 286 long exp = strtol(str, (char **) &str, DEC_BASE); 287 288 if (exponent > 0 && exp > LONG_MAX - exponent) { 289 exponent = LONG_MAX; 290 } else if (exponent < 0 && exp < LONG_MIN - exponent) { 291 exponent = LONG_MIN; 292 } else { 293 exponent += exp; 294 } 295 } 296 297 *sptr = str; 298 299 /* Return multiplied by a power of ten. */ 300 return mul_pow2(mul_pow5(significand, exponent), exponent); 301 } 302 303 /** 304 * Derive a hexadecimal digit from its character representation. 305 * 306 * @param ch Character representation of the hexadecimal digit. 307 * @return Digit value represented by an integer. 308 */ 317 309 static inline int hex_value(char ch) 318 310 { … … 325 317 326 318 /** 327 * @param val Integer value. 328 * @return How many leading zero bits there are. (Maximum is 3) 329 */ 330 static inline int leading_zeros(uint64_t val) 331 { 332 for (int i = 3; i > 0; --i) { 333 if ((val >> (64 - i)) == 0) { 334 return i; 335 } 336 } 337 338 return 0; 339 } 340 319 * Convert hexadecimal string representation of the floating point number. 320 * Function expects the string pointer to be already pointed at the first 321 * digit (i.e. leading optional sign and 0x prefix were already consumed 322 * by the caller). 323 * 324 * @param sptr Pointer to the storage of the string pointer. Upon successful 325 * conversion, the string pointer is updated to point to the first 326 * unrecognized character. 327 * @return Representation of the input floating-point number. 328 */ 341 329 static long double parse_hexadecimal(const char **sptr) 342 330 { 343 // TODO: Use strtol(), at least for exponent. 344 345 /* this function currently always rounds to zero */ 346 // TODO: honor rounding mode 331 assert(sptr != NULL && *sptr != NULL); 347 332 348 333 const int DEC_BASE = 10; … … 350 335 const char DECIMAL_POINT = '.'; 351 336 const char EXPONENT_MARK = 'p'; 352 /* The highest amount of digits that can be safely parsed353 * before an overflow occurs.354 */355 const int PARSE_HEX_DIGS = 16;356 357 /* significand */358 uint64_t significand = 0;359 360 /* position in the input string */361 int i = 0;362 363 /* number of digits parsed so far */364 int parsed_digits = 0;365 366 int exponent = 0;367 337 368 338 const char *str = *sptr; 369 370 /* digits before decimal point */ 371 while (posix_isxdigit(str[i])) { 372 if (parsed_digits == 0 && str[i] == '0') { 339 long double significand = 0; 340 long exponent = 0; 341 342 /* number of bits parsed so far */ 343 int parsed_bits = 0; 344 bool after_decimal = false; 345 346 while (posix_isxdigit(*str) || (!after_decimal && *str == DECIMAL_POINT)) { 347 if (*str == DECIMAL_POINT) { 348 after_decimal = true; 349 str++; 350 continue; 351 } 352 353 if (parsed_bits == 0 && *str == '0') { 373 354 /* Nothing, just skip leading zeros. */ 374 } else if (parsed_digits < PARSE_HEX_DIGS) { 375 significand *= HEX_BASE; 376 significand += hex_value(str[i]); 377 parsed_digits++; 378 } else if (parsed_digits == PARSE_HEX_DIGS) { 379 /* The first digit may have had leading zeros, 380 * so we need to parse one more digit and shift 381 * the value accordingly. 382 */ 383 384 int zeros = leading_zeros(significand); 385 significand = (significand << zeros) | 386 (hex_value(str[i]) >> (4 - zeros)); 387 388 exponent += (4 - zeros); 389 parsed_digits++; 355 } else if (parsed_bits <= LDBL_MANT_DIG) { 356 significand = significand * HEX_BASE + hex_value(*str); 357 parsed_bits += 4; 390 358 } else { 391 359 exponent += 4; 392 360 } 393 361 394 i++; 395 } 396 397 if (str[i] == DECIMAL_POINT) { 398 i++; 399 400 /* digits after decimal point */ 401 while (posix_isxdigit(str[i])) { 402 if (parsed_digits == 0 && str[i] == '0') { 403 /* Skip leading zeros and decrement exponent. */ 404 exponent -= 4; 405 } else if (parsed_digits < PARSE_HEX_DIGS) { 406 significand *= HEX_BASE; 407 significand += hex_value(str[i]); 408 exponent -= 4; 409 parsed_digits++; 410 } else if (parsed_digits == PARSE_HEX_DIGS) { 411 /* The first digit may have had leading zeros, 412 * so we need to parse one more digit and shift 413 * the value accordingly. 414 */ 415 416 int zeros = leading_zeros(significand); 417 significand = (significand << zeros) | 418 (hex_value(str[i]) >> (4 - zeros)); 419 420 exponent -= zeros; 421 parsed_digits++; 422 } else { 423 /* ignore */ 424 } 425 426 i++; 427 } 362 if (after_decimal) { 363 exponent -= 4; 364 } 365 366 str++; 428 367 } 429 368 430 369 /* exponent */ 431 if (tolower(str[i]) == EXPONENT_MARK) { 432 i++; 433 434 bool negative = false; 435 int exp = 0; 436 437 switch (str[i]) { 438 case '-': 439 negative = true; 440 /* fallthrough */ 441 case '+': 442 i++; 443 } 444 445 while (isdigit(str[i])) { 446 if (exp < 65536) { 447 exp *= DEC_BASE; 448 exp += str[i] - '0'; 449 } 450 451 i++; 452 } 453 454 if (negative) { 455 exp = -exp; 456 } 457 458 exponent += exp; 459 } 460 461 long double result = (long double) significand; 462 result = mul_pow2(result, exponent); 463 464 *sptr = &str[i]; 465 return result; 370 if (tolower(*str) == EXPONENT_MARK) { 371 str++; 372 373 /* Returns MIN/MAX value on error, which is ok. */ 374 long exp = strtol(str, (char **) &str, DEC_BASE); 375 376 if (exponent > 0 && exp > LONG_MAX - exponent) { 377 exponent = LONG_MAX; 378 } else if (exponent < 0 && exp < LONG_MIN - exponent) { 379 exponent = LONG_MIN; 380 } else { 381 exponent += exp; 382 } 383 } 384 385 *sptr = str; 386 387 /* Return multiplied by a power of two. */ 388 return mul_pow2(significand, exponent); 466 389 } 467 390 … … 478 401 * @param nptr Input string. 479 402 * @param endptr If non-NULL, *endptr is set to the position of the first 480 * unrecognized character.403 * unrecognized character. 481 404 * @return An approximate representation of the input floating-point number. 482 405 */ … … 512 435 513 436 if (endptr != NULL) { 514 *endptr = (char *) &nptr[i + 3];515 } 516 errno = E RANGE;517 return negative ? -0.0l : +0.0l;437 *endptr = (char *) nptr; 438 } 439 errno = EINVAL; 440 return 0; 518 441 } 519 442 … … 567 490 /** @} 568 491 */ 569 -
uspace/lib/posix/string.c
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file String manipulation. 34 34 */ 35 35 … … 48 48 49 49 /** 50 * Returns true ifs2 is a prefix of s1.51 * 52 * @param s1 53 * @param s2 54 * @return 50 * Decides whether s2 is a prefix of s1. 51 * 52 * @param s1 String in which to look for a prefix. 53 * @param s2 Prefix string to look for. 54 * @return True if s2 is a prefix of s1, false otherwise. 55 55 */ 56 56 static bool begins_with(const char *s1, const char *s2) … … 69 69 * if no occurence is found. 70 70 * 71 * @param s1 72 * @param s2 73 * @return 71 * @param s1 String in which to look for the bytes. 72 * @param s2 String of bytes to look for. 73 * @return Pointer to the found byte on success, pointer to the 74 * string terminator otherwise. 74 75 */ 75 76 static char *strpbrk_null(const char *s1, const char *s2) … … 83 84 84 85 /** 85 * 86 * @param dest 87 * @param src 88 * @return 89 */ 90 char *posix_strcpy(char *dest, const char *src) 86 * Copy a string. 87 * 88 * @param dest Destination pre-allocated buffer. 89 * @param src Source string to be copied. 90 * @return Pointer to the destination buffer. 91 */ 92 char *posix_strcpy(char *restrict dest, const char *restrict src) 91 93 { 92 94 posix_stpcpy(dest, src); … … 95 97 96 98 /** 97 * 98 * @param dest 99 * @param src 100 * @param n 101 * @return 102 */ 103 char *posix_strncpy(char *dest, const char *src, size_t n) 99 * Copy fixed length string. 100 * 101 * @param dest Destination pre-allocated buffer. 102 * @param src Source string to be copied. 103 * @param n Number of bytes to be stored into destination buffer. 104 * @return Pointer to the destination buffer. 105 */ 106 char *posix_strncpy(char *restrict dest, const char *restrict src, size_t n) 104 107 { 105 108 posix_stpncpy(dest, src, n); … … 108 111 109 112 /** 110 * 111 * @param dest 112 * @param src 113 * @return Pointer to the nul character in the dest string 113 * Copy a string. 114 * 115 * @param dest Destination pre-allocated buffer. 116 * @param src Source string to be copied. 117 * @return Pointer to the nul character in the destination string. 114 118 */ 115 119 char *posix_stpcpy(char *restrict dest, const char *restrict src) … … 132 136 133 137 /** 134 * 135 * @param dest 136 * @param src 137 * @param n 138 * @return Pointer to the first written nul character or &dest[n] 138 * Copy fixed length string. 139 * 140 * @param dest Destination pre-allocated buffer. 141 * @param src Source string to be copied. 142 * @param n Number of bytes to be stored into destination buffer. 143 * @return Pointer to the first written nul character or &dest[n]. 139 144 */ 140 145 char *posix_stpncpy(char *restrict dest, const char *restrict src, size_t n) … … 162 167 163 168 /** 164 * 165 * @param dest 166 * @param src 167 * @return 168 */ 169 char *posix_strcat(char *dest, const char *src) 169 * Concatenate two strings. 170 * 171 * @param dest String to which src shall be appended. 172 * @param src String to be appended after dest. 173 * @return Pointer to destination buffer. 174 */ 175 char *posix_strcat(char *restrict dest, const char *restrict src) 170 176 { 171 177 assert(dest != NULL); … … 177 183 178 184 /** 179 * 180 * @param dest 181 * @param src 182 * @param n 183 * @return 184 */ 185 char *posix_strncat(char *dest, const char *src, size_t n) 185 * Concatenate a string with part of another. 186 * 187 * @param dest String to which part of src shall be appended. 188 * @param src String whose part shall be appended after dest. 189 * @param n Number of bytes to append after dest. 190 * @return Pointer to destination buffer. 191 */ 192 char *posix_strncat(char *restrict dest, const char *restrict src, size_t n) 186 193 { 187 194 assert(dest != NULL); … … 195 202 196 203 /** 197 * 198 * @param dest 199 * @param src 200 * @param c 201 * @param n 204 * Copy limited number of bytes in memory. 205 * 206 * @param dest Destination buffer. 207 * @param src Source buffer. 208 * @param c Character after which the copying shall stop. 209 * @param n Number of bytes that shall be copied if not stopped earlier by c. 202 210 * @return Pointer to the first byte after c in dest if found, NULL otherwise. 203 211 */ 204 void *posix_memccpy(void * dest, const void *src, int c, size_t n)212 void *posix_memccpy(void *restrict dest, const void *restrict src, int c, size_t n) 205 213 { 206 214 assert(dest != NULL); … … 223 231 224 232 /** 225 * 226 * @param s 227 * @return Newly allocated string 233 * Duplicate a string. 234 * 235 * @param s String to be duplicated. 236 * @return Newly allocated copy of the string. 228 237 */ 229 238 char *posix_strdup(const char *s) … … 233 242 234 243 /** 235 * 236 * @param s 237 * @param n 238 * @return Newly allocated string of length at most n 244 * Duplicate a specific number of bytes from a string. 245 * 246 * @param s String to be duplicated. 247 * @param n Maximum length of the resulting string.. 248 * @return Newly allocated string copy of length at most n. 239 249 */ 240 250 char *posix_strndup(const char *s, size_t n) … … 255 265 256 266 /** 257 * 258 * @param mem1 259 * @param mem2 260 * @param n 267 * Compare bytes in memory. 268 * 269 * @param mem1 First area of memory to be compared. 270 * @param mem2 Second area of memory to be compared. 271 * @param n Maximum number of bytes to be compared. 261 272 * @return Difference of the first pair of inequal bytes, 262 * or 0 if areas have the same content 273 * or 0 if areas have the same content. 263 274 */ 264 275 int posix_memcmp(const void *mem1, const void *mem2, size_t n) … … 272 283 for (size_t i = 0; i < n; ++i) { 273 284 if (s1[i] != s2[i]) { 274 return s 2[i] - s1[i];285 return s1[i] - s2[i]; 275 286 } 276 287 } … … 280 291 281 292 /** 282 * 283 * @param s1 284 * @param s2 285 * @return 293 * Compare two strings. 294 * 295 * @param s1 First string to be compared. 296 * @param s2 Second string to be compared. 297 * @return Difference of the first pair of inequal characters, 298 * or 0 if strings have the same content. 286 299 */ 287 300 int posix_strcmp(const char *s1, const char *s2) … … 294 307 295 308 /** 296 * 297 * @param s1 298 * @param s2 299 * @param n 300 * @return 309 * Compare part of two strings. 310 * 311 * @param s1 First string to be compared. 312 * @param s2 Second string to be compared. 313 * @param n Maximum number of characters to be compared. 314 * @return Difference of the first pair of inequal characters, 315 * or 0 if strings have the same content. 301 316 */ 302 317 int posix_strncmp(const char *s1, const char *s2, size_t n) … … 307 322 for (size_t i = 0; i < n; ++i) { 308 323 if (s1[i] != s2[i]) { 309 return s 2[i] - s1[i];324 return s1[i] - s2[i]; 310 325 } 311 326 if (s1[i] == '\0') { … … 318 333 319 334 /** 320 * 321 * @param mem 322 * @param c 323 * @param n 324 * @return 335 * Find byte in memory. 336 * 337 * @param mem Memory area in which to look for the byte. 338 * @param c Byte to look for. 339 * @param n Maximum number of bytes to be inspected. 340 * @return Pointer to the specified byte on success, 341 * NULL pointer otherwise. 325 342 */ 326 343 void *posix_memchr(const void *mem, int c, size_t n) … … 339 356 340 357 /** 341 * 342 * @param s 343 * @param c 344 * @return 358 * Scan string for a first occurence of a character. 359 * 360 * @param s String in which to look for the character. 361 * @param c Character to look for. 362 * @return Pointer to the specified character on success, 363 * NULL pointer otherwise. 345 364 */ 346 365 char *posix_strchr(const char *s, int c) … … 353 372 354 373 /** 355 * 356 * @param s 357 * @param c 358 * @return 374 * Scan string for a last occurence of a character. 375 * 376 * @param s String in which to look for the character. 377 * @param c Character to look for. 378 * @return Pointer to the specified character on success, 379 * NULL pointer otherwise. 359 380 */ 360 381 char *posix_strrchr(const char *s, int c) … … 376 397 } 377 398 399 /** 400 * Scan string for a first occurence of a character. 401 * 402 * @param s String in which to look for the character. 403 * @param c Character to look for. 404 * @return Pointer to the specified character on success, pointer to the 405 * string terminator otherwise. 406 */ 378 407 char *gnu_strchrnul(const char *s, int c) 379 408 { … … 388 417 389 418 /** 390 * 391 * @param s1 392 * @param s2 393 * @return 419 * Scan a string for a first occurence of one of provided bytes. 420 * 421 * @param s1 String in which to look for the bytes. 422 * @param s2 String of bytes to look for. 423 * @return Pointer to the found byte on success, 424 * NULL pointer otherwise. 394 425 */ 395 426 char *posix_strpbrk(const char *s1, const char *s2) … … 403 434 404 435 /** 405 * 406 * @param s1 407 * @param s2 408 * @return 436 * Get the length of a complementary substring. 437 * 438 * @param s1 String that shall be searched for complementary prefix. 439 * @param s2 String of bytes that shall not occur in the prefix. 440 * @return Length of the prefix. 409 441 */ 410 442 size_t posix_strcspn(const char *s1, const char *s2) … … 418 450 419 451 /** 420 * 421 * @param s1 422 * @param s2 423 * @return 452 * Get length of a substring. 453 * 454 * @param s1 String that shall be searched for prefix. 455 * @param s2 String of bytes that the prefix must consist of. 456 * @return Length of the prefix. 424 457 */ 425 458 size_t posix_strspn(const char *s1, const char *s2) … … 438 471 439 472 /** 440 * 441 * @param s1 442 * @param s2 443 * @return 473 * Find a substring. 474 * 475 * @param s1 String in which to look for a substring. 476 * @param s2 Substring to look for. 477 * @return Pointer to the first character of the substring in s1, or NULL if 478 * not found. 444 479 */ 445 480 char *posix_strstr(const char *s1, const char *s2) … … 467 502 468 503 /** 504 * String comparison using collating information. 505 * 469 506 * Currently ignores locale and just calls strcmp. 470 507 * 471 * @param s1 472 * @param s2 473 * @return 508 * @param s1 First string to be compared. 509 * @param s2 Second string to be compared. 510 * @return Difference of the first pair of inequal characters, 511 * or 0 if strings have the same content. 474 512 */ 475 513 int posix_strcoll(const char *s1, const char *s2) … … 482 520 483 521 /** 484 * strcoll is equal to strcmp here, so this just makes a copy. 485 * 486 * @param s1 487 * @param s2 488 * @param n 489 * @return 490 */ 491 size_t posix_strxfrm(char *s1, const char *s2, size_t n) 522 * Transform a string in such a way that the resulting string yields the same 523 * results when passed to the strcmp as if the original string is passed to 524 * the strcoll. 525 * 526 * Since strcoll is equal to strcmp here, this just makes a copy. 527 * 528 * @param s1 Transformed string. 529 * @param s2 Original string. 530 * @param n Maximum length of the transformed string. 531 * @return Length of the transformed string. 532 */ 533 size_t posix_strxfrm(char *restrict s1, const char *restrict s2, size_t n) 492 534 { 493 535 assert(s1 != NULL || n == 0); … … 504 546 505 547 /** 506 * 507 * @param errnum 508 * @return 548 * Get error message string. 549 * 550 * @param errnum Error code for which to obtain human readable string. 551 * @return Error message. 509 552 */ 510 553 char *posix_strerror(int errnum) … … 518 561 519 562 /** 520 * 521 * @param errnum Error code 522 * @param buf Buffer to store a human readable string to 523 * @param bufsz Size of buffer pointed to by buf 524 * @return 563 * Get error message string. 564 * 565 * @param errnum Error code for which to obtain human readable string. 566 * @param buf Buffer to store a human readable string to. 567 * @param bufsz Size of buffer pointed to by buf. 568 * @return Zero on success, errno otherwise. 525 569 */ 526 570 int posix_strerror_r(int errnum, char *buf, size_t bufsz) … … 541 585 542 586 /** 543 * 544 * @param s 545 * @return 587 * Get length of the string. 588 * 589 * @param s String which length shall be determined. 590 * @return Length of the string. 546 591 */ 547 592 size_t posix_strlen(const char *s) … … 553 598 554 599 /** 555 * 556 * @param s 557 * @param n 558 * @return 600 * Get limited length of the string. 601 * 602 * @param s String which length shall be determined. 603 * @param n Maximum number of bytes that can be examined to determine length. 604 * @return The lower of either string length or n limit. 559 605 */ 560 606 size_t posix_strnlen(const char *s, size_t n) … … 573 619 574 620 /** 575 * 576 * @param signum 577 * @return 621 * Get description of a signal. 622 * 623 * @param signum Signal number. 624 * @return Human readable signal description. 578 625 */ 579 626 char *posix_strsignal(int signum) -
uspace/lib/posix/string.h
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file String manipulation. 34 34 */ 35 35 … … 103 103 extern size_t posix_strnlen(const char *s, size_t n); 104 104 105 /* Signal messages */105 /* Signal Messages */ 106 106 extern char *posix_strsignal(int signum); 107 107 108 /* Legacy declarations */108 /* Legacy Declarations */ 109 109 #ifndef POSIX_STRINGS_H_ 110 110 extern int posix_ffs(int i); -
uspace/lib/posix/strings.c
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Additional string manipulation. 34 34 */ 35 35 … … 45 45 46 46 /** 47 * Find first set bit (beginning with the least significant bit). 47 48 * 48 * @param i 49 * @return 49 * @param i Integer in which to look for the first set bit. 50 * @return Index of first set bit. Bits are numbered starting at one. 50 51 */ 51 52 int posix_ffs(int i) … … 82 83 83 84 /** 85 * Compare two strings (case-insensitive). 84 86 * 85 * @param s1 86 * @param s2 87 * @return 87 * @param s1 First string to be compared. 88 * @param s2 Second string to be compared. 89 * @return Difference of the first pair of inequal characters, 90 * or 0 if strings have the same content. 88 91 */ 89 92 int posix_strcasecmp(const char *s1, const char *s2) … … 93 96 94 97 /** 98 * Compare part of two strings (case-insensitive). 95 99 * 96 * @param s1 97 * @param s2 98 * @param n 99 * @return 100 * @param s1 First string to be compared. 101 * @param s2 Second string to be compared. 102 * @param n Maximum number of characters to be compared. 103 * @return Difference of the first pair of inequal characters, 104 * or 0 if strings have the same content. 100 105 */ 101 106 int posix_strncasecmp(const char *s1, const char *s2, size_t n) … … 116 121 117 122 /** 123 * Compare two memory areas. 118 124 * 119 * @param mem1 120 * @param mem2 121 * @param n 122 * @return 125 * @param mem1 Pointer to the first area to compare. 126 * @param mem2 Pointer to the second area to compare. 127 * @param n Common size of both areas. 128 * @return If n is 0, return zero. If the areas match, return 129 * zero. Otherwise return non-zero. 123 130 */ 124 131 int posix_bcmp(const void *mem1, const void *mem2, size_t n) … … 128 135 129 136 /** 137 * Copy bytes in memory with overlapping areas. 130 138 * 131 * @param dest132 * @param src133 * @param n 139 * @param src Source area. 140 * @param dest Destination area. 141 * @param n Number of bytes to copy. 134 142 */ 135 void posix_bcopy(const void * dest, void *src, size_t n)143 void posix_bcopy(const void *src, void *dest, size_t n) 136 144 { 137 145 /* Note that memmove has different order of arguments. */ 138 memmove( src, dest, n);146 memmove(dest, src, n); 139 147 } 140 148 141 149 /** 150 * Reset bytes in memory area to zero. 142 151 * 143 * @param mem 144 * @param n 152 * @param mem Memory area to be zeroed. 153 * @param n Number of bytes to reset. 145 154 */ 146 155 void posix_bzero(void *mem, size_t n) … … 150 159 151 160 /** 161 * Scan string for a first occurence of a character. 152 162 * 153 * @param s 154 * @param c 155 * @return 163 * @param s String in which to look for the character. 164 * @param c Character to look for. 165 * @return Pointer to the specified character on success, 166 * NULL pointer otherwise. 156 167 */ 157 168 char *posix_index(const char *s, int c) … … 161 172 162 173 /** 163 * 164 * @param s 165 * @param c 166 * @return 174 * Scan string for a last occurence of a character. 175 * 176 * @param s String in which to look for the character. 177 * @param c Character to look for. 178 * @return Pointer to the specified character on success, 179 * NULL pointer otherwise. 167 180 */ 168 181 char *posix_rindex(const char *s, int c) -
uspace/lib/posix/strings.h
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Additional string manipulation. 34 34 */ 35 35 … … 37 37 #define POSIX_STRINGS_H_ 38 38 39 /* Search Functions */ 39 40 #ifndef POSIX_STRING_H_ 40 /* Search Functions */41 41 extern int posix_ffs(int i); 42 42 #endif … … 56 56 /* Legacy Functions */ 57 57 extern int posix_bcmp(const void *mem1, const void *mem2, size_t n); 58 extern void posix_bcopy(const void * dest, void *src, size_t n);58 extern void posix_bcopy(const void *src, void *dest, size_t n); 59 59 extern void posix_bzero(void *mem, size_t n); 60 60 extern char *posix_index(const char *s, int c); -
uspace/lib/posix/sys/mman.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Memory management declarations. 33 33 */ 34 34 -
uspace/lib/posix/sys/stat.c
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file File status handling. 34 34 */ 35 35 … … 80 80 int rc = fstat(fd, &hst); 81 81 if (rc < 0) { 82 /* fstat() returns negative error code instead of using errno. 83 */ 82 /* fstat() returns negative error code instead of using errno. */ 84 83 errno = -rc; 85 84 return -1; … … 96 95 * @return Zero on success, -1 otherwise. 97 96 */ 98 int posix_lstat(const char * path, struct posix_stat *st)97 int posix_lstat(const char *restrict path, struct posix_stat *restrict st) 99 98 { 100 99 /* There are currently no symbolic links in HelenOS. */ … … 109 108 * @return Zero on success, -1 otherwise. 110 109 */ 111 int posix_stat(const char * path, struct posix_stat *st)110 int posix_stat(const char *restrict path, struct posix_stat *restrict st) 112 111 { 113 112 struct stat hst; 114 113 int rc = stat(path, &hst); 115 114 if (rc < 0) { 116 /* stat() returns negative error code instead of using errno. 117 */ 115 /* stat() returns negative error code instead of using errno. */ 118 116 errno = -rc; 119 117 return -1; -
uspace/lib/posix/sys/stat.h
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file File status handling. 34 34 */ 35 35 -
uspace/lib/posix/sys/types.h
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Data types definitions. 34 34 */ 35 35 … … 49 49 typedef sysarg_t posix_dev_t; 50 50 51 /* PThread types */51 /* PThread Types */ 52 52 typedef struct posix_thread_attr posix_thread_attr_t; 53 53 54 /* Clock types */54 /* Clock Types */ 55 55 typedef long posix_clock_t; 56 56 typedef int posix_clockid_t; -
uspace/lib/posix/sys/wait.c
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Support for waiting. 34 34 */ 35 35 … … 65 65 /** @} 66 66 */ 67 -
uspace/lib/posix/sys/wait.h
r5889fc74 r6c69d19 30 30 * @{ 31 31 */ 32 /** @file 32 /** @file Support for waiting. 33 33 */ 34 34 -
uspace/lib/posix/time.c
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Time measurement support. 34 34 */ 35 35 … … 63 63 #define SECS_PER_DAY (SECS_PER_HOUR * HOURS_PER_DAY) 64 64 65 /** 66 * 67 * @param year 68 * @return 69 */ 65 70 static bool _is_leap_year(time_t year) 66 71 { … … 76 81 } 77 82 83 /** 84 * 85 * @param year 86 * @param mon 87 * @return 88 */ 78 89 static int _days_in_month(time_t year, time_t mon) 79 90 { … … 92 103 } 93 104 105 /** 106 * 107 * @param year 108 * @param mon 109 * @param mday 110 * @return 111 */ 94 112 static int _day_of_year(time_t year, time_t mon, time_t mday) 95 113 { … … 102 120 } 103 121 104 /* Integer division that rounds to negative infinity. 122 /** 123 * Integer division that rounds to negative infinity. 124 * 125 * @param op1 126 * @param op2 127 * @return 105 128 */ 106 129 static time_t _floor_div(time_t op1, time_t op2) … … 113 136 } 114 137 115 /* Modulo that rounds to negative infinity. 138 /** 139 * Modulo that rounds to negative infinity. 140 * 141 * @param op1 142 * @param op2 143 * @return 116 144 */ 117 145 static time_t _floor_mod(time_t op1, time_t op2) … … 132 160 } 133 161 162 /** 163 * 164 * @param year 165 * @param mon 166 * @param mday 167 * @return 168 */ 134 169 static time_t _days_since_epoch(time_t year, time_t mon, time_t mday) 135 170 { … … 139 174 } 140 175 141 /* Assumes normalized broken-down time. */ 176 /** 177 * Assumes normalized broken-down time. 178 * 179 * @param tm 180 * @return 181 */ 142 182 static time_t _secs_since_epoch(const struct posix_tm *tm) 143 183 { … … 147 187 } 148 188 189 /** 190 * 191 * @param year 192 * @param mon 193 * @param mday 194 * @return 195 */ 149 196 static int _day_of_week(time_t year, time_t mon, time_t mday) 150 197 { … … 165 212 }; 166 213 214 /** 215 * 216 * @param ltm 217 * @param ptm 218 */ 167 219 static void _posix_to_long_tm(struct _long_tm *ltm, struct posix_tm *ptm) 168 220 { … … 179 231 } 180 232 233 /** 234 * 235 * @param ptm 236 * @param ltm 237 */ 181 238 static void _long_to_posix_tm(struct posix_tm *ptm, struct _long_tm *ltm) 182 239 { … … 196 253 } 197 254 255 /** 256 * 257 * @param tm 258 */ 198 259 static void _normalize_time(struct _long_tm *tm) 199 260 { … … 241 302 } 242 303 243 /* Which day the week-based year starts on relative to the first calendar day. 304 /** 305 * Which day the week-based year starts on relative to the first calendar day. 244 306 * E.g. if the year starts on December 31st, the return value is -1. 307 * 308 * @param year 309 * @return 245 310 */ 246 311 static int _wbyear_offset(int year) … … 250 315 } 251 316 252 /* Returns week-based year of the specified time. 317 /** 318 * Returns week-based year of the specified time. 253 319 * Assumes normalized broken-down time. 320 * 321 * @param tm 322 * @return 254 323 */ 255 324 static int _wbyear(const struct posix_tm *tm) … … 268 337 } 269 338 270 /** Week number of the year, assuming weeks start on sunday. 271 * The first Sunday of January is the first day of week 1; 272 * days in the new year before this are in week 0. 339 /** 340 * Week number of the year, assuming weeks start on sunday. 341 * The first Sunday of January is the first day of week 1; 342 * days in the new year before this are in week 0. 273 343 * 274 344 * @param tm Normalized broken-down time. … … 281 351 } 282 352 283 /** Week number of the year, assuming weeks start on monday. 284 * If the week containing January 1st has four or more days in the new year, 285 * then it is considered week 1. Otherwise, it is the last week of the previous 286 * year, and the next week is week 1. Both January 4th and the first Thursday 287 * of January are always in week 1. 353 /** 354 * Week number of the year, assuming weeks start on monday. 355 * If the week containing January 1st has four or more days in the new year, 356 * then it is considered week 1. Otherwise, it is the last week of the previous 357 * year, and the next week is week 1. Both January 4th and the first Thursday 358 * of January are always in week 1. 288 359 * 289 360 * @param tm Normalized broken-down time. … … 305 376 } 306 377 307 /** Week number of the year, assuming weeks start on monday. 308 * The first Monday of January is the first day of week 1; 309 * days in the new year before this are in week 0. 378 /** 379 * Week number of the year, assuming weeks start on monday. 380 * The first Monday of January is the first day of week 1; 381 * days in the new year before this are in week 0. 310 382 * 311 383 * @param tm Normalized broken-down time. … … 324 396 char *posix_tzname[2]; 325 397 398 /** 399 * 400 */ 326 401 void posix_tzset(void) 327 402 { … … 333 408 } 334 409 410 /** 411 * 412 * @param time1 413 * @param time0 414 * @return 415 */ 335 416 double posix_difftime(time_t time1, time_t time0) 336 417 { … … 338 419 } 339 420 340 /** This function first normalizes the provided broken-down time 341 * (moves all values to their proper bounds) and then tries to 342 * calculate the appropriate time_t representation. 343 * 344 * @param timeptr Broken-down time. 421 /** 422 * This function first normalizes the provided broken-down time 423 * (moves all values to their proper bounds) and then tries to 424 * calculate the appropriate time_t representation. 425 * 426 * @param tm Broken-down time. 345 427 * @return time_t representation of the time, undefined value on overflow 346 428 */ … … 358 440 } 359 441 442 /** 443 * 444 * @param timer 445 * @return 446 */ 360 447 struct posix_tm *posix_gmtime(const time_t *timer) 361 448 { … … 364 451 } 365 452 453 /** 454 * 455 * @param timer 456 * @param result 457 * @return 458 */ 366 459 struct posix_tm *posix_gmtime_r(const time_t *restrict timer, 367 460 struct posix_tm *restrict result) … … 394 487 /** 395 488 * 396 * @param time p489 * @param timer 397 490 * @return 398 491 */ … … 403 496 } 404 497 498 /** 499 * 500 * @param timer 501 * @param result 502 * @return 503 */ 405 504 struct posix_tm *posix_localtime_r(const time_t *restrict timer, 406 505 struct posix_tm *restrict result) … … 413 512 /** 414 513 * 415 * @param t m514 * @param timeptr 416 515 * @return 417 516 */ … … 422 521 } 423 522 523 /** 524 * 525 * @param timeptr 526 * @param buf 527 * @return 528 */ 424 529 char *posix_asctime_r(const struct posix_tm *restrict timeptr, 425 530 char *restrict buf) … … 448 553 /** 449 554 * 450 * @param time p555 * @param timer 451 556 * @return 452 557 */ … … 460 565 } 461 566 567 /** 568 * 569 * @param timer 570 * @param buf 571 * @return 572 */ 462 573 char *posix_ctime_r(const time_t *timer, char *buf) 463 574 { … … 477 588 * @return 478 589 */ 479 size_t posix_strftime(char * s, size_t maxsize,480 const char * format, const struct posix_tm *tm)590 size_t posix_strftime(char *restrict s, size_t maxsize, 591 const char *restrict format, const struct posix_tm *restrict tm) 481 592 { 482 593 // TODO: use locale … … 655 766 } 656 767 768 /** 769 * 770 * @param s 771 * @param maxsize 772 * @param format 773 * @param tm 774 * @param loc 775 * @return 776 */ 777 extern size_t posix_strftime_l(char *restrict s, size_t maxsize, 778 const char *restrict format, const struct posix_tm *restrict tm, 779 posix_locale_t loc) 780 { 781 // TODO 782 not_implemented(); 783 } 784 785 /** 786 * 787 * @param clock_id 788 * @param res 789 * @return 790 */ 657 791 int posix_clock_getres(posix_clockid_t clock_id, struct posix_timespec *res) 658 792 { … … 670 804 } 671 805 806 /** 807 * 808 * @param clock_id 809 * @param tp 810 * @return 811 */ 672 812 int posix_clock_gettime(posix_clockid_t clock_id, struct posix_timespec *tp) 673 813 { … … 688 828 } 689 829 830 /** 831 * 832 * @param clock_id 833 * @param tp 834 * @return 835 */ 690 836 int posix_clock_settime(posix_clockid_t clock_id, 691 837 const struct posix_timespec *tp) … … 706 852 } 707 853 854 /** 855 * 856 * @param clock_id 857 * @param flags 858 * @param rqtp 859 * @param rmtp 860 * @return 861 */ 708 862 int posix_clock_nanosleep(posix_clockid_t clock_id, int flags, 709 863 const struct posix_timespec *rqtp, struct posix_timespec *rmtp) … … 735 889 }; 736 890 891 /** 892 * 893 * @param clockid 894 * @param evp 895 * @param timerid 896 * @return 897 */ 737 898 int posix_timer_create(posix_clockid_t clockid, 738 899 struct posix_sigevent *restrict evp, … … 743 904 } 744 905 906 /** 907 * 908 * @param timerid 909 * @return 910 */ 745 911 int posix_timer_delete(posix_timer_t timerid) 746 912 { … … 749 915 } 750 916 917 /** 918 * 919 * @param timerid 920 * @return 921 */ 751 922 int posix_timer_getoverrun(posix_timer_t timerid) 752 923 { … … 755 926 } 756 927 928 /** 929 * 930 * @param timerid 931 * @param value 932 * @return 933 */ 757 934 int posix_timer_gettime(posix_timer_t timerid, 758 935 struct posix_itimerspec *value) … … 762 939 } 763 940 941 /** 942 * 943 * @param timerid 944 * @param flags 945 * @param value 946 * @param ovalue 947 * @return 948 */ 764 949 int posix_timer_settime(posix_timer_t timerid, int flags, 765 950 const struct posix_itimerspec *restrict value, … … 783 968 if (task_stats) { 784 969 total_cycles = (posix_clock_t) (task_stats->kcycles + task_stats->ucycles); 785 }786 free(task_stats);787 task_stats = 0;970 free(task_stats); 971 task_stats = 0; 972 } 788 973 789 974 return total_cycles; -
uspace/lib/posix/time.h
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Time measurement support. 34 34 */ 35 35 … … 94 94 95 95 /* Timezones */ 96 97 96 extern int posix_daylight; 98 97 extern long posix_timezone; 99 98 extern char *posix_tzname[2]; 100 101 99 extern void posix_tzset(void); 102 100 103 /* time_t */ 104 101 /* Elapsed Time */ 105 102 extern double posix_difftime(time_t time1, time_t time0); 106 103 107 104 /* Broken-down Time */ 108 extern time_t posix_mktime(struct posix_tm *t imeptr);105 extern time_t posix_mktime(struct posix_tm *tm); 109 106 extern struct posix_tm *posix_gmtime(const time_t *timer); 110 107 extern struct posix_tm *posix_gmtime_r(const time_t *restrict timer, … … 120 117 extern char *posix_ctime(const time_t *timer); 121 118 extern char *posix_ctime_r(const time_t *timer, char *buf); 122 123 119 extern size_t posix_strftime(char *restrict s, size_t maxsize, 124 120 const char *restrict format, const struct posix_tm *restrict tm); 125 126 121 extern size_t posix_strftime_l(char *restrict s, size_t maxsize, 127 122 const char *restrict format, const struct posix_tm *restrict tm, 128 123 posix_locale_t loc); 129 124 130 /* Clocks. */ 131 125 /* Clocks */ 132 126 extern int posix_clock_getres(posix_clockid_t clock_id, 133 127 struct posix_timespec *res); … … 139 133 const struct posix_timespec *rqtp, struct posix_timespec *rmtp); 140 134 141 /* Timers. */142 143 135 #if 0 144 136 137 /* Timers */ 145 138 extern int posix_timer_create(posix_clockid_t clockid, 146 139 struct posix_sigevent *restrict evp, … … 159 152 extern posix_clock_t posix_clock(void); 160 153 161 162 154 #ifndef LIBPOSIX_INTERNAL 163 155 #define tm posix_tm 164 165 156 #define timespec posix_timespec 166 157 #define itimerspec posix_itimerspec 167 158 #define timer_t posix_timer_t 168 159 160 #define daylight posix_daylight 161 #define timezone posix_timezone 162 #define tzname posix_tzname 163 #define tzset posix_tzset 164 169 165 #define difftime posix_difftime 166 170 167 #define mktime posix_mktime 171 168 #define gmtime posix_gmtime … … 174 171 #define localtime_r posix_localtime_r 175 172 176 #define daylight posix_daylight177 #define timezone posix_timezone178 #define tzname posix_tzname179 #define tzset posix_tzset180 181 173 #define asctime posix_asctime 182 174 #define asctime_r posix_asctime_r … … 184 176 #define ctime_r posix_ctime_r 185 177 #define strftime posix_strftime 178 #define strftime_l posix_strftime_l 186 179 187 180 #define clock_getres posix_clock_getres -
uspace/lib/posix/unistd.c
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Miscellaneous standard definitions. 34 34 */ 35 35 … … 90 90 /* Always returns false, because there is no easy way to find 91 91 * out under HelenOS. */ 92 return false;92 return 0; 93 93 } 94 94 … … 207 207 /* Check file existence by attempt to open it. */ 208 208 int fd = open(path, O_RDONLY); 209 if (fd < 0) { 210 /* FIXME: open() returns error code as negative retval. */ 211 errno = -fd; 212 fd = -1; 213 } else { 209 if (fd != -1) { 214 210 close(fd); 215 211 } … … 239 235 clk_tck = ((long) cpu_stats[0].frequency_mhz) * 1000000L; 240 236 } 241 free(cpu_stats); 242 cpu_stats = 0; 237 if (cpu_stats) { 238 free(cpu_stats); 239 cpu_stats = 0; 240 } 243 241 244 242 long phys_pages = 0; … … 248 246 phys_pages = (long) (mem_stats->total / getpagesize()); 249 247 avphys_pages = (long) (mem_stats->free / getpagesize()); 250 }251 free(mem_stats);252 mem_stats = 0;248 free(mem_stats); 249 mem_stats = 0; 250 } 253 251 254 252 switch (name) { -
uspace/lib/posix/unistd.h
r5889fc74 r6c69d19 31 31 * @{ 32 32 */ 33 /** @file 33 /** @file Miscellaneous standard definitions. 34 34 */ 35 35
Note:
See TracChangeset
for help on using the changeset viewer.