- Timestamp:
- Jun 23, 2005, 8:07:14 AM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/emx/src/lib/time/strptime.c
-
Property cvs2svn:cvs-rev
changed from
1.7
to1.8
r2069 r2070 38 38 if (!(s = parse_fmt (s, FMT, tm, &mask))) \ 39 39 return NULL; 40 #define NUMBER(DST,MIN,MAX,ADD ) \41 if (!(s = parse_number (s, DST, MIN, MAX, ADD ))) \40 #define NUMBER(DST,MIN,MAX,ADD,LEN) \ 41 if (!(s = parse_number (s, DST, MIN, MAX, ADD, LEN))) \ 42 42 return NULL; 43 43 #define STRING(STR) \ … … 49 49 50 50 static const char *parse_number (const char *s, int *dst, 51 int min, int max, int add )51 int min, int max, int add, int len) 52 52 { 53 53 int n; … … 58 58 return NULL; 59 59 n = 0; 60 while (isdigit (*s) )60 while (isdigit (*s) && len-- > 0) 61 61 n = n * 10 + (*s++ - '0'); /* TODO: check for overflow */ 62 62 if (n < min || (max >= 0 && n > max)) … … 109 109 110 110 #define MASK_CENTURY 0x00000001 111 #define MASK_YEAR 2 0x00000002112 #define MASK_YEAR 4 0x00000004113 #define MASK_YEAR (MASK_YEAR2 | MASK_YEAR4)111 #define MASK_YEAR_ANY 0x10000000 112 #define MASK_YEAR2 0x10000002 113 #define MASK_YEAR4 0x10000004 114 114 #define MASK_YEARDAY 0x00000008 115 115 #define MASK_MONTH 0x00000010 116 116 #define MASK_MONTHDAY 0x00000020 117 #define MASK_WEEKS 0x00000040 118 #define MASK_WEEKM 0x00000080 119 #define MASK_WEEK (MASK_WEEKM | MASK_WEEKS) 117 #define MASK_WEEK_ANY 0x20000000 118 #define MASK_WEEKS 0x20000040 119 #define MASK_WEEKM 0x20000080 120 #define MASK_WEEKI 0x20001000 120 121 #define MASK_WEEKDAY 0x00000100 121 122 #define MASK_HOUR 0x00000200 … … 190 191 191 192 case 'C': /* Century number */ 192 NUMBER (¢ury, 0, 99, 0 );193 NUMBER (¢ury, 0, 99, 0, 2); 193 194 mask |= MASK_CENTURY; 194 195 break; … … 196 197 case 'd': /* Day of the month (1-31) */ 197 198 case 'e': 198 NUMBER (&tm->tm_mday, 1, 31, 0 );199 NUMBER (&tm->tm_mday, 1, 31, 0, 2); 199 200 mask |= MASK_MONTHDAY; 200 201 break; … … 204 205 break; 205 206 207 case 'F': /* ISO Date - C99 */ 208 RECURSE ("%Y-%m-%d"); 209 break; 210 206 211 case 'H': /* Hour (00-23) */ 207 212 case 'k': 208 NUMBER (&tm->tm_hour, 0, 23, 0 );213 NUMBER (&tm->tm_hour, 0, 23, 0, 2); 209 214 mask |= MASK_HOUR; 210 215 break; … … 212 217 case 'I': /* Hour (01-12) */ 213 218 case 'l': 214 NUMBER (&tm->tm_hour, 1, 12, 0 );219 NUMBER (&tm->tm_hour, 1, 12, 0, 2); 215 220 mask |= MASK_HOUR; 216 221 break; 217 222 218 223 case 'j': /* Day of the year (1-366) */ 219 NUMBER (&tm->tm_yday, 1, 366, -1 );224 NUMBER (&tm->tm_yday, 1, 366, -1, 3); 220 225 mask |= MASK_YEARDAY; 221 226 break; 222 227 223 228 case 'm': /* Month (01-12) */ 224 NUMBER (&tm->tm_mon, 1, 12, -1 );229 NUMBER (&tm->tm_mon, 1, 12, -1, 2); 225 230 mask |= MASK_MONTH; 226 231 break; 227 232 228 233 case 'M': /* Minutes (00-59) */ 229 NUMBER (&tm->tm_min, 0, 59, 0 );234 NUMBER (&tm->tm_min, 0, 59, 0, 2); 230 235 mask |= MASK_MINUTE; 231 236 break; … … 237 242 break; 238 243 239 case 'p': /* am or pm*/244 case 'p': /* AM or PM */ 240 245 if (!(mask & MASK_HOUR) 241 246 || (tm->tm_hour < 1) 242 247 || (tm->tm_hour > 12)) 243 248 return NULL; 244 if ((t = parse_string (s, __libc_gLocaleTime.am)) != NULL) 249 if ( (t = parse_string (s, "AM")) != NULL 250 || (t = parse_string (s, __libc_gLocaleTime.am)) != NULL) 245 251 { 246 252 if (tm->tm_hour == 12) 247 253 tm->tm_hour = 0; 248 254 } 249 else if ((t = parse_string (s, __libc_gLocaleTime.pm)) != NULL) 255 else if ( (t = parse_string (s, "PM")) != NULL 256 || (t = parse_string (s, __libc_gLocaleTime.pm)) != NULL) 250 257 { 251 258 if (tm->tm_hour != 12) … … 257 264 break; 258 265 266 case 'P': /* am or pm */ 267 if (!(mask & MASK_HOUR) 268 || (tm->tm_hour < 1) 269 || (tm->tm_hour > 12)) 270 return NULL; 271 if ( (t = parse_string (s, "am")) != NULL 272 || (t = parse_string (s, __libc_gLocaleTime.am)) != NULL) 273 { 274 if (tm->tm_hour == 12) 275 tm->tm_hour = 0; 276 } 277 else if ( (t = parse_string (s, "pm")) != NULL 278 || (t = parse_string (s, __libc_gLocaleTime.pm)) != NULL) 279 { 280 if (tm->tm_hour != 12) 281 tm->tm_hour += 12; 282 } 283 else 284 return NULL; 285 s = t; 286 break; 287 259 288 case 'r': /* HH:MM:SS am/pm */ 260 289 RECURSE ("%I:%M:%S %p"); … … 266 295 267 296 case 'S': /* Seconds (00-61(?)) */ 268 NUMBER (&tm->tm_sec, 0, 61, 0 );297 NUMBER (&tm->tm_sec, 0, 61, 0, 2); 269 298 mask |= MASK_SECOND; 270 299 break; … … 281 310 282 311 case 'w': /* Weekday (0-6), 0 = Sunday */ 283 NUMBER (&tm->tm_wday, 0, 6, 0 );312 NUMBER (&tm->tm_wday, 0, 6, 0, 1); 284 313 mask |= MASK_WEEKDAY; 285 314 break; 286 315 287 316 case 'U': /* Week number (0-53), 0 = Sunday */ 288 NUMBER (&week, 0, 53, 0 );317 NUMBER (&week, 0, 53, 0, 2); 289 318 mask |= MASK_WEEKS; 290 319 break; 291 320 292 321 case 'W': /* Week number (0-53), 0 = Monday */ 293 NUMBER (&week, 0, 53, 0 );322 NUMBER (&week, 0, 53, 0, 2); 294 323 mask |= MASK_WEEKM; 295 324 break; … … 304 333 305 334 case 'y': 306 NUMBER (&tm->tm_year, 0, 99, 0 );335 NUMBER (&tm->tm_year, 0, 99, 0, 2); 307 336 if (tm->tm_year < 69) 308 337 tm->tm_year += 100; … … 311 340 312 341 case 'Y': 313 NUMBER (&tm->tm_year, 1900, -1, -1900 );342 NUMBER (&tm->tm_year, 1900, -1, -1900, 4); 314 343 mask |= MASK_YEAR4; 315 344 /* Ignore century since it was explicitely given */ 316 century = -1; mask &= ~MASK_CENTURY; 345 century = -1; 346 mask &= ~MASK_CENTURY; 317 347 break; 318 348 … … 325 355 if (mask & MASK_CENTURY) 326 356 { 327 if (!(mask & MASK_YEAR ))357 if (!(mask & MASK_YEAR_ANY)) 328 358 tm->tm_year = 0; 329 359 tm->tm_year = (century - 19) * 100 + (tm->tm_year % 100); … … 335 365 mask |= *retmask; 336 366 337 if ((mask & MASK_YEAR ) && (mask & MASK_YEARDAY)367 if ((mask & MASK_YEAR_ANY) && (mask & MASK_YEARDAY) 338 368 && (mask & (MASK_MONTH | MASK_MONTHDAY)) != (MASK_MONTH | MASK_MONTHDAY)) 339 369 { … … 341 371 const unsigned short *md = _leap_year (tm->tm_year + 1900) ? 342 372 _month_day_leap : _month_day_non_leap; 343 for (tm->tm_mon = 0; tm->tm_mon < 12 && tm->tm_yday < md [tm->tm_mon];344 tm->tm_mon++);373 for (tm->tm_mon = 11; tm->tm_mon > 0 && tm->tm_yday < md [tm->tm_mon]; tm->tm_mon--) 374 /* nothing */; 345 375 tm->tm_mday = 1 + tm->tm_yday - md [tm->tm_mon]; 346 376 mask |= MASK_MONTH | MASK_MONTHDAY; … … 349 379 if (!(mask & MASK_YEARDAY)) 350 380 { 351 if ((mask & MASK_WEEK ) && (mask & MASK_WEEKDAY) && (mask & MASK_YEAR)381 if ((mask & MASK_WEEK_ANY) && (mask & MASK_WEEKDAY) && (mask & MASK_YEAR_ANY) 352 382 && (tm->tm_year >= 70) && (tm->tm_year <= 206)) 353 383 { 354 384 /* Compute day of the year given week number and weekday */ 355 int dow = (4 + _year_day [tm->tm_year]) % 7; 356 if (mask & MASK_WEEKM) 357 dow--; 358 dow = (tm->tm_wday - dow) % 7; 359 if (dow < 0) dow += 7; 385 int dow = (mask & MASK_WEEKM) == MASK_WEEKM ? 3 : 4; 386 dow = (dow + _year_day [tm->tm_year]) % 7; 387 if (!dow) 388 week--; 389 dow = (tm->tm_wday - ((mask & MASK_WEEKM) == MASK_WEEKM) - dow) % 7; 390 if (dow < 0) 391 dow += 7; 360 392 tm->tm_yday = week * 7 + dow; 361 393 mask |= MASK_YEARDAY; 362 394 } 363 else if ((mask & MASK_YEAR ) && (mask & MASK_MONTH) && (mask & MASK_MONTHDAY))395 else if ((mask & MASK_YEAR_ANY) && (mask & MASK_MONTH) && (mask & MASK_MONTHDAY)) 364 396 { 365 397 /* Compute year day from month and day of the month */ … … 371 403 } 372 404 373 if (!(mask & MASK_WEEKDAY) && (mask & MASK_YEAR ) && (mask & MASK_YEARDAY))405 if (!(mask & MASK_WEEKDAY) && (mask & MASK_YEAR_ANY) && (mask & MASK_YEARDAY)) 374 406 { 375 407 /* Compute day of the week if it was not given */ … … 385 417 } 386 418 387 if (((mask & (MASK_WEEK | MASK_WEEKDAY | MASK_YEAR)) == (MASK_WEEK | MASK_WEEKDAY | MASK_YEAR))419 if (((mask & (MASK_WEEK_ANY | MASK_WEEKDAY | MASK_YEAR_ANY)) == (MASK_WEEK_ANY | MASK_WEEKDAY | MASK_YEAR_ANY)) 388 420 && ((mask & (MASK_MONTH | MASK_MONTHDAY)) != (MASK_MONTH | MASK_MONTHDAY))) 389 421 { … … 393 425 int days; 394 426 395 for (days = tm->tm_yday, tm->tm_mon = 0; days >= md [tm->tm_mon]; 396 days -= md [tm->tm_mon], tm->tm_mon++) 397 ; 398 tm->tm_mday = 1 + days; 427 for (tm->tm_mon = 11; tm->tm_mon > 0 && tm->tm_yday < md [tm->tm_mon]; tm->tm_mon--) 428 /* nothing */; 429 tm->tm_mday = 1 + tm->tm_yday - md [tm->tm_mon]; 399 430 mask |= MASK_MONTH | MASK_MONTHDAY; 400 431 } … … 403 434 that are not located inside the tm structure. */ 404 435 if (retmask) 405 *retmask |= mask & ~(MASK_WEEK | MASK_CENTURY);436 *retmask |= mask & ~(MASK_WEEKI | MASK_WEEKM | MASK_WEEKS | MASK_CENTURY); 406 437 407 438 return s; -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.