/***************************************************************************
 *                                                                         *
 *   CNCUTL.C                                                              *
 *                                                                         *
 *   Copyright (c) 1988-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   These are the Worldgroup command concatenation utilities.             *
 *                                                                         *
 *                                 - T. Stryker & S. Brinker 7/5/88        *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"

#define FILREV "$Revision: 4 $"

                                   /* constants for backward compatibility */
#define SIGIDC '/'                 /*   forum name identifier character    */
#define SIGSIZ 10                  /*   max size of SIG names (incl. '\0') */

CHAR *nxtcmd;                      /* pointer to next char. for command con*/

INT maxcat,                        /* maximum number of concat'd commands  */
    numcat;                        /* number of commands concat'd so far   */

VOID
bgncnc(VOID)                  /* prepare input for command concatenation   */
{
     nxtcmd=margv[0];
     clrprf();
     rstrin();
}

INT
endcnc(VOID)                  /* check for end of command concatenation    */
{
     if (margc == 0) {
          return(1);
     }
     movmem(nxtcmd,input,strlen(nxtcmd)+1);
     parsin();
     if (++numcat >= maxcat) {
          return(1);
     }
     return(margc == 0);
}

CHAR
cncchr(VOID)                  /* gobble-character command concatenation    */
{
     CHAR retval;

     if ((retval=toupper(*nxtcmd)) != '\0') {
          nxtcmd++;
     }
     return(retval);
}

INT
cncint(VOID)                  /* atoi() look-alike for command concat.     */
{
     return((INT)cnclon());
}

LONG
cnclon(VOID)                  /* atol() look-alike for command concat.     */
{
     LONG retval=0L;

     while (isdigit(*nxtcmd)) {
          retval=retval*10+*(nxtcmd++)-'0';
     }
     return(retval);
}

CHAR *
cncuid(VOID)                  /* grab a userid; prepares for Btrieve too   */
{
     CHAR *rp;
     static CHAR retval[UIDSIZ];

     if (*nxtcmd == SIGIDC) {
          return(cncsig());
     }
     setmem(retval,UIDSIZ,0);
     for (rp=retval ; isuidc(*nxtcmd) && rp-retval < UIDSIZ-1 ; nxtcmd++,rp++) {
          *rp=*nxtcmd;
     }
     return(retval);
}

CHAR *
cncsig(VOID)                  /* grab a sig name with or w/o leading slash */
{
     CHAR *rp;
     static CHAR retval[SIGSIZ];

     setmem(retval,SIGSIZ,0);
     if (*nxtcmd == SIGIDC) {
          nxtcmd++;
     }
     retval[0]=SIGIDC;
     rp=retval+1;
     while (*nxtcmd != '\0' && *nxtcmd != ' ' && rp-retval < SIGSIZ-1) {
          *rp++=*nxtcmd++;
     }
     return(retval);
}

CHAR
cncyesno(VOID)                /* yes/no -- returns a char, chomps rest too */
{
     CHAR retval;
     struct lingo *lptr;

     lptr=languages[clingo];
     if ((retval=cncchr()) == toupper(lptr->yes[0])) {
          if (strlen(lptr->yes) > 1 && sameto(&lptr->yes[1],nxtcmd)) {
               nxtcmd+=strlen(&lptr->yes[1]);
          }
          retval='Y';
     }
     else if (retval == toupper(lptr->no[0])) {
          if (strlen(lptr->no) > 1 && sameto(&lptr->no[1],nxtcmd)) {
               nxtcmd+=strlen(&lptr->no[1]);
          }
          retval='N';
     }
     return(retval);
}

CHAR *
cncwrd(VOID)                  /* grab one space-delimited word             */
{
     CHAR *rp;
     static CHAR retval[UIDSIZ];

     rp=retval;
     setmem(retval,UIDSIZ,0);
     while (*nxtcmd != '\0' && *nxtcmd != ' ' && rp-retval < UIDSIZ-1) {
          *rp++=*nxtcmd++;
     }
     return(retval);
}

CHAR *
cncbgw(                       /* grab a big space-delimited word           */
CHAR *buffer,                 /* buffer where to put it (returned val too) */
INT sizbuf)                   /* size for buffer, including NUL terminator */
{
     CHAR *rp;

     setmem(rp=buffer,sizbuf,0);
     while (*nxtcmd != '\0' && *nxtcmd != ' ' && rp-buffer < sizbuf-1) {
          *rp++=*nxtcmd++;
     }
     return(buffer);
}

CHAR *
cncall(VOID)                  /* grab rest of input; ends concatenation    */
{
     CHAR *retval;

     retval=nxtcmd;
     nxtcmd="";
     return(retval);
}

CHAR
morcnc(VOID)                  /* check for more commands to be concat'd    */
{                             /*  (rets 0 if not or the next char if so)   */
     if (numcat >= maxcat) {
          return(0);
     }
     while (isspace(*nxtcmd)) {
          nxtcmd++;
     }
     return(toupper(*nxtcmd));
}

INT
cnchex(VOID)                  /* take a hex number and return decimal amt  */
{
     INT i,retval=0,flag=0;
     static CHAR hex[6]={
          'A','B','C','D','E','F'
     };

     while (1) {
          if (isdigit(*nxtcmd)) {
               retval=(retval<<4)+(*nxtcmd-'0');
          }
          else {
               for (i=0 ; i < 6 ; i++) {
                    if (toupper(*nxtcmd) == hex[i]) {
                         retval=(retval<<4)+10+i;
                         break;
                    }
               }
               if (i == 6) {
                    return(flag && (*nxtcmd == ' ' || *nxtcmd == '\0') ? retval
                                                                       : -1);
               }
          }
          nxtcmd++;
          flag=1;
     }
}

CHAR *
cncnum(VOID)                       /* return an ASCII-coded decimal        */
{
     INT i=0;
     static CHAR retval[12];

     if (*nxtcmd == '-') {
          retval[i++]=*(nxtcmd++);
     }
     while (isdigit(*nxtcmd) && i < 11) {
          retval[i++]=*(nxtcmd++);
     }
     retval[i]='\0';
     return(retval);
}

INT
cnclng(VOID)                  /* return a language index (or -1=invalid)   */
{
     INT ilingo;
     CHAR *cp;

     if (alldgs(cp=cncwrd()) && (ilingo=atoi(cp)-1) >= 0 && ilingo < nlingo) {
          return(ilingo);
     }
     return(lngfnd(cp));
}
