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>