/*      Copyright (C) 2001, 2002, 2003, 2004 Stijn van Dongen
 *
 * This file is part of Zoem. You can redistribute and/or modify Zoem under the
 * terms of the GNU General Public License;  either version 2 of the License or
 * (at your option) any later  version.  You should have received a copy of the
 * GPL along with Zoem, in the file COPYING.
*/

#ifndef zoem_parse_h__
#define zoem_parse_h__

#include "segment.h"

#include "util/ting.h"

#define  YAM_ARG_MAX 10

extern mcxTing      key_and_args_g[];

extern mcxTing*     key_g;

extern mcxTing*     arg1_g;
extern mcxTing*     arg2_g;
extern mcxTing*     arg3_g;
extern mcxTing*     arg4_g;
extern mcxTing*     arg5_g;
extern mcxTing*     arg6_g;
extern mcxTing*     arg7_g;
extern mcxTing*     arg8_g;
extern mcxTing*     arg9_g;
extern mcxTing*     arg10_g;

extern int          n_args_g;
extern int          tracing_g;

yamSeg*  yamDoKey
(  yamSeg *seg
)  ;


int yamFindKey
(  yamSeg*  seg
)  ;


int yamParseScopes
(  yamSeg*  seg
,  int      n
,  int      delta
)  ;


/* ****************************************************************** */

/*
 * The stuff below was meant as a stack-based (non-global) replacement for
 * parseScopes. The concept was created at the same time when I was considering
 * a fully stack-based zoem (without the global arg1_g etc).  However, each use
 * of yamElemsParse instantiates an appropriate amount of mcxTings, that need
 * to be cleared with yamElemsClear afterwards. That is a bit annoying.
 *
 * The idea for making zoem stack based was to let both yamDigest and yamOutput
 * declare an mcxTing args[10] on the stack and pass that to down to parseKey,
 * expandKey, expandUser, zoem primitives, and possibly a few others.  Now zoem
 * will never be threaded, and the arg1_g etc are handy as 'scratch' space. So
 * as it stands I am not going to make a stack-zoem after all.
 *
 * I keep one or two instances of yamElemsParse alive: it is used in expandTr2
 * and expandSplit2.
 *
 * The current yamElemsParse has the disadvantage that you can not specify what
 * is allowed, e.g. p-s-s or s-s (as in Tr2), you have to parse and do
 * validation later.  Another routine yamElemsValidate could do that job, but
 * is now missing.
*/


typedef struct
{  mcxTing*    txt
;  mcxbool     plain
;  int         n_scopes    /* nr of scopes after this scope or this plain */
;  
}  yamElem     ;

void yamElemsPrint
(  yamElem*    elems
,  int         n_filled
)  ;

void yamElemsClear
(  yamElem*    elems
,  int         n_filled
)  ;

/*
 * when mode is ALLOW_MIX it will parse 'foo{bar}{baz}duh{zit}{zot}{zat}'.
 * beware: it will even parse 'foo baz {bar} duh doh {that}',
 * which is p-p-s-p-p-s (p for plain, s for scope).
*/

#define YAM_ALLOW_MIX   1
#define YAM_SCOPES_ONLY 2

int yamElemsParse
(  yamSeg*  seg
,  int      n_elems
,  yamElem* elems
,  mcxmode  mode
)  ;

/* ****************************************************************** */


yamSeg* yamExpandKey
(  yamSeg*   seg
)  ;

yamSeg*  yamFormatted1
(  yamSeg*  seg
,  const char* arg
)  ;

int checkusrsig
(  char* p
,  int   len
,  int*  k
)  ;

int checkusrname
(  char* p
,  int   len
)  ;

int checkusrtag
(  char* p
,  int   len
,  int*  k
)  ;

int checkusrcall
(  mcxTing* txt
,  int offset
)  ;

int seescope
(  char* p
,  int   len
)  ;


void mod_parse_init
(  int   traceflags
)  ;

void mod_parse_exit
(  void
)  ;

int yamTracingSet
(  int  traceflags
)  ;

void traceputlines
(  const char* s
,  int len
)  ;

void traceput
(  const char* s
,  mcxTing* txt
)  ;

void yamScratchStats
(  void
)  ;

#endif

