Annotation of freem/src/merr.c, revision 1.1.1.1
1.1 snw 1: /*
2: * *
3: * * *
4: * * *
5: * ***************
6: * * * * *
7: * * MUMPS *
8: * * * * *
9: * ***************
10: * * *
11: * * *
12: * *
13: *
14: * merr.c
15: * stuff for handling program bogosity
16: *
17: *
18: * Author: Serena Willis <jpw@coherent-logic.com>
19: * Copyright (C) 1998 MUG Deutschland
20: * Copyright (C) 2020 Coherent Logic Development LLC
21: *
22: *
23: * This file is part of FreeM.
24: *
25: * FreeM is free software: you can redistribute it and/or modify
26: * it under the terms of the GNU Affero Public License as published by
27: * the Free Software Foundation, either version 3 of the License, or
28: * (at your option) any later version.
29: *
30: * FreeM is distributed in the hope that it will be useful,
31: * but WITHOUT ANY WARRANTY; without even the implied warranty of
32: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33: * GNU Affero Public License for more details.
34: *
35: * You should have received a copy of the GNU Affero Public License
36: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
37: *
38: **/
39:
40: #include <string.h>
41: #include <stdlib.h>
42:
43: #include "mpsdef.h"
44: #include "merr.h"
45: #include "jobtab.h"
46:
47: merr_stackent merr_stack[NESTLEVLS + 1];
48: char etrap[256];
49: char ecode[256];
50: char user_ecode[256];
51: int estack;
52: int etrap_lvl = 0;
53: int merr_topstk = 0;
54:
55: typedef struct err_lut {
56: int ecode;
57: const char *canonical_name;
58: } err_lut;
59:
60: err_lut errtab[] = {
61: {0, "ZOK"},
62: {1, "ZINRPT"},
63: {2, "ZBKERR"},
64: {3, "ZNOSTAND"},
65: {4, "ZUNDEF"},
66: {5, "ZLBLUNDEF"},
67: {6, "ZMISSOPD"},
68: {7, "ZMISSOP"},
69: {8, "ZILLOP"},
70: {9, "ZQUOTER"},
71: {10, "ZCOMMAER"},
72: {11, "ZASSIGNER"},
73: {12, "ZARGER"},
74: {13, "ZSPACER"},
75: {14, "ZBRAER"},
76: {15, "ZLVLERR"},
77: {16, "ZDIVER"},
78: {17, "ZILLFUN"},
79: {18, "ZFUNARG"},
80: {19, "ZZTERR"},
81: {20, "ZNEXTER"},
82: {21, "ZSELER"},
83: {22, "ZCMMND"},
84: {23, "ZARGLIST"},
85: {24, "ZINVEXPR"},
86: {25, "ZINVREF"},
87: {26, "ZMXSTR"},
88: {27, "ZTOOPARA"},
89: {28, "ZNOPEN"},
90: {29, "ZNODEVICE"},
91: {30, "ZPROTECT"},
92: {31, "ZGLOBER"},
93: {32, "ZFILERR"},
94: {33, "ZPGMOV"},
95: {34, "ZSTKOV"},
96: {35, "ZSTORE"},
97: {36, "ZNOREAD"},
98: {37, "ZNOWRITE"},
99: {38, "ZNOPGM"},
100: {39, "ZNAKED"},
101: {40, "ZSBSCR"},
102: {41, "ZISYNTX"},
103: {42, "ZDBDGD"},
104: {43, "ZKILLER"},
105: {44, "ZHUPER"},
106: {45, "ZMXNUM"},
107: {46, "ZNOVAL"},
108: {47, "ZTYPEMISMATCH"},
109: {48, "ZMEMOV"},
110: {49, "ZNAMERES"},
111: {50, "ZSCKCREAT"},
112: {51, "ZSCKIFAM"},
113: {52, "ZSCKITYP"},
114: {53, "ZSCKIPRT"},
115: {54, "ZSCKCERR"},
116: {55, "ZSCKAERR"},
117: {56, "ZSCKACON"},
118: {57, "ZSCKNCON"},
119: {58, "ZSCKEOPT"},
120: {59, "ZSCKERCV"},
121: {60, "ZSCKESND"},
122: {61, "ZNORPI"},
123: {62, "ZCREDEF"},
124: {63, "ZCMODIFY"},
125: {64, "ZFILEXWR"},
126: {65, "ZINEWMUL"},
127: {66, "ZINVHORO"},
128: {67, "ZTYPMISMATCH"},
129: {68, "ZINVTYPE"},
130: {69, "ZINVLIBOPT"},
131: {80, "ZECODEINV"},
132: {81, "ZASSERT"},
133: {82, "ZUSERERR"},
134: {83, "ZOBJFLDACCV"},
135: {84, "ZOBJCONFLICT"},
136: {85, "ZOBJPRIVOVFL"},
137: {86, "ZOBJACINVALID"},
138: {128, "ZSYNTERR"},
139: {140, "M1"},
140: {141, "M2"},
141: {142, "M3"},
142: {143, "M4"},
143: {144, "M5"},
144: {145, "M6"},
145: {146, "M7"},
146: {147, "M8"},
147: {148, "M9"},
148: {149, "M10"},
149: {150, "M11"},
150: {151, "M12"},
151: {152, "M13"},
152: {153, "M14"},
153: {154, "M15"},
154: {155, "M16"},
155: {156, "M17"},
156: {157, "M18"},
157: {158, "M19"},
158: {159, "M20"},
159: {160, "M21"},
160: {161, "M22"},
161: {162, "M23"},
162: {163, "M24"},
163: {164, "M25"},
164: {165, "M26"},
165: {166, "M27"},
166: {167, "M28"},
167: {168, "M29"},
168: {169, "M30"},
169: {170, "M31"},
170: {171, "M32"},
171: {172, "M33"},
172: {173, "M34"},
173: {174, "M35"},
174: {175, "M36"},
175: {176, "M37"},
176: {177, "M38"},
177: {178, "M39"},
178: {179, "M40"},
179: {180, "M41"},
180: {181, "M42"},
181: {182, "M43"},
182: {183, "M44"},
183: {184, "M45"},
184: {185, "M46"},
185: {186, "M47"},
186: {187, "M48"},
187: {188, "M49"},
188: {189, "M50"},
189: {190, "M51"},
190: {191, "M52"},
191: {192, "M53"},
192: {193, "M54"},
193: {194, "M55"},
194: {195, "M56"},
195: {196, "M57"},
196: {197, "M58"},
197: {198, "M59"},
198: {199, "M60"},
199: {214, "M75"},
200: {240, "M101"},
201: {241, "M102"},
202: {242, "M103"},
203: {243, "M104"},
204: {254, "ZASYNC"},
205: {255, "ZCTRLB"},
206: {-1, NULL}
207: };
208:
209: inline int merr_raise(int num)
210: {
211: char place[256];
212: char cod[256];
213:
214: if (merr_in_break ()) {
215: ierr = num - CTRLB;
216: }
217: else {
218: ierr = num;
219: }
220:
221: if (num != OK) {
222: merr_set_ecode_ierr ();
223:
224: stcpy (merr_stack[nstx].MCODE, code);
225: stcpy (merr_stack[nstx].ECODE, ecode);
226:
227: if (direct_mode == 1 && nstx == 0) {
228: stcpy (merr_stack[nstx].PLACE, "@\201\0");
229: }
230: else {
231: if (!rtn_get_offset (merr_stack[nstx].PLACE)) {
232: stcpy (merr_stack[nstx].PLACE, "???\201");
233: }
234: }
235:
236: if (nstx > merr_topstk) merr_topstk = nstx;
237: }
238:
239: return ierr;
240: }
241:
242: inline int merr(void)
243: {
244: return ierr < OK ? ierr + CTRLB : ierr;
245: }
246:
247: short merr_in_break(void)
248: {
249: if (ierr < OK) {
250: return TRUE;
251: }
252: else {
253: return FALSE;
254: }
255: }
256:
257: void merr_set_break(void)
258: {
259: if (!merr_in_break ()) {
260: ierr = ierr - CTRLB;
261: }
262: }
263:
264: void merr_clear_break(void)
265: {
266: if (merr_in_break ()) {
267: ierr = ierr + CTRLB;
268: }
269: }
270:
271: int merr_num_to_code (int num, char *code)
272: {
273:
274: err_lut *p;
275:
276: for (p = errtab; p->canonical_name != NULL; ++p) {
277:
278: if (p->ecode == num) {
279: strcpy (code, p->canonical_name);
280: return 1;
281: }
282:
283: }
284:
285: return -1;
286:
287: }
288:
289: int merr_code_to_num (char *code)
290: {
291:
292: err_lut *p;
293:
294: for (p = errtab; p->canonical_name != NULL; ++p) {
295:
296: if (strcmp (p->canonical_name, code) == 0) {
297: return p->ecode;
298: }
299:
300: }
301:
302: return -1;
303:
304: }
305:
306: void merr_set_ecode_ierr (void)
307: {
308: char *cod;
309: char *t;
310:
311: cod = (char *) malloc (256 * sizeof (char));
312: NULLPTRCHK(cod,"merr_set_ecode_ierr");
313:
314: t = (char *) malloc (256 * sizeof (char));
315: NULLPTRCHK(t,"merr_set_ecode_ierr");
316:
317: if ((merr_num_to_code (merr (), cod)) == -1) goto done;
318:
319: snprintf (t, 255, ",%s,\201", cod);
320: merr_set_ecode (t);
321:
322: job_set_ecode (pid, cod);
323:
324: done:
325:
326: free (cod);
327: free (t);
328: return;
329:
330: }
331:
332: int merr_set_ecode (char *t_code)
333: {
334: int ec;
335: char *tmp;
336:
337: if (t_code[0] == '\201') {
338: stcpy (ecode, "\201");
339: return 0;
340: }
341:
342: if (t_code[1] != 'M' && t_code[1] != 'Z' && t_code[1] != 'U') {
343: return M101;
344: }
345:
346: stcpy (ecode, t_code);
347:
348: if (stcmp (t_code, "") == 0) {
349: merr_clear ();
350: stcpy (t_code, ",ZOK,");
351: stcpy (user_ecode, t_code);
352: }
353:
354: tmp = strtok (t_code, ",");
355:
356: /* caller may set ierr with return value */
357: if (ecode[1] == 'U') {
358: stcpy (user_ecode, ecode);
359: return USERERR;
360: }
361: else {
362: ec = merr_code_to_num (tmp);
363: return (ec);
364: }
365: }
366:
367: void merr_dump (int num, char *rtn, char *nsn, char *tcod, int tpos)
368: {
369: char *tbuf;
370: char *dbuf;
371: char *nem;
372: char *nrt;
373: char *real_ecode;
374: err_lut *p;
375:
376: tbuf = (char *) malloc (STRLEN * sizeof (char));
377: NULLPTRCHK(tbuf,"merr_dump");
378:
379: dbuf = (char *) malloc (STRLEN * sizeof (char));
380: NULLPTRCHK(dbuf,"merr_dump");
381:
382: nem = (char *) malloc (STRLEN * sizeof (char));
383: NULLPTRCHK(nem,"merr_dump");
384:
385: nrt = (char *) malloc (STRLEN * sizeof (char));
386: NULLPTRCHK(nrt,"merr_dump");
387:
388: real_ecode = (char *) malloc (STRLEN * sizeof (char));
389: NULLPTRCHK(real_ecode,"merr_dump");
390:
391: stcpy (nrt, rtn);
392: stcnv_m2c (nrt);
393:
394: stcpy (nem, errmes[num]);
395: stcnv_m2c (nem);
396:
397: for (p = errtab; p->canonical_name != NULL; ++p) {
398:
399: if (p->ecode == num) {
400:
401: if (strcmp (p->canonical_name, "ZUSERERR") == 0) {
402: stcpy (real_ecode, &user_ecode[1]);
403: stcnv_m2c (real_ecode);
404: real_ecode [strlen (real_ecode) - 1] = NUL;
405:
406: snprintf (tbuf, STRLEN - 1, "^$JOB\202%d\202USER_ERRORS\202%s\201", pid, &user_ecode[1]);
407: tbuf [stlen (tbuf) - 1] = '\201';
408:
409: global (get_sym, tbuf, dbuf);
410:
411: if (merr () == OK) {
412: stcpy (nem, dbuf);
413: stcnv_m2c (nem);
414: }
415: else {
416: merr_clear ();
417: }
418:
419: }
420: else {
421: strcpy (real_ecode, p->canonical_name);
422: }
423:
424: if (!stlen (err_suppl)) {
425: sprintf (tbuf, "\r\n>> Error %s: %s in %s.%s::%s [$STACK = %d]\r\n\201", real_ecode, nem, shm_env, nsn, nrt, nstx);
426: }
427: else {
428: stcnv_m2c (err_suppl);
429: sprintf (tbuf, "\r\n>> Error %s: %s (%s) in %s::%s [$STACK = %d]\r\n\201", real_ecode, nem, err_suppl, nsn, nrt, nstx);
430: err_suppl[0] = EOL;
431: }
432: write_m (tbuf);
433: write_m (">> \201");
434: write_m (tcod);
435: write_m ("\r\n\201");
436: write_t (tpos);
437: write_m ("^\201");
438:
439: goto done;
440: }
441:
442: }
443:
444:
445: done:
446:
447: free (tbuf);
448: free (dbuf);
449: free (nem);
450: free (nrt);
451: free (real_ecode);
452:
453: return;
454: }
455:
456:
457: void merr_set_iochan_err(int channel, short frm_err, char *err_text)
458: {
459: if (channel > MAXDEV || channel < 0) {
460: merr_raise (ARGLIST);
461: return;
462: }
463:
464: devstat[channel].mdc_err = 1;
465: devstat[channel].frm_err = frm_err;
466:
467: strncpy (devstat[channel].err_txt, err_text, 79);
468:
469: return;
470: }
471:
472: void merr_clear_iochan_err(int channel)
473: {
474: if (channel > MAXDEV || channel < 0) {
475: merr_raise (ARGLIST);
476: return;
477: }
478:
479: devstat[channel].mdc_err = 1;
480: devstat[channel].frm_err = OK;
481: devstat[channel].err_txt[0] = '\0';
482:
483: return;
484:
485: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>