version 1.1, 2025/01/19 02:04:04
|
version 1.15, 2025/05/18 18:15:38
|
Line 1
|
Line 1
|
/* |
/* |
* * |
* $Id$ |
* * * |
|
* * * |
|
* *************** |
|
* * * * * |
|
* * MUMPS * |
|
* * * * * |
|
* *************** |
|
* * * |
|
* * * |
|
* * |
|
* |
|
* symtab.c |
|
* FreeM local system table and user-defined special variable table |
* FreeM local system table and user-defined special variable table |
* |
* |
* |
* |
* Author: Serena Willis <jpw@coherent-logic.com> |
* Author: Serena Willis <snw@coherent-logic.com> |
* Copyright (C) 1998 MUG Deutschland |
* Copyright (C) 1998 MUG Deutschland |
* Copyright (C) 2020 Coherent Logic Development LLC |
* Copyright (C) 2020, 2025 Coherent Logic Development LLC |
* |
* |
* |
* |
* This file is part of FreeM. |
* This file is part of FreeM. |
Line 35
|
Line 23
|
* You should have received a copy of the GNU Affero Public License |
* You should have received a copy of the GNU Affero Public License |
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* |
* |
|
* $Log$ |
|
* Revision 1.15 2025/05/18 18:15:38 snw |
|
* Add ZEDIT command for editing routines |
|
* |
|
* Revision 1.14 2025/05/14 12:22:04 snw |
|
* Further work on shared memory |
|
* |
|
* Revision 1.13 2025/04/19 21:52:20 snw |
|
* Remove extraneous symbol table debugging message |
|
* |
|
* Revision 1.12 2025/04/14 19:56:27 snw |
|
* Working towards FreeBSD fix |
|
* |
|
* Revision 1.11 2025/04/13 04:22:43 snw |
|
* Fix snprintf calls |
|
* |
|
* Revision 1.10 2025/04/10 01:24:39 snw |
|
* Remove C++ style comments |
|
* |
|
* Revision 1.9 2025/04/09 19:52:02 snw |
|
* Eliminate as many warnings as possible while building with -Wall |
|
* |
|
* Revision 1.8 2025/04/04 12:46:13 snw |
|
* Patch Solaris 8 crash and bump version to 0.63.1-rc1 |
|
* |
|
* Revision 1.7 2025/03/26 15:17:12 snw |
|
* Fall back to global-backed SSVNs when memory-backed globals fail in attempt to fix Tru64 |
|
* |
|
* Revision 1.6 2025/03/24 04:13:11 snw |
|
* Replace action macro dat with fra_dat to avoid symbol conflict on OS/2 |
|
* |
|
* Revision 1.5 2025/03/24 02:01:41 snw |
|
* Work around some OS/2 incompatibilities in symbol table code |
|
* |
|
* Revision 1.4 2025/03/09 19:50:47 snw |
|
* Second phase of REUSE compliance and header reformat |
|
* |
|
* |
|
* SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC |
|
* SPDX-License-Identifier: AGPL-3.0-or-later |
**/ |
**/ |
|
|
#include <stdlib.h> |
#include <stdlib.h> |
Line 49
|
Line 77
|
#include "merr.h" |
#include "merr.h" |
#include "consttbl.h" |
#include "consttbl.h" |
#include "shmmgr.h" |
#include "shmmgr.h" |
|
#include "log.h" |
|
|
/* Turn this on to get tons of lovely debugging messages about |
/* Turn this on to get tons of lovely debugging messages about |
symbol-table calls */ |
symbol-table calls */ |
/* #define DEBUG_SYM */ |
/* #define DEBUG_SYM */ |
|
|
|
short st_use_shm = FALSE; |
short restoring_consts = FALSE; |
short restoring_consts = FALSE; |
int semid_symtab; |
int semid_symtab; |
|
|
#if !defined(__OpenBSD__) && !defined(__APPLE__) |
#if !defined(__OpenBSD__) && !defined(__APPLE__) && !defined(__OS2__) |
union semun { |
union semun { |
int val; /* Value for SETVAL */ |
int val; /* Value for SETVAL */ |
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ |
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ |
Line 94 long str2long(char *string)
|
Line 124 long str2long(char *string)
|
return value; |
return value; |
} |
} |
|
|
void symtab_init () |
void symtab_init (void) |
{ |
{ |
register int i; |
register int i; |
union semun arg; |
union semun arg; |
Line 113 void symtab_init ()
|
Line 143 void symtab_init ()
|
shm_config->hdr->PSIZE = DEFPSIZE; |
shm_config->hdr->PSIZE = DEFPSIZE; |
shm_config->hdr->argptr = mbpartition; |
shm_config->hdr->argptr = mbpartition; |
|
|
fprintf (stderr, "symtab_init: initializing memory-backed globals\r\n"); |
|
|
logprintf (FM_LOG_INFO, "symtab_init: initializing memory-backed globals"); |
|
|
semid_symtab = semget (symtab_sk, 1, 0666 | IPC_CREAT); |
semid_symtab = semget (symtab_sk, 1, 0666 | IPC_CREAT); |
if (semid_symtab == -1) { |
if (semid_symtab == -1) { |
fprintf (stderr, "symtab_init: failed to create symbol table semaphore\r\n"); |
logprintf (FM_LOG_FATAL, "symtab_init: failed to create symbol table semaphore"); |
exit (1); |
|
} |
} |
else { |
else { |
fprintf (stderr, "symtab_init: symbol table semaphore created with semid %d\r\n", semid_symtab); |
logprintf (FM_LOG_INFO, "symtab_init: symbol table semaphore created with semid %d", semid_symtab); |
} |
} |
|
|
|
#if defined(__sun__) |
|
logprintf (FM_LOG_WARNING, "symtab_init: falling back to global-backed structured system variables"); |
|
shm_config->hdr->use_mb_globals = FALSE; |
|
return; |
|
#endif |
|
|
|
|
arg.val = 1; |
arg.val = 1; |
if (semctl (semid_symtab, 0, SETVAL, arg) == -1) { |
if (semctl (semid_symtab, 0, SETVAL, arg) == -1) { |
fprintf (stderr, "symtab_init: failed to initialize symbol table semaphore\r\n"); |
logprintf (FM_LOG_FATAL, "symtab_init: failed to initialize symbol table semaphore"); |
exit (1); |
|
} |
} |
else { |
else { |
fprintf (stderr, "symtab_init: symbol table semaphore initialized\r\n"); |
logprintf (FM_LOG_INFO, "symtab_init: symbol table semaphore initialized"); |
} |
} |
|
|
fprintf (stderr, "symtab_init: allocating partition for memory-backed globals\r\n"); |
logprintf (FM_LOG_INFO, "symtab_init: allocating partition for memory-backed globals"); |
|
|
mbpartition = (char *) shm_alloc ((size_t) PSIZE + 2); |
mbpartition = (char *) shm_alloc ((size_t) PSIZE + 2); |
NULLPTRCHK(mbpartition,"symtab_init"); |
if (mbpartition != NULL) { |
|
shm_config->hdr->use_mb_globals = TRUE; |
shm_config->hdr->partition = mbpartition; |
shm_config->hdr->partition = mbpartition; |
|
} |
|
else { |
|
logprintf (FM_LOG_WARNING, "symtab_init: falling back to global-backed structured system variables"); |
|
shm_config->hdr->use_mb_globals = FALSE; |
|
} |
|
|
if (symtab_get_sem ()) { |
if (symtab_get_sem ()) { |
for (i = 0; i < 128; i++) shm_config->hdr->alphptr[i] = 0L; |
for (i = 0; i < 128; i++) shm_config->hdr->alphptr[i] = 0L; |
Line 150 void symtab_init ()
|
Line 191 void symtab_init ()
|
|
|
semid_symtab = semget (symtab_sk, 1, 0); |
semid_symtab = semget (symtab_sk, 1, 0); |
if (semid_symtab == -1) { |
if (semid_symtab == -1) { |
fprintf (stderr, "symtab_init: could not attach to symbol table semaphore\r\n"); |
logprintf (FM_LOG_FATAL, "symtab_init: could not attach to symbol table semaphore"); |
exit (1); |
exit (1); |
} |
} |
|
|
mbpartition = shm_config->hdr->partition; |
|
|
|
|
if (shm_config->hdr->use_mb_globals == TRUE) { |
|
mbpartition = SOA(shm_config->hdr->partition); |
|
} |
|
|
|
symtab_release_sem (); |
} |
} |
|
|
} |
} |
Line 181 short symtab_get_sem(void)
|
Line 225 short symtab_get_sem(void)
|
sleep (1); |
sleep (1); |
|
|
} |
} |
fprintf (stderr, "symtab_get_sem: fail\r\n"); |
logprintf (FM_LOG_ERROR, "symtab_get_sem: fail"); |
|
|
have_symtab_sem = FALSE; |
have_symtab_sem = FALSE; |
return FALSE; |
return FALSE; |
Line 206 void symtab_shm (short action, char *key
|
Line 250 void symtab_shm (short action, char *key
|
unsigned long stptrs[128]; |
unsigned long stptrs[128]; |
register int i; |
register int i; |
char *old_partition = partition; |
char *old_partition = partition; |
|
|
|
/* |
|
global (action, key, data); |
|
return; |
|
*/ |
|
|
|
if (shm_config->hdr->use_mb_globals == FALSE) { |
|
symtab_bltin (action, key, data); |
|
return; |
|
} |
partition = mbpartition; |
partition = mbpartition; |
|
|
writing_mb = TRUE; |
writing_mb = TRUE; |
Line 259 void symtab_shm (short action, char *key
|
Line 313 void symtab_shm (short action, char *key
|
|
|
} |
} |
else { |
else { |
fprintf (stderr, "symtab_shm: failed to acquire symbol table sempahore\r\n"); |
logprintf (FM_LOG_FATAL, "symtab_shm: failed to acquire symbol table sempahore"); |
} |
} |
|
|
writing_mb = FALSE; |
writing_mb = FALSE; |
Line 357 void symtab_bltin (short action, char *k
|
Line 411 void symtab_bltin (short action, char *k
|
stcnv_m2c (tt_with); |
stcnv_m2c (tt_with); |
stcnv_m2c (tt_key); |
stcnv_m2c (tt_key); |
|
|
snprintf (key, 100, "%s%s\201\201", tt_with, tt_key); |
sprintf (key, "%s%s\201\201", tt_with, tt_key); |
|
|
|
|
no_with: |
no_with: |
Line 563 no_with:
|
Line 617 no_with:
|
/* OLD get_sym routine */ |
/* OLD get_sym routine */ |
if ((i = alphptr[(int) key[0]])) { |
if ((i = alphptr[(int) key[0]])) { |
|
|
// printf ("alphptr match; writing_mb = %d\r\n", writing_mb); |
/* printf ("alphptr match; writing_mb = %d\r\n", writing_mb); */ |
|
|
k = 1; |
k = 1; |
j = i + 1; /* first char always matches! */ |
j = i + 1; /* first char always matches! */ |
Line 612 no_with:
|
Line 666 no_with:
|
|
|
return; |
return; |
|
|
|
|
|
|
|
|
|
|
case set_sym: /* store/create variable */ |
case set_sym: /* store/create variable */ |
|
|
|
|
Line 948 old0: /* entry from getinc */
|
Line 998 old0: /* entry from getinc */
|
/* end of set_sym section */ |
/* end of set_sym section */ |
|
|
|
|
case dat: |
case fra_dat: |
|
|
|
|
/* note: we assume EOL<DELIM<ASCII */ |
/* note: we assume EOL<DELIM<ASCII */ |
Line 1813 zinvend:
|
Line 1863 zinvend:
|
*newptr++ = k1; |
*newptr++ = k1; |
*newptr++ = set_sym; |
*newptr++ = set_sym; |
|
|
//if (mcmnd != ZNEW) test = FALSE; |
/*if (mcmnd != ZNEW) test = FALSE; */ |
|
|
return; |
return; |
|
|
Line 1880 zinvend:
|
Line 1930 zinvend:
|
|
|
char esbuf[256]; |
char esbuf[256]; |
|
|
snprintf (esbuf, 255, "%d\201", estack); |
snprintf (esbuf, sizeof (esbuf) - 1, "%d\201", estack); |
|
|
j = stcpy (newptr, esbuf); |
j = stcpy (newptr, esbuf); |
|
|
Line 2475 unsubscr:
|
Line 2525 unsubscr:
|
|
|
|
|
/******************************************************************************/ |
/******************************************************************************/ |
short int collate (s, t) |
|
char *s; |
|
char *t; |
|
/* if 't' follows 's' in MUMPS collating sequence a 1 is returned |
/* if 't' follows 's' in MUMPS collating sequence a 1 is returned |
* otherwise 0 |
* otherwise 0 |
*/ |
*/ |
|
|
|
short int collate (char *s, char *t) |
{ |
{ |
short dif; |
short dif; |
|
|
Line 2552 short int numeric (char *str)
|
Line 2601 short int numeric (char *str)
|
} /* end of numeric() */ |
} /* end of numeric() */ |
|
|
/******************************************************************************/ |
/******************************************************************************/ |
short int comp (s, t) |
|
char *s; |
|
char *t; |
|
/* s and t are strings representing */ |
/* s and t are strings representing */ |
/* MUMPS numbers. comp returns t>s */ |
/* MUMPS numbers. comp returns t>s */ |
|
|
|
short int comp (char *s, char *t) |
{ |
{ |
|
|
register int s1 = s[0], t1 = t[0], point = '.'; |
register int s1 = s[0], t1 = t[0], point = '.'; |
Line 2621 short int comp (s, t)
|
Line 2669 short int comp (s, t)
|
|
|
} /* end of comp() */ |
} /* end of comp() */ |
/******************************************************************************/ |
/******************************************************************************/ |
void intstr (str, integ) /* converts integer to string */ |
void intstr (char *str, short integ) /* converts integer to string */ |
char *str; |
|
short integ; |
|
{ |
{ |
|
|
if (integ < 0) { |
if (integ < 0) { |
Line 2662 void intstr (str, integ) /* converts i
|
Line 2708 void intstr (str, integ) /* converts i
|
} /* end of intstr() */ |
} /* end of intstr() */ |
|
|
/******************************************************************************/ |
/******************************************************************************/ |
void lintstr (str, integ) /* converts long integer to string */ |
void lintstr (char *str, long integ) /* converts long integer to string */ |
char *str; |
|
long integ; |
|
{ |
{ |
char result[11]; /* 32 bit = 10 digits+sign */ |
char result[11]; /* 32 bit = 10 digits+sign */ |
register int i = 0; |
register int i = 0; |
Line 2700 void lintstr (str, integ) /* converts
|
Line 2744 void lintstr (str, integ) /* converts
|
* alphabet for each character a pointer to the first variable beginning |
* alphabet for each character a pointer to the first variable beginning |
* with that letter is maintained. (0 indicates there's no such var.) |
* with that letter is maintained. (0 indicates there's no such var.) |
*/ |
*/ |
void udfsvn (action, key, data) /* symbol table functions */ |
|
short action; /* set_sym get_sym */ |
void udfsvn (short action, char *key, char *data) /* symbol table functions */ |
char *key; /* lvn as ASCII-string */ |
|
char *data; |
|
{ |
{ |
|
|
long keyl; /* length of key */ |
long keyl; /* length of key */ |
Line 2910 old:
|
Line 2952 old:
|
|
|
|
|
/******************************************************************************/ |
/******************************************************************************/ |
long getpmore () |
long getpmore (void) |
{ /* try to get more 'partition' space. returns size increment */ |
{ /* try to get more 'partition' space. returns size increment */ |
|
|
long siz; |
long siz; |
Line 2932 long getpmore ()
|
Line 2974 long getpmore ()
|
} /* end getpmore */ |
} /* end getpmore */ |
|
|
/******************************************************************************/ |
/******************************************************************************/ |
long getumore () |
long getumore (void) |
{ /* try to get more udfsvntab space. returns size increment */ |
{ /* try to get more udfsvntab space. returns size increment */ |
long siz, dif; |
long siz, dif; |
|
|
Line 2958 long getumore ()
|
Line 3000 long getumore ()
|
} /* end getumore */ |
} /* end getumore */ |
|
|
/******************************************************************************/ |
/******************************************************************************/ |
long getrmore () |
long getrmore (void) |
{ /* try to get more routine space. returns size increment */ |
{ /* try to get more routine space. returns size increment */ |
long siz, dif; |
long siz, dif; |
short i; |
short i; |
Line 2990 long getrmore ()
|
Line 3032 long getrmore ()
|
} /* end getrmore */ |
} /* end getrmore */ |
|
|
/******************************************************************************/ |
/******************************************************************************/ |
short int getnewmore () |
short int getnewmore (void) |
{ /* enlarge new_buffers */ |
{ /* enlarge new_buffers */ |
char *newbuf; |
char *newbuf; |
int i; |
int i; |