Annotation of freem/src/mref.c, revision 1.7
1.1 snw 1: /*
1.7 ! snw 2: * $Id: mref.c,v 1.6 2025/04/09 15:16:50 snw Exp $
1.1 snw 3: * supporting functions for handling freem_ref_t structures
4: *
5: *
1.3 snw 6: * Author: Serena Willis <snw@coherent-logic.com>
1.1 snw 7: * Copyright (C) 1998 MUG Deutschland
1.4 snw 8: * Copyright (C) 2020, 2025 Coherent Logic Development LLC
1.1 snw 9: *
10: *
11: * This file is part of FreeM.
12: *
13: * FreeM is free software: you can redistribute it and/or modify
14: * it under the terms of the GNU Affero Public License as published by
15: * the Free Software Foundation, either version 3 of the License, or
16: * (at your option) any later version.
17: *
18: * FreeM is distributed in the hope that it will be useful,
19: * but WITHOUT ANY WARRANTY; without even the implied warranty of
20: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21: * GNU Affero Public License for more details.
22: *
23: * You should have received a copy of the GNU Affero Public License
24: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
25: *
1.5 snw 26: * $Log: mref.c,v $
1.7 ! snw 27: * Revision 1.6 2025/04/09 15:16:50 snw
! 28: * Fix buffer overruns in mref_to_external and ssvn.c
! 29: *
1.6 snw 30: * Revision 1.5 2025/03/22 18:43:54 snw
31: * Make STRLEN 255 chars and add BIGSTR macro for larger buffers
32: *
1.5 snw 33: * Revision 1.4 2025/03/09 19:50:47 snw
34: * Second phase of REUSE compliance and header reformat
35: *
1.4 snw 36: *
37: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
38: * SPDX-License-Identifier: AGPL-3.0-or-later
1.1 snw 39: **/
40:
41: #include <stdio.h>
42: #include <stdlib.h>
43: #include <string.h>
44: #include <mpsdef0.h>
45:
46: #include "freem.h"
47:
48: #define MREF_CHECK(ref,index,type) if (ref->status != MREF_ST_INIT || index > 255 || index < 0) return (type) NULL
1.2 snw 49: #define MREF_CHECK_EXIT(ref,index,type) if (ref->status != MREF_ST_INIT || index > 255 || index < 0) exit (type) NULL
1.1 snw 50:
51: extern short g_numeric (char *str);
52:
53: freem_ref_t *mref_init (freem_ref_t *ref, short ref_type, char *name)
54: {
55: if (strlen (name) > 255) {
56: ref->status = MREF_ST_ERR;
57: return ref;
58: }
59:
60: ref->reftype = ref_type;
61: ref->status = MREF_ST_INIT;
62: strncpy (ref->name, name, 255);
63: ref->subscript_count = 0;
64:
65: return ref;
66: }
67:
68: char *mref_get_name (freem_ref_t *ref)
69: {
70: MREF_CHECK (ref, 0, char *);
71:
72: return ref->name;
73: }
74:
75: char *mref_get_subscript (freem_ref_t *ref, int index)
76: {
77: /* ref must be initialized, and index within range */
78: MREF_CHECK (ref, index, char *);
79:
80: return ref->subscripts[index];
81: }
82:
83: freem_ref_t *mref_set_subscript (freem_ref_t *ref, int index, char *value)
84: {
85: MREF_CHECK (ref, index, freem_ref_t *);
86:
87: if (ref->subscript_count == 0 && index == 0) ref->subscript_count = 1;
88:
89: if (ref->subscript_count < (index + 1)) {
90: ref->subscript_count = index + 1;
91: }
92:
93: strncpy (ref->subscripts[index], value, 255);
94:
95: return ref;
96: }
97:
98: void mref_to_internal_prealloc (char *res, freem_ref_t *ref)
99: {
100: register int i;
101:
1.2 snw 102: /* MREF_CHECK (ref, 0, char *); */
1.1 snw 103:
104: strncpy (res, ref->name, STRLEN - 1);
105:
106: for (i = 0; i < ref->subscript_count; i++) {
107: strncat (res, "\202", STRLEN - 1);
108: strncat (res, ref->subscripts[i], STRLEN - 1);
109: }
110:
111: strncat (res, "\201", STRLEN - 1);
112: stcnv_c2m (res);
113:
114: }
115:
116: char *mref_to_internal (freem_ref_t *ref)
117: {
118:
119: char *tmp = (char *) malloc (STRLEN * sizeof(char));
120: register int i;
121:
122: MREF_CHECK (ref, 0, char *);
123:
124: strncpy (tmp, ref->name, STRLEN - 1);
125:
126: for (i = 0; i < ref->subscript_count; i++) {
127: strncat (tmp, "\202", STRLEN - 1);
128: strncat (tmp, ref->subscripts[i], STRLEN - 1);
129: }
130:
131: strncat (tmp, "\201", STRLEN - 1);
132: stcnv_c2m (tmp);
133:
134: return tmp;
135: }
136:
137: /* convert a DELIM-delimited, EOL-terminated key to a freem_ref_t* */
138: freem_ref_t *internal_to_mref (freem_ref_t *ref, char *key)
139: {
140: register int i;
141: register int j;
142: char *ptr = key;
143: char ch;
144: char *nam = (char *) malloc (STRLEN * sizeof(char));
145: char *tmp = (char *) malloc (STRLEN * sizeof(char));
146:
147: MREF_CHECK (ref, 0, freem_ref_t *);
148:
149: /* shunt the name into ref->name */
150: i = 0;
151: while ((ch = *(ptr++)) != DELIM && ch != EOL) {
152: nam[i++] = ch;
153: }
154:
155: nam[i] = '\0';
156:
157: if (nam[0] == '^') {
158:
159: if (nam[1] == '$') {
160: ref->reftype = MREF_RT_SSVN;
161: }
162: else {
163: ref->reftype = MREF_RT_GLOBAL;
164: }
165:
166: }
167: else {
168: ref->reftype = MREF_RT_LOCAL;
169: }
170:
1.5 snw 171: strncpy (ref->name, nam, STRLEN);
1.1 snw 172:
173: /* if no subscripts, return the ref */
174: if (*(ptr - 1) == EOL) {
175: ref->subscript_count = 0;
176:
177: free (nam);
178: free (tmp);
179:
180: return ref;
181: }
182:
183:
184: /* grab the subscripts */
185: i = 0;
186: j = 0;
187: while ((ch = *(ptr++)) != EOL) {
188:
189: switch (ch) {
190:
191: case '\001':
192: break;
193: case DELIM:
194:
195: tmp[j] = '\0';
196:
197: mref_set_subscript (ref, i++, tmp);
198: ref->subscript_count++;
199:
200: j = 0;
201: tmp[j] = '\0';
202:
203: break;
204:
205:
206: default:
207: tmp[j++] = ch;
208:
209: }
210:
211: }
212:
213: tmp[j] = '\0';
214:
215: /* grab the last one */
216: mref_set_subscript (ref, i, tmp);
217:
218: free (nam);
219: free (tmp);
220:
221: return ref;
222:
223: }
224:
225: void mref_to_external (freem_ref_t *ref, char *buf)
226: {
227: register int i;
228: register int j;
229: short is_numeric = FALSE;
230: short is_ref = FALSE;
231: char *t_buf = (char *) malloc (STRLEN * sizeof (char));
232: NULLPTRCHK(t_buf,"mref_to_external");
233:
234: strcpy (buf, ref->name);
235:
236: if (ref->subscript_count) {
237:
238: strcat (buf, "(");
239:
240:
241: for (i = 0; i < ref->subscript_count; i++) {
242:
243: if (ref->subscripts[i][0] == '.') {
244: is_ref = TRUE;
245: }
246: else {
247: is_ref = FALSE;
248: }
249:
250: strcpy (t_buf, ref->subscripts[i]);
251:
252: for (j = 0; j < strlen (t_buf); j++) {
253: if (t_buf[j] == '\001') t_buf[j] = '\201';
254: }
255:
256: stcnv_c2m (t_buf);
257:
258: is_numeric = numeric (t_buf);
259:
260:
261: if (!is_numeric && !is_ref) strcat (buf, "\"");
262:
263: for (j = 0; j < strlen (ref->subscripts[i]); j++) {
264: if (ref->subscripts[i][j] == '\001') ref->subscripts[i][j] = '\201';
265: }
266: strcat (buf, ref->subscripts[i]);
267: if (!is_numeric && !is_ref) strcat (buf, "\"");
268:
269: if (i < (ref->subscript_count - 1)) {
270: strcat (buf, ",");
271: }
272:
273: }
1.6 snw 274: stncnv_m2c (buf, STRLEN);
1.1 snw 275:
276: strcat (buf, ")");
277:
278: }
279:
280: free (t_buf);
281: return;
282:
283: }
284:
285: /* returns TRUE if b is a descendant of a */
286: short mref_is_descendant(freem_ref_t *a, freem_ref_t *b)
287: {
288: register int i;
289:
290: if (a->subscript_count > b->subscript_count) return FALSE;
291: if ((strcmp (a->name, b->name) == 0) && (a->subscript_count == 0)) return TRUE;
292:
293:
294: for (i = 0; i < a->subscript_count; i++) {
1.7 ! snw 295: if (strcmp (b->subscripts[i], a->subscripts[i]) != 0 ) {
1.1 snw 296:
297: return FALSE;
298: }
299: }
300:
301: return TRUE;
302: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>