--- freem/src/routine.c 2025/01/19 02:04:04 1.1.1.1 +++ freem/src/routine.c 2025/05/01 03:56:29 1.10 @@ -1,23 +1,11 @@ /* - * * - * * * - * * * - * *************** - * * * * * - * * MUMPS * - * * * * * - * *************** - * * * - * * * - * * - * - * routine.c + * $Id: routine.c,v 1.10 2025/05/01 03:56:29 snw Exp $ * Routine buffer management * * - * Author: Serena Willis + * Author: Serena Willis * 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. @@ -35,6 +23,34 @@ * You should have received a copy of the GNU Affero Public License * along with FreeM. If not, see . * + * $Log: routine.c,v $ + * 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 @@ -210,6 +226,12 @@ short rtn_get_superclass(char *rou, char 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) { strcpy (buf, p); found_super = TRUE; @@ -252,8 +274,8 @@ short rtn_get_path(char *rou, char *buf) 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) { (void) fclose (fp); @@ -309,7 +331,6 @@ m_entry *rtn_get_entries(char *rou) char cur_label[255]; int has_args = 0; char *paren_pos; - char *curarg; if (rtn_get_path (rou, rou_path) == FALSE) { return (m_entry *) NULL; @@ -1135,3 +1156,190 @@ void lineref (char **adrr) return; } /* 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]) && !isblank (line[0])) { + 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; + +} +