Blob Blame Raw

struct ArgDesc;
typedef int (*ArgFunc)(const struct ArgDesc *desc, const char *arg);

typedef struct ArgDesc {
  char c;
  void *data;
  ArgFunc func;
  const char *desc;
} ArgDesc;


int pargInt(const ArgDesc *desc, const char *arg)
  { *(int*)desc->data = atoi(arg); return TRUE; }
int pargDouble(const ArgDesc *desc, const char *arg)
  { *(double*)desc->data = atof(arg); return TRUE; }
int pargString(const ArgDesc *desc, const char *arg)
  { *(const char**)desc->data = arg; return TRUE; }


int parseArgs(const ArgDesc *descs, int argc, char **argv) {
  for(; argc; --argc, ++argv) {
    int found = FALSE;
    for(const ArgDesc *desc = descs; desc->c && desc->data; ++desc) {
      if ((*argv)[0] == '-' && (*argv)[1] == desc->c && !(*argv)[2]) {
        if (desc->func) {
          --argc; ++argv;
          if (!argc || !desc->func(desc, *argv)) {
            fprintf(stderr, "Wrong argument for -%c: %s\n", desc->c, *argv);
            fflush(stderr);
            return FALSE;
          }
        } else {
          *((int*)desc->data) = TRUE;
        }
        found = TRUE;
        break;
      }
    }
    if (!found) {
      fprintf(stderr, "Unknown arg: %s\n", *argv);
      fflush(stderr);
      return FALSE;
    }
  }
  return TRUE;
}


void printUsage(const ArgDesc *descs) {
  printf("Available command-line arguments:\n");
  for(const ArgDesc *desc = descs; desc->c && desc->data; ++desc)
    printf("   -%c %s - %s\n", desc->c, desc->func ? "<arg>" : "     ", desc->desc);
  fflush(stdout);
}