1: /*
2: * $Id: cmd_read.c,v 1.4 2025/03/24 04:05:36 snw Exp $
3: * Implementation of the READ command
4: *
5: *
6: * Author: Serena Willis <snw@coherent-logic.com>
7: * Copyright (C) 1998 MUG Deutschland
8: * Copyright (C) 2023, 2025 Coherent Logic Development LLC
9: *
10: *
11: * This file is part of FreeM.
12: *
13: * FreeM is free software: you can redistribute it and/or modify
14: * it under the terms of the GNU Affero Public License as published by
15: * the Free Software Foundation, either version 3 of the License, or
16: * (at your option) any later version.
17: *
18: * FreeM is distributed in the hope that it will be useful,
19: * but WITHOUT ANY WARRANTY; without even the implied warranty of
20: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21: * GNU Affero Public License for more details.
22: *
23: * You should have received a copy of the GNU Affero Public License
24: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
25: *
26: * $Log: cmd_read.c,v $
27: * Revision 1.4 2025/03/24 04:05:36 snw
28: * Replace crlf with frm_crlf to avoid symbol conflict with readline on OS/2
29: *
30: * Revision 1.3 2025/03/09 19:14:24 snw
31: * First phase of REUSE compliance and header reformat
32: *
33: *
34: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
35: * SPDX-License-Identifier: AGPL-3.0-or-later
36: **/
37:
38: #include <string.h>
39: #include <stdlib.h>
40: #include "mpsdef.h"
41: #include "mcommand.h"
42: #if !defined(MSDOS)
43: # include "io_socket.h"
44: #endif
45:
46: MRESULT cmd_read(MACTION *ra)
47: {
48: register int i;
49: register char ch;
50: char vn[255];
51: char an[255];
52:
53: if (io != HOME && devopen[io] != 'r' && devopen[io] != '+' && io < FIRSTSCK) {
54: return NOREAD;
55: }
56:
57: read_command:
58:
59: switch (*codptr)
60: {
61: case '!':
62: if (frm_crlf[io]) {
63: write_m ("\012\201");
64: }
65: else {
66: write_m ("\012\015\201");
67: }
68:
69: if (*++codptr == '!' || *codptr == '#' || *codptr == '?') goto read_command;
70:
71: goto cont_read;
72:
73: case '#':
74: write_m ("\015\014\201");
75:
76: if (*++codptr == '!' || *codptr == '#' || *codptr == '?') goto read_command;
77:
78: goto cont_read;
79:
80: case '?':
81: codptr++;
82:
83: expr (STRING);
84:
85: if (merr ()) return merr ();
86:
87: write_t ((short) intexpr (argptr));
88:
89: goto cont_read;
90:
91: case '/':
92: codptr++;
93:
94: expr (NAME);
95: if (merr ()) return merr ();
96:
97: write_f (varnam);
98:
99: codptr++;
100:
101: goto cont_read;
102:
103: case '"':
104: i = 0;
105:
106: for (;;) {
107:
108: while ((ch = *++codptr) > '"') argptr[i++] = ch;
109:
110: /* EOL < "any ASCII character" */
111: if (ch == '"' && (ch = *++codptr) != '"') {
112: argptr[i] = EOL;
113: write_m (argptr);
114:
115: goto cont_read;
116: }
117:
118: if ((argptr[i++] = ch) == EOL) {
119: return QUOTER;
120: }
121: }
122: }
123:
124: i = InFieldLen; /* no length limit */
125: InFieldLen = 255; /* Not necessarily tied to STRLEN */
126:
127: if (*codptr == '*') {
128: codptr++;
129: i = 0;
130: } /* single char read */
131:
132: if (*codptr == '$') {
133: return INVREF;
134: }
135:
136: expr (NAME);
137:
138: if (merr ()) return merr ();
139:
140: stcpy (vn, varnam);
141: codptr++; /* lvn */
142:
143: if (i != 0 && *codptr == '#') { /* length limit */
144: codptr++;
145:
146: expr (STRING);
147:
148: if ((i = intexpr (argptr)) <= 0) return ARGER;
149: if (merr ()) return merr ();
150: }
151:
152: frm_timeout = (-1L);
153: timeoutms = 0; /* no timeout */
154:
155: if (*codptr == ':')
156: { /* timeout */
157: int i, ch;
158:
159: codptr++;
160:
161: expr (STRING);
162: numlit (argptr);
163:
164: if (merr ()) return merr ();
165:
166: frm_timeout = 0;
167: timeoutms = 0;
168:
169: if (argptr[0] != '-') {
170:
171: i = 0;
172:
173: for (;;) { /* get integer and fractional part */
174:
175: if ((ch = argptr[i++]) == EOL) break;
176:
177: if (ch == '.') {
178:
179: timeoutms = (argptr[i++] - '0') * 100;
180:
181: if ((ch = argptr[i++]) != EOL) {
182: timeoutms += (ch - '0') * 10;
183:
184: if ((ch = argptr[i]) != EOL) {
185: timeoutms += (ch - '0');
186: }
187:
188: }
189: break;
190: }
191: frm_timeout = frm_timeout * 10 + ch - '0';
192: }
193: }
194: } /* if (*codptr == ':') */
195:
196: #if 0
197: set_io (UNIX);
198: printf ("READ: io = %d timeout = %d timeoutms = %d count = %d\n", io, frm_timeout, timeoutms, i);
199: set_io (MUMPS);
200: #endif
201:
202: if (io < FIRSTSCK) {
203: /* $IO is not a socket device */
204: read_m (argptr, frm_timeout, timeoutms, i);
205: }
206: else {
207: /* $IO _is_ a socket device */
208: msck_read (io, argptr, frm_timeout, timeoutms, i);
209: }
210:
211: if (vn[0] != '^') {
212: stcpy (an, argptr);
213: symtab (set_sym, vn, an);
214: }
215: else {
216: stcpy (an, argptr);
217: if (vn[1] == '$') {
218: ssvn (set_sym, vn, an);
219: }
220: else {
221: global (set_sym, vn, an);
222: }
223: }
224:
225: if (merr () != OK) {
226: stcpy (varerr, vn);
227: return merr ();
228: }
229:
230: cont_read:
231:
232: *ra = RA_CONTINUE;
233: return OK;
234: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>