File:  [Coherent Logic Development] / freem / src / mlib.c
Revision 1.3: download - view: text, annotated - select for diffs
Sun Mar 9 19:50:47 2025 UTC (12 months, 3 weeks ago) by snw
Branches: MAIN
CVS tags: v0-62-2, v0-62-1, v0-62-0, HEAD
Second phase of REUSE compliance and header reformat

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

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