Annotation of freem/src/mref.c, revision 1.6
1.1 snw 1: /*
1.6 ! snw 2: * $Id: mref.c,v 1.5 2025/03/22 18:43:54 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.6 ! snw 27: * Revision 1.5 2025/03/22 18:43:54 snw
! 28: * Make STRLEN 255 chars and add BIGSTR macro for larger buffers
! 29: *
1.5 snw 30: * Revision 1.4 2025/03/09 19:50:47 snw
31: * Second phase of REUSE compliance and header reformat
32: *
1.4 snw 33: *
34: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
35: * SPDX-License-Identifier: AGPL-3.0-or-later
1.1 snw 36: **/
37:
38: #include <stdio.h>
39: #include <stdlib.h>
40: #include <string.h>
41: #include <mpsdef0.h>
42:
43: #include "freem.h"
44:
45: #define MREF_CHECK(ref,index,type) if (ref->status != MREF_ST_INIT || index > 255 || index < 0) return (type) NULL
1.2 snw 46: #define MREF_CHECK_EXIT(ref,index,type) if (ref->status != MREF_ST_INIT || index > 255 || index < 0) exit (type) NULL
1.1 snw 47:
48: extern short g_numeric (char *str);
49:
50: freem_ref_t *mref_init (freem_ref_t *ref, short ref_type, char *name)
51: {
52: if (strlen (name) > 255) {
53: ref->status = MREF_ST_ERR;
54: return ref;
55: }
56:
57: ref->reftype = ref_type;
58: ref->status = MREF_ST_INIT;
59: strncpy (ref->name, name, 255);
60: ref->subscript_count = 0;
61:
62: return ref;
63: }
64:
65: char *mref_get_name (freem_ref_t *ref)
66: {
67: MREF_CHECK (ref, 0, char *);
68:
69: return ref->name;
70: }
71:
72: char *mref_get_subscript (freem_ref_t *ref, int index)
73: {
74: /* ref must be initialized, and index within range */
75: MREF_CHECK (ref, index, char *);
76:
77: return ref->subscripts[index];
78: }
79:
80: freem_ref_t *mref_set_subscript (freem_ref_t *ref, int index, char *value)
81: {
82: MREF_CHECK (ref, index, freem_ref_t *);
83:
84: if (ref->subscript_count == 0 && index == 0) ref->subscript_count = 1;
85:
86: if (ref->subscript_count < (index + 1)) {
87: ref->subscript_count = index + 1;
88: }
89:
90: strncpy (ref->subscripts[index], value, 255);
91:
92: return ref;
93: }
94:
95: void mref_to_internal_prealloc (char *res, freem_ref_t *ref)
96: {
97: register int i;
98:
1.2 snw 99: /* MREF_CHECK (ref, 0, char *); */
1.1 snw 100:
101: strncpy (res, ref->name, STRLEN - 1);
102:
103: for (i = 0; i < ref->subscript_count; i++) {
104: strncat (res, "\202", STRLEN - 1);
105: strncat (res, ref->subscripts[i], STRLEN - 1);
106: }
107:
108: strncat (res, "\201", STRLEN - 1);
109: stcnv_c2m (res);
110:
111: }
112:
113: char *mref_to_internal (freem_ref_t *ref)
114: {
115:
116: char *tmp = (char *) malloc (STRLEN * sizeof(char));
117: register int i;
118:
119: MREF_CHECK (ref, 0, char *);
120:
121: strncpy (tmp, ref->name, STRLEN - 1);
122:
123: for (i = 0; i < ref->subscript_count; i++) {
124: strncat (tmp, "\202", STRLEN - 1);
125: strncat (tmp, ref->subscripts[i], STRLEN - 1);
126: }
127:
128: strncat (tmp, "\201", STRLEN - 1);
129: stcnv_c2m (tmp);
130:
131: return tmp;
132: }
133:
134: /* convert a DELIM-delimited, EOL-terminated key to a freem_ref_t* */
135: freem_ref_t *internal_to_mref (freem_ref_t *ref, char *key)
136: {
137: register int i;
138: register int j;
139: char *ptr = key;
140: char ch;
141: char *nam = (char *) malloc (STRLEN * sizeof(char));
142: char *tmp = (char *) malloc (STRLEN * sizeof(char));
143:
144: MREF_CHECK (ref, 0, freem_ref_t *);
145:
146: /* shunt the name into ref->name */
147: i = 0;
148: while ((ch = *(ptr++)) != DELIM && ch != EOL) {
149: nam[i++] = ch;
150: }
151:
152: nam[i] = '\0';
153:
154: if (nam[0] == '^') {
155:
156: if (nam[1] == '$') {
157: ref->reftype = MREF_RT_SSVN;
158: }
159: else {
160: ref->reftype = MREF_RT_GLOBAL;
161: }
162:
163: }
164: else {
165: ref->reftype = MREF_RT_LOCAL;
166: }
167:
1.5 snw 168: strncpy (ref->name, nam, STRLEN);
1.1 snw 169:
170: /* if no subscripts, return the ref */
171: if (*(ptr - 1) == EOL) {
172: ref->subscript_count = 0;
173:
174: free (nam);
175: free (tmp);
176:
177: return ref;
178: }
179:
180:
181: /* grab the subscripts */
182: i = 0;
183: j = 0;
184: while ((ch = *(ptr++)) != EOL) {
185:
186: switch (ch) {
187:
188: case '\001':
189: break;
190: case DELIM:
191:
192: tmp[j] = '\0';
193:
194: mref_set_subscript (ref, i++, tmp);
195: ref->subscript_count++;
196:
197: j = 0;
198: tmp[j] = '\0';
199:
200: break;
201:
202:
203: default:
204: tmp[j++] = ch;
205:
206: }
207:
208: }
209:
210: tmp[j] = '\0';
211:
212: /* grab the last one */
213: mref_set_subscript (ref, i, tmp);
214:
215: free (nam);
216: free (tmp);
217:
218: return ref;
219:
220: }
221:
222: void mref_to_external (freem_ref_t *ref, char *buf)
223: {
224: register int i;
225: register int j;
226: short is_numeric = FALSE;
227: short is_ref = FALSE;
228: char *t_buf = (char *) malloc (STRLEN * sizeof (char));
229: NULLPTRCHK(t_buf,"mref_to_external");
230:
231: strcpy (buf, ref->name);
232:
233: if (ref->subscript_count) {
234:
235: strcat (buf, "(");
236:
237:
238: for (i = 0; i < ref->subscript_count; i++) {
239:
240: if (ref->subscripts[i][0] == '.') {
241: is_ref = TRUE;
242: }
243: else {
244: is_ref = FALSE;
245: }
246:
247: strcpy (t_buf, ref->subscripts[i]);
248:
249: for (j = 0; j < strlen (t_buf); j++) {
250: if (t_buf[j] == '\001') t_buf[j] = '\201';
251: }
252:
253: stcnv_c2m (t_buf);
254:
255: is_numeric = numeric (t_buf);
256:
257:
258: if (!is_numeric && !is_ref) strcat (buf, "\"");
259:
260: for (j = 0; j < strlen (ref->subscripts[i]); j++) {
261: if (ref->subscripts[i][j] == '\001') ref->subscripts[i][j] = '\201';
262: }
263: strcat (buf, ref->subscripts[i]);
264: if (!is_numeric && !is_ref) strcat (buf, "\"");
265:
266: if (i < (ref->subscript_count - 1)) {
267: strcat (buf, ",");
268: }
269:
270: }
1.6 ! snw 271: stncnv_m2c (buf, STRLEN);
1.1 snw 272:
273: strcat (buf, ")");
274:
275: }
276:
277: free (t_buf);
278: return;
279:
280: }
281:
282: /* returns TRUE if b is a descendant of a */
283: short mref_is_descendant(freem_ref_t *a, freem_ref_t *b)
284: {
285: register int i;
286:
287: //printf ("checking if %s is a descendant of %s\r\n", b->name, a->name);
288: //printf ("a: %d b: %d\r\n", a->subscript_count, b->subscript_count);
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++) {
295:
296: //printf("\ta[%d] = '%s'\r\n\tb[%d] = '%s'\r\n", i, a->subscripts[i], i, b->subscripts[i]);
297:
298: if (strcmp (b->subscripts[i], a->subscripts[i]) != 0 ) {
299: //printf ("not descendant [%d]\r\n", strcmp (b->subscripts[i], a->subscripts[i]));
300: return FALSE;
301: }
302: }
303:
304: //printf ("is descendant\r\n");
305:
306: return TRUE;
307: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>