File:  [Coherent Logic Development] / freem / src / merr.c
Revision 1.2: download - view: text, annotated - select for diffs
Sun Mar 9 15:20:18 2025 UTC (12 months, 3 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Begin formatting overhaul and REUSE compliance

    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 <snw@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>