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