/* Parsuje pojedyńczy opcjonalny argument, zwraca wartość wywołania `scanf`. */ static int parseopt( const char *arg, const char *val, struct params *result ) { /* * Wczytujemy do `temp`, bo typ np. `timeout` może różnić * się na różnych systemach. W ten sposób wczytujemy * do `uint` i rzutujemy do dowolnego typu. */ uint tmp; const int retv = sscanf(val, "%u", &tmp); if (OPTARG(arg, "-t", "--timeout")) { result->timeout = tmp; } else if (OPTARG(arg, "-m", "--maxttl")) { result->maxttl = tmp; } else if (OPTARG(arg, "-r", "--requests")) { result->reqc = tmp; } else { printf("Unknown option: %s.\n", arg); printf("Try with `--help` for more information.\n"); exit(1); } return retv; }
bool Parser::OPTIONS(int& pos) { int p{ pos }; for (;;) { if (!OPTARG(p)) break; } Fragment f; TEXT(p, f); pos = p; return true; }
/** * Parsuje i zwraca argumenty wywołania, * w przypadku braku któregokolwiek zwraca wartości domyślne. * * @param argv Argumenty wywołania (bez nazwy programu!). * @param argc Ilość argumentów. * @return Ładna struktura z zapakowanymi wszystkimi potrzebnymi danymi. */ struct params parseargs(char **argv, const size_t argc) { /* Domyślne wartości, zgodne z treścią zadania. */ struct params result = { { 0 }, 1000, 30, 3 }; /* Czy wczytany został adres do którego drogę chcemy wyliczać? */ bool addr = false; for (uint i = 0; i < argc; i++) { int retv = 0; if (OPTARG(argv[i], "-h", "--help")) { printhelp(); exit(1); } else if (argv[i][0] == '-' && i < argc - 1) { retv = parseopt(argv[i], argv[i + 1], &result); i++; } else { retv = handle( "parse ip adress", inet_pton(AF_INET, argv[i], &result.addr.sin_addr) ); addr = true; } /* * `sscanf` zwraca ilość poprawnie zczytanych * parametrów a `inet_pton` 1 jeżeli uda mu się * sparsować adres. Wystarczy więc sprawdzić czy * `retv` jest większy od zera, w przeciwnym razie * argument jest nieprawidłowy. */ if (retv <= 0) { printf("Incorrect argument: %s.\n", argv[i]); printf("Try with `--help` for more information.\n"); exit(1); } } if (!addr) { printf("Remote server address not given.\n"); exit(1); } return result; }