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