/* @(#)prepa1.c 17.1.1.1 (ESO-DMD) 01/25/02 17:37:37 */ /*=========================================================================== 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 ===========================================================================*/ /*+++++++++++++++ MIDAS monitor routines PREPA1 +++++++++++++++++++++++++ .LANGUAGE C .IDENTIFICATION Module PREPA1 .AUTHOR K. Banse ESO - Garching .KEYWORDS MIDAS monitor .ENVIRONMENT VMS and UNIX .PURPOSE synchronize fore- and background processes; get the MIDAS command string + take action accordingly .ALGORITHM loop on command input (from terminal or procedure file), test for background activity and synchronize system commands are executed directly, all others are executed as command procedures holds NUMBIZ, REDOBIZ, MYREAD, COM_WINDOW .VERSION [1.00] 930125: pulled out from "old" prepa.c + prepb.c 010425 last modif ------------------------------------------------------------------------*/ #include #include #include #include #include #include static int ord[MAX_COMWIN][2]; static int comwinmax; static int lwa; static char *comwinadr; static char wstr[84]; static float rwa; static double dwa; /* */ int NUMBIZ(curcom) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE handle the command recalling business (via number or pattern) .ALGORITHM cumbersome but straight forward .RETURNS status = 1, 2, 3 according to nbra for redobiz = 0 just continue in calling module = -1 go + get new input ------------------------------------------------------------------*/ int *curcom; /* IN/OUT: current command no. */ { char *cpntr, *ccpntr; static char *nptr[2] = {"string","no."}; int combi, iwa, iwc, nbra, m, mm; register int nr; ccpntr = TOKEN[0].STR; cpntr = ccpntr; if ( (*cpntr == ':') || ((*cpntr == '.') && (*(cpntr+1) == ':')) ) { cpntr++; /* point to 2. character */ if (*cpntr == '.') /* is it ":." ? */ nbra = 3; else if ((*ccpntr == '.') && (*cpntr == ':')) /* is it ".:" ? */ nbra = 2; else nbra = 1; COM_WINDOW("FST",&m); /* search for com.string in buffer */ if (m >= 0) { comwincur = comwinp + m; *curcom = comwincur->COMNO; /* update current command */ return nbra; } mm = 0; } /* It's a number. Test, if simple repeat or edit or lock/unlock */ else { combi = -1; if (*cpntr == '.') /* is it ".no" ? */ { nbra = 2; cpntr ++; } else if (*(cpntr+TOKEN[0].LEN-1) == '.') /* is it "no." ? */ { nbra = 3; *(cpntr+TOKEN[0].LEN-1) = '\0'; /* replace '.' by NULL */ } else { iwc = CGN_INDEXC(cpntr,'+'); /* look for xxx+yyy */ if (iwc > 0) { combi = iwc; /* save offset */ *(cpntr+combi) = '\0'; } else { iwc = CGN_INDEXC(cpntr,'/'); /* look for xxx/LOCK,UNLOCK */ if (iwc > 0) { (void)strncpy(LINE.STR,cpntr,iwc); LINE.STR[iwc] = '\0'; COM_WINDOW(cpntr+iwc,&iwa); /* lock or unlock command xxx */ return (-1); /* get new command */ } } nbra = 1; } convert_comno: mm = CGN_CNVT(cpntr,1,1,&lwa,&rwa,&dwa); /* convert to binary */ if (mm < 1) { (void)strcpy(wstr,"Invalid syntax..."); goto error_1; } if (lwa <= 0) lwa = *curcom; /* 0 means last used command */ m = lwa; /* save that command no. */ COM_WINDOW("FNO",&m); /* find command with given no. */ if (m >= 0) { comwincur = comwinp + m; *curcom = lwa; /* update current command */ if (combi > 0) /* we have xxx+yyy construct */ { if (combi < 9999) { comwincur->LREF = FRONT.COMCNT; /* set last_used entry */ (void)strcpy(KAUX.STR,&LINE.STR[1]); /* save returned string */ cpntr += (combi+1); /* point to 2. number */ combi = 9999; /* update combiflag */ goto convert_comno; } else { iwc = (int)strlen(KAUX.STR); /* length of saved string */ LINE.STR[0] = ' '; /* change '+' to ' ' */ LINE.LEN += iwc; for (nr=LINE.LEN; nr>=iwc; nr--) LINE.STR[nr] = LINE.STR[nr-iwc]; /* includes the '\0' */ (void)strncpy(LINE.STR,KAUX.STR,iwc); } } return (nbra); /* indicate that we need to redo it */ } mm = 1; } (void) sprintf(wstr,"Command %s not in buffer ",nptr[mm]); error_1: FRONT.COMCNT --; (void) printf("%s\n\r",wstr); return(-1); /* look for next command */ } /* */ int REDOBIZ(nbra) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE handle the command recalling business (via number or pattern) .ALGORITHM cumbersome but straight forward .RETURNS status = 1 we have to go back to main start loop if psw = 1, we have to go back to parsing only = 0 just continue in calling module ------------------------------------------------------------------*/ int nbra; /* IN: switch (coming from numbiz */ { int iwa; if (nbra == 1) { comwincur->LREF = FRONT.COMCNT; /* set last_used entry */ FRONT.COMCNT--; /* no increment comm_count for numbers */ (void) printf("%s\n\r",LINE.STR); } else { /* nbra = 2 or 3 */ TTEDIT(LINE.STR,80); /* edit this command */ LINE.LEN = (int)strlen(LINE.STR); if (nbra != 2) { if (LINE.LEN == 0) /* may happen in edit mode ... */ { COM_WINDOW("SH",&iwa); return (0); /* get new command */ } if (LINE.LEN > MAX_WINLEN) { (void)strncpy(comwincur->STR,LINE.STR,MAX_WINLEN); comwincur->STR[MAX_WINLEN] = '\0'; } else (void)strcpy(comwincur->STR,LINE.STR); comwincur->LREF = FRONT.COMCNT; /* set last_used entry */ FRONT.COMCNT--; /* don't increment com_count */ } if (LINE.STR[0] == '+') return (0); /* do not execute */ } return(1); /* parse that command again */ } /* */ int MYREAD() /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE display a prompt string on the terminal + read the user input .ALGORITHM use QIOW system service to display prompt string with time out option and get user input as character string convert this string to relevant data via GEN_CNVT .RETURNS = 0 normally = 1 if end of playback file reached ------------------------------------------------------------------*/ { int amount, off, reclen, start; int kk, nn, partial, promend5; char atom1[16], atom2[16]; char *rec, *cpntrc; static char intrpt[80]; promend5 = FRONT.PEND + 5; rec = KAUX.STR; off = 0; /* offset within command buffer */ LINE.LEN = 0; amount = MAX_LINE; /* test playback switch, = 0 for terminal input, > 0 for input from playback file */ sect_100: cpntrc = &LINE.STR[off]; /* point to begin of command line */ if (FRONT.PLAYBACK == 0) { /* read a line from terminal and wait for `timeout' seconds */ TERM.INTENA = 1; if (off == 0) TTPRO(FRONT.PROMPT,cpntrc,amount); else { CGN_FILL(KAUX.STR,' ',promend5); KAUX.STR[promend5] = '\0'; TTPRO(KAUX.STR,cpntrc,amount); } TERM.INTENA = 0; if (TERM.TIMEOUT != 0) return (0); /* special treatment ... */ partial = (int)strlen(cpntrc); if (partial <= 0) { LINE.LEN = 0; return (0); /* nothing came in... */ } } else { start = 0; read_play: /* read a line from playback file */ reclen = osaread(FRONT.PP,rec,96); if (reclen == -1) { /* end of playback file reached */ FRONT.PLAYBACK = 0; (void) printf("--- end of playback reached ---\n"); osaclose(FRONT.PP); return (-1); /* indicate it to caller */ } if (reclen == 0) goto read_play; if (rec[reclen-1] == 13) reclen --; /* get rid of RETURN char. */ if (off > 0) goto sect_200; /* for logfiles check, if it was a MIDAS command */ if (FRONT.PLAYBACK == 11) { /* test for Midas prompt */ nn = 0; (void) CGN_EXTRSS(FRONT.PROMPT,20,' ',&nn,atom1,14); (void) CGN_EXTRSS(rec,reclen,' ',&start,atom2,14); if (strcmp(atom1,atom2) == 0) { kk = CGN_EXTRSS(rec,reclen,' ',&start,atom2,12); goto sect_200; /* start -> begin of command line */ } start = 0; goto read_play; } sect_200: partial = reclen - start; (void)strcpy(cpntrc,&rec[start]); /* build up LINE.STR */ if (off == 0) (void)strcpy(rec,FRONT.PROMPT); else CGN_FILL(rec,' ',promend5); (void)strcpy(rec+promend5,cpntrc); /* old line with new prompt */ (void)printf("%s\n\r",rec); } /* for all options update counters + pointers */ off += partial; LINE.LEN = off ; nn = LINE.LEN - 1; /* test for continuation */ if (LINE.STR[nn] != '-') /* no. we are done ... */ { if (LINE.STR[nn] == '\\') /* but don't forget the interrupt. business */ { if (LINE.LEN == 1) /* recall interrupted command line */ { (void)strncpy(KAUX.STR,FRONT.PROMPT,promend5); (void)strcpy(&KAUX.STR[promend5],intrpt); /* get saved string back */ (void)printf("%s\n\r",KAUX.STR); LINE.LEN = CGN_COPY(LINE.STR,intrpt); goto sect_2000; /* handle like continuation line */ } else /* save interrupted command line */ { (void)strcpy(intrpt,LINE.STR); /* simulate continuation... */ intrpt[partial-1] = ' '; /* change '\' to ' ' */ LINE.LEN = -1; /* indicate interruption to PREPA */ return (0); } } } else { sect_2000: /* yes...delete continuation char. */ off = LINE.LEN -1; amount = MAX_LINE - off; if (amount >= 0) goto sect_100; /* get max. MAX_LINE chars... */ } /* normal return here */ LINE.STR[LINE.LEN] = '\0'; return (0); } /* */ int COM_WINDOW(action,curcom) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE handle the interactions with the command buffer .ALGORITHM straight forward .RETURNS 0 if o.k., else we have problems -----------------------------------------------------------------*/ char *action; /* IN: = ADD, for adding an entry */ /* = SHOW, for showing the command window */ /* = READ, for reading from procedure into window */ /* = WRITE, for writing the window to procedure */ /* = CLEAR, for initializing window */ /* = /LOCK,UNLOCK for locking,unlocking an entry */ /* = EXtend (Init) to (re)create command buffer */ int *curcom /* IO: current command no. in command window */; { int kk, kret, n, nn, m, mm; register int nr; static char title[78]; /* ADD => store command in command window */ if (*action == 'A') { m = comwinp->LREF + comwinp->FIX; mm = 0; /* start with 1. entry */ comwincur = comwinp + 1; for (nr=1; nrLREF + comwincur->FIX) < m ) { m = comwincur->LREF + comwincur->FIX; /* m = oldest entry */ mm = nr; } comwincur ++; } comwincur = comwinp + mm; if (LINE.LEN > MAX_WINLEN) { (void) strncpy(comwincur->STR,LINE.STR,MAX_WINLEN); /* store command */ comwincur->STR[MAX_WINLEN] = '\0'; } else (void)strcpy(comwincur->STR,LINE.STR); comwincur->COMNO = FRONT.COMCNT; /* and set comno + last_used entry */ comwincur->LREF = FRONT.COMCNT; *curcom = FRONT.COMCNT; } /* FNO and FST => find matching commands */ else if (*action == 'F') { kret = -1; /* indicate that no match */ if (*(++action) == 'S') { if ((TOKEN[0].STR[1] == '.') || (TOKEN[0].STR[1] == ':')) m = 2; else m = 1; kk = sort_it(); /* sort according to comand no. */ for (nr=kk; nr>=0; nr--) /* to begin with most recent command */ { n = ord[nr][1]; comwincur = comwinp + n; if (CGN_INDEXS(comwincur->STR,&TOKEN[0].STR[m]) >= 0) { kret = n; break; } } } else { mm = *curcom; /* save parameter */ comwincur = comwinp; for (nr=0; nrCOMNO == mm) { kret = nr; break; } comwincur ++; } } *curcom = kret; if (kret != -1) /* copy string if if found */ LINE.LEN = CGN_COPY(LINE.STR,comwincur->STR); } /* SHOW => display command buffer */ else if (*action == 'S') { kk = sort_it(); /* sort according to comand no. */ (void) printf("%s\n\r",title); for (nr=0; nr<=kk; nr++) { comwincur = comwinp + ord[nr][1]; (void) sprintf(KAUX.STR,"%4d %s",comwincur->COMNO,comwincur->STR); (void) printf("%s\n\r",KAUX.STR); } FRONT.COMCNT --; /* keep counter at same value */ } /* READ => store commands from a procedure into command buffer */ else if (*action == 'R') { if (cmw_read(curcom) < 0) return (-22); } /* WRITE => save commands from command buffer in procedure */ else if (*action == 'W') { kk = cmw_write(moncnt,*curcom); if (kk < 0) return (-22); } /* CLEAR => reset FRONT.COMCNT + clear command buffer */ else if (*action == 'C') { cmw_clear(); } /* /LOCK, /UNLOCK => lock or unlock an entry */ else if (*action == '/') { FRONT.COMCNT --; /* keep counter at same value */ nn = CGN_CNVT(LINE.STR,1,1,&lwa,&rwa,&dwa); /* get command no. */ if ( (lwa <= 0) || (nn < 1) ) return (-1); /* invalid command no. */ comwincur = comwinp; mm = lwa; for (nr=0; nrCOMNO == mm) { if ( (action[1] == 'L') || (action[1] == 'l') ) comwincur->FIX = 1000; /* set lock flag */ else comwincur->FIX = 0; /* clear lock flag */ break; } comwincur ++; } } /* Extend (or Init) command buffer */ else { if (*action == 'I') { comwinmax = 15; /* initial value */ if (FRONT.TITLE[0] == 'F') /* FrontEnd version */ (void)strcpy(title,"no. command:"); else { (void)strcpy(title, "no. command: (Midas unit , version 12345pl"); title[39] = FRONT.DAZUNIT[0]; title[40] = FRONT.DAZUNIT[1]; (void)strcpy(&title[51],&FRONT.TITLE[1]); if (FRONT.TITLE[0] == 'P') (void)strcat(title,", parallel)"); else (void)strcat(title,", noparallel)"); } nn = 1; } else { if (TOKEN[1].STR[0] == '?') lwa = 15; /* default, if no params */ else { nn = CGN_CNVT(TOKEN[1].STR,1,1,&lwa,&rwa,&dwa); if ( (lwa <= 0) || (nn < 1) ) return (-1); /* invalid command no. */ if (lwa > MAX_COMWIN) /* keep in [2,MAX_COMWIN] */ lwa = MAX_COMWIN; else if (lwa < 2) lwa = 2; } nn = cmw_write(0,*curcom); /* save contents of current buffer */ if (nn < 0) return (-22); free(comwinadr); /* free allocated memory */ comwinmax = lwa; /* only now update comwinmax ... */ } kk = (sizeof(struct COMWIN_STRUCT)) * comwinmax; if ((comwinadr = malloc((unsigned int) kk)) == NULL) return (-99); comwinp = (struct COMWIN_STRUCT *) comwinadr; cmw_clear(); if (nn == 0) /* only if we saved something before */ { TOKEN[1].STR[0] = '?'; /* force to default frame name */ cmw_read(curcom); } } return (0); } /* */ int cmw_read(curcom) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE store commands from a procedure into command buffer .ALGORITHM open file + read records .RETURNS no. of lines in procedure file, -1 if problems ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int *curcom; { int lcount, lrec, kk, idum, mm, m, cur; int fp; register int nr; char frame[200]; char frname[80]; if (TOKEN[1].STR[0] == '?') { idum = 1; /* use as 1. time flag */ mm = CGN_COPY(frame,FRONT.STARTUP); (void)strcpy(&frame[mm],"midtemp .prg"); /* default procedure */ frame[mm+7] = FRONT.DAZUNIT[0]; frame[mm+8] = FRONT.DAZUNIT[1]; } else { idum = 0; /* use as 1. time flag */ CGN_CLEANF(TOKEN[1].STR,6,frame,70,&kk,&kk); } cur = 0; /* start with 1. entry */ lcount = 0; /* init record count */ open_file: fp = osaopen(frame,0); /* open for read */ if (fp == -1) { if (TOKEN[1].STR[0] == '*') { *curcom = cur; return (0); } else { if (idum == 0) { idum = -1; mm = CGN_COPY(frame,FRONT.STARTUP); CGN_CLEANF(TOKEN[1].STR,6,&frame[mm],20,&kk,&kk); goto open_file; } else { (void)strcpy(frname,"READ/COMM "); (void)strcat(frname,frame); return (-1); } } } read_loop: lrec = osaread(fp,KAUX.STR,MAX_WINLEN); /* read in procedure file */ if (lrec == 0) goto read_loop; if (lrec < 0) { osaclose(fp); *curcom = cur; return (lcount); } else { if ( KAUX.STR[0] == '!') goto read_loop; /* omit comment lines */ lcount ++ ; m = comwinp->LREF; cur = 0; for (nr=1; nrLREF < m) { m = comwincur->LREF; /* m = oldest entry */ cur = nr; } } FRONT.COMCNT ++; /* increment command counter */ comwincur = comwinp + cur; /* pointer to current entry */ (void)strcpy(comwincur->STR,KAUX.STR); /* store command */ comwincur->COMNO = FRONT.COMCNT; /* and set comno + last_used entry */ comwincur->LREF = FRONT.COMCNT; goto read_loop; /* read next line */ } } /* */ int cmw_write(parflag,curcom) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE save commands from command buffer in procedure .ALGORITHM create file + write records .RETURNS 0 if o.k., else we have problems ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int parflag; int curcom; { int kk, jj, nn, mm, m; int fp; register int nr; char frame[200], frname[80]; static char parms[8] = {'1','2','3','4','5','6','7','8'}; jj = sort_it(); /* sort currently stored commands */ if (jj < 0) return(1); /* nothing to do! */ if ((parflag > 1) && (TOKEN[1].STR[0] != '?')) CGN_CLEANF(TOKEN[1].STR,6,frame,70,&kk,&kk); /* append type .prg */ else { mm = CGN_COPY(frame,FRONT.STARTUP); (void)strcpy(&frame[mm],"midtemp .prg"); /* default procedure */ frame[mm+7] = FRONT.DAZUNIT[0]; frame[mm+8] = FRONT.DAZUNIT[1]; } fp = osaopen(frame,1); /* open for write */ if (fp == -1) { (void)strcpy(frname,"WRITE/COMM "); (void)strcat(frname,frame); return (-1); } for (m=0; m<=jj; m++) /* loop through sorted command no.s */ { comwincur = comwinp + ord[m][1]; /* get sorted command no. */ if (comwincur->COMNO != curcom) /* omit WRITE/COMM command itself */ { (void)strcpy(LINE.STR,comwincur->STR); for (nr=2; nr= 0) { nn = kk + TOKEN[nr].LEN; (void)strcpy(KAUX.STR,&LINE.STR[nn]); LINE.STR[kk++] = '{'; LINE.STR[kk++] = 'P'; LINE.STR[kk++] = parms[nr-2]; LINE.STR[kk++] = '}'; (void)strcpy(&LINE.STR[kk],KAUX.STR); } } osawrite(fp,LINE.STR,(int)strlen(LINE.STR)); } } osaclose(fp); /* close procedure file midtemp.prg */ return (0); } /* */ void cmw_clear() /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE clear command buffer + reset FRONT.COMCNT .ALGORITHM straight forward .RETURNS nothing ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ { register int nr; FRONT.COMCNT = 0; /* reset counter */ comwincur = comwinp; for (nr=0; nrCOMNO = -1; /* clear command numbers */ comwincur->LREF = 0; comwincur->FIX = 0; comwincur ++; } } /* */ int sort_it() /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE sort the command buffer + return no. of commands in buffer .ALGORITHM straight forward .RETURNS highest index of commands in buffer ------------------------------------------------------------*/ { int ordr[2]; int nn, jj, m; register int nr; jj = -1; comwincur = comwinp; for (nr=0; nrCOMNO > -1) { jj ++; ord[nr][0] = comwincur->COMNO; ord[nr][1] = nr; } comwincur ++; } if (jj < 0) return (jj); /* if more than one command, sort them */ for (nr=jj; nr>0; nr--) { for (nn=1,m=0; nn<=nr; nn++,m++) { if (ord[m][0] > ord[nn][0]) { ordr[0] = ord[nn][0]; ordr[1] = ord[nn][1]; ord[nn][0] = ord[m][0]; ord[nn][1] = ord[m][1]; ord[m][0] = ordr[0]; ord[m][1] = ordr[1]; } } } return (jj); }