static double get_multiplier(sge_rlim_t *rlimp, char **dptr, const char *where, char *err_str, int err_len) { double mul = 1; *rlimp = 1; /* parse for k,K,m,M multipliers at the end of the value * string; strtod returns dptr to point to this location */ switch (**dptr) { case 'k': mul = 1000; *rlimp = 1000; (*dptr)++; break; case 'K': mul = 1024; *rlimp = 1024; (*dptr)++; break; case 'm': mul = 1000 * 1000; *rlimp = 1000 * 1000; (*dptr)++; break; case 'M': mul = 1024 * 1024; *rlimp = 1024 * 1024; (*dptr)++; break; case 'g': mul = 1000 * 1000 * 1000; *rlimp = mul_infinity(mul_infinity(1000, 1000), 1000); (*dptr)++; break; case 'G': mul = 1024 * 1024 * 1024; *rlimp = mul_infinity(mul_infinity(1024, 1024), 1024); (*dptr)++; break; case ',': /* no multiplier */ case '\0': /* no multiplier */ case '/': /* no multiplier */ case ' ': /* no multiplier */ break; default: snprintf(err_str, err_len, MSG_GDI_UNRECOGNIZEDVALUETRAILER_SS , *dptr, where); return 0; } if ((**dptr != ',') && (**dptr != '\0') && (**dptr != '/')) { snprintf(err_str, err_len, MSG_GDI_UNEXPECTEDENDOFNUMERICALVALUE_SC , where, **dptr); return 0; } return mul; }
u_long32 sge_parse_num_val(sge_rlim_t *rlimp, double *dvalp, const char *str, const char *where, char *err_str, int err_len) { double dummy; sge_rlim_t rlim, rlmuli; double dval; u_long32 ldummy; char *dptr; double muli; if (!rlimp) rlimp = &rlim; if (!dvalp) dvalp = &dval; if (err_str) err_str[0] = '\0'; if (!strcasecmp(str, "true")) { /* C-language says bool is a numeric. For reasons of simplicity we agree. */ *dvalp = 1; *rlimp = 1; return 1; } else if (!strcasecmp(str, "false")) { *dvalp = 0; *rlimp = 0; return 0; } else if (!strcasecmp(str, "infinity")) { *dvalp = DBL_MAX; /* use this for comparing limits */ *rlimp = RLIM_INFINITY; /* use this for limit setting */ return 0xFFFFFFFF; /* return max ulong in 32 bit */ } else if (strchr(str, ':')) { /* This is a time value in the format hr:min:sec */ /* find the hours first */ double t = strtod(str, &dptr); if (t > 0x7fffffff) { snprintf(err_str, err_len, MSG_GDI_NUMERICALVALUEFORHOUREXCEEDED_SS , where, str); return 0; } ldummy = (u_long32)(3600 * t); *rlimp = (sge_rlim_t)(long)mul_infinity(t, 3600.0); *dvalp = 3600 * t; if ((*dptr) != ':') { snprintf(err_str, err_len, MSG_GDI_NUMERICALVALUEINVALID_SS , where, str); return 0; } /* now go for the minutes */ dptr++; t = strtod(dptr, &dptr); if (t > 0x7fffffff) { snprintf(err_str, err_len, MSG_GDI_NUMERICALVALUEFORMINUTEEXCEEDED_SS , where, str); return 0; } ldummy += (u_long32)(60 * t); *rlimp = add_infinity(*rlimp, (sge_rlim_t)(60*t)); *dvalp += 60 * t; if ((*dptr) != ':') { snprintf(err_str, err_len, MSG_GDI_NUMERICALVALUEINVALID_SS , where, str); return 0; } /* the seconds finally */ dptr++; t = strtod(dptr, &dptr); ldummy += (u_long32)t; *rlimp = (sge_rlim_t)(long)add_infinity(*rlimp, t); *dvalp += t; while(*dptr) { if (!isspace((int) *dptr)) { snprintf(err_str, err_len, MSG_GDI_NUMERICALVALUEINVALID_SS , where, str); return 0; } dptr++; } return (ldummy); } else if (strchr(str, '.') || *str != '0') { /* obviously this is no hex and no oct * ==> allow for both decimal and fixed float */ double t = strtod(str, &dptr); if (t > 0x7fffffff) dummy = 0x7fffffff; else dummy = t; if ((dummy == 0.0) && (dptr == str)) { /* no valid number ==> bail */ snprintf(err_str, err_len, MSG_GDI_NUMERICALVALUEINVALIDNONUMBER_SS , where, str); return 0; } /* OK, we got it */ if (!(muli = get_multiplier(&rlmuli, &dptr, where, err_str, err_len))) return 0; dummy = (u_long32) (dummy * muli); *dvalp = t * muli; if (t > RLIM_MAX || rlmuli>= RLIM_MAX || (double)(RLIM_MAX/muli)<t) *rlimp = RLIM_INFINITY; else *rlimp = (sge_rlim_t)(t*rlmuli); return (u_long32)dummy; } else { /* if (strchr(str, '.') || *str != '0') */ /* This is either a hex or an octal ==> no fixed float allowed; * just use strtol */ u_long32 t = strtol(str, &dptr, 0); /* base=0 will handle both hex and oct */ ldummy = t; *rlimp = t; *dvalp = t; if (dptr == str) { /* no valid number ==> bail */ snprintf(err_str, err_len, MSG_GDI_NUMERICALVALUEINVALIDNOHEXOCTNUMBER_SS , where, str); return 0; } /* OK, we got it */ if (!(muli = get_multiplier(&rlmuli, &dptr, where, err_str, err_len))) return 0; ldummy *= (u_long32)muli; *rlimp = mul_infinity(*rlimp, rlmuli); *dvalp *= muli; return (u_long32)ldummy; } }