125 lines
2.7 KiB
C
125 lines
2.7 KiB
C
// Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
|
|
// See LICENSE.md for license information.
|
|
// SPDX-License-Identifier: MIT
|
|
//
|
|
// gateArg.c - command lines for the gate tools (gateArg.h).
|
|
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "gateArg.h"
|
|
#include "toolFile.h"
|
|
|
|
#define DECIMAL 10
|
|
#define PORT_MAX 65535L
|
|
|
|
|
|
void gateArgBad(const char *name, const char *text) {
|
|
toolFailCode(GATE_USAGE_EXIT, "bad %s: %s", name, text);
|
|
}
|
|
|
|
|
|
double gateArgDouble(const char *name, const char *text) {
|
|
double value;
|
|
|
|
if (!gateArgParseDouble(text, &value)) {
|
|
gateArgBad(name, text);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
|
|
long gateArgLong(const char *name, const char *text) {
|
|
long value;
|
|
|
|
if (!gateArgParseLong(text, &value)) {
|
|
gateArgBad(name, text);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
|
|
void gateArgPair(const char *name, const char *text, char separator, long *first, long *second) {
|
|
char *copy;
|
|
char *split;
|
|
size_t len;
|
|
bool good;
|
|
|
|
len = strlen(text);
|
|
copy = (char *)malloc(len + 1u);
|
|
if (copy == NULL) {
|
|
toolFail("out of memory");
|
|
}
|
|
memcpy(copy, text, len + 1u);
|
|
split = strchr(copy, separator);
|
|
good = split != NULL && strchr(split + 1, separator) == NULL;
|
|
if (good) {
|
|
*split = '\0';
|
|
good = gateArgParseLong(copy, first) && gateArgParseLong(split + 1, second);
|
|
}
|
|
free(copy);
|
|
if (!good) {
|
|
gateArgBad(name, text);
|
|
}
|
|
}
|
|
|
|
|
|
bool gateArgParseDouble(const char *text, double *out) {
|
|
char *end;
|
|
|
|
if (text[0] == '\0' || isspace((unsigned char)text[0])) {
|
|
return false;
|
|
}
|
|
*out = strtod(text, &end);
|
|
return *end == '\0' && isfinite(*out);
|
|
}
|
|
|
|
|
|
bool gateArgParseLong(const char *text, long *out) {
|
|
char *end;
|
|
|
|
if (text[0] == '\0' || isspace((unsigned char)text[0])) {
|
|
return false;
|
|
}
|
|
errno = 0;
|
|
*out = strtol(text, &end, DECIMAL);
|
|
return *end == '\0' && errno != ERANGE;
|
|
}
|
|
|
|
|
|
uint16_t gateArgPort(const char *text) {
|
|
long port;
|
|
|
|
port = gateArgLong("port", text);
|
|
if (port < 0 || port > PORT_MAX) {
|
|
gateArgBad("port", text);
|
|
}
|
|
return (uint16_t)port;
|
|
}
|
|
|
|
|
|
bool gateModeRun(const GateModeT *modes, size_t count, int argc, char **argv, int *exitCode) {
|
|
size_t m;
|
|
|
|
for (m = 0; argc >= 2 && m < count; m++) {
|
|
if (strcmp(argv[1], modes[m].name) == 0 && argc == modes[m].argCount + 2) {
|
|
*exitCode = modes[m].run(argv + 2);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
int gateUsage(const char *const *lines, size_t count) {
|
|
size_t i;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
fprintf(stderr, "%s\n", lines[i]);
|
|
}
|
|
return GATE_USAGE_EXIT;
|
|
}
|