Changeset 505
- Timestamp:
- 12/11/06 12:21:34 (2 years ago)
- Files:
-
- cherokee/trunk/ChangeLog (modified) (1 diff)
- cherokee/trunk/cherokee/dtm.c (modified) (22 diffs)
- cherokee/trunk/cherokee/dtm.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
cherokee/trunk/ChangeLog
r501 r505 1 2006-12-10 A.D.F <adefacc@tin.it> 2 3 * cherokee/dtm.h: 4 - added constant DTM_TIME_EVAL; 5 - new function prototypes: 6 cherokee_dtm_wday_name(); 7 cherokee_dtm_month_name(); 8 cherokee_dtm_gmttm2str(); 9 10 * cherokee/dtm.c: 11 - general cleanup; 12 - added new internal arrays; 13 - added new functions to convert a weekday index (0-6) 14 or a month index (0-11) to the corresponding short name 15 (3 characters long); 16 - added new function cherokee_dtm_gmttm2str() in order 17 to allow fast conversion from a gmt struct tm 18 to a string (40 mlsec. for 100000 calls on my PC). 19 1 20 2006-12-08 Alvaro Lopez Ortega <alvaro@alobbs.com> 2 21 cherokee/trunk/cherokee/dtm.c
r495 r505 42 42 #include "dtm.h" 43 43 44 typedef struct RecNameLen_s { 45 const char *name1; /* first name */ 44 45 /* Local macro. 46 */ 47 #define is_leap(y) ( (y) % 4 == 0 && ( (y) % 100 || (y) % 400 == 0 ) ) 48 49 50 /* Local structs and types. 51 */ 52 typedef struct DtmNameLen_s { 53 const char *name1; /* first name (short, 3 letters) */ 46 54 size_t len1; /* first name length */ 47 const char *name2; /* second name */55 const char *name2; /* second name (long) */ 48 56 size_t len2; /* second name length */ 49 } RecNameLen_t; 50 51 52 /* 53 ** Returns TRUE if it matches an existing weekday name. 54 */ 55 static int 56 cvt_wday_name2idx( const char* str_wday, size_t len_wday, int* ptm_wday ) 57 { 58 static RecNameLen_t wday_tab[] = { 57 } DtmNameLen_t; 58 59 60 /* Weekday names (short and long names). 61 */ 62 static DtmNameLen_t wday_name_tab[] = { 59 63 { "Sun", 3, "Sunday", 6 }, 60 64 { "Mon", 3, "Monday", 6 }, … … 66 70 }; 67 71 68 /* Fast test on min. length. 69 */ 70 if (len_wday < 3) 71 return 0; 72 73 /* Fast guess of day of week. 74 */ 75 switch( str_wday[0] ) { 76 case 's': 77 case 'S': 78 if ( str_wday[1] == 'u' || 79 str_wday[1] == 'U') 80 *ptm_wday = 0; 81 else 82 *ptm_wday = 6; 83 break; 84 85 case 'm': 86 case 'M': 87 *ptm_wday = 1; 88 break; 89 90 case 't': 91 case 'T': 92 if ( str_wday[1] == 'u' || 93 str_wday[1] == 'U') 94 *ptm_wday = 2; 95 else 96 *ptm_wday = 4; 97 break; 98 99 case 'w': 100 case 'W': 101 *ptm_wday = 3; 102 break; 103 104 case 'f': 105 case 'F': 106 *ptm_wday = 5; 107 break; 108 109 default: 110 return 0; 111 } 112 113 /* If length matches the length of short name, then compare the name. 114 */ 115 if ( len_wday == wday_tab[*ptm_wday].len1 ) { 116 return ( strncasecmp( 117 str_wday, 118 wday_tab[*ptm_wday].name1, 119 wday_tab[*ptm_wday].len1 ) == 0 ); 120 } 121 122 /* If length matches the length of long name, then compare the name. 123 */ 124 if ( len_wday == wday_tab[*ptm_wday].len2 ) { 125 return ( strncasecmp( 126 str_wday, 127 wday_tab[*ptm_wday].name2, 128 wday_tab[*ptm_wday].len2 ) == 0 ); 129 } 130 131 /* No match. 132 */ 133 return 0; 134 } 135 136 137 /* Returns TRUE if it matches an existing month name. */ 138 static int 139 cvt_mon_name2idx( const char* str_mon, size_t len_mon, int* ptm_mon ) 140 { 141 static RecNameLen_t mon_tab[] = { 72 73 /* Month names (short and long names). 74 */ 75 static DtmNameLen_t month_name_tab[] = { 142 76 { "Jan", 3, "January", 7 }, 143 77 { "Feb", 3, "February", 8 }, … … 154 88 }; 155 89 90 91 /* Number of days in each month (non leap year). 92 */ 93 static const int month_days_tab[12] = { 94 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 95 }; 96 97 98 /* Number of days in the years for each month (non leap year). 99 */ 100 static const int month_ydays_tab[12] = { 101 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 102 }; 103 104 105 /* Given the weekday index (...6), 106 ** it returns the short name of the weekday. 107 */ 108 const char * 109 cherokee_dtm_wday_name(int idxName) 110 { 111 if (idxName < 0 || idxName > 6) 112 return "???"; 113 return wday_name_tab[idxName].name1; 114 } 115 116 117 /* Given the index of the month (0...11), 118 ** it returns the short name of the month. 119 */ 120 const char * 121 cherokee_dtm_month_name(int idxName) 122 { 123 if (idxName < 0 || idxName > 11) 124 return "???"; 125 return month_name_tab[idxName].name1; 126 } 127 128 129 /* 130 ** Returns TRUE if it matches an existing weekday name. 131 */ 132 static int 133 cvt_wday_name2idx( const char* str_wday, size_t len_wday, struct tm *ptm ) 134 { 135 int tm_wday = 0; 136 137 /* Fast test on min. length. 138 */ 139 if (len_wday < 3) 140 return 0; 141 142 /* Fast guess of day of week (Sunday ... Saturday). 143 */ 144 switch( str_wday[0] ) { 145 case 's': 146 case 'S': 147 if ( str_wday[1] == 'u' || 148 str_wday[1] == 'U') 149 tm_wday = 0; 150 else 151 tm_wday = 6; 152 break; 153 154 case 'm': 155 case 'M': 156 tm_wday = 1; 157 break; 158 159 case 't': 160 case 'T': 161 if ( str_wday[1] == 'u' || 162 str_wday[1] == 'U') 163 tm_wday = 2; 164 else 165 tm_wday = 4; 166 break; 167 168 case 'w': 169 case 'W': 170 tm_wday = 3; 171 break; 172 173 case 'f': 174 case 'F': 175 tm_wday = 5; 176 break; 177 178 default: 179 return 0; 180 } 181 /* Assign the value. 182 */ 183 ptm->tm_wday = tm_wday; 184 185 /* If length matches the length of short name, then compare the name. 186 */ 187 if ( len_wday == wday_name_tab[tm_wday].len1 ) { 188 return ( strncasecmp( 189 str_wday, 190 wday_name_tab[tm_wday].name1, 191 wday_name_tab[tm_wday].len1 ) == 0 ); 192 } 193 194 /* If length matches the length of long name, then compare the name. 195 */ 196 if ( len_wday == wday_name_tab[tm_wday].len2 ) { 197 return ( strncasecmp( 198 str_wday, 199 wday_name_tab[tm_wday].name2, 200 wday_name_tab[tm_wday].len2 ) == 0 ); 201 } 202 203 /* No match. 204 */ 205 return 0; 206 } 207 208 209 /* Returns TRUE if it matches an existing month name. */ 210 static int 211 cvt_mon_name2idx( const char* str_mon, size_t len_mon, struct tm *ptm ) 212 { 213 int tm_mon = 0; 214 156 215 /* First fast test on min. length. 157 216 */ … … 159 218 return 0; 160 219 161 /* Fast guess of month name .220 /* Fast guess of month name (January ... December). 162 221 */ 163 222 switch( str_mon[0] ) { … … 166 225 if ( str_mon[1] == 'a' || 167 226 str_mon[1] == 'A') 168 *ptm_mon = 0;227 tm_mon = 0; 169 228 else 170 229 if ( str_mon[2] == 'n' || 171 230 str_mon[2] == 'N') 172 *ptm_mon = 5;231 tm_mon = 5; 173 232 else 174 *ptm_mon = 6;233 tm_mon = 6; 175 234 break; 176 235 177 236 case 'f': 178 237 case 'F': 179 *ptm_mon = 1;238 tm_mon = 1; 180 239 break; 181 240 … … 184 243 if ( str_mon[2] == 'r' || 185 244 str_mon[2] == 'R') 186 *ptm_mon = 2;245 tm_mon = 2; 187 246 else 188 *ptm_mon = 4;247 tm_mon = 4; 189 248 break; 190 249 … … 193 252 if ( str_mon[2] == 'r' || 194 253 str_mon[2] == 'R') 195 *ptm_mon = 3;254 tm_mon = 3; 196 255 else 197 *ptm_mon = 7;256 tm_mon = 7; 198 257 break; 199 258 200 259 case 's': 201 260 case 'S': 202 *ptm_mon = 8;261 tm_mon = 8; 203 262 break; 204 263 205 264 case 'o': 206 265 case 'O': 207 *ptm_mon = 9;266 tm_mon = 9; 208 267 break; 209 268 210 269 case 'n': 211 270 case 'N': 212 *ptm_mon = 10;271 tm_mon = 10; 213 272 break; 214 273 215 274 case 'd': 216 275 case 'D': 217 *ptm_mon = 11;276 tm_mon = 11; 218 277 break; 219 278 … … 221 280 return 0; 222 281 } 282 /* Assign the value. 283 */ 284 ptm->tm_mon = tm_mon; 223 285 224 286 /* If length matches the length of short name, then compare the name. 225 287 */ 226 if ( len_mon == mon _tab[*ptm_mon].len1 )288 if ( len_mon == month_name_tab[tm_mon].len1 ) 227 289 { 228 290 return ( strncasecmp( 229 291 str_mon, 230 mon _tab[*ptm_mon].name1,231 mon _tab[*ptm_mon].len1 ) == 0 );292 month_name_tab[tm_mon].name1, 293 month_name_tab[tm_mon].len1 ) == 0 ); 232 294 } 233 295 234 296 /* If length matches the length of long name, then compare the name. 235 297 */ 236 if ( len_mon == mon _tab[*ptm_mon].len2 )298 if ( len_mon == month_name_tab[tm_mon].len2 ) 237 299 { 238 300 return ( strncasecmp( 239 301 str_mon, 240 mon _tab[*ptm_mon].name2,241 mon _tab[*ptm_mon].len2 ) == 0 );302 month_name_tab[tm_mon].name2, 303 month_name_tab[tm_mon].len2 ) == 0 ); 242 304 } 243 305 … … 253 315 */ 254 316 static int 255 dft_dmyhms r2tm( char *cp, struct tm *ptm )317 dft_dmyhms2tm( char *psz, struct tm *ptm ) 256 318 { 257 319 size_t idx = 0; 258 320 259 --idx; 260 do { 261 ++idx; 262 } 263 while( cp[idx] == ' ' ); 264 265 cp += idx; 266 idx = 0; 267 321 /* Caller has already skipped blank characters. 322 */ 268 323 ptm->tm_wday = 0; 269 324 270 if ( cp[2] == ':' ) { 325 /* Date formats known here, start with two digits. 326 */ 327 if ( !isdigit( psz[0] ) || !isdigit( psz[1] ) ) 328 return 0; 329 330 if ( psz[2] == ':' ) { 271 331 272 332 /* HH:MM:SS GMT DD-mth-YY … … 276 336 */ 277 337 if ( 278 !isdigit( cp[0] ) || !isdigit( cp[1] ) || 279 cp[2] != ':' || 280 !isdigit( cp[3] ) || !isdigit( cp[4] ) || 281 cp[5] != ':' || 282 !isdigit( cp[6] ) || !isdigit( cp[7] ) 338 /* !isdigit( psz[0] ) || !isdigit( psz[1] ) || 339 * psz[2] != ':' || 340 */ 341 !isdigit( psz[3] ) || !isdigit( psz[4] ) || 342 psz[5] != ':' || 343 !isdigit( psz[6] ) || !isdigit( psz[7] ) 283 344 ) 284 345 return 0; 285 346 286 ptm->tm_hour = ( cp[0] - '0') * 10 + (cp[1] - '0');287 ptm->tm_min = ( cp[3] - '0') * 10 + (cp[4] - '0');288 ptm->tm_sec = ( cp[6] - '0') * 10 + (cp[7] - '0');347 ptm->tm_hour = (psz[0] - '0') * 10 + (psz[1] - '0'); 348 ptm->tm_min = (psz[3] - '0') * 10 + (psz[4] - '0'); 349 ptm->tm_sec = (psz[6] - '0') * 10 + (psz[7] - '0'); 289 350 290 351 idx += 8; 291 if ( cp[idx] != ' ')352 if ( psz[idx] != ' ') 292 353 return 0; 293 354 do { 294 355 ++idx; 295 356 } 296 while( cp[idx] == ' ' );297 298 cp+= idx;357 while( psz[idx] == ' ' ); 358 359 psz += idx; 299 360 idx = 0; 300 361 301 if ( cp[0] != 'G' ||302 cp[1] != 'M' ||303 cp[2] != 'T' ||304 cp[3] != ' ' )362 if ( psz[0] != 'G' || 363 psz[1] != 'M' || 364 psz[2] != 'T' || 365 psz[3] != ' ' ) 305 366 return 0; 306 367 … … 309 370 ++idx; 310 371 } 311 while( cp[idx] == ' ' );312 cp+= idx;372 while( psz[idx] == ' ' ); 373 psz += idx; 313 374 314 375 /* day 315 376 */ 316 377 ptm->tm_mday = 0; 317 for ( idx = 0; idx < 2 && isdigit( cp[idx] ); ++idx ) {318 ptm->tm_mday = ptm->tm_mday * 10 + (cp[idx] - '0');378 for ( idx = 0; idx < 2 && isdigit( psz[idx] ); ++idx ) { 379 ptm->tm_mday = ptm->tm_mday * 10 + (psz[idx] - '0'); 319 380 } 320 381 if ( idx == 0 ) 321 382 return 0; 322 383 323 if ( cp[idx] != '-')384 if ( psz[idx] != '-') 324 385 return 0; 325 386 326 387 ++idx; 327 cp+= idx;388 psz += idx; 328 389 329 390 /* month 330 391 */ 331 392 ptm->tm_mon = 0; 332 for ( idx = 0; isalpha( cp[idx] ); ++idx )393 for ( idx = 0; isalpha( psz[idx] ); ++idx ) 333 394 ; 334 395 335 if (! cvt_mon_name2idx( cp, idx, &(ptm->tm_mon)) )336 return 0; 337 338 if ( cp[idx] != '-')396 if (! cvt_mon_name2idx( psz, idx, ptm ) ) 397 return 0; 398 399 if ( psz[idx] != '-') 339 400 return 0; 340 401 341 402 ++idx; 342 cp+= idx;403 psz += idx; 343 404 344 405 /* year 345 406 */ 346 407 ptm->tm_year = 0; 347 for ( idx = 0; idx < 4 && isdigit( cp[idx] ); ++idx ) {348 ptm->tm_year = ptm->tm_year * 10 + (cp[idx] - '0');408 for ( idx = 0; idx < 4 && isdigit( psz[idx] ); ++idx ) { 409 ptm->tm_year = ptm->tm_year * 10 + (psz[idx] - '0'); 349 410 } 350 411 if ( idx == 0 ) 351 412 return 0; 352 413 353 if ( isdigit( cp[idx] ) ) 354 return 0; 355 356 } else { 414 if ( isdigit( psz[idx] ) ) 415 return 0; 416 417 /* OK, date deformatted and converted. 418 */ 419 return 1; 420 } 421 422 if ( psz[2] == '-') { 357 423 358 424 /* DD-mth-YY HH:MM:SS GMT … … 361 427 /* day 362 428 */ 363 ptm->tm_mday = 0; 364 for ( idx = 0; idx < 2 && isdigit( cp[idx] ); ++idx ) { 365 ptm->tm_mday = ptm->tm_mday * 10 + (cp[idx] - '0'); 429 ptm->tm_mday = (psz[0] - '0') * 10 + (psz[1] - '0'); 430 psz += 3; 431 432 /* month 433 */ 434 ptm->tm_mon = 0; 435 for ( idx = 0; isalpha( psz[idx] ); ++idx ) 436 ; 437 if (! cvt_mon_name2idx( psz, idx, ptm ) ) 438 return 0; 439 440 if ( psz[idx] != '-') 441 return 0; 442 ++idx; 443 psz += idx; 444 445 /* year 446 */ 447 ptm->tm_year = 0; 448 for ( idx = 0; idx < 4 && isdigit( psz[idx] ); ++idx ) { 449 ptm->tm_year = ptm->tm_year * 10 + (psz[idx] - '0'); 366 450 } 367 451 if ( idx == 0 ) 368 452 return 0; 369 453 370 if ( cp[idx] != '-') 371 return 0; 372 373 ++idx; 374 cp += idx; 375 376 /* month 377 */ 378 ptm->tm_mon = 0; 379 for ( idx = 0; isalpha( cp[idx] ); ++idx ) 380 ; 381 if (! cvt_mon_name2idx( cp, idx, &(ptm->tm_mon) ) ) 382 return 0; 383 384 if ( cp[idx] != '-') 385 return 0; 386 ++idx; 387 cp += idx; 388 389 /* year 390 */ 391 ptm->tm_year = 0; 392 for ( idx = 0; idx < 4 && isdigit( cp[idx] ); ++idx ) { 393 ptm->tm_year = ptm->tm_year * 10 + (cp[idx] - '0'); 394 } 395 if ( idx == 0 ) 396 return 0; 397 398 if ( cp[idx] != ' ' ) 454 if ( psz[idx] != ' ' ) 399 455 return 0; 400 456 … … 402 458 ++idx; 403 459 } 404 while( cp[idx] == ' ' );405 406 cp+= idx;460 while( psz[idx] == ' ' ); 461 462 psz += idx; 407 463 idx = 0; 408 464 … … 410 466 */ 411 467 if ( 412 !isdigit( cp[0] ) || !isdigit( cp[1] ) ||413 cp[2] != ':' ||414 !isdigit( cp[3] ) || !isdigit( cp[4] ) ||415 cp[5] != ':' ||416 !isdigit( cp[6] ) || !isdigit( cp[7] )468 !isdigit( psz[0] ) || !isdigit( psz[1] ) || 469 psz[2] != ':' || 470 !isdigit( psz[3] ) || !isdigit( psz[4] ) || 471 psz[5] != ':' || 472 !isdigit( psz[6] ) || !isdigit( psz[7] ) 417 473 ) 418 474 return 0; 419 475 420 ptm->tm_hour = ( cp[0] - '0') * 10 + (cp[1] - '0');421 ptm->tm_min = ( cp[3] - '0') * 10 + (cp[4] - '0');422 ptm->tm_sec = ( cp[6] - '0') * 10 + (cp[7] - '0');476 ptm->tm_hour = (psz[0] - '0') * 10 + (psz[1] - '0'); 477 ptm->tm_min = (psz[3] - '0') * 10 + (psz[4] - '0'); 478 ptm->tm_sec = (psz[6] - '0') * 10 + (psz[7] - '0'); 423 479 424 480 idx += 8; 425 if ( cp[idx] != ' ')481 if ( psz[idx] != ' ') 426 482 return 0; 427 483 do { 428 484 ++idx; 429 485 } 430 while( cp[idx] == ' ' );431 cp+= idx;486 while( psz[idx] == ' ' ); 487 psz += idx; 432 488 idx = 0; 433 489 434 if ( cp[0] != 'G' ||435 cp[1] != 'M' ||436 cp[2] != 'T' )490 if ( psz[0] != 'G' || 491 psz[1] != 'M' || 492 psz[2] != 'T' ) 437 493 return 0; 438 494 idx += 3; 439 } 440 return 1; 495 496 /* OK, date deformatted and converted. 497 */ 498 return 1; 499 } 500 501 /* Unknown date format. 502 */ 503 return 0; 441 504 } 442 505 443 506 444 /* is leap year */ 445 #define is_leap(y) ( (y) % 4 == 0 && ( (y) % 100 || (y) % 400 == 0 ) ) 446 447 /* Basically the same as mktime(). 507 /* It's almost the same as mktime(), 508 ** excepted for the following assumptions: 509 ** - it assumes to handle only UTC/GMT times, 510 ** thus ignoring time zone and daylight saving time; 511 ** - field values must be right (within the expected ranges). 448 512 */ 449 513 static time_t 450 cvt_tm2time( struct tm *ptm )514 cvt_tm2time( struct tm *ptm ) 451 515 { 452 516 time_t t; 453 517 int tm_year = ptm->tm_year + 1900; 454 518 455 static int monthtab[12] = {456 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334457 };458 459 519 /* Years since epoch, converted to days. */ 460 520 t = ( ptm->tm_year - 70 ) * 365; … … 464 524 465 525 /* Days for the beginning of this month. */ 466 t += month tab[ptm->tm_mon];526 t += month_ydays_tab[ptm->tm_mon]; 467 527 468 528 /* Leap day for this year. */ … … 482 542 483 543 484 #ifdef DTM_DBG485 #define RET_TIME_ERR(n) return ((time_t) (n))486 #else487 #define RET_TIME_ERR(n) return ((time_t) -1)488 #endif489 490 544 /* 491 545 ** Deformat a date time string from one of the http formats 492 546 ** (commonly used) to a time_t time. 493 547 ** (str) is assumed to be a zero terminated string. 548 ** On error, it returns DTM_TIME_EVAL (-1). 494 549 */ 495 550 time_t 496 cherokee_dtm_str2time( char* str )551 cherokee_dtm_str2time( char* cstr ) 497 552 { 498 553 struct tm tm; 499 char* cp;554 char* psz = cstr; 500 555 size_t idx = 0; 501 #ifdef CHECK_MIN_LEN502 size_t len = 0;503 #endif /* CHECK_MIN_LEN */504 int tm_sec = 0;505 int tm_min = 0;506 int tm_hour = 0;507 int tm_wday = 0;508 int tm_mday = 0;509 int tm_mon = 0;510 int tm_year = 0;511 time_t t;512 556 513 557 /* Zero struct tm. … … 517 561 /* Skip initial blank character(s). 518 562 */ 519 for ( cp = str; *cp == ' ' || *cp == '\t'; ++cp ) 520 continue; 521 522 #ifdef CHECK_MIN_LEN 523 /* Test min. length. 524 */ 525 len = strlen( cp ); 526 if ( len < 21 ) 527 RET_TIME_ERR(-1); 528 #endif /* CHECK_MIN_LEN */ 563 while ( *psz == ' ' || *psz == '\t' ) 564 ++psz; 529 565 530 566 /* Guess category of date time. 531 567 */ 532 if ( isalpha( * cp) ) {568 if ( isalpha( *psz ) ) { 533 569 /* wdy[,] ... 534 570 ** wdy = short or long name of the day of week. 535 571 */ 536 572 537 /* deformat day of week 538 */ 539 tm_wday = 0; 540 for ( idx = 0; isalpha( cp[idx] ); ++idx ) 573 /* deformat day (name) of week 574 */ 575 for ( idx = 0; isalpha( psz[idx] ); ++idx ) 541 576 ; 542 if (! cvt_wday_name2idx( cp, idx, &tm_wday) )543 RET_TIME_ERR(-2);577 if (! cvt_wday_name2idx( psz, idx, &tm ) ) 578 return DTM_TIME_EVAL; 544 579 545 580 /* Another guess of the type of date time format. 546 581 */ 547 if ( cp[idx] == ',' ) {582 if ( psz[idx] == ',' ) { 548 583 549 584 /* ----------------------------- … … 556 591 */ 557 592 ++idx; 558 if ( cp[idx] != ' ')559 RET_TIME_ERR(-3);593 if ( psz[idx] != ' ') 594 return DTM_TIME_EVAL; 560 595 do { 561 596 ++idx; 562 597 } 563 while( cp[idx] == ' ' );564 cp+= idx;598 while( psz[idx] == ' ' ); 599 psz += idx; 565 600 566 601 /* Deformat day of month. 567 602 */ 568 tm_mday = 0; 569 for ( idx = 0; idx < 2 && isdigit( cp[idx] ); ++idx ) { 570 tm_mday = tm_mday * 10 + (cp[idx] - '0'); 603 for ( idx = 0; idx < 2 && isdigit( psz[idx] ); ++idx ) { 604 tm.tm_mday = tm.tm_mday * 10 + (psz[idx] - '0'); 571 605 } 572 606 if ( idx == 0 ) 573 RET_TIME_ERR(-4);607 return DTM_TIME_EVAL; 574 608 575 609 /* Skip field separator(s). 576 610 */ 577 if ( cp[idx] != ' ' && cp[idx] != '-')578 RET_TIME_ERR(-5);611 if ( psz[idx] != ' ' && psz[idx] != '-') 612 return DTM_TIME_EVAL; 579 613 do { 580 614 ++idx; 581 615 } 582 while( cp[idx] == ' ' || cp[idx] == '-' );583 cp+= idx;616 while( psz[idx] == ' ' || psz[idx] == '-' ); 617 psz += idx; 584 618 585 619 /* Deformat month. 586 620 */ 587 tm_mon = 0; 588 for ( idx = 0; isalpha( cp[idx] ); ++idx ) 621 for ( idx = 0; isalpha( psz[idx] ); ++idx ) 589 622 ; 590 if (! cvt_mon_name2idx( cp, idx, &tm_mon) )591 RET_TIME_ERR(-6);623 if (! cvt_mon_name2idx( psz, idx, &tm ) ) 624 return DTM_TIME_EVAL; 592 625 593 626 /* Skip field separator(s). 594 627 */ 595 if ( cp[idx] != ' ' && cp[idx] != '-')596 RET_TIME_ERR(-7);628 if ( psz[idx] != ' ' && psz[idx] != '-') 629 return DTM_TIME_EVAL; 597 630 do { 598 631 ++idx; 599 632 } 600 while( cp[idx] == ' ' || cp[idx] == '-' );601 cp+= idx;633 while( psz[idx] == ' ' || psz[idx] == '-' ); 634 psz += idx; 602 635 603 636 /* Deformat year. 604 637 */ 605 tm_year = 0; 606 for ( idx = 0; idx < 4 && isdigit( cp[idx] ); ++idx ) { 607 tm_year = tm_year * 10 + (cp[idx] - '0'); 638 for ( idx = 0; idx < 4 && isdigit( psz[idx] ); ++idx ) { 639 tm.tm_year = tm.tm_year * 10 + (psz[idx] - '0'); 608 640 } 609 641 if ( idx == 0 ) 610 RET_TIME_ERR(-8);642 return DTM_TIME_EVAL; 611 643 612 644 /* Skip field separator(s). 613 645 */ 614 if ( cp[idx] != ' ')615 RET_TIME_ERR(-9);646 if ( psz[idx] != ' ') 647 return DTM_TIME_EVAL; 616 648 do { 617 649 ++idx; 618 650 } 619 while( cp[idx] == ' ' );620 cp+= idx;651 while( psz[idx] == ' ' ); 652 psz += idx; 621 653 idx = 0; 622 654 623 655 /* Deformat hours, minutes, seconds. 624 656 */ 625 if (!isdigit( cp[0] ) || !isdigit( cp[1] ) ||626 cp[2] != ':' ||627 !isdigit( cp[3] ) || !isdigit( cp[4] ) ||628 cp[5] != ':' ||629 !isdigit( cp[6] ) || !isdigit( cp[7] )657 if (!isdigit( psz[0] ) || !isdigit( psz[1] ) || 658 psz[2] != ':' || 659 !isdigit( psz[3] ) || !isdigit( psz[4] ) || 660 psz[5] != ':' ||