1*0Sigor@sysoev.ru 2*0Sigor@sysoev.ru /* 3*0Sigor@sysoev.ru * Copyright (C) Igor Sysoev 4*0Sigor@sysoev.ru * Copyright (C) NGINX, Inc. 5*0Sigor@sysoev.ru */ 6*0Sigor@sysoev.ru 7*0Sigor@sysoev.ru #include <nxt_main.h> 8*0Sigor@sysoev.ru 9*0Sigor@sysoev.ru 10*0Sigor@sysoev.ru /* 11*0Sigor@sysoev.ru * nxt_time_parse() parses a time string given in RFC822, RFC850, or ISOC 12*0Sigor@sysoev.ru * formats and returns nxt_time_t value >= 0 on success or -1 on failure. 13*0Sigor@sysoev.ru */ 14*0Sigor@sysoev.ru 15*0Sigor@sysoev.ru nxt_time_t 16*0Sigor@sysoev.ru nxt_time_parse(const u_char *p, size_t len) 17*0Sigor@sysoev.ru { 18*0Sigor@sysoev.ru size_t n; 19*0Sigor@sysoev.ru u_char c; 20*0Sigor@sysoev.ru uint64_t s; 21*0Sigor@sysoev.ru nxt_int_t yr, month, day, hour, min, sec; 22*0Sigor@sysoev.ru nxt_uint_t year, days; 23*0Sigor@sysoev.ru const u_char *end; 24*0Sigor@sysoev.ru 25*0Sigor@sysoev.ru static nxt_int_t mday[12] = { 26*0Sigor@sysoev.ru 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 27*0Sigor@sysoev.ru }; 28*0Sigor@sysoev.ru 29*0Sigor@sysoev.ru enum { 30*0Sigor@sysoev.ru RFC822 = 0, /* "Mon, 28 Sep 1970 12:00:00" */ 31*0Sigor@sysoev.ru RFC850, /* "Monday, 28-Sep-70 12:00:00" */ 32*0Sigor@sysoev.ru ISOC, /* "Mon Sep 28 12:00:00 1970" */ 33*0Sigor@sysoev.ru } fmt; 34*0Sigor@sysoev.ru 35*0Sigor@sysoev.ru fmt = RFC822; 36*0Sigor@sysoev.ru end = p + len; 37*0Sigor@sysoev.ru 38*0Sigor@sysoev.ru while (p < end) { 39*0Sigor@sysoev.ru c = *p++; 40*0Sigor@sysoev.ru 41*0Sigor@sysoev.ru if (c == ',') { 42*0Sigor@sysoev.ru break; 43*0Sigor@sysoev.ru } 44*0Sigor@sysoev.ru 45*0Sigor@sysoev.ru if (c == ' ') { 46*0Sigor@sysoev.ru fmt = ISOC; 47*0Sigor@sysoev.ru break; 48*0Sigor@sysoev.ru } 49*0Sigor@sysoev.ru } 50*0Sigor@sysoev.ru 51*0Sigor@sysoev.ru while (p < end) { 52*0Sigor@sysoev.ru if (*p != ' ') { 53*0Sigor@sysoev.ru break; 54*0Sigor@sysoev.ru } 55*0Sigor@sysoev.ru 56*0Sigor@sysoev.ru p++; 57*0Sigor@sysoev.ru } 58*0Sigor@sysoev.ru 59*0Sigor@sysoev.ru if (nxt_slow_path(p + 18 > end)) { 60*0Sigor@sysoev.ru /* Lesser than RFC850 "28-Sep-70 12:00:00" length. */ 61*0Sigor@sysoev.ru return -1; 62*0Sigor@sysoev.ru } 63*0Sigor@sysoev.ru 64*0Sigor@sysoev.ru day = 0; 65*0Sigor@sysoev.ru 66*0Sigor@sysoev.ru if (fmt != ISOC) { 67*0Sigor@sysoev.ru day = nxt_int_parse(p, 2); 68*0Sigor@sysoev.ru if (nxt_slow_path(day <= 0)) { 69*0Sigor@sysoev.ru return -1; 70*0Sigor@sysoev.ru } 71*0Sigor@sysoev.ru p += 2; 72*0Sigor@sysoev.ru 73*0Sigor@sysoev.ru if (*p == ' ') { 74*0Sigor@sysoev.ru if (nxt_slow_path(p + 18 > end)) { 75*0Sigor@sysoev.ru /* Lesser than RFC822 " Sep 1970 12:00:00" length. */ 76*0Sigor@sysoev.ru return -1; 77*0Sigor@sysoev.ru } 78*0Sigor@sysoev.ru 79*0Sigor@sysoev.ru /* RFC822 */ 80*0Sigor@sysoev.ru 81*0Sigor@sysoev.ru } else if (*p == '-') { 82*0Sigor@sysoev.ru fmt = RFC850; 83*0Sigor@sysoev.ru 84*0Sigor@sysoev.ru } else { 85*0Sigor@sysoev.ru return -1; 86*0Sigor@sysoev.ru } 87*0Sigor@sysoev.ru 88*0Sigor@sysoev.ru p++; 89*0Sigor@sysoev.ru } 90*0Sigor@sysoev.ru 91*0Sigor@sysoev.ru switch (*p) { 92*0Sigor@sysoev.ru 93*0Sigor@sysoev.ru case 'J': 94*0Sigor@sysoev.ru month = p[1] == 'a' ? 0 : p[2] == 'n' ? 5 : 6; 95*0Sigor@sysoev.ru break; 96*0Sigor@sysoev.ru 97*0Sigor@sysoev.ru case 'F': 98*0Sigor@sysoev.ru month = 1; 99*0Sigor@sysoev.ru break; 100*0Sigor@sysoev.ru 101*0Sigor@sysoev.ru case 'M': 102*0Sigor@sysoev.ru month = p[2] == 'r' ? 2 : 4; 103*0Sigor@sysoev.ru break; 104*0Sigor@sysoev.ru 105*0Sigor@sysoev.ru case 'A': 106*0Sigor@sysoev.ru month = p[1] == 'p' ? 3 : 7; 107*0Sigor@sysoev.ru break; 108*0Sigor@sysoev.ru 109*0Sigor@sysoev.ru case 'S': 110*0Sigor@sysoev.ru month = 8; 111*0Sigor@sysoev.ru break; 112*0Sigor@sysoev.ru 113*0Sigor@sysoev.ru case 'O': 114*0Sigor@sysoev.ru month = 9; 115*0Sigor@sysoev.ru break; 116*0Sigor@sysoev.ru 117*0Sigor@sysoev.ru case 'N': 118*0Sigor@sysoev.ru month = 10; 119*0Sigor@sysoev.ru break; 120*0Sigor@sysoev.ru 121*0Sigor@sysoev.ru case 'D': 122*0Sigor@sysoev.ru month = 11; 123*0Sigor@sysoev.ru break; 124*0Sigor@sysoev.ru 125*0Sigor@sysoev.ru default: 126*0Sigor@sysoev.ru return -1; 127*0Sigor@sysoev.ru } 128*0Sigor@sysoev.ru 129*0Sigor@sysoev.ru p += 3; 130*0Sigor@sysoev.ru yr = 0; 131*0Sigor@sysoev.ru 132*0Sigor@sysoev.ru switch (fmt) { 133*0Sigor@sysoev.ru 134*0Sigor@sysoev.ru case RFC822: 135*0Sigor@sysoev.ru if (nxt_slow_path(*p++ != ' ')) { 136*0Sigor@sysoev.ru return -1; 137*0Sigor@sysoev.ru } 138*0Sigor@sysoev.ru 139*0Sigor@sysoev.ru yr = nxt_int_parse(p, 4); 140*0Sigor@sysoev.ru if (nxt_slow_path(yr <= 0)) { 141*0Sigor@sysoev.ru return -1; 142*0Sigor@sysoev.ru } 143*0Sigor@sysoev.ru p += 4; 144*0Sigor@sysoev.ru 145*0Sigor@sysoev.ru break; 146*0Sigor@sysoev.ru 147*0Sigor@sysoev.ru case RFC850: 148*0Sigor@sysoev.ru if (nxt_slow_path(*p++ != '-')) { 149*0Sigor@sysoev.ru return -1; 150*0Sigor@sysoev.ru } 151*0Sigor@sysoev.ru 152*0Sigor@sysoev.ru yr = nxt_int_parse(p, 2); 153*0Sigor@sysoev.ru if (nxt_slow_path(yr <= 0)) { 154*0Sigor@sysoev.ru return -1; 155*0Sigor@sysoev.ru } 156*0Sigor@sysoev.ru p += 2; 157*0Sigor@sysoev.ru 158*0Sigor@sysoev.ru yr += (yr < 70) ? 2000 : 1900; 159*0Sigor@sysoev.ru 160*0Sigor@sysoev.ru break; 161*0Sigor@sysoev.ru 162*0Sigor@sysoev.ru default: /* ISOC */ 163*0Sigor@sysoev.ru if (nxt_slow_path(*p++ != ' ')) { 164*0Sigor@sysoev.ru return -1; 165*0Sigor@sysoev.ru } 166*0Sigor@sysoev.ru 167*0Sigor@sysoev.ru if (p[0] != ' ') { 168*0Sigor@sysoev.ru n = 2; 169*0Sigor@sysoev.ru 170*0Sigor@sysoev.ru if (p[1] == ' ') { 171*0Sigor@sysoev.ru n = 1; 172*0Sigor@sysoev.ru } 173*0Sigor@sysoev.ru 174*0Sigor@sysoev.ru } else { 175*0Sigor@sysoev.ru p++; 176*0Sigor@sysoev.ru n = 1; 177*0Sigor@sysoev.ru } 178*0Sigor@sysoev.ru 179*0Sigor@sysoev.ru day = nxt_int_parse(p, n); 180*0Sigor@sysoev.ru if (nxt_slow_path(day <= 0)) { 181*0Sigor@sysoev.ru return -1; 182*0Sigor@sysoev.ru } 183*0Sigor@sysoev.ru p += n; 184*0Sigor@sysoev.ru 185*0Sigor@sysoev.ru if (nxt_slow_path(p + 14 > end)) { 186*0Sigor@sysoev.ru /* Lesser than ISOC " 12:00:00 1970" length. */ 187*0Sigor@sysoev.ru return -1; 188*0Sigor@sysoev.ru } 189*0Sigor@sysoev.ru 190*0Sigor@sysoev.ru break; 191*0Sigor@sysoev.ru } 192*0Sigor@sysoev.ru 193*0Sigor@sysoev.ru if (nxt_slow_path(*p++ != ' ')) { 194*0Sigor@sysoev.ru return -1; 195*0Sigor@sysoev.ru } 196*0Sigor@sysoev.ru 197*0Sigor@sysoev.ru hour = nxt_int_parse(p, 2); 198*0Sigor@sysoev.ru if (nxt_slow_path(hour < 0)) { 199*0Sigor@sysoev.ru return -1; 200*0Sigor@sysoev.ru } 201*0Sigor@sysoev.ru p += 2; 202*0Sigor@sysoev.ru 203*0Sigor@sysoev.ru if (nxt_slow_path(*p++ != ':')) { 204*0Sigor@sysoev.ru return -1; 205*0Sigor@sysoev.ru } 206*0Sigor@sysoev.ru 207*0Sigor@sysoev.ru min = nxt_int_parse(p, 2); 208*0Sigor@sysoev.ru if (nxt_slow_path(min < 0)) { 209*0Sigor@sysoev.ru return -1; 210*0Sigor@sysoev.ru } 211*0Sigor@sysoev.ru p += 2; 212*0Sigor@sysoev.ru 213*0Sigor@sysoev.ru if (nxt_slow_path(*p++ != ':')) { 214*0Sigor@sysoev.ru return -1; 215*0Sigor@sysoev.ru } 216*0Sigor@sysoev.ru 217*0Sigor@sysoev.ru sec = nxt_int_parse(p, 2); 218*0Sigor@sysoev.ru if (nxt_slow_path(sec < 0)) { 219*0Sigor@sysoev.ru return -1; 220*0Sigor@sysoev.ru } 221*0Sigor@sysoev.ru 222*0Sigor@sysoev.ru if (fmt == ISOC) { 223*0Sigor@sysoev.ru p += 2; 224*0Sigor@sysoev.ru 225*0Sigor@sysoev.ru if (nxt_slow_path(*p++ != ' ')) { 226*0Sigor@sysoev.ru return -1; 227*0Sigor@sysoev.ru } 228*0Sigor@sysoev.ru 229*0Sigor@sysoev.ru yr = nxt_int_parse(p, 4); 230*0Sigor@sysoev.ru if (nxt_slow_path(yr < 0)) { 231*0Sigor@sysoev.ru return -1; 232*0Sigor@sysoev.ru } 233*0Sigor@sysoev.ru } 234*0Sigor@sysoev.ru 235*0Sigor@sysoev.ru if (nxt_slow_path(hour > 23 || min > 59 || sec > 59)) { 236*0Sigor@sysoev.ru return -1; 237*0Sigor@sysoev.ru } 238*0Sigor@sysoev.ru 239*0Sigor@sysoev.ru year = yr; 240*0Sigor@sysoev.ru 241*0Sigor@sysoev.ru if (day == 29 && month == 1) { 242*0Sigor@sysoev.ru 243*0Sigor@sysoev.ru if (nxt_slow_path((year & 3) != 0)) { 244*0Sigor@sysoev.ru /* Not a leap year. */ 245*0Sigor@sysoev.ru return -1; 246*0Sigor@sysoev.ru } 247*0Sigor@sysoev.ru 248*0Sigor@sysoev.ru if (nxt_slow_path((year % 100 == 0) && (year % 400) != 0)) { 249*0Sigor@sysoev.ru /* Not a leap year. */ 250*0Sigor@sysoev.ru return -1; 251*0Sigor@sysoev.ru } 252*0Sigor@sysoev.ru 253*0Sigor@sysoev.ru } else if (nxt_slow_path(day > mday[(nxt_uint_t) month])) { 254*0Sigor@sysoev.ru return -1; 255*0Sigor@sysoev.ru } 256*0Sigor@sysoev.ru 257*0Sigor@sysoev.ru /* 258*0Sigor@sysoev.ru * Shift new year to March 1 and start months 259*0Sigor@sysoev.ru * from 1 (not 0), as required for Gauss' formula. 260*0Sigor@sysoev.ru */ 261*0Sigor@sysoev.ru 262*0Sigor@sysoev.ru if (--month <= 0) { 263*0Sigor@sysoev.ru month += 12; 264*0Sigor@sysoev.ru year -= 1; 265*0Sigor@sysoev.ru } 266*0Sigor@sysoev.ru 267*0Sigor@sysoev.ru /* Gauss' formula for Gregorian days since March 1, 1 BCE. */ 268*0Sigor@sysoev.ru 269*0Sigor@sysoev.ru /* Days in years including leap years since March 1, 1 BCE. */ 270*0Sigor@sysoev.ru days = 365 * year + year / 4 - year / 100 + year / 400 271*0Sigor@sysoev.ru 272*0Sigor@sysoev.ru /* Days before the month. */ 273*0Sigor@sysoev.ru + 367 * (nxt_uint_t) month / 12 - 30 274*0Sigor@sysoev.ru 275*0Sigor@sysoev.ru /* Days before the day. */ 276*0Sigor@sysoev.ru + (nxt_uint_t) day - 1; 277*0Sigor@sysoev.ru 278*0Sigor@sysoev.ru /* 279*0Sigor@sysoev.ru * 719527 days were between March 1, 1 BCE and March 1, 1970, 280*0Sigor@sysoev.ru * 31 and 28 days were in January and February 1970. 281*0Sigor@sysoev.ru */ 282*0Sigor@sysoev.ru days = days - 719527 + 31 + 28; 283*0Sigor@sysoev.ru 284*0Sigor@sysoev.ru s = (uint64_t) days * 86400 285*0Sigor@sysoev.ru + (nxt_uint_t) hour * 3600 286*0Sigor@sysoev.ru + (nxt_uint_t) min * 60 287*0Sigor@sysoev.ru + (nxt_uint_t) sec; 288*0Sigor@sysoev.ru 289*0Sigor@sysoev.ru #if (NXT_TIME_T_SIZE <= 4) 290*0Sigor@sysoev.ru 291*0Sigor@sysoev.ru /* Y2038 */ 292*0Sigor@sysoev.ru 293*0Sigor@sysoev.ru if (nxt_slow_path(s > 0x7fffffff)) { 294*0Sigor@sysoev.ru return -1; 295*0Sigor@sysoev.ru } 296*0Sigor@sysoev.ru 297*0Sigor@sysoev.ru #endif 298*0Sigor@sysoev.ru 299*0Sigor@sysoev.ru return (nxt_time_t) s; 300*0Sigor@sysoev.ru } 301*0Sigor@sysoev.ru 302*0Sigor@sysoev.ru 303*0Sigor@sysoev.ru /* 304*0Sigor@sysoev.ru * nxt_term_parse() parses term string given in format "200", "10m", 305*0Sigor@sysoev.ru * or "1d 1h" and returns nxt_int_t value >= 0 on success, -1 on failure, 306*0Sigor@sysoev.ru * and -2 on overflow. The maximum valid value is 2^31 - 1 or about 307*0Sigor@sysoev.ru * 68 years in seconds or about 24 days in milliseconds. 308*0Sigor@sysoev.ru */ 309*0Sigor@sysoev.ru 310*0Sigor@sysoev.ru nxt_int_t 311*0Sigor@sysoev.ru nxt_term_parse(const u_char *p, size_t len, nxt_bool_t seconds) 312*0Sigor@sysoev.ru { 313*0Sigor@sysoev.ru u_char c, ch; 314*0Sigor@sysoev.ru nxt_uint_t val, term, scale, max; 315*0Sigor@sysoev.ru const u_char *end; 316*0Sigor@sysoev.ru 317*0Sigor@sysoev.ru enum { 318*0Sigor@sysoev.ru st_first_digit = 0, 319*0Sigor@sysoev.ru st_digit, 320*0Sigor@sysoev.ru st_letter, 321*0Sigor@sysoev.ru st_space, 322*0Sigor@sysoev.ru } state; 323*0Sigor@sysoev.ru 324*0Sigor@sysoev.ru enum { 325*0Sigor@sysoev.ru st_start = 0, 326*0Sigor@sysoev.ru st_year, 327*0Sigor@sysoev.ru st_month, 328*0Sigor@sysoev.ru st_week, 329*0Sigor@sysoev.ru st_day, 330*0Sigor@sysoev.ru st_hour, 331*0Sigor@sysoev.ru st_min, 332*0Sigor@sysoev.ru st_sec, 333*0Sigor@sysoev.ru st_msec, 334*0Sigor@sysoev.ru st_last, 335*0Sigor@sysoev.ru } step; 336*0Sigor@sysoev.ru 337*0Sigor@sysoev.ru val = 0; 338*0Sigor@sysoev.ru term = 0; 339*0Sigor@sysoev.ru state = st_first_digit; 340*0Sigor@sysoev.ru step = seconds ? st_start : st_month; 341*0Sigor@sysoev.ru 342*0Sigor@sysoev.ru end = p + len; 343*0Sigor@sysoev.ru 344*0Sigor@sysoev.ru while (p < end) { 345*0Sigor@sysoev.ru 346*0Sigor@sysoev.ru ch = *p++; 347*0Sigor@sysoev.ru 348*0Sigor@sysoev.ru if (state == st_space) { 349*0Sigor@sysoev.ru 350*0Sigor@sysoev.ru if (ch == ' ') { 351*0Sigor@sysoev.ru continue; 352*0Sigor@sysoev.ru } 353*0Sigor@sysoev.ru 354*0Sigor@sysoev.ru state = st_first_digit; 355*0Sigor@sysoev.ru } 356*0Sigor@sysoev.ru 357*0Sigor@sysoev.ru if (state != st_letter) { 358*0Sigor@sysoev.ru 359*0Sigor@sysoev.ru /* Values below '0' become >= 208. */ 360*0Sigor@sysoev.ru c = ch - '0'; 361*0Sigor@sysoev.ru 362*0Sigor@sysoev.ru if (c <= 9) { 363*0Sigor@sysoev.ru val = val * 10 + c; 364*0Sigor@sysoev.ru state = st_digit; 365*0Sigor@sysoev.ru continue; 366*0Sigor@sysoev.ru } 367*0Sigor@sysoev.ru 368*0Sigor@sysoev.ru if (state == st_first_digit) { 369*0Sigor@sysoev.ru return -1; 370*0Sigor@sysoev.ru } 371*0Sigor@sysoev.ru 372*0Sigor@sysoev.ru state = st_letter; 373*0Sigor@sysoev.ru } 374*0Sigor@sysoev.ru 375*0Sigor@sysoev.ru switch (ch) { 376*0Sigor@sysoev.ru 377*0Sigor@sysoev.ru case 'y': 378*0Sigor@sysoev.ru if (step > st_start) { 379*0Sigor@sysoev.ru return -1; 380*0Sigor@sysoev.ru } 381*0Sigor@sysoev.ru step = st_year; 382*0Sigor@sysoev.ru max = NXT_INT32_T_MAX / (365 * 24 * 60 * 60); 383*0Sigor@sysoev.ru scale = 365 * 24 * 60 * 60; 384*0Sigor@sysoev.ru break; 385*0Sigor@sysoev.ru 386*0Sigor@sysoev.ru case 'M': 387*0Sigor@sysoev.ru if (step >= st_month) { 388*0Sigor@sysoev.ru return -1; 389*0Sigor@sysoev.ru } 390*0Sigor@sysoev.ru step = st_month; 391*0Sigor@sysoev.ru max = NXT_INT32_T_MAX / (30 * 24 * 60 * 60); 392*0Sigor@sysoev.ru scale = 30 * 24 * 60 * 60; 393*0Sigor@sysoev.ru break; 394*0Sigor@sysoev.ru 395*0Sigor@sysoev.ru case 'w': 396*0Sigor@sysoev.ru if (step >= st_week) { 397*0Sigor@sysoev.ru return -1; 398*0Sigor@sysoev.ru } 399*0Sigor@sysoev.ru step = st_week; 400*0Sigor@sysoev.ru max = NXT_INT32_T_MAX / (7 * 24 * 60 * 60); 401*0Sigor@sysoev.ru scale = 7 * 24 * 60 * 60; 402*0Sigor@sysoev.ru break; 403*0Sigor@sysoev.ru 404*0Sigor@sysoev.ru case 'd': 405*0Sigor@sysoev.ru if (step >= st_day) { 406*0Sigor@sysoev.ru return -1; 407*0Sigor@sysoev.ru } 408*0Sigor@sysoev.ru step = st_day; 409*0Sigor@sysoev.ru max = NXT_INT32_T_MAX / (24 * 60 * 60); 410*0Sigor@sysoev.ru scale = 24 * 60 * 60; 411*0Sigor@sysoev.ru break; 412*0Sigor@sysoev.ru 413*0Sigor@sysoev.ru case 'h': 414*0Sigor@sysoev.ru if (step >= st_hour) { 415*0Sigor@sysoev.ru return -1; 416*0Sigor@sysoev.ru } 417*0Sigor@sysoev.ru step = st_hour; 418*0Sigor@sysoev.ru max = NXT_INT32_T_MAX / (60 * 60); 419*0Sigor@sysoev.ru scale = 60 * 60; 420*0Sigor@sysoev.ru break; 421*0Sigor@sysoev.ru 422*0Sigor@sysoev.ru case 'm': 423*0Sigor@sysoev.ru if (p < end && *p == 's') { 424*0Sigor@sysoev.ru if (seconds || step >= st_msec) { 425*0Sigor@sysoev.ru return -1; 426*0Sigor@sysoev.ru } 427*0Sigor@sysoev.ru p++; 428*0Sigor@sysoev.ru step = st_msec; 429*0Sigor@sysoev.ru max = NXT_INT32_T_MAX; 430*0Sigor@sysoev.ru scale = 1; 431*0Sigor@sysoev.ru break; 432*0Sigor@sysoev.ru } 433*0Sigor@sysoev.ru 434*0Sigor@sysoev.ru if (step >= st_min) { 435*0Sigor@sysoev.ru return -1; 436*0Sigor@sysoev.ru } 437*0Sigor@sysoev.ru step = st_min; 438*0Sigor@sysoev.ru max = NXT_INT32_T_MAX / 60; 439*0Sigor@sysoev.ru scale = 60; 440*0Sigor@sysoev.ru break; 441*0Sigor@sysoev.ru 442*0Sigor@sysoev.ru case 's': 443*0Sigor@sysoev.ru if (step >= st_sec) { 444*0Sigor@sysoev.ru return -1; 445*0Sigor@sysoev.ru } 446*0Sigor@sysoev.ru step = st_sec; 447*0Sigor@sysoev.ru max = NXT_INT32_T_MAX; 448*0Sigor@sysoev.ru scale = 1; 449*0Sigor@sysoev.ru break; 450*0Sigor@sysoev.ru 451*0Sigor@sysoev.ru case ' ': 452*0Sigor@sysoev.ru if (step >= st_sec) { 453*0Sigor@sysoev.ru return -1; 454*0Sigor@sysoev.ru } 455*0Sigor@sysoev.ru step = st_last; 456*0Sigor@sysoev.ru max = NXT_INT32_T_MAX; 457*0Sigor@sysoev.ru scale = 1; 458*0Sigor@sysoev.ru break; 459*0Sigor@sysoev.ru 460*0Sigor@sysoev.ru default: 461*0Sigor@sysoev.ru return -1; 462*0Sigor@sysoev.ru } 463*0Sigor@sysoev.ru 464*0Sigor@sysoev.ru if (!seconds && step != st_msec) { 465*0Sigor@sysoev.ru scale *= 1000; 466*0Sigor@sysoev.ru max /= 1000; 467*0Sigor@sysoev.ru } 468*0Sigor@sysoev.ru 469*0Sigor@sysoev.ru if (val > max) { 470*0Sigor@sysoev.ru return -2; 471*0Sigor@sysoev.ru } 472*0Sigor@sysoev.ru 473*0Sigor@sysoev.ru term += val * scale; 474*0Sigor@sysoev.ru 475*0Sigor@sysoev.ru if (term > NXT_INT32_T_MAX) { 476*0Sigor@sysoev.ru return -2; 477*0Sigor@sysoev.ru } 478*0Sigor@sysoev.ru 479*0Sigor@sysoev.ru val = 0; 480*0Sigor@sysoev.ru 481*0Sigor@sysoev.ru state = st_space; 482*0Sigor@sysoev.ru } 483*0Sigor@sysoev.ru 484*0Sigor@sysoev.ru if (!seconds) { 485*0Sigor@sysoev.ru val *= 1000; 486*0Sigor@sysoev.ru } 487*0Sigor@sysoev.ru 488*0Sigor@sysoev.ru return term + val; 489*0Sigor@sysoev.ru } 490