|
|
| version 1.1, 2025/01/19 02:04:04 | version 1.10, 2025/03/24 04:13:11 |
|---|---|
| Line 1 | Line 1 |
| /* | /* |
| * * | * $Id$ |
| * * * | |
| * * * | |
| * *************** | |
| * * * * * | |
| * * MUMPS * | |
| * * * * * | |
| * *************** | |
| * * * | |
| * * * | |
| * * | |
| * | |
| * expr.c | |
| * expression parser | * expression parser |
| * | * |
| * | * |
| * 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, 2023 Coherent Logic Development LLC | * Copyright (C) 2020, 2023, 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.10 2025/03/24 04:13:11 snw | |
| * Replace action macro dat with fra_dat to avoid symbol conflict on OS/2 | |
| * | |
| * Revision 1.9 2025/03/24 01:32:22 snw | |
| * Guard declaration of time function in expr.c for portability | |
| * | |
| * Revision 1.8 2025/03/22 04:47:18 snw | |
| * Silently truncate long names in STRING exprs when evaluates to an obsolete MDC standard | |
| * | |
| * Revision 1.7 2025/03/22 03:39:23 snw | |
| * Fix reverse query polyfill call-in from C side and make NAME exprs silently truncate long names in obsolete MDC dialects | |
| * | |
| * Revision 1.6 2025/03/22 03:05:19 snw | |
| * Comply with X11-96/13 portable length of names | |
| * | |
| * Revision 1.5 2025/03/09 19:14:24 snw | |
| * First phase of REUSE compliance and header reformat | |
| * | |
| * | |
| * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC | |
| * SPDX-License-Identifier: AGPL-3.0-or-later | |
| **/ | **/ |
| #if !defined(__osf__) | #if !defined(__osf__) |
| Line 134 | Line 144 |
| #define GET 'Y' | #define GET 'Y' |
| #define GETX ':' | #define GETX ':' |
| #if !defined(__OpenBSD__) && !defined(_AIX) && !defined(__osf__) && !defined(MSDOS) && !defined(__vax__) | #if !defined(__OpenBSD__) && !defined(_AIX) && !defined(__osf__) && !defined(MSDOS) && !defined(__vax__) && !defined(__OS2__) |
| long time (); | long time (); |
| #endif | #endif |
| void cond_round (char *a, int digits); | |
| void cond_round (); | void zkey (char *a, long type); |
| void zdate (); | int levenshtein (char *word1, char *word2); |
| void zkey (); | |
| void ztime (); | |
| int levenshtein (); | |
| time_t horolog_to_unix (char *horo); | time_t horolog_to_unix (char *horo); |
| extern int xecline(int typ); | extern int xecline(int typ); |
| short rbuf_slot_from_name(char *); | short rbuf_slot_from_name(char *); |
| Line 181 void expr (short extyp) | Line 188 void expr (short extyp) |
| volatile int ch = 0; | volatile int ch = 0; |
| short group; /* flag to scan grouped patterns */ | short group; /* flag to scan grouped patterns */ |
| int max_namlen = 255; | |
| if ((rtn_dialect () == D_MDS) || (rtn_dialect () == D_M5) || (rtn_dialect () == D_FREEM)) { | |
| max_namlen = 255; | |
| } | |
| else { | |
| max_namlen = 8; | |
| } | |
| #ifdef DEBUG_NEWPTR | #ifdef DEBUG_NEWPTR |
| int loop; | int loop; |
| Line 209 void expr (short extyp) | Line 225 void expr (short extyp) |
| (((ch == '/' && varnam[i - 1] != '/') || | (((ch == '/' && varnam[i - 1] != '/') || |
| (ch == '%' && varnam[i - 1] == '/')) && | (ch == '%' && varnam[i - 1] == '/')) && |
| (varnam[1] == '.' || varnam[1] == '/'))))) || (f != '^') && (ch == '.')) { | (varnam[1] == '.' || varnam[1] == '/'))))) || (f != '^') && (ch == '.')) { |
| varnam[i++] = ch; | |
| if ((i + 1) <= max_namlen) { | |
| varnam[i++] = ch; | |
| } | |
| else { | |
| if ((rtn_dialect () == D_M77) || | |
| (rtn_dialect () == D_M84) || | |
| (rtn_dialect () == D_M90) || | |
| (rtn_dialect () == D_M95)) { | |
| /* silently truncate... yeah, the standard is stupid af */ | |
| continue; | |
| } | |
| else { | |
| merr_raise (M56); | |
| return; | |
| } | |
| } | |
| } | } |
| varnam[i] = EOL; | varnam[i] = EOL; |
| #if 0 | |
| { | |
| char gooby[256]; | |
| stcpy (gooby, varnam); | |
| stcnv_m2c (gooby); | |
| printf ("name = '%s'\r\n", gooby); | |
| } | |
| #endif | |
| if (ch == '(') { /* it's an array */ | if (ch == '(') { /* it's an array */ |
| Line 337 scan_name: | Line 375 scan_name: |
| merr_raise (INVEXPR); | merr_raise (INVEXPR); |
| return; | return; |
| } | } |
| varnam[i++] = ch; | if ((i + 1) <= max_namlen) { |
| varnam[i++] = ch; | |
| } | |
| else { | |
| if ((rtn_dialect () == D_M77) || | |
| (rtn_dialect () == D_M84) || | |
| (rtn_dialect () == D_M90) || | |
| (rtn_dialect () == D_M95)) { | |
| /* silently truncate... yeah, the standard is stupid af */ | |
| continue; | |
| } | |
| else { | |
| merr_raise (M56); | |
| return; | |
| } | |
| } | |
| lastch = ch; | lastch = ch; |
| } | } |
| Line 354 scan_name: | Line 407 scan_name: |
| else { /* local variable name */ | else { /* local variable name */ |
| while (isalnum (ch = *++codptr)) { | while (isalnum (ch = *++codptr)) { |
| varnam[i++] = ch; | |
| if ((i + 1) <= max_namlen) { | |
| varnam[i++] = ch; | |
| } | |
| else { | |
| if ((rtn_dialect () == D_M77) || | |
| (rtn_dialect () == D_M84) || | |
| (rtn_dialect () == D_M90) || | |
| (rtn_dialect () == D_M95)) { | |
| /* silently truncate... yeah, the standard is stupid af */ | |
| continue; | |
| } | |
| else { | |
| merr_raise (M56); | |
| return; | |
| } | |
| } | |
| } | } |
| varnam[i] = EOL; | varnam[i] = EOL; |
| Line 494 var1: | Line 564 var1: |
| case 'd': /* $DATA */ | case 'd': /* $DATA */ |
| ch = dat; | ch = fra_dat; |
| glv_fcn: | glv_fcn: |
| Line 2227 f20: | Line 2297 f20: |
| stcnv_c2m (qryarg_ext); | stcnv_c2m (qryarg_ext); |
| /* put the $QUERY argument into the local variable %INT.REVQ */ | /* put the $QUERY argument into the local variable %INT.REVQ */ |
| symtab (set_sym, "%INT.REVQ\201\201", qryarg_ext); | symtab (set_sym, "%INTREVQ\201\201", qryarg_ext); |
| /* set up for calling into polyfill wrapper */ | /* set up for calling into polyfill wrapper */ |
| code[0] = '\201'; | code[0] = '\201'; |
| Line 5546 errexfun: | Line 5616 errexfun: |
| /* $STORAGE */ | /* $STORAGE */ |
| case 's': | case 's': |
| snprintf (a, 255 , "%d\201", DEFPSIZE); | snprintf (a, 255 , "%ld\201", DEFPSIZE); |
| goto exec; | goto exec; |
| /* $WITH */ | /* $WITH */ |