/* @(#)miderr.c 17.1.1.1 (ESO-DMD) 01/25/02 17:36:22 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*+++++++++++++++++++++ Module MIDERR +++++++++++++++++++++++++++++++++++++++ .LANGUAGE C .IDENTIFICATION Module MIDERR .COMMENTS holds MID_ERROR, MID_ERRFIL, MID_DSPERR, MID_INITER, MID_E1, MID_E2, MID_PUTERR .AUTHOR Klaus Banse ESO - Garching .KEYWORDS Midas errors .ENVIRONMENT VMS and UNIX .VERSION 010917 last modif ------------------------------------------------------------------------*/ #include #include /* #include it doesn't work apparently... */ #define READ 0 #define WRITE 1 #define READ_WRITE 2 #define APPEND 3 static char caller[16], work[104], mess[84], *messpntr, *pntr; /* */ void MID_ERRFIL(ulevel,label) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE: display error messages .ALGORITHM: straight forward .RETURNS: nothing --------------------------------------------------------------------*/ int ulevel; /* IN: user level */ char *label; /* IN: label */ { int mm, fp; if (ulevel == 2) return; /* experts leave already */ /* for novices + users we do more */ fp = CGN_OPEN("MID_MONIT:errpar.dat",READ); if (fp == -1) { (void) printf("problems opening system errorfile %s ...\n\r",mess); return; } while (osaread(fp,mess,80) >= 1) /* read a file record */ { if (strncmp(mess,label,6) == 0) /* compare with given label */ { (void) osaread(fp,mess,80); /* match - read next record */ mm = CGN_INDEXC(mess,'\n'); if (mm >= 0) mess[mm] = '\0'; else mess[79] = '\0'; (void)printf("%s\n",mess); /* and print it */ if (ulevel == 1) { /* for novice users */ loop: /* get more records */ if ( osaread(fp,mess,80) != -1) { if ( strncmp(mess,"_END",4) != 0) { (void)printf("%s\n",mess); goto loop; } } } break; } } (void)osaclose(fp); /* close error message file */ } /* */ void MID_DSPERR() /*+++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE display error messages .ALGORITHM straight forward .RETURNS nothing --------------------------------------------------------*/ { int mm, kk, source, prflag, usr_level, mesoff, kk1; static int fflag = 0; char saverr[8]; if (ERRO_DISP != 0) { prflag = KIWORDS[OFF_ERROR]; /* print flag = ERROR(1) */ if (fflag == 0) { fflag = 1; if (prflag > 0) { kk = OFF_APPLIC + 2; /* point to name */ pntr = &KCWORDS[kk]; CGN_FILL(work,' ',58); (void) strncpy(work,pntr,58); /* current length of APPLIC - 2 */ work[58] = '\0'; kk = CGN_INDEXC(work,' '); if (kk > 0) work[kk] = '\0'; else kk = 58; (void) printf("--- in module %s ---\n\r",work); if (KIWORDS[OFF_ERROR+3] != 0) mm = MID_LOG('G',work,kk); } } usr_level = KIWORDS[OFF_ERROR+1]; /* user level = ERROR(2) */ kk1 = ERRO_INDX; /* empty error message stack */ for (kk=kk1; kk > -1; kk--) /* loop from kk1 down to 0 */ { mesoff = ERROS[kk][1]; pntr = &ERRO_MESAGS[mesoff]; if ((kk == kk1) || (kk == 0) || (prflag != 0)) { (void) printf("%s \n\r",pntr); if (KIWORDS[OFF_ERROR+3] != 0) mm = MID_LOG('G',pntr,(int)strlen(pntr)); if (kk == kk1) /* save error of top of stack */ { (void) SCKWRC("MID$ERRMESS",1,pntr,1,80,&mm); /* => MID$ERRMESS */ source = ERROS[kk][0]; mm = CGN_INDEXS(pntr,"- "); /* get to error itself... */ pntr += (mm + 2); (void) strncpy(saverr,pntr,6); } if (kk == 0) { if (source == 1) /* MIDAS error: */ MID_ERRFIL(usr_level,saverr); /* write canned help text */ #if vms else if (source == 2) { /* - Operating or File system interfaces: */ int istat; mm = sscanf(saverr,"%d",&istat); if ((mm != 0) && (istat != 0)) { char tmp[260]; OSY_MESSAGE(istat,tmp); /* obtain full message */ (void)printf("%s\n",tmp); } } #endif } } } ERRO_INDX = -1; ERRO_OFF = 0; } } /* */ void MID_ERROR(subsystem,text,status,print) /*+++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE display error/warning/info messages .ALGORITHM store message into error stack + display complete stack if relevant store warning/error status and error source into key PROGSTAT .RETURNS nothing. --------------------------------------------------------*/ char *subsystem /* subsystem from which error resulted OSY or FSY or \ MIDAS */; char *text /* text to be stored in the error stack */; int status /* error status */; int print /* print flag, if set dump contents of error stack + \ reset pointer */; { int mm, kk, source, ind, istat; static int errtab_off = 8; char *osmsg(); static char fixtype[20] = {'(','O','S','Y',')','(','F','S','Y',')', '(','E','R','R',')','(','I','/','W',')'}; static char aux1 [3] = {' ','-',' '}; static char aux2 [9] = {' ','-',' ','I','N','V','E','R','R'}; if (KEYALL.ORIGIN == -1) { if (ERRO_CONT == 1) return; else if ((ERRO_CONT == 0) && (status < 0)) return; MID_ABORT(status,0); } /* init message string */ mm = strlen(text); /* get length of text */ if (mm > 65) mm = 65; /* minimize... */ CGN_FILL(mess,' ',6); /* subsystem may either be OSY, FSY, APP or MIDAS */ if ((*subsystem == 'O') || (*subsystem == 'F')) { source = 2; /* OSY or FSY error... */ pntr = fixtype; (void) strncpy(mess,pntr,5); /* copy type of error */ messpntr = mess + 6; #if vms (void) sprintf(messpntr,"%s - %d (or %x hex)",text,status,status); istat = status; #else (void) sprintf(messpntr,"%s %s",text,osmsg()); /* istat = oserror; */ istat = -1; #endif KIWORDS[OFF_PRSTAT+3] = istat; /* save host system error */ } else if (*subsystem == 'A') { source = 100; /* application provided error */ ERRO_INDX = -1; /* reset error stack */ ERRO_OFF = 0; (void) strcpy(mess,"(APP) application error"); (void) sprintf(work," - %d ",status); /* append error */ (void) strcat(mess,work); } else { if ( (ERRO_LOG == 0) || ((ERRO_LOG == 1) && (status < 0)) ) return; source = 1; /* error from MIDASLIB... */ if (status > 0) pntr = fixtype + 10; else pntr = fixtype + 15; (void) strncpy(mess,pntr,5); /* copy type of error */ messpntr = mess + 6; (void) strncpy(messpntr,text,mm); /* copy user message */ messpntr += mm; /* adapt to count in MESS */ ind = (status + errtab_off) * 6; /* get offset into error table */ if (ind >= (ETABLIM*6)) { (void) strncpy(messpntr,aux2,9); messpntr += 9; /* determine final length */ } else { (void) strncpy(messpntr,aux1,3); pntr = ERRTAB + ind; messpntr += 3; (void) strncpy(messpntr,pntr,6); messpntr += 6; /* determine final length */ } *messpntr = '\0'; /* fix the end */ } /* put all relevant stuff on error stack */ istat = MID_PUTERR(source); if (istat != 0) /* something went wrong... */ { if (print > 0) { if (istat == 1) (void) printf(" error stack overflow... \n\r"); else (void) printf(" error message buffer overflow... \n\r"); MID_DSPERR(); /* display contents of error stack */ } ERRO_INDX = -1; ERRO_OFF = 0; istat = MID_PUTERR(source); } KCWORDS[OFF_APPLIC] = 'x'; /* indicate that module was "aborted" */ if (print < 1) return; /* low level MIDAS routines exit here... */ ind = ERRO_INDX; /* we may need it later... */ MID_DSPERR(); if (source == 100) return; /* do the rest in SCETER ... */ /* finally check continuation flag for high level interfaces */ if ( (ERRO_CONT == -1) || /* stop on everything */ ((status > 0) && (ERRO_CONT == 0)) ) /* stop on errors only */ { if (caller[0] != '*') { /* print high level calling routine */ kk = ERROS[ind][1]; pntr = &ERRO_MESAGS[kk]; mm = CGN_INDEXS(pntr,"- "); /* get to error itself... */ pntr += mm; (void) printf("(ERR) %s: %s\n\r",caller,pntr); caller[0] = '*'; } MID_ABORT(status,source); /* now exit (but set ERROR(6) first) */ } } /* */ void MID_INITER() /*+++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE initialize error structures .ALGORITHM straight forward .RETURNS nothing --------------------------------------------------------*/ { /* reset pointers */ ERRO_INDX = -1; /* last used entry in stack */ ERRO_OFF = 0; /* offset to first free char. in message buffer */ ERRO_CONT = 0; /* stop on errors only */ ERRO_LOG = 2; /* log warnings + errors */ ERRO_DISP = 1; /* display only errors */ caller[0] = '*'; /* clear high level calling routine */ } /* */ int MID_PUTERR(source) /*+++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE put error message into error stack .ALGORITHM straight forward .RETURNS istat: 0, if o.k; 1, overflow in error stack; 2, overflow in message buffer -------------------------------------------------------*/ int source /* IN : source of error */; { int mm, meslen; /* check index of error stack */ mm = ERRO_INDX + 1; /* point to next free slot in stack */ if (mm >= ERRO_MAXENT) return (1); meslen = strlen(mess); /* test, if full message + '\0' fits... */ if ( (ERRO_OFF + meslen) >= ERRO_MAXLEN) return (2); /* we still got space for this one... */ ERRO_INDX = mm; /* update stack index */ ERROS[mm][0] = source; ERROS[mm][1] = ERRO_OFF; /* set offset */ /* finally put the actual message into message buffer */ (void) strcpy(&ERRO_MESAGS[ERRO_OFF],mess); ERRO_OFF += (meslen + 1); /* update message offset */ return (0); } /* */ void MID_E1(funcno,text,status,print) /*+++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE display error/warning/info messages .ALGORITHM call MID_ERROR .RETURNS nothing. --------------------------------------------------------*/ int funcno; /* IN: no. of function from which error resulted */ char *text /* text to be stored in the error stack */; int status /* error status */; int print /* print flag, if set dump contents of error stack + \ reset pointer */; { int mm; static char modu_1[] = "SPROSEPIFOPNFCREKRDxKPROKWRxKINFIPUTIGETKFNDFINFFXMP"; mm = (funcno - 1) * 4; (void) strcpy(work,"SC "); (void) strncpy(&work[2],&modu_1[mm],4); (void) strcpy(&work[6],": "); (void) strcpy(&work[8],text); MID_ERROR("MIDAS",work,status,print); } /* */ void MID_E2(funcno,imno,text,status,print) /*+++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE display error/warning/info workages .ALGORITHM call MID_ERROR .RETURNS nothing. --------------------------------------------------------*/ int funcno; /* IN: no. of function from which error resulted */ int imno; /* IN: FCT entry no. of frame involved */ char *text /* text to be stored in the error stack */; int status /* error status */; int print /* print flag, if set dump contents of error stack + \ reset pointer */; { int mm; static char modu_2[] = "FCLOFMAPFUNMDDELDWRxDRDxDINFDCOPDFNDFGETFPUTPGETPPUT"; mm = (funcno - 1) * 4; (void) strcpy(work,"SC "); (void) strncpy(&work[2],&modu_2[mm],4); (void) strcpy(&work[6],": "); mm = MID_RETNAM(imno,&work[8],80); /* get name of file */ if (mm < 0) (void) strcpy(&work[8],"wrong file number"); (void) strcat(work," + "); (void) strcat(work,text); MID_ERROR("MIDAS",work,status,print); } /* */ void MID_E3(callfunc) /*+++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE put name of high level calling rotuine into internal buffer .ALGORITHM use strcpy ... .RETURNS nothing. --------------------------------------------------------*/ char *callfunc; { (void) strcpy(caller,callfunc); } void MID_ABORT(erro,source) /*+++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE abort application program, but close keyfile correctly .ALGORITHM as it should be... .RETURNS nothing. --------------------------------------------------------*/ int erro, source; { if (KEYALL.ORIGIN != -1) { KIWORDS[OFF_PRSTAT] = erro; /* store status and error source */ KIWORDS[OFF_PRSTAT+1] = source; /* into key PROGSTAT */ MID_LOG('O',work,5); /* leave like in SCSEPI ... */ work[0] = ' '; MID_MOVKEY("O",work); /* update keyfile */ } ospexit(0); /* and get out of here! */ } /* */ void error_ret(fnam,addon,myerrno,status) char *fnam, *addon; int myerrno, status; { int mm; char txt[80]; mm = CGN_INDEXC(fnam,' '); if (mm <= 0) mm = (int) strlen(fnam); (void) strncpy(txt,fnam,mm); txt[mm++] = ' '; (void) strcpy(&txt[mm],addon); MID_E1(myerrno,txt,status,1); }