1/* $NetBSD: parse_cross.c,v 1.1.1.1 2024/06/11 09:15:38 wiz Exp $ */ 2 3#if HAVE_CONFIG_H 4#include "config.h" 5#endif 6#include <nbcompat.h> 7#if HAVE_SYS_CDEFS_H 8#include <sys/cdefs.h> 9#endif 10__RCSID("$NetBSD: parse_cross.c,v 1.1.1.1 2024/06/11 09:15:38 wiz Exp $"); 11 12#if HAVE_ERR_H 13#include <err.h> 14#endif 15#include "lib.h" 16#include "add.h" 17 18/* 19 * ${OPSYS}/${MACHINE_ARCH} ${OS_VERSION} 20 * 21 * or just 22 * 23 * ${MACHINE_ARCH} 24 */ 25void 26parse_cross(const char *text, char **machine_arch, char **opsys, 27 char **os_version) 28{ 29 static const char safeset[] = /* XXX */ 30 "abcdefghijklmnopqrstuvwxyz" 31 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 32 "0123456789" 33 "-._"; 34 char *copy = xstrdup(text); 35 char *p = copy, *q, *r; 36 37 /* 38 * If there's no /, treat it as a single MACHINE_ARCH. 39 */ 40 if ((q = strchr(p, '/')) == NULL) { 41 *machine_arch = copy; 42 *opsys = NULL; 43 *os_version = NULL; 44 } else { 45 /* 46 * NUL-terminate at the slash so p := text[0..slash) 47 * is the OPSYS. 48 */ 49 *q++ = '\0'; 50 51 /* 52 * If there's no SPC, fail. 53 */ 54 if (*(r = strchr(q, ' ')) == '\0') { 55 goto fail; 56 } 57 58 /* 59 * NUL-terminate at the space so 60 * 61 * q := text(slash..space) 62 * 63 * is the MACHINE_ARCH. 64 */ 65 *r++ = '\0'; 66 67 /* 68 * The rest is already NUL-terminated, so 69 * 70 * r := text(space..NUL) 71 * 72 * is the OS_VERSION. 73 */ 74 *opsys = p; 75 *machine_arch = q; 76 *os_version = r; 77 } 78 79 /* 80 * Verify that MACHINE_ARCH, and, if specified, OPSYS and 81 * OS_VERSION lie within the safe set, so we can reserve large 82 * amounts of the space of inputs for additional syntax. 83 * Ideally we would impose more constraints here with a 84 * regular expression to restrict the space even more, but 85 * this'll do for now. 86 */ 87 if ((*machine_arch)[strspn(*machine_arch, safeset)] != '\0') { 88 goto fail; 89 } 90 if (*opsys != NULL && (*opsys)[strspn(*opsys, safeset)] != '\0') { 91 goto fail; 92 } 93 if (*os_version != NULL && 94 (*os_version)[strspn(*os_version, safeset)] != '\0') { 95 goto fail; 96 } 97 return; 98 99fail: errx(1, "Invalid -m argument: ${OPSYS}/${MACHINE_ARCH} ${OS_VERSION}"); 100} 101