Annotation of freem/src/mlib.c, revision 1.4
1.1 snw 1: /*
1.4 ! snw 2: * $Id: mlib.c,v 1.3 2025/03/09 19:50:47 snw Exp $
1.1 snw 3: * Function prototypes, structs, and macros for FreeM
4: * binding library
5: *
6: *
1.2 snw 7: * Author: Serena Willis <snw@coherent-logic.com>
1.1 snw 8: * Copyright (C) 1998 MUG Deutschland
1.3 snw 9: * Copyright (C) 2020, 2025 Coherent Logic Development LLC
1.1 snw 10: *
11: *
12: * This file is part of FreeM.
13: *
14: * FreeM is free software: you can redistribute it and/or modify
15: * it under the terms of the GNU Affero Public License as published by
16: * the Free Software Foundation, either version 3 of the License, or
17: * (at your option) any later version.
18: *
19: * FreeM is distributed in the hope that it will be useful,
20: * but WITHOUT ANY WARRANTY; without even the implied warranty of
21: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22: * GNU Affero Public License for more details.
23: *
24: * You should have received a copy of the GNU Affero Public License
25: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
26: *
1.4 ! snw 27: * $Log: mlib.c,v $
! 28: * Revision 1.3 2025/03/09 19:50:47 snw
! 29: * Second phase of REUSE compliance and header reformat
! 30: *
1.3 snw 31: *
32: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
33: * SPDX-License-Identifier: AGPL-3.0-or-later
1.1 snw 34: **/
35:
36: #include <stdlib.h>
37:
38: #include "mpsdef.h"
39: #include "freem.h"
40: #include "init.h"
41: #include "transact.h"
42: #include "version.h"
43:
44: #include <stdio.h>
45: #include <ctype.h>
46: #include <string.h>
47: #include <errno.h>
48:
49: /* the following function prototypes are not in freem.h, as they are intended to be
50: * private and internal to mlib.c
51: */
52: void mref2str(freem_ref_t *ref, char *key);
53: void freem_release_io(void);
54: void freem_return_io(void);
55:
56: extern int xecline(int typ);
57:
58: void mref2str(freem_ref_t *ref, char *key)
59: {
60: register int i;
61:
62: for (i = 0; i < 256; i++) key[i] = NUL;
63:
64: switch (ref->reftype) {
65:
66: case MREF_RT_LOCAL: /* do nothing for locals, as they have no sigil */
67: break;
68:
69: case MREF_RT_GLOBAL:
70: strcat (key, "^");
71: break;
72:
73: case MREF_RT_SSVN:
74: strcat (key, "^$");
75: break;
76:
77: }
78:
79: if (ref->subscript_count > 0) {
80: strcat (key, ref->name);
81: strcat (key, "\202");
82:
83: for (i = 0; i < ref->subscript_count; i++) {
84: strcat (key, ref->subscripts[i]);
85:
86: if (i < ref->subscript_count - 1) strcat (key, "\202");
87: }
88: }
89: else {
90: strcat (key, ref->name);
91: }
92:
93: // ends with EOL
94: strncat (key, "\201", 2);
95:
96: }
97:
98: pid_t freem_init(char *environment_name, char *namespace_name)
99: {
100: int ierr_sav;
101: int errno_sav;
102:
103: libflag = TRUE;
104: noclear = TRUE;
105: frm_filter = TRUE;
106: direct_mode = FALSE;
107:
108: errno = 0;
109:
110: strcpy (shm_env, environment_name);
111: snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, shm_env);
112:
113: init (namespace_name);
114: ierr_sav = ierr;
115: errno_sav = errno;
116:
117: freem_release_io ();
118:
119:
120: if (ierr_sav > OK || errno_sav != 0) {
121: return -1;
122: }
123: else {
124: return pid;
125: }
126: }
127:
128: short freem_version(char *result)
129: {
130: strncpy (result, FREEM_VERSION_ID, 255);
131:
132: return OK;
133: }
134:
135: short freem_get(freem_ref_t *ref)
136: {
137: char key[256];
138: char result[256];
139:
140: freem_return_io ();
141:
142: // set up the EOL-delimited string
143: mref2str (ref, key);
144:
145: switch (ref->reftype) {
146:
147: case MREF_RT_LOCAL:
148: // call into the symbol table to get the local var
149: symtab (get_sym, key, result);
150: ref->status = merr ();
151: break;
152:
153: case MREF_RT_GLOBAL:
154: // call into the FreeM global handler; result in &result
155: global (get_sym, key, result);
156: ref->status = merr ();
157: break;
158:
159: case MREF_RT_SSVN:
160: // call into the SSVN code
161: ssvn (get_sym, key, result);
162: ref->status = merr ();
163: break;
164:
165: }
166:
167: stcnv_m2c (result);
168:
169: strncpy (ref->value, result, 255);
170:
171: freem_release_io ();
172:
173: return ref->status;
174: }
175:
176: short freem_set(freem_ref_t *ref)
177: {
178: char key[256];
179: char data[256];
180:
181: freem_return_io ();
182:
183: mref2str (ref, key);
184:
185: snprintf (data, 254, "%s\201", ref->value);
186:
187: switch (ref->reftype) {
188:
189: case MREF_RT_LOCAL:
190: // call into the symbol table to set the local var
191: symtab (set_sym, key, data);
192: ref->status = merr ();
193: break;
194:
195: case MREF_RT_GLOBAL:
196: // call into the FreeM global handler; data in &data
197: global (set_sym, key, data);
198: ref->status = merr ();
199: break;
200:
201: case MREF_RT_SSVN:
202: // call into the SSVN code
203: ssvn (set_sym, key, data);
204: ref->status = merr ();
205: break;
206:
207: }
208:
209: freem_release_io ();
210:
211:
212: return ref->status;
213: }
214:
215: short freem_kill(freem_ref_t *ref)
216: {
217: char key[256];
218: char result[256];
219:
220: mref2str (ref, key);
221:
222: freem_return_io ();
223:
224: switch (ref->reftype) {
225:
226: case MREF_RT_LOCAL:
227: // call into the symbol table to kill the local var
228: symtab (kill_sym, key, result);
229: ref->status = merr ();
230: break;
231:
232: case MREF_RT_GLOBAL:
233: // call into the FreeM global handler; result in &result
234: global (kill_sym, key, result);
235: ref->status = merr ();
236: break;
237:
238: case MREF_RT_SSVN:
239: // call into the SSVN code
240: ssvn (kill_sym, key, result);
241: ref->status = merr ();
242: break;
243:
244: }
245:
246: stcnv_m2c (result);
247:
248: strncpy (ref->value, result, 255);
249:
250: freem_release_io ();
251:
252:
253: return ref->status;
254: }
255:
256: short freem_data(freem_ref_t *ref)
257: {
258: char key[256];
259: char result[256];
260:
261: mref2str (ref, key);
262:
263: freem_return_io ();
264:
265: switch (ref->reftype) {
266:
267: case MREF_RT_LOCAL:
268: // call into the symbol table
1.4 ! snw 269: symtab (fra_dat, key, result);
1.1 snw 270: ref->status = merr ();
271: break;
272:
273: case MREF_RT_GLOBAL:
274: // call into the FreeM global handler; result in &result
1.4 ! snw 275: global (fra_dat, key, result);
1.1 snw 276: ref->status = merr ();
277: break;
278:
279: case MREF_RT_SSVN:
280: // call into the SSVN code
1.4 ! snw 281: ssvn (fra_dat, key, result);
1.1 snw 282: ref->status = merr ();
283: break;
284:
285: }
286:
287: stcnv_m2c (result);
288:
289: strncpy (ref->value, result, 255);
290:
291: freem_release_io ();
292:
293: return ref->status;
294: }
295:
296: short freem_order(freem_ref_t *ref)
297: {
298: char key[256];
299: char result[256];
300:
301: mref2str (ref, key);
302:
303: freem_return_io ();
304:
305: switch (ref->reftype) {
306:
307: case MREF_RT_LOCAL:
308: // call into the symbol table for $ORDER
309: symtab (fra_order, key, result);
310: ref->status = merr ();
311: break;
312:
313: case MREF_RT_GLOBAL:
314: // call into the FreeM global handler; result in &result
315: global (fra_order, key, result);
316: ref->status = merr ();
317: break;
318:
319: case MREF_RT_SSVN:
320: // call into the SSVN code
321: ssvn (fra_order, key, result);
322: ref->status = merr ();
323: break;
324:
325: }
326:
327: stcnv_m2c (result);
328:
329: strncpy (ref->value, result, 255);
330: freem_release_io ();
331:
332: return ref->status;
333: }
334:
335: short freem_query(freem_ref_t *ref)
336: {
337: char key[256];
338: char result[256];
339:
340: mref2str (ref, key);
341:
342: freem_return_io ();
343:
344: switch (ref->reftype) {
345:
346: case MREF_RT_LOCAL:
347: // call into the symbol table
348: symtab (fra_query, key, result);
349: ref->status = merr ();
350: break;
351:
352: case MREF_RT_GLOBAL:
353: // call into the FreeM global handler; result in &result
354: global (fra_query, key, result);
355: ref->status = merr ();
356: break;
357:
358: case MREF_RT_SSVN:
359: // call into the SSVN code
360: ssvn (fra_query, key, result);
361: ref->status = merr ();
362: break;
363:
364: }
365:
366: stcnv_m2c (result);
367:
368: strncpy (ref->value, result, 255);
369:
370: freem_release_io ();
371:
372: return ref->status;
373: }
374:
375: short freem_lock(freem_ref_t *ref, long lck_timeout)
376: {
377: char key[256];
378: char buf[256];
379:
380: mref2str (ref, key);
381: snprintf (buf, 255, "+%s\201", key);
382:
383: freem_return_io ();
384:
385: lock (buf, lck_timeout, 'l');
386: ref->status = merr ();
387:
388: freem_release_io ();
389:
390: return ref->status;
391: }
392:
393: short freem_unlock(freem_ref_t *ref, long lck_timeout)
394: {
395: char key[256];
396: char buf[256];
397:
398: mref2str (ref, key);
399: snprintf (buf, 255, "-%s\201", key);
400:
401: freem_return_io ();
402:
403: lock (buf, lck_timeout, 'l');
404: ref->status = merr ();
405:
406: freem_release_io ();
407:
408: return ref->status;
409: }
410:
411: short freem_tstart(char *tp_id, short serial, short restartable, char **sym_save)
412: {
413: return tp_tstart (tp_id, serial, restartable, sym_save);
414: }
415:
416: short freem_trestart(void)
417: {
418: return tp_trestart ();
419: }
420:
421: short freem_trollback(int tp_levels)
422: {
423: return tp_trollback (tp_levels);
424: }
425:
426: short freem_tcommit(void)
427: {
428: return tp_tcommit ();
429: }
430:
431: int freem_tlevel(void)
432: {
433: return tp_level;
434: }
435:
436: short freem_function(freem_ent_t *ent)
437: {
438: register int i;
439: char buf[STRLEN] = {0};
440: char tmp[STRLEN] = {0};
441: char tmp1[STRLEN] = {0};
442:
443: freem_return_io ();
444:
445: if (ent->argument_count > 0) {
446: snprintf (buf, STRLEN - 1, "S %%ZFRMRTN=$$%s(", ent->name);
447:
448: for (i = 0; i < ent->argument_count; i++) {
449:
450: strncpy (tmp1, ent->arguments[i], STRLEN - 1);
451: stcnv_c2m (tmp1);
452:
453: if (znamenumeric (tmp1) == TRUE) {
454: /* arguments that are canonical MUMPS numbers don't get quoted */
455: snprintf (tmp, STRLEN - 1, "%s", ent->arguments[i]);
456: }
457: else {
458: /* string arguments do get quoted */
459: snprintf (tmp, STRLEN - 1, "\"%s\"", ent->arguments[i]);
460: }
461:
462: strcat (buf, tmp);
463:
464: if(i < ent->argument_count - 1) {
465: strcat (buf, ",");
466: }
467: }
468:
469: strcat (buf, ")");
470: }
471: else {
472: snprintf (buf, STRLEN - 1, "S %%ZFRMRTN=$$%s", ent->name);
473: }
474:
475: stcnv_c2m (buf);
476: sprintf (tmp, "%%ZFRMXEC\201");
477: symtab (set_sym, tmp, buf);
478: snprintf ((char *) ztrap, 12, "^%%ZFRMXEC\201");
479:
480: xecline (3);
481: ent->status = merr ();
482:
483: tmp[0] = NUL;
484: ent->value[0] = NUL;
485:
486: snprintf (tmp, 255, "%%ZFRMRTN\201");
487: symtab (get_sym, tmp, ent->value);
488: stcnv_m2c (ent->value);
489:
490: freem_release_io ();
491:
492: return ent->status;
493: }
494:
495: short freem_procedure(freem_ent_t *ent)
496: {
497: register int i;
498: char buf[STRLEN] = {0};
499: char tmp[STRLEN] = {0};
500: char tmp1[STRLEN] = {0};
501:
502: freem_return_io ();
503:
504: if (ent->argument_count > 0) {
505: snprintf (buf, STRLEN - 1, "DO %s(", ent->name);
506:
507: for (i = 0; i < ent->argument_count; i++) {
508:
509: strncpy (tmp1, ent->arguments[i], STRLEN - 1);
510: stcnv_c2m (tmp1);
511:
512: if (znamenumeric (tmp1) == TRUE) {
513: /* arguments that are canonical MUMPS numbers don't get quoted */
514: snprintf (tmp, STRLEN - 1, "%s", ent->arguments[i]);
515: }
516: else {
517: /* string arguments do get quoted */
518: snprintf (tmp, STRLEN - 1, "\"%s\"", ent->arguments[i]);
519: }
520:
521: strcat (buf, tmp);
522:
523: if(i < ent->argument_count - 1) {
524: strcat (buf, ",");
525: }
526: }
527:
528: strcat (buf, ")");
529: }
530: else {
531: snprintf (buf, STRLEN - 1, "DO %s", ent->name);
532: }
533:
534: stcnv_c2m (buf);
535: sprintf (tmp, "%%ZFRMXEC\201");
536: symtab (set_sym, tmp, buf);
537:
538:
539: snprintf ((char *) ztrap, 12, "^%%ZFRMXEC\201");
540:
541:
542: xecline (3);
543: ent->status = merr ();
544:
545: tmp[0] = NUL;
546: ent->value[0] = NUL;
547:
548: freem_release_io ();
549:
550: return ent->status;
551: }
552:
553: short freem_errmsg(int code, char *msg)
554: {
555: char emtmp[256];
556: char cvtmp[256];
557:
558: if (code > MAXERR || code < 0) {
559: return FALSE;
560: }
561:
562: stcpy (cvtmp, errmes[code]);
563: stcnv_m2c (cvtmp);
564:
565: merr_num_to_code (code, emtmp);
566:
567: sprintf (msg, "%s: %s", emtmp, cvtmp);
568:
569: return TRUE;
570: }
571:
572: void freem_release_io(void)
573: {
574: set_io (UNIX);
575: }
576:
577: void freem_return_io(void)
578: {
579: set_io (MUMPS);
580: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>