static const char * get_weight_vector(grn_ctx *ctx, grn_query *query, const char *source) { const char *p; if (!query->opt.weight_vector && !query->weight_set && !(query->opt.weight_vector = GRN_CALLOC(sizeof(int) * DEFAULT_WEIGHT_VECTOR_SIZE))) { GRN_LOG(ctx, GRN_LOG_ALERT, "get_weight_vector malloc fail"); return source; } for (p = source; p < query->str_end; ) { unsigned int key; int value; /* key, key is not zero */ key = grn_atoui(p, query->str_end, &p); if (!key || key > GRN_ID_MAX) { break; } /* value */ if (*p == ':') { p++; value = grn_atoi(p, query->str_end, &p); } else { value = 1; } if (query->weight_set) { int *pval; if (grn_hash_add(ctx, query->weight_set, &key, sizeof(unsigned int), (void **)&pval, NULL)) { *pval = value; } } else if (key < DEFAULT_WEIGHT_VECTOR_SIZE) { query->opt.weight_vector[key - 1] = value; } else { GRN_FREE(query->opt.weight_vector); query->opt.weight_vector = NULL; if (!(query->weight_set = grn_hash_create(ctx, NULL, sizeof(unsigned int), sizeof(int), 0))) { return source; } p = source; /* reparse */ continue; } if (*p != ',') { break; } p++; } return p; }
grn_rc grn_str2timeval(const char *str, uint32_t str_len, grn_timeval *tv) { struct tm tm; const char *r1, *r2, *rend = str + str_len; uint32_t uv; memset(&tm, 0, sizeof(struct tm)); tm.tm_year = (int)grn_atoui(str, rend, &r1) - 1900; if ((r1 + 1) >= rend || (*r1 != '/' && *r1 != '-')) { return GRN_INVALID_ARGUMENT; } r1++; tm.tm_mon = (int)grn_atoui(r1, rend, &r1) - 1; if ((r1 + 1) >= rend || (*r1 != '/' && *r1 != '-') || tm.tm_mon < 0 || tm.tm_mon >= 12) { return GRN_INVALID_ARGUMENT; } r1++; tm.tm_mday = (int)grn_atoui(r1, rend, &r1); if ((r1 + 1) >= rend || *r1 != ' ' || tm.tm_mday < 1 || tm.tm_mday > 31) { return GRN_INVALID_ARGUMENT; } tm.tm_hour = (int)grn_atoui(++r1, rend, &r2); if ((r2 + 1) >= rend || r1 == r2 || *r2 != ':' || tm.tm_hour < 0 || tm.tm_hour >= 24) { return GRN_INVALID_ARGUMENT; } r1 = r2 + 1; tm.tm_min = (int)grn_atoui(r1, rend, &r2); if ((r2 + 1) >= rend || r1 == r2 || *r2 != ':' || tm.tm_min < 0 || tm.tm_min >= 60) { return GRN_INVALID_ARGUMENT; } r1 = r2 + 1; tm.tm_sec = (int)grn_atoui(r1, rend, &r2); if (r1 == r2 || tm.tm_sec < 0 || tm.tm_sec > 61 /* leap 2sec */) { return GRN_INVALID_ARGUMENT; } r1 = r2; tm.tm_yday = -1; tm.tm_isdst = -1; /* tm_yday is set appropriately (0-365) on successful completion. */ tv->tv_sec = mktime(&tm); if (tm.tm_yday == -1) { return GRN_INVALID_ARGUMENT; } if ((r1 + 1) < rend && *r1 == '.') { r1++; } uv = grn_atoi(r1, rend, &r2); while (r2 < r1 + 6) { uv *= 10; r2++; } if (uv >= GRN_TIME_USEC_PER_SEC) { return GRN_INVALID_ARGUMENT; } tv->tv_nsec = GRN_TIME_USEC_TO_NSEC(uv); return GRN_SUCCESS; }
grn_rc grn_str2timeval(const char *str, uint32_t str_len, grn_timeval *tv) { struct tm tm; const char *r1, *r2, *rend = str + str_len; uint32_t uv; memset(&tm, 0, sizeof(struct tm)); tm.tm_year = (int)grn_atoui(str, rend, &r1) - 1900; if ((r1 + 1) >= rend || (*r1 != '/' && *r1 != '-') || tm.tm_year < 0) { return GRN_INVALID_ARGUMENT; } r1++; tm.tm_mon = (int)grn_atoui(r1, rend, &r1) - 1; if ((r1 + 1) >= rend || (*r1 != '/' && *r1 != '-') || tm.tm_mon < 0 || tm.tm_mon >= 12) { return GRN_INVALID_ARGUMENT; } r1++; tm.tm_mday = (int)grn_atoui(r1, rend, &r1); if ((r1 + 1) >= rend || *r1 != ' ' || tm.tm_mday < 1 || tm.tm_mday > 31) { return GRN_INVALID_ARGUMENT; } tm.tm_hour = (int)grn_atoui(++r1, rend, &r2); if ((r2 + 1) >= rend || r1 == r2 || *r2 != ':' || tm.tm_hour < 0 || tm.tm_hour >= 24) { return GRN_INVALID_ARGUMENT; } r1 = r2 + 1; tm.tm_min = (int)grn_atoui(r1, rend, &r2); if ((r2 + 1) >= rend || r1 == r2 || *r2 != ':' || tm.tm_min < 0 || tm.tm_min >= 60) { return GRN_INVALID_ARGUMENT; } r1 = r2 + 1; tm.tm_sec = (int)grn_atoui(r1, rend, &r2); if (r1 == r2 || tm.tm_sec < 0 || tm.tm_sec > 61 /* leap 2sec */) { return GRN_INVALID_ARGUMENT; } r1 = r2; if ((tv->tv_sec = (int32_t) mktime(&tm)) == -1) { return GRN_INVALID_ARGUMENT; } if ((r1 + 1) < rend && *r1 == '.') { r1++; } uv = grn_atoi(r1, rend, &r2); while (r2 < r1 + 6) { uv *= 10; r2++; } if (uv >= 1000000) { return GRN_INVALID_ARGUMENT; } tv->tv_usec = uv; return GRN_SUCCESS; }