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>