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