Annotation of freem/src/mlib.c, revision 1.3

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>