| 3958 | |
| 3959 | if (tty && cfg->pause_ms > 0) usleep((useconds_t)cfg->pause_ms * 1000); |
| 3960 | free(question); |
| 3961 | ds4_tokens_free(&think_close_tokens); |
| 3962 | buf_free(&raw); |
| 3963 | return EVAL_RUN_OK; |
| 3964 | } |
| 3965 | |
| 3966 | static int next_pending_case(eval_ui *ui, int start) { |
| 3967 | if (ui->ncases <= 0) return -1; |
| 3968 | for (int off = 0; off < ui->ncases; off++) { |
| 3969 | int i = (start + off) % ui->ncases; |
| 3970 | if (ui->status[i] == EVAL_PENDING) return i; |
| 3971 | } |
| 3972 | return -1; |
| 3973 | } |
| 3974 | |
| 3975 | static int parse_case_sequence(const char *arg, int ncases, int **seq_out, int *len_out) { |
| 3976 | int cap = 8; |
| 3977 | int len = 0; |
| 3978 | int *seq = malloc((size_t)cap * sizeof(*seq)); |
| 3979 | if (!seq) { |
| 3980 | fprintf(stderr, "ds4-eval: out of memory while parsing --case-sequence\n"); |
| 3981 | return -1; |
| 3982 | } |
| 3983 | |
| 3984 | const char *p = arg; |
| 3985 | while (p && *p) { |
| 3986 | while (isspace((unsigned char)*p)) p++; |
| 3987 | if (!*p) break; |
| 3988 | errno = 0; |
| 3989 | char *end = NULL; |
| 3990 | long v = strtol(p, &end, 10); |
| 3991 | if (end == p || errno != 0 || v < 1 || v > ncases) { |
| 3992 | fprintf(stderr, |
| 3993 | "ds4-eval: invalid --case-sequence entry near '%s' " |
| 3994 | "(valid range: 1..%d)\n", |
| 3995 | p, ncases); |
| 3996 | free(seq); |
| 3997 | return -1; |
| 3998 | } |
| 3999 | if (len == cap) { |
| 4000 | cap *= 2; |
| 4001 | int *new_seq = realloc(seq, (size_t)cap * sizeof(*seq)); |
| 4002 | if (!new_seq) { |
| 4003 | fprintf(stderr, "ds4-eval: out of memory while parsing --case-sequence\n"); |
| 4004 | free(seq); |
| 4005 | return -1; |
| 4006 | } |
| 4007 | seq = new_seq; |
| 4008 | } |
| 4009 | seq[len++] = (int)v - 1; |
| 4010 | p = end; |
| 4011 | while (isspace((unsigned char)*p)) p++; |
| 4012 | if (*p == ',') { |
| 4013 | p++; |
| 4014 | continue; |
| 4015 | } |
| 4016 | if (*p) { |
| 4017 | fprintf(stderr, "ds4-eval: expected comma in --case-sequence near '%s'\n", p); |