#include "config.h"
/*
 * Copyright (c) 1986, 2014 by The Trustees of Columbia University in
 * the City of New York.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  + Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *  + Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 *  + Neither the name of Columbia University nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.

 Author: Andrew Lowry
*/
/* cmtxt
**
** This module contains the default break table and handlers for
** parsing a line of text.  Parsing succeeds if the current input
** consists of characters allowed by the break table and terminated
** by a newline character.  Completion always beeps, and standard
** help is always the same.  If parsing succeeds, the line of text,
** up to but not including the newline character, is copied into
** the atom buffer.
**
** The break table determines which characters are allowed in the
** text.  The _br1st array specifies characters allowed in the first
** position, and _brrst specifies characters allowed in subsequent
** positions.  The default break table allows all printing characters
** in the interior of the text, and all but question mark at the front
** (so help works at the beginning, but not after the field has begun).
** Also, space and tab are break characters in the first position, so
** they will be skipped by the input loop.
**/

#define TXTERR			/* declare cmtxt parse errors here */

#include "ccmdlib.h"		/* get ccmd package symbols */
#include "cmfncs.h"		/* and internal symbols */

/* Forward declarations for handlers */

PASSEDSTATIC int txtcplt ARGS((char *text, int textlen, fdb *fdbp,
	 int full, const char **cplt, int *cpltlen));
PASSEDSTATIC int txthlp ARGS((char *text, int textlen, fdb *fdbp,
	 int cust, int lines));
PASSEDSTATIC int txtprs ARGS((char *text, int textlen, fdb *fdbp,
	 int *parselen, pval *value));

/* standard break table */

static brktab txtbrk = {
  {					/* print chars except ?, space, tab */
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
  },
  {					/* all print characters */
    0xff, 0xbf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
  }
};

ftspec ft_txt = { txtprs, txthlp, txtcplt, 0, &txtbrk }; /* handler structure */



/* txtprs
**
** Purpose:
**   Attempt to parse a line of text.  Succeeds if the current input contains
**   a newline character, and if the text up to that newline obeys the break
**   table in effect.  A successful parse turns off the CM_CFM flag as a
**   side effect.
**/

PASSEDSTATIC int
#if HAVE_STDC
txtprs(char *text, int textlen, fdb *fdbp, int *parselen, pval *value)
#else /* K&R style */
txtprs(text,textlen,fdbp,parselen,value)
char *text;
int textlen;
fdb *fdbp;
int *parselen;
pval *value;
#endif /* HAVE_STDC */
{
  int nlpos;				/* position of newline char */
  int i;				/* for scanning text */
  brktab *btab;				/* break table to use */

  if (textlen == 0)
    return(CMxINC);			/* incomplete parse */
  for (nlpos = 0; nlpos < textlen; nlpos++) /* search text for a newline */
    if (text[nlpos] == NEWLINE)		/* fails if quoted */
      break;				/* found it */
  if (nlpos >= textlen)
    return(CMxINC);			/* no newline in text */
  if ((btab = fdbp->_cmbrk) == NULL) 	/* get user specified break table */
    btab = &txtbrk;			/* or used standard */
  for (i = 0; i < nlpos; i++)		/* check included text */
    if ((text[i] & CC_QUO) == 0)	/* accept all quoted chars */
      if (BREAK(btab,text[i],i))
        return(TXTxNP);			/* bad characters in text */
  for (i = 0; i < nlpos; i++)		/* copy to atom buffer */
    if (i >= cmcsb._cmabc-1)		/* leave room for null at end */
      return(CMxAOVF);			/* no room */
    else
      cmcsb._cmabp[i] = text[i] & CC_CHR; /* else copy the text */
  cmcsb._cmabp[nlpos] = NULCHAR;	/* tie off with a null */
  cmcsb._cmflg |= CM_NAC;		/* core routines don't copy to atom */
  cmcsb._cmflg &= ~CM_CFM;		/* no longer confirmed */
  *parselen = nlpos;			/* number of chars consumed */
  value->_pvstr = cmcsb._cmabp;		/* set parse value */
  return(CMxOK);			/* good parse */
}



/* txthlp
**
** Always the same thing...
**/

PASSEDSTATIC int
#if HAVE_STDC
txthlp(char *text, int textlen, fdb *fdbp, int cust, int lines)
#else /* K&R style */
txthlp(text,textlen,fdbp,cust, lines)
char *text;
int textlen,cust;
fdb *fdbp;
int lines;
#endif /* HAVE_STDC */
{
  cmxputs("line of text");
  return(lines -1);
}



/* txtcplt - Always beep
**/

PASSEDSTATIC int
#if HAVE_STDC
txtcplt(char *text, int textlen, fdb *fdbp, int full, const char **cplt, int *cpltlen)
#else /* K&R style */
txtcplt(text,textlen,fdbp,full,cplt,cpltlen)
char *text;
const char **cplt;
int textlen,full,*cpltlen;
fdb *fdbp;
#endif /* HAVE_STDC */
{
  *cplt = NULL;
  return(CMP_BEL);		/* beep at them */
}
