/*
* $Id: views.c,v 1.6 2025/03/09 19:50:47 snw Exp $
* implementation of VIEW command and $VIEW intrinsic function
*
*
* Author: Serena Willis <snw@coherent-logic.com>
* Copyright (C) 1998 MUG Deutschland
* Copyright (C) 2020, 2025 Coherent Logic Development LLC
*
*
* This file is part of FreeM.
*
* FreeM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FreeM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero Public License for more details.
*
* You should have received a copy of the GNU Affero Public License
* along with FreeM. If not, see <https://www.gnu.org/licenses/>.
*
* $Log: views.c,v $
* Revision 1.6 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 "mpsdef.h"
#include "mwapi_window.h"
#define LOCK 'l'
#define ZDEALLOCATE 'D'
/* system services */
#include <signal.h>
#if !defined(__APPLE__) && !defined(__gnu_hurd__) && !defined(EMSCRIPTEN)
# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__AMIGA)
# include <termios.h>
# if !defined(__AMIGA)
# define TCGETA TIOCGETA
# define TCSETA TIOCSETA
# endif
# define termio termios
# else
# if !defined(MSDOS)
# include <termio.h>
# endif
# endif
#else
# include <termios.h>
#endif
#ifdef __CYGWIN__
#include <errno.h>
#endif /* __CYGWIN__ */
#include <errno.h> /* snw */
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/ioctl.h>
#endif
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include "shmmgr.h"
/* 01/18/99 rlf Apparently, tell disappeared with libc-6 */
#if defined(LINUX_GLIBC) || defined(__APPLE__)
long int tell (int fd)
{
return lseek (fd, 0, SEEK_CUR);
}
#else
long int tell ();
#endif /* LINUX_GLIBC */
#if defined(MWAPI_GTK)
void destroy(GtkWidget* widget, gpointer data)
{
gtk_main_quit();
}
#endif
void view_com (void)
{
/* process VIEW command */
char tmp[256];
char tmp2[256];
int arg1;
register long int i;
register long int j;
register long int ch;
if (*codptr == SP || *codptr == EOL) { /* no argument form of VIEW */
merr_raise (ARGER);
return;
}
expr (STRING);
arg1 = intexpr (argptr);
if (merr () > OK) return;
if (*codptr == ':') {
codptr++;
expr (STRING);
if (merr () > OK) return;
switch (arg1) {
/* VIEW 52: G0 input translation table */
case 52:
stcpy0 (G0I[io], argptr, 256L);
for (i = 0; i < 256; i++) {
if (G0I[io][i] == EOL) {
while (i < 256) {
G0I[io][i] = (char) i;
i++;
}
break;
}
}
break;
/* VIEW 53: G0 output translation table */
case 53:
stcpy0 (G0O[io], argptr, 256L);
for (i = 0; i < 256; i++) {
if (G0O[io][i] == EOL) {
while (i < 256) {
G0O[io][i] = (char) i;
i++;
}
break;
}
}
break;
/* VIEW 54: G1 input translation table */
case 54:
stcpy0 (G1I[io], argptr, 256L);
for (i = 0; i < 256; i++) {
if (G1I[io][i] == EOL) {
while (i < 256) {
G1I[io][i] = (char) i;
i++;
}
break;
}
}
break;
/* VIEW 55: G1 output translation table */
case 55:
stcpy0 (G1O[io], argptr, 256L);
for (i = 0; i < 256; i++) {
if (G1O[io][i] == EOL) {
while (i < 256) {
G1O[io][i] = (char) i;
i++;
}
break;
}
}
break;
/* VIEW 62: random: seed number */
case 62:
i = intexpr (argptr);
if (merr () == MXNUM) return;
if (i < 0) {
merr_raise (ARGER);
}
else {
nrandom = i;
}
break;
/* VIEW 63: random: parameter a */
case 63:
i = intexpr (argptr);
if (merr () == MXNUM) return;
if (i <= 0) {
merr_raise (ARGER);
}
else {
ran_a = i;
}
break;
/* VIEW 64: random: parameter b */
case 64:
i = intexpr (argptr);
if (merr () == MXNUM) return;
if (i < 0) {
merr_raise (ARGER);
}
else {
ran_b = i;
}
break;
/* VIEW 65: random: parameter c */
case 65:
i = intexpr (argptr);
if (merr () == MXNUM) return;
if (i <= 0) {
merr_raise (ARGER);
}
else {
ran_c = i;
}
break;
/* VIEW 66: SIGTERM handling flag */
case 66:
killerflag = tvexpr (argptr);
break;
/* VIEW 67: SIGHUP handling flag */
case 67:
huperflag = tvexpr (argptr);
break;
/* ... reserved ... */
/* VIEW 70: ZSORT/ZSYNTAX flag */
case 70:
s_fun_flag = tvexpr (argptr);
break;
/* VIEW 71: ZNEXT/ZNAME flag */
case 71:
n_fun_flag = tvexpr (argptr);
break;
/* VIEW 72: ZPREVIOUS/ZPIECE flag */
case 72:
p_fun_flag = tvexpr (argptr);
break;
/* VIEW 73: ZDATA/ZDATE flag */
case 73:
d_fun_flag = tvexpr (argptr);
break;
/* VIEW 79: old ZJOB vs. new ZJOB flag */
case 79:
zjobflag = tvexpr (argptr);
break;
/* VIEW 80: 7 vs. 8 bit flag */
case 80:
eightbit = tvexpr (argptr);
break;
/* VIEW 81: PF1 flag */
case 81:
PF1flag = tvexpr (argptr);
break;
/* VIEW 82: not used */
/* VIEW 83: text in $ZE flag */
case 83:
etxtflag = tvexpr (argptr);
break;
/* VIEW 84: not used */
/* VIEW 85: not used */
/* VIEW 86: not used */
case 87: /* VIEW 87: date type definition */
i = intexpr (argptr);
if (i < 0 || i >= NO_DATETYPE) {
merr_raise (ARGER);
return;
}
if (*codptr != ':') {
datetype = i;
break;
}
if (i == 0) {
merr_raise (ARGER);
return;
}
codptr++;
expr (STRING);
j = intexpr (argptr);
if (*codptr != ':') {
merr_raise (ARGER);
return;
}
codptr++;
expr (STRING);
if (j > 0 && j < 15 && stlen (argptr) > MONTH_LEN) {
merr_raise (M75);
}
else if (j > 0 && j < 13) {
stcpy (month[i][j - 1], argptr);
}
else if (j == 13) {
stcpy (dat1char[i], argptr);
}
else if (j == 14) {
stcpy (dat2char[i], argptr);
}
else if (j == 15) {
dat3char[i] = (*argptr);
}
else if (j == 16) {
if ((j = intexpr (argptr)) < 0 || j > 2) {
merr_raise (ARGER);
return;
}
dat4flag[i] = j;
}
else if (j == 17) {
dat5flag[i] = tvexpr (argptr);
}
else if (j == 18) {
if ((j = intexpr (argptr) + 672411L) <= 0L) {
merr_raise (ARGER);
return;
}
datGRbeg[i] = j;
}
else {
merr_raise (ARGER);
}
if (merr () > OK) return;
break;
case 88: /* VIEW 88: time type definition */
i = intexpr (argptr);
if (i < 0 || i >= NO_TIMETYPE) {
merr_raise (ARGER);
return;
}
if (*codptr != ':') {
timetype = i;
break;
}
codptr++;
expr (STRING);
j = intexpr (argptr);
if (*codptr != ':') {
merr_raise (ARGER);
return;
}
codptr++;
expr (STRING);
if (j == 1) {
tim1char[i] = (*argptr);
}
else if (j == 2) {
tim2char[i] = (*argptr);
}
else if (j == 3) {
tim3char[i] = (*argptr);
}
else if (j == 4) {
tim4flag[i] = tvexpr (argptr);
}
else if (j == 5) {
tim5flag[i] = tvexpr (argptr);
}
else {
merr_raise (ARGER);
}
if (merr () > OK) return;
break;
case 91: /* VIEW 91: missing QUIT expr default expression */
stcpy (exfdefault, argptr);
break;
case 92: /* VIEW 92: EUR2DEM: type mismatch error */
typemmflag = tvexpr (argptr);
break;
case 93: /* VIEW 93: zkey production rule definition */
i = intexpr (argptr);
if (i < 1 || i > NO_V93) {
merr_raise (ARGER);
return;
}
if (*codptr != ':') {
v93 = i;
break;
}
codptr++;
expr (STRING);
stcpy (v93a[i - 1], argptr);
break;
case 96: /* VIEW 96: global prefix */
if (stlen (argptr) > MONTH_LEN) {
merr_raise (M75);
}
else {
stcpy (glo_prefix, argptr);
}
break;
case 97: /* VIEW 97: global postfix */
if (stlen (argptr) > MONTH_LEN) {
merr_raise (M75);
}
else {
stcpy (glo_ext, argptr);
}
break;
case 98: /* VIEW 98: routine extension */
if (stlen (argptr) > MONTH_LEN) {
merr_raise (M75);
}
else {
stcpy (rou_ext, argptr);
}
break;
case 101: /* VIEW 101: set ierr */
merr_raise (intexpr (argptr));
break;
case 102: /* VIEW 102 set deferred_ierr */
deferred_ierr = intexpr (argptr);
break;
case 103: /* MERGE to ^$WINDOW complete. Parameter is empty (for all windows) or string for window name in subscript 1 */
#if defined(MWAPI_GTK)
mwapi_on_merge_complete (argptr);
#endif
break;
#if !defined(__APPLE__) && !defined(__gnu_hurd__) && !defined(__AMIGA) && !defined(EMSCRIPTEN) && !defined(MSDOS)
case 113: /* VIEW 113: set termio infos */
{
struct termio tpara;
i = intexpr (argptr);
if (i < 1 || i > MAXDEV) {
merr_raise (NODEVICE);
}
else if (devopen[i] == 0) {
merr_raise (NOPEN);
}
else if (*codptr != ':') {
merr_raise (ARGER);
}
else {
codptr++;
expr (STRING);
j = intexpr (argptr);
}
if (merr () > OK) return;
ioctl (fileno (opnfile[i]), TCGETA, &tpara);
j = 0;
tpara.c_iflag = intexpr (argptr);
while ((ch = argptr[j]) != EOL) {
j++;
if (ch == ':') break;
}
tpara.c_oflag = intexpr (&argptr[j]);
while ((ch = argptr[j]) != EOL) {
j++;
if (ch == ':') break;
}
tpara.c_cflag = intexpr (&argptr[j]);
while ((ch = argptr[j]) != EOL) {
j++;
if (ch == ':') break;
}
tpara.c_lflag = intexpr (&argptr[j]);
ioctl (fileno (opnfile[i]), TCSETA, &tpara);
return;
}
#endif /* __APPLE__ */
/* VIEW 133: remember ZLOAD directory on ZSAVE */
case 133:
zsavestrategy = tvexpr (argptr);
return;
default:
merr_raise (ARGER);
return;
} /* end switch one parameter VIEWs */
}
else { /* no parameters VIEWs */
switch (arg1) {
/* VIEW 21: close all globals */
case 21:
close_all_globals ();
return;
/* VIEW 29: symtab copy */
case 29: /* get space if needed */
if (apartition == NULL) apartition = calloc ((unsigned) (PSIZE + 1), 1);
for (i = 0; i <= PSIZE; i++) apartition[i] = partition[i];
asymlen = symlen;
for (i = 0; i < 128; i++) aalphptr[i] = alphptr[i];
return;
}
merr_raise (ARGER);
return;
}
return;
} /* end view_com() */
/*
* f = number of arguments
* a = the arguments
*/
void view_fun (int f, char *a) /* process VIEW function */
{
int i;
if (standard) {
merr_raise (NOSTAND);
return;
} /* non_standard */
if (f == 1) {
f = intexpr (a);
switch (f) {
/* $V(21) returns size of last global */
case 21:
if (oldfil[inuse][0] != NUL) {
lseek (olddes[inuse], 0L, 2);
lintstr (a, (long) tell (olddes[inuse]));
}
else {
*a = EOL;
}
break;
/* $V(22): number of v22_aliases */
case 22:
i = 0;
f = 0;
while (f < v22ptr) {
i++;
f += UNSIGN (v22ali[f]) + 1;
}
intstr (a, i);
break;
/* $V(23): contents of 'input buffer' */
case 23:
stcpy (a, ug_buf[io]);
break;
/* $V(24)/$V(25) number of screen lines */
case 24:
case 25:
intstr (a, N_LINES);
break;
/* $V(26): DO-FOR-XEC stack pointer */
case 26:
intstr (a, nstx);
break;
/* $V(27): DO-FOR-XEC stack pointer (copy on error) */
case 27:
intstr (a, nesterr);
break;
/* $V(30): number of mumps arguments */
case 30:
intstr (a, m_argc);
break;
/* $V(31): environment variables */
case 31:
f = 0;
while (m_envp[f] && m_envp[f][0] != NUL) f++;
intstr (a, f);
break;
/* $V(52): G0 input translation table */
case 52:
stcpy0 (a, G0I[io], 257L);
a[255] = EOL;
break;
/* $V(53): G0 output translation table */
case 53:
stcpy0 (a, G0O[io], 257L);
a[255] = EOL;
break;
/* $V(54): G1 input translation table */
case 54:
stcpy0 (a, G1I[io], 257L);
a[255] = EOL;
break;
/* $V(55): G1 output translation table */
case 55:
stcpy0 (a, G1O[io], 257L);
a[255] = EOL;
break;
/* $V(60): partial pattern match flag */
case 60:
intstr (a, pattrnflag);
break;
/* $V(61): partial pattern supplement character */
case 61:
a[0] = pattrnchar;
a[1] = EOL;
break;
/* $V(62): random: seed number */
case 62:
lintstr (a, nrandom);
break;
/* $V(63): random: parameter a */
case 63:
lintstr (a, ran_a);
break;
/* $V(64): random: parameter b */
case 64:
lintstr (a, ran_b);
break;
/* $V(65): random: parameter c */
case 65:
lintstr (a, ran_c);
break;
/* $V(66): SIGTERM handling flag */
case 66:
intstr (a, killerflag);
break;
/* $V(67): SIGHUP handling flag */
case 67:
intstr (a, huperflag);
break;
/* ... reserved ... */
/* $V(70): ZSORT/ZSYNTAX flag */
case 70:
intstr (a, s_fun_flag);
break;
/* $V(71): ZNEXT/ZNAME flag */
case 71:
intstr (a, n_fun_flag);
break;
/* $V(72): ZPREVIOUS/ZPIECE flag */
case 72:
intstr (a, p_fun_flag);
break;
/* $V(73): ZDATA/ZDATE flag */
case 73:
intstr (a, d_fun_flag);
break;
/* ... reserved ... */
/* $V(79): old ZJOB vs. new ZJOB flag */
case 79:
intstr (a, zjobflag);
break;
/* $V(80): 7 vs. 8 bit flag */
case 80:
intstr (a, eightbit);
break;
/* $V(81): PF1 flag */
case 81:
intstr (a, PF1flag);
break;
/* $V(82): order counter */
case 82:
intstr (a, ordercounter);
break;
/* $V(83): text in $ZE flag */
case 83:
intstr (a, etxtflag);
break;
/* $V(84): path of current routine */
case 84: /* look whether we know where the routine came from */
for (i = 0; i < NO_OF_RBUF; i++) {
int j;
if (pgms[i][0] == 0) {
*a = EOL;
return;
} /* buffer empty */
j = 0;
while (rou_name[j] == pgms[i][j]) {
if (rou_name[j++] == EOL) {
stcpy (a, path[i]);
i = stlen (a);
if (i > 0) a[i - 1] = EOL;
return;
}
}
}
*a = EOL;
break; /* not found */
/* $V(85): path of last global */
case 85:
if (oldfil[inuse][0]) {
stcpy (a, oldfil[inuse]);
}
else {
*a = EOL;
}
i = 0;
while (a[i] != EOL) {
if (a[i] == '^') {
if (i > 0) {
i--;
}
a[i] = EOL;
break;
}
i++;
}
break;
/* $V(86): path of current device */
case 86:
stcpy (a, act_oucpath[io]);
break;
/* $V(87): date type definitions */
case 87:
intstr (a, datetype);
break;
/* $V(88): date type definitions */
case 88:
intstr (a, timetype);
break;
/* $V(91): missig QUIT expr default expression */
case 91:
stcpy (a, exfdefault);
break;
/* $V(92): type mismatch error */
case 92:
intstr (a, typemmflag);
break;
/* $V(93): zkey production default rule definition */
case 93:
lintstr (a, v93);
break;
/* $V(98): routine extention */
case 98:
stcpy (a, rou_ext);
break;
/* $V(100): exit status of last kill */
case 100:
intstr (a, v100);
break;
/* $V(114): Number of rows in terminal */
case 114:
intstr (a, n_lines);
break;
/* $V(115): Number of columns in terminal */
case 115:
intstr (a, n_columns);
break;
/* $V(133): remember ZLOAD directory on ZSAVE */
case 133:
intstr (a, zsavestrategy);
break;
default:
merr_raise (ARGER);
return;
}
return;
}
if (f == 2) {
char tmp[256];
stcpy (tmp, argstck[arg + 1]);
i = intexpr (argstck[arg + 1]);
f = intexpr (a);
if (merr () == MXNUM) return;
if (f == 16) {
if (i <= OK || i >= MAXERR) {
merr_raise (ARGER);
return;
}
else {
stcpy (a, errmes[i]);
}
}
else if (f == 22) { /* return v22_alias entry */
if (i) { /* give one of the names which are aliases */
f = 0;
while (f < v22ptr) {
i--;
if (i == 0) {
stcpy (a, &v22ali[f + 1]);
return;
}
f += UNSIGN (v22ali[f]) + 1;
}
a[0] = EOL;
return; /* that number had no entry in the table */
}
if (tstglvn (tmp) == FALSE) {
merr_raise (INVREF);
return;
}
if (v22ptr) { /* there are aliases */
int k, j;
i = 0;
while (i < v22ptr) {
k = i + UNSIGN (v22ali[i]) + 1;
j = 0; /* is current reference an alias ??? */
while (v22ali[++i] == tmp[j]) {
if (v22ali[i] == EOL) break;
j++;
}
/* yes, it is, return it */
if (v22ali[i] == EOL && tmp[j] == EOL) {
stcpy (a, &v22ali[i + 1]);
return;
}
i = k;
}
}
a[0] = EOL; /* entry was not in the table */
return;
}
else if (f == 24) { /* return screen line */
if (i < -N_LINES || i > N_LINES || i == 0) {
*a = EOL;
}
else if (i < 0) {
stcpy0 (a, (*screen).screena[(unsigned int) (*screen).sclines[-i - 1]], (long) N_COLUMNS);
a[80] = EOL;
return;
}
else {
stcpy0 (a, (*screen).screenx[(unsigned int) (*screen).sclines[i - 1]], (long) N_COLUMNS);
a[80] = EOL;
return;
}
}
else if (f == 25) { /* return screen line with attribute */
i--;
if (i < 0 || i >= N_LINES) {
*a = EOL;
}
else {
v25 (a, i);
}
return;
}
else if (f == 26) { /* $V(26) returns DO-FOR-XEC stack pointer */
if (i < 1 || i > nstx) {
merr_raise (ARGER);
return;
}
getraddress (a, i);
return;
} /* $V(27) returns DO-FOR-XEC stack pointer(error state) */
else if (f == 27) {
if (i < 1 || i > nesterr) {
merr_raise (ARGER);
return;
}
stcpy (a, callerr[i]);
return;
}
else if (f == 30) { /* $V(30): arguments of mumps */
if (i < 1 || i > m_argc) {
merr_raise (ARGER);
return;
}
strcpy (a, m_argv[i - 1]);
a[strlen (a)] = EOL;
return;
/* guard against very long environment name=value entries */
}
else if (f == 31) { /* $V(31): environment variables */
f = 0;
while (m_envp[f] && m_envp[f++][0] != NUL) {
if (f != i) continue;
if ((f = strlen (m_envp[i - 1])) > STRLEN) {
merr_raise (M75);
return;
}
strcpy (a, m_envp[i - 1]);
a[f] = EOL;
return;
}
merr_raise (ARGER);
return;
}
else if (f == 93) { /* $V(93): zkey production rule definition */
if (i <= 0 || i > NO_V93) {
merr_raise (ARGER);
}
else {
strcpy (a, v93a[i - 1]);
}
return;
}
#if !defined(__APPLE__) && !defined(__gnu_hurd__) && !defined(__AMIGA) && !defined(EMSCRIPTEN) && !defined(MSDOS)
else if (f == 113) { /* $V(113): get termio infos */
struct termio tpara;
if (i < 1 || i > MAXDEV) {
merr_raise (NODEVICE);
return;
}
if (devopen[i] == 0) {
merr_raise (NOPEN);
return;
}
ioctl (fileno (opnfile[i]), TCGETA, &tpara);
intstr (a, tpara.c_iflag);
i = stlen (a);
a[i++] = ':';
intstr (&a[i], tpara.c_oflag);
i = stlen (a);
a[i++] = ':';
intstr (&a[i], tpara.c_cflag);
i = stlen (a);
a[i++] = ':';
intstr (&a[i], tpara.c_lflag);
return;
}
#endif
else {
merr_raise (ARGER);
return;
}
}
else if (f == 3) {
char tmp[256];
stcpy (tmp, argstck[arg + 2]);
i = intexpr (argstck[arg + 1]);
f = intexpr (a);
if (merr () == MXNUM) return;
if (f == 87) { /* $V(87): date type definitions */
if (i < 0 || i >= NO_DATETYPE) {
merr_raise (ARGER);
return;
}
f = intexpr (tmp);
if (f > 0 && f < 13) {
stcpy (a, month[i][f - 1]);
return;
}
switch (f) {
case 13:
{
stcpy (a, dat1char[i]);
return;
}
case 14:
{
stcpy (a, dat2char[i]);
return;
}
case 15:
{
a[0] = dat3char[i];
a[1] = EOL;
return;
}
case 16:
{
a[0] = dat4flag[i] + '0';
a[1] = EOL;
return;
}
case 17:
{
a[0] = dat5flag[i] + '0';
a[1] = EOL;
return;
}
case 18:
{
lintstr (a, datGRbeg[i] - 672411L);
return;
}
}
}
else if (f == 88) { /* $V(88): time type definitions */
if (i < 0 || i >= NO_TIMETYPE) {
merr_raise (ARGER);
return;
}
f = intexpr (tmp);
switch (f) {
case 1:
{
a[0] = tim1char[i];
a[1] = EOL;
return;
}
case 2:
{
a[0] = tim2char[i];
a[1] = EOL;
return;
}
case 3:
{
a[0] = tim3char[i];
a[1] = EOL;
return;
}
case 4:
{
a[0] = tim4flag[i] + '0';
a[1] = EOL;
return;
}
case 5:
{
a[0] = tim5flag[i] + '0';
a[1] = EOL;
return;
}
}
}
merr_raise (ARGER);
return;
}
else {
merr_raise (FUNARG);
return;
}
return;
} /* end view_fun() */
void m_tolower (char *str)
{
int ch;
while ((ch = *str) != EOL) {
ch = *str;
if (ch <= 'Z' && ch >= 'A') {
ch += 32;
*str = ch;
}
str++;
}
return;
} /* end tolower() */
/*
* size = desired size for 'partition'
*/
short int newpsize (long size)
{
char *newpart = NULL;
char *anewpart = NULL;
long dif, j;
if (size == PSIZE) return 0; /* nothing changes */
if (size <= (PSIZE - symlen + 512)) return 0; /* cannot decrease it now */
if (apartition && size <= (PSIZE - asymlen + 512)) return 0; /* cannot decrease it now */
if (writing_mb) {
newpart = shm_alloc ((size_t) (size+1));
}
else {
newpart = calloc ((unsigned) (size + 1), 1);
}
if (newpart == NULL) return 1; /* could not allocate stuff */
if (apartition) {
anewpart = calloc ((unsigned) (size + 1), 1);
if (anewpart == NULL) {
free (newpart);
return 1;
}
/* no more space */
}
dif = argptr - partition + 256;
if (dif > PSIZE) dif = PSIZE;
stcpy0 (newpart, partition, dif); /* intermediate results */
dif = size - PSIZE;
stcpy0 (&newpart[symlen + dif], &partition[symlen], PSIZE - symlen);
if (apartition) stcpy0 (&anewpart[asymlen + dif], &apartition[asymlen], PSIZE - asymlen);
for (j = '%'; j <= 'z'; j++) { /* update alphpointers */
if (alphptr[j]) alphptr[j] += dif;
if (aalphptr[j]) aalphptr[j] += dif;
}
PSIZE = size;
symlen += dif;
asymlen += dif;
if (writing_mb) {
shm_free (partition);
}
else {
free (partition); /* free previously allocated space */
}
if (apartition) free (apartition); /* free previously allocated space */
dif = newpart - partition;
partition = newpart;
if (apartition) apartition = anewpart;
s = &partition[symlen] - 256; /* pointer to symlen_offset */
argptr += dif; /* pointer to beg of tmp-storage */
for (j = 0; j <= PARDEPTH; j++) {
if (argstck[j]) argstck[j] += dif;
}
return 0;
} /* end newpsize() */
/* change size of svn_table to 'size' */
short int newusize (long size)
{
char *newsvn;
long dif, j;
if (size <= (UDFSVSIZ - svnlen)) return 0; /* cannot decrease it now */
if (size == UDFSVSIZ) return 0; /* nothing changes */
newsvn = calloc ((unsigned) (size + 1), 1);
if (newsvn == NULL) return 1; /* could not allocate stuff */
stcpy0 (newsvn, svntable, svnlen); /* intermediate results */
dif = size - UDFSVSIZ;
stcpy0 (&newsvn[svnlen + dif], &svntable[svnlen], UDFSVSIZ - svnlen);
for (j = '%'; j <= 'z'; j++) { /* update svn_alphpointers */
if (svnaptr[j]) svnaptr[j] += dif;
}
UDFSVSIZ = size;
svnlen += dif;
free (svntable); /* free previously allocated space */
svntable = newsvn;
return 0;
} /* end newusize() */
/*
* allocate 'nbrbuf' routine buffers
* of 'size' bytes
*/
short int newrsize (long size, long nbrbuf)
{
char *newrbuf;
int i;
long dif;
unsigned long total;
if (size <= (rouend - rouptr + 1)) return 0; /* making it smaller would be a mistake */
if (nbrbuf > MAXNO_OF_RBUF) nbrbuf = MAXNO_OF_RBUF;
total = (unsigned) nbrbuf *(unsigned) size;
/* some overflow ??? */
if ((total / (unsigned) size) != (unsigned) nbrbuf) {
merr_raise (ARGER);
return 1;
}
newrbuf = calloc (total, 1); /* routine buffer pool */
while (newrbuf == NULL) { /* could not allocate stuff... */
if (--nbrbuf < 2) return 1; /* ...so try with less buffers */
total = (unsigned) nbrbuf *(unsigned) size;
newrbuf = calloc (total, 1);
}
/* clear all routine buffers but one */
for (i = 0; i < MAXNO_OF_RBUF; i++) { /* empty routine buffers */
pgms[i][0] = 0;
ages[i] = 0L;
}
/* transfer to new buffer */
stcpy0 (newrbuf, rouptr, (long) (rouend - rouptr + 1));
dif = newrbuf - rouptr;
rouend += dif;
ends[0] = rouend;
stcpy (pgms[0], rou_name);
rouins += dif;
if (roucur == (buff + (NO_OF_RBUF * PSIZE0 + 1))) {
roucur = newrbuf + (nbrbuf * size + 1);
}
else {
roucur += dif;
}
rouptr = newrbuf;
free (buff); /* free previously allocated space */
buff = newrbuf;
NO_OF_RBUF = nbrbuf;
PSIZE0 = size;
return 0;
} /* end newrsize() */
void zreplace (char *a, char *b, char *c)
{
long int ch, f, l, m, n;
char d[256];
if (b[0] == EOL) return; /* 2nd argument was empty */
l = stlen (c); /* length of 3rd argument */
n = 0;
f = 0;
for (;;) {
m = 0;
while ((ch = a[f + m]) == b[m] && ch != EOL) m++;
if (b[m] == EOL) {
if (n + l > STRLEN) {
merr_raise (M75);
return;
}
stcpy0 (&d[n], c, l);
n += l;
f += m;
}
else {
m = 1;
if (n + 1 > STRLEN) {
merr_raise (M75);
return;
}
d[n++] = a[f++];
}
if (a[f] == EOL) break;
}
d[n] = EOL;
stcpy (a, d);
return;
} /* end zreplace() */
short int tstglvn (char *a) /* tests whether 'a' is a proper unsubscripted glvn */
{
int i, ch;
i = 0;
if (a[0] == '^') {
while (((ch = a[++i]) >= 'A' && ch <= 'Z') ||
(ch >= 'a' && ch <= 'z') ||
(ch >= '0' && ch <= '9') ||
((ch == '%' && i == 1) ||
(standard == 0 &&
(((ch == '.' || ch == '/') && i == 1) ||
(((ch == '/' && a[i - 1] != '/') ||
(ch == '%' && a[i - 1] == '/')) &&
(a[1] == '.' || a[1] == '/'))))));
return a[i] == EOL;
}
if ((ch = a[i++]) != '%' && (ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) return FALSE;
while ((ch = a[i++]) != EOL) {
if ((ch < '0' || ch > '9') && (ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
return FALSE;
}
}
return TRUE;
} /* end tstnam() */
void zname (char *a, char *b)
{
int i, j, f, n;
i = 0;
j = 0;
f = FALSE; /* we are in name section (vs.subscr.) */
n = FALSE; /* part is numeric (vs.alphabetic) */
while ((a[i] = b[j++]) != EOL) {
if (a[i] == '"') a[++i] = '"';
if (a[i] == DELIM) {
if (f) {
if (n == FALSE) a[i++] = '"';
if (i >= (STRLEN-2)/*was 253*/) {
a[i] = EOL;
merr_raise (M75);
return;
}
a[i] = ',';
if ((n = znamenumeric (&b[j])) == FALSE) a[++i] = '"';
}
else {
a[i] = '(';
f = TRUE;
if ((n = znamenumeric (&b[j])) == FALSE) a[++i] = '"';
}
}
if (++i >= STRLEN) {
a[STRLEN] = EOL;
if (b[j] != EOL) {
merr_raise (M75);
return;
}
}
}
if (f) {
if (i > (STRLEN-2) /* was 253 */) {
merr_raise (M75);
return;
}
if (n == FALSE) a[i++] = '"';
a[i++] = ')';
a[i] = EOL;
}
return;
} /* end zname() */
/* boolean function that tests whether str is a canonical numeric */
short int znamenumeric (char *str)
{
register int ptr = 0;
register int ch;
register int point;
if (str[0] == '-') ptr = 1;
if (str[ptr] == EOL) return FALSE;
if (str[ptr] == DELIM) return FALSE;
if (str[ptr] == '0') return str[1] == EOL || str[1] == DELIM; /* leading zero */
point = FALSE;
while ((ch = str[ptr++]) != EOL && ch != DELIM) {
if (ch > '9') return FALSE;
if (ch < '0') {
if (ch != '.') return FALSE;
if (point) return FALSE; /* multiple points */
point = TRUE;
}
}
if (point) {
if ((ch = str[ptr - 2]) == '0') return FALSE; /* trailing zero */
if (ch == '.') return FALSE; /* trailing point */
}
return TRUE;
} /* end of znamenumeric() */
void procv22 (char *key) /* process v22 translation */
{
int i, j, k1;
char tmp1[256];
if (*key == EOL || *key == 0) return;
i = 0;
j = 0;
while (i < v22ptr) {
k1 = i + UNSIGN (v22ali[i]) + 1;
/* is current reference an alias ??? */
j = 0;
while (v22ali[++i] == key[j]) {
if (v22ali[i] == EOL) break;
j++;
}
/* yes, it is, so resolve it now! */
if (v22ali[i] == EOL && (key[j] == EOL || key[j] == DELIM)) {
stcpy (tmp1, key);
stcpy (key, &v22ali[i + 1]);
stcat (key, &tmp1[j]);
i = 0;
continue; /* try again, it might be a double alias! */
}
i = k1;
}
return;
} /* end of procv22() */
void v25 (char *a, int i)
{
short c, exc, k, l, p;
k = 0;
exc = ~((*screen).screena[(unsigned int) (*screen).sclines[i]][0]);
for (l = 0; l < N_COLUMNS; l++) {
p = exc;
exc = (*screen).screena[(unsigned int) (*screen).sclines[i]][l];
c = (*screen).screenx[(unsigned int) (*screen).sclines[i]][l];
#ifdef NEVER
/* this may result in a problem, when in a system */
/* different G0O/G1O sets are in use !!! */
if (((exc == 1 && (p == 0)) || ((exc == 0) && (p == 1))) && (G0O[HOME][c] == G1O[HOME][c])) {
exc = p; /* if char looks same in SI/SO, delay SI/SO */
}
#endif /* NEVER */
if (exc != p) { /* set attribute */
#ifdef SCO
p = p & ~04; /* suppress SGR(3) */
if (p & 0200) p = p & 0201; /* no display */
if (p & 0100) p = p & 0101; /* inverse */
#endif /* SCO */
if ((p & 01) != (exc & 01)) a[k++] = (exc & 01) ? SO : SI;
if ((p & ~01) != (exc & ~01)) {
a[k++] = ESC;
a[k++] = '[';
for (p = 1; p < 8; p++) {
if (exc & (1 << p)) {
#ifdef SCO
if (p == 1) {
a[k++] = '1';
a[k++] = ';';
continue;
}
#endif /* SCO */
a[k++] = '1' + p;
a[k++] = ';';
}
}
if (a[k - 1] == ';') k--;
a[k++] = 'm';
}
}
a[k++] = c;
}
if (exc & 01) a[k++] = SI;
a[k] = EOL;
return;
} /* end of v25() */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>