/* parse - Various useful parse routines Included are confrm Get confirmation (cr) getfnm Get file name getenm Get event name getrol Get rest of line. getuqs Get unquoted string getlin Get a line of text noise Process noise words COMNDi Call COMND; say "invalid" if bad return */ #include "minder.h" /* Get minder defs */ #include "comnd.h" /* Use COMND defs */ #include "setjmp.h" /* setjmp/longjmp def */ /* Local definitions */ extern char **venkfr(); /* valid event name fetch routine */ extern EVT *evnadr(); /* Convert addr of EVT_NAM to addr of EVT block */ /* External variables */ extern EVT *Evthdr; /* Heads the list of EVT blocks */ extern CFB Inicfb; /* CFB for initialization */ extern CSB Tmpcsb; /* Temp command state block */ extern jmp_buf Tmpenv; /* setjmp buffer for Tmpcsb */ extern char *Usrnam; /* Addr of current user's name */ /* External routines */ /* Locals */ static WORD CCevt[] = { /* CC for event names */ 0x0000, /* ^@ ^A ^B ^C ^D ^E ^F ^G */ 0x3000, /* ^H ^I ^J ^K ^L ^M ^N ^O */ 0x0000, /* ^P ^Q ^R ^S ^T ^U ^V ^W */ 0x0000, /* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */ 0xC000, /* sp ! " # $ % & ' */ 0x0023, /* ( ) * + , - . / */ 0xAAAA, /* 0 1 2 3 4 5 6 7 */ 0xA000, /* 8 9 : ; < = > ? */ 0x2AAA, /* @ A B C D E F G */ 0xAAAA, /* H I J K L M N O */ 0xAAAA, /* P Q R S T U V W */ 0xA802, /* X Y Z [ \ ] ^ _ */ 0x2AAA, /* ` a b c d e f g */ 0xAAAA, /* h i j k l m n o */ 0xAAAA, /* p q r s t u v w */ 0xA800 /* x y z { | } ~ dl */ }; static CFB Cfmcfb = {_CMCFM, 0, 0, 0, 0, 0}; static CGK Enfcgk = {0, venkfr}; /* keyword fetch block for evnames */ static CFB Fnmcfb = {_CMUQS, _CFHPP|_CFSDH, 0, 0, "File name", 0}; static CFB Glncfb = {_CMTXT, _CFSDH, 0, 0, 0, 0}; static CFB Noicfb = {_CMNOI, 0, 0, 0, 0, 0}; static CFB Rolcfb = {_CMTXT, _CFHPP|_CFSDH, 0, 0, "x", 0}; static CFB Uqscfb = {_CMUQS, _CFHPP|_CFSDH, 0, 0, "x", 0}; static CFB Vencfb = {_CMGSK, _CFHPP|_CFCC, 0, &Enfcgk, "Event name, ", 0, CCevt}; /* *//* getenm (CSBptr) Get a valid event name from the current parse Accepts : CSBptr Address of command state block Returns : NULL if error address of EVT block for event if no error */ EVT *getenm (CSBptr) CSB *CSBptr; /* Addr of command state block */ { if (COMNDi (CSBptr, &Vencfb) != _CROK) /* Get event name */ return (NULL); /* Return failure if failed.. */ return (evnadr (CSBptr -> CSB_RVL._ADR)); /* Return the result */ } /* *//* getfnm (CSBptr, fnm) Get file name from current parse Accepts : CSBptr Address of command state block fnm Where to put the file name Returns : TRUE if OK parse FALSE if not */ getfnm (CSBptr, fnm) CSB *CSBptr; /* Addr of CSB */ char *fnm; /* File name */ { if (COMNDi (CSBptr, &Fnmcfb) != _CROK) /* Do the parse */ return (FALSE); strcpy (fnm, CSBptr -> CSB_ABF); /* Copy name from atom buffer */ return (TRUE); } /* *//* getuqs (CSBptr, help, uqs) Get unquoted string from current parse Accepts : CSBptr Address of command state block help Help text for incremental help uqs Where to put the string Returns : TRUE if OK parse FALSE if not */ getuqs (CSBptr, help, uqs) CSB *CSBptr; /* Addr of CSB */ char *help; /* Help text */ char *uqs; /* String buffer */ { Uqscfb.CFB_HLP = help; /* Set help text */ if (COMNDi (CSBptr, &Uqscfb) != _CROK) /* Do the parse */ return (FALSE); strcpy (uqs, CSBptr -> CSB_ABF); /* Copy string from atom buffer */ return (TRUE); } /* *//* getrol (CSBptr, help, text) Get rest of line from current parse Accepts : CSBptr Address of command state block help Help text for incremental help text Where to put the string Returns : TRUE if OK parse FALSE if not */ getrol (CSBptr, help, text) CSB *CSBptr; /* Addr of CSB */ char *help; /* Help text */ char *text; /* Text buffer */ { Rolcfb.CFB_HLP = help; /* Set help text */ if (COMNDi (CSBptr, &Rolcfb) != _CROK) /* Do the parse */ return (FALSE); strcpy (text, CSBptr -> CSB_ABF); /* Copy text from atom buffer */ return (TRUE); } /* *//* getlin (prmpt) Gets a line of text, using the temporay command block Accepts : prompt Address of prompt string Returns : */ getlin (prmpt) char *prmpt; /* Addr of prompt string */ { Tmpcsb.CSB_PMT = prmpt; /* Set prompt */ if (COMND (&Tmpcsb, &Inicfb) != _CROK) /* eh? */ { printf ("Fatal error initializing COMND\n"); exit(); } setjmp (Tmpenv); /* Mark here for reparse */ COMND (&Tmpcsb, &Glncfb); /* Collect line */ confrm(&Tmpcsb); /* Confirm */ } /* *//* noise (CSBptr, gws) Parse a guide word string Accepts : CSBptr Address of command state block gws Address of guide word string Returns : TRUE if ok, FALSE if not */ noise (CSBptr, gws) CSB *CSBptr; /* Addr of command state block */ char *gws; /* Addr of guide word string */ { IND int i; /* Scratch */ Noicfb.CFB_DEF = gws; /* Store addr of guide word string */ i = COMND (CSBptr, &Noicfb); /* Get confirmation */ if (i == _CROK) /* If ok */ return (TRUE); /* return */ printf ("Invalid guide string\n"); /* Give error */ return (FALSE); /* Return */ } /* *//* confrm (CSBptr) Get confirmation Accepts : CSBptr Address of command state block Returns : TRUE if ok, FALSE if not */ confrm (CSBptr) CSB *CSBptr; /* Addr of command state block */ { IND int i; /* Scratch */ i = COMND (CSBptr, &Cfmcfb); /* Get confirmation */ if (i == _CROK) /* If ok */ return (TRUE); /* return */ printf (" Not confirmed; CR expected, not \""); echups (CSBptr); printf ("\"\n"); return (FALSE); /* Return */ } /* *//* COMNDi (CSBptr, CFBptr) Call COMND; say "invalid" if bad return. Accepts : CSBptr Address of the command state block to use CFBptr Address of command function block Returns : Value as returned by COMND */ COMNDi (CSBptr, CFBptr) CSB *CSBptr; /* Command state block addr */ CFB *CFBptr; /* Command function block addr */ { IND int i; /* Scratch */ i = COMND (CSBptr, CFBptr); /* do the COMND call */ if (i != _CROK) /* If it wasn't ok... */ { printf (" ??Invalid -- Can not recognize \""); echups (CSBptr); printf ("\"... use ? instead.\n"); } return (i); /* Return the result */ } /* *//* echups (CSBptr) Echo the unparsed portion of the command line Accepts : CSBptr Addr of CSB Returns : */ echups (CSBptr) CSB *CSBptr; /* Addr of command state block */ { IND int i; /* Scratch */ IND char *sptr; /* String ptr */ sptr = &CSBptr->CSB_BUF[CSBptr->CSB_PRS]; /* Get start address */ i = CSBptr->CSB_FLN - CSBptr->CSB_PRS; /* # of chars */ while (i--) putchar(*sptr++); } /* *//* venkfr (base, str) Fetches next user name given previous name in list This is a keyword fetch routine which is used in conjunction with the COMND general-storage-keyword facility. Accepts : base Base variable (ignored) str Address of previous event name ptr in list, or NULL to return the first one Returns : NULL if no more names in list address of event name pointer (in EVT block) if some. */ char **venkfr (base, str) char *base; /* A base address */ char **str; /* Addr of string pointer */ { IND EVT *EVTptr; /* Points to EVT block */ if (str == NULL) /* If null pointer */ EVTptr = Evthdr; /* use list header */ else /* Otherwise */ EVTptr = evnadr (str) -> EVT_FLK; /* get next in list */ while (EVTptr) /* Validate recipient */ { if (chkfor(EVTptr)) /* If OK */ break; /* then use it */ if (Usrnam) /* OK if from us, too */ if (EVTptr -> EVT_FRM) if (nccmp (Usrnam, EVTptr -> EVT_FRM) == 0) break; EVTptr = EVTptr -> EVT_FLK; /* try the next one */ } if (EVTptr) /* If any pointer */ return (&EVTptr -> EVT_NAM); /* return addr of name pointer */ else /* Otherwise */ return (NULL); /* Come up empty */ } /* *//* evnadr (str) Convert address of a EVT_NAM element to the address of the EVT block. Accepts : str Address of a EVT_NAM element. Returns : Address of a corresponding EVT block. */ EVT *evnadr (str) char **str; /* Points to str ptr */ { IND EVT *EVTptr; /* EVT ptr */ IND int i; /* integer */ IND char *cp1, *cp2; /* CHAR pointers */ cp1 = str; /* Get byte address */ EVTptr = str; /* Calculate offset from base */ cp2 = &EVTptr -> EVT_NAM; i = cp2-cp1; /* Byte offset */ cp1 = cp1-i; /* Adjust it the other way */ return (cp1); /* Return it. */ }