version 1.1.1.1, 2025/01/19 02:04:04
|
version 1.11, 2025/05/06 15:18:55
|
Line 1
|
Line 1
|
/* |
/* |
* * |
* $Id$ |
* * * |
|
* * * |
|
* *************** |
|
* * * * * |
|
* * MUMPS * |
|
* * * * * |
|
* *************** |
|
* * * |
|
* * * |
|
* * |
|
* |
|
* routine.c |
|
* Routine buffer management |
* Routine buffer management |
* |
* |
* |
* |
* 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) 2023 Coherent Logic Development LLC |
* Copyright (C) 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.11 2025/05/06 15:18:55 snw |
|
* Remove isblank call from routine.c to fix broken Solaris 8 build |
|
* |
|
* Revision 1.10 2025/05/01 03:56:29 snw |
|
* -m |
|
* |
|
* Revision 1.9 2025/04/30 20:03:09 snw |
|
* Work on entryref parser |
|
* |
|
* Revision 1.8 2025/04/30 17:19:16 snw |
|
* Improve backtraces in debugger |
|
* |
|
* Revision 1.7 2025/04/30 14:41:03 snw |
|
* Further debugger work |
|
* |
|
* Revision 1.6 2025/04/13 04:22:43 snw |
|
* Fix snprintf calls |
|
* |
|
* Revision 1.5 2025/04/09 19:52:02 snw |
|
* Eliminate as many warnings as possible while building with -Wall |
|
* |
|
* Revision 1.4 2025/03/27 03:27:35 snw |
|
* Install init scripts to share/freem/examples/init and fix regression in method dispatch |
|
* |
|
* Revision 1.3 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 <string.h> |
#include <string.h> |
Line 210 short rtn_get_superclass(char *rou, char
|
Line 229 short rtn_get_superclass(char *rou, char
|
|
|
if (ch == ')') after_parens = TRUE; |
if (ch == ')') after_parens = TRUE; |
|
|
|
/* ignore comments in search for superclass */ |
|
if (ch == ';' && after_parens == TRUE) { |
|
found_super = FALSE; |
|
break; |
|
} |
|
|
if (ch == ':' && after_parens == TRUE) { |
if (ch == ':' && after_parens == TRUE) { |
strcpy (buf, p); |
strcpy (buf, p); |
found_super = TRUE; |
found_super = TRUE; |
Line 252 short rtn_get_path(char *rou, char *buf)
|
Line 277 short rtn_get_path(char *rou, char *buf)
|
stcnv_m2c (pth); |
stcnv_m2c (pth); |
} |
} |
|
|
snprintf (buf, PATHLEN, "%s/%s.m", pth, rou); |
snprintf (buf, PATHLEN - 1, "%s/%s.m", pth, rou); |
|
|
if ((fp = fopen (buf, "r")) != NULL) { |
if ((fp = fopen (buf, "r")) != NULL) { |
(void) fclose (fp); |
(void) fclose (fp); |
|
|
Line 309 m_entry *rtn_get_entries(char *rou)
|
Line 334 m_entry *rtn_get_entries(char *rou)
|
char cur_label[255]; |
char cur_label[255]; |
int has_args = 0; |
int has_args = 0; |
char *paren_pos; |
char *paren_pos; |
char *curarg; |
|
|
|
if (rtn_get_path (rou, rou_path) == FALSE) { |
if (rtn_get_path (rou, rou_path) == FALSE) { |
return (m_entry *) NULL; |
return (m_entry *) NULL; |
Line 1135 void lineref (char **adrr)
|
Line 1159 void lineref (char **adrr)
|
|
|
return; |
return; |
} /* end of lineref() */ |
} /* end of lineref() */ |
|
|
|
char *m_text(char *lref, char *buf) |
|
{ |
|
char *old_codptr; |
|
char old_code[STRLEN]; |
|
|
|
old_codptr = codptr; |
|
stcpy (old_code, code); |
|
|
|
sprintf (code, "$TEXT(%s)\201", lref); |
|
codptr = code; |
|
|
|
expr (STRING); |
|
|
|
if (merr () != OK) { |
|
stcpy (code, old_code); |
|
codptr = old_codptr; |
|
return (char *) NULL; |
|
} |
|
|
|
stcpy (buf, argptr); |
|
stcpy (code, old_code); |
|
codptr = old_codptr; |
|
|
|
return buf; |
|
} |
|
|
|
|
|
|
|
/* routine_get_line() |
|
* char *entryref: [cstr/in] M entryref |
|
* char *buf: [cstr/out] buffer to contain resulting line |
|
* |
|
* returns a pointer to buf [cstr] on success; otherwise NULL */ |
|
char *routine_get_line(char *entryref, char *buf) |
|
{ |
|
FILE *fp; |
|
char routine_path[PATHLEN]; |
|
|
|
char *routine_p; |
|
char *label_p; |
|
char *offset_p; |
|
|
|
short have_label = FALSE; |
|
short have_offset = FALSE; |
|
|
|
char r[256]; |
|
char l[256]; |
|
char o[256]; |
|
char txtbuf[256]; |
|
char line[2048]; |
|
int curline; |
|
char curtag[256]; |
|
int cur_offset; |
|
int os; |
|
|
|
register int i; |
|
register int j; |
|
char ch; |
|
|
|
short in_tag = FALSE; |
|
|
|
/* |
|
* entryref can be: |
|
* +0 (returns rou_name) |
|
* label |
|
* ^routine |
|
* +offset |
|
* +offset^routine |
|
* label^routine |
|
* label+offset^routine |
|
*/ |
|
|
|
/* handle +0 */ |
|
if (strcmp (entryref, "+0") == 0) { |
|
stcpy (buf, rou_name); |
|
stcnv_m2c (buf); |
|
return buf; |
|
} |
|
|
|
if ((routine_p = strchr (entryref, '^')) != NULL) { |
|
/* have a routine */ |
|
stcpy (r, routine_p); |
|
stcnv_m2c (r); |
|
|
|
if ((entryref[0] != '^') && (isalpha (entryref[0]))) { |
|
/* we have a label */ |
|
char ch; |
|
char *src; |
|
char *dst; |
|
|
|
src = entryref; |
|
dst = l; |
|
|
|
while (((ch = *src++) != '\0') && (ch != '^') && (ch != '+')) { |
|
*dst++ = ch; |
|
} |
|
*dst = '\0'; |
|
have_label = TRUE; |
|
} |
|
} |
|
else { |
|
/* no routine implies current routine */ |
|
stcpy (r, rou_name); |
|
stcnv_m2c (r); |
|
} |
|
|
|
if (r[0] == '^') { |
|
strcpy (txtbuf, &(r[1])); |
|
strcpy (r, txtbuf); |
|
} |
|
|
|
if (rtn_get_path (r, routine_path) == FALSE) { |
|
sprintf (buf, ""); |
|
return NULL; |
|
} |
|
|
|
if ((fp = fopen (routine_path, "r")) == NULL) { |
|
sprintf (buf, ""); |
|
return NULL; |
|
} |
|
|
|
if ((offset_p = strchr (entryref, '+')) != NULL) { |
|
stcpy (o, offset_p + 1); |
|
os = atoi (o); |
|
sprintf (o, "%d\0", os); |
|
have_offset = TRUE; |
|
} |
|
else { |
|
have_offset = FALSE; |
|
os = 1; |
|
} |
|
|
|
in_tag = FALSE; |
|
cur_offset = 0; |
|
while (fgets (line, sizeof (line) - 1, fp) != NULL) { |
|
|
|
if (!have_label && !have_offset) { |
|
strcpy (buf, line); |
|
fclose (fp); |
|
return buf; |
|
} |
|
|
|
if ((isalpha (line[0])) && (line[0] != ' ') && (line[0] != '\t')) { |
|
j = 0; |
|
|
|
for (i = 0; i < strlen (line); i++) { |
|
ch = line[i]; |
|
|
|
if ((!isalpha (ch)) && (!isdigit (ch))) { |
|
curtag[j] = '\0'; |
|
cur_offset = 0; |
|
if (have_label && (strcmp (curtag, l) == 0)) { |
|
in_tag = TRUE; |
|
if (!have_offset) { |
|
strcpy (buf, line); |
|
fclose (fp); |
|
return buf; |
|
} |
|
} |
|
else { |
|
in_tag = FALSE; |
|
} |
|
break; |
|
} |
|
else { |
|
curtag[j++] = ch; |
|
} |
|
} |
|
} |
|
else { |
|
cur_offset++; |
|
|
|
if (in_tag && (cur_offset == os)) { |
|
strcpy (buf, line); |
|
fclose (fp); |
|
return buf; |
|
} |
|
} |
|
|
|
} |
|
|
|
fclose (fp); |
|
return FALSE; |
|
|
|
} |
|
|