int main(int argc, const char **argv) { assert(argc == 1 || argc == 3); if (argc == 3) return setcmp(argv[1], argv[2]); int rc = 0; char *line = NULL; size_t alloc_size = 0; ssize_t len; while ((len = getline(&line, &alloc_size, stdin)) >= 0) { if (len > 0 && line[len-1] == '\n') line[--len] = '\0'; if (len == 0) continue; char *s1 = line; char *s2 = strchr(line, ' '); if (s2 == NULL) s2 = strchr(line, '\t'); assert(s2); *s2++ = '\0'; rc |= setcmp(s1, s2); } free(line); return rc; }
static void fine_step_tune(int (*setcmp)(int regval), int regval, int step) { /* Registers are not always stable, timeout if best fit not found soon enough */ unsigned long abort = current_tick + HZ*2; int flags = 0; while (TIME_BEFORE(current_tick, abort)) { int cmp; regval = regval + step; cmp = setcmp(regval); if (cmp == 0) break; step = abs(step); if (cmp < 0) { flags |= TOO_SMALL; if (step == 1) flags |= APPROACH_UP_1; } else { step = -step; flags |= TOO_BIG; if (step == -1) step |= APPROACH_DOWN_1; } if ((flags & APPROACH_UP_1) && (flags & APPROACH_DOWN_1)) break; /* approached with step=1: best fit value found */ if ((flags & TOO_SMALL) && (flags & TOO_BIG)) { step /= 2; if (step == 0) step = 1; flags &= ~(TOO_SMALL | TOO_BIG); } } }