%{
#if !defined(lint) && !defined(__INSIGHT__)
static char sos__rcsid[] = "tok.l,v 1.1.1.1 1995/06/16 21:10:48 seth Exp";
static char sos__copyright[] = "Copyright (c) 1994, 1995 SOS Corporation";
static char sos__contact[] = "SOS Corporation <sos-info@soscorp.com> +1 800 SOS UNIX";
#endif /* not lint */

/*
 * ++Copyright Released Product++
 *
 * Copyright (c) 1994, 1995 Sources of Supply Corporation ("SOS").
 * All rights reserved.
 *
 * The SOS Released Product License Agreement specifies the terms and
 * conditions for redistribution.  You may find the License Agreement
 * in the file LICENSE.
 *
 * SOS Corporation
 * 461 5th Ave.; 16th floor
 * New York, NY 10017
 *
 * +1 800 SOS UNIX
 * <sos-info@soscorp.com>
 *
 * --Copyright Released Product--
 */

/*
 * Break the configuration file into tokens
 */

#include "interface.h"
#include "readconf.h"
#include "parse.tab.h"

extern char *startfile;
extern int newline;

#define MAXDEPTH 10
#define MAX_STR_CONST 1024

char **curfile = &startfile;
YY_BUFFER_STATE include_stack[MAXDEPTH];
int include_init = 0;
char *include_stack_name[MAXDEPTH];
int include_newline_stack[MAXDEPTH];
int include_stack_ptr = 0;
char string_buf[MAX_STR_CONST];
char *string_buf_ptr;

void
FreeIncludeFiles()
{
  int x;

  if (!include_init)
    {
      InitIncludeFiles();
      return;
    }

  for(x=0;x<MAXDEPTH;x++)
    {
      if (include_stack_name[x])
	free(include_stack_name[x]);
      if (include_stack[x])
	yy_delete_buffer(include_stack[x]);
    }

  InitIncludeFiles();
}

void
InitIncludeFiles()
{
  int x;

  include_init = 1;
  include_stack_ptr = 0;

  for(x=0;x<MAXDEPTH;x++)
    {
      include_stack_name[x] = NULL;
      include_newline_stack[x] = 0;
      include_stack[x] = NULL;
    }
}

%}
%x zzstr sosincl sosts sosds sosas sosss sosgs sosus

%%
%{
/**********************************************************************
 * Series of statements to handle %include "filename"                 *
 **********************************************************************/
%}
^"%include"[ \t]+\"	string_buf_ptr = string_buf; BEGIN(sosincl);
<sosincl>\n		{ sprintf(bs_auth_extended,"Unterminated string constant in #include");
			  return(_ERROR); }
<sosincl>[^\"\\\n]+	{ strncpy(string_buf_ptr,yytext,yyleng); string_buf_ptr+=yyleng; }
<sosincl>\"		{ /* Saw closing quote -- all done */
			  char *tmp;
			  BEGIN(INITIAL);
			  if (!include_init)
			    InitIncludeFiles();
			  *string_buf_ptr = '\0';
			  if (include_stack_ptr >= MAXDEPTH)
			    {
			      sprintf(bs_auth_extended,"#includes nested too deeply\n");
			      return(_ERROR);
			    }

			  include_newline_stack[include_stack_ptr] = newline;
			  newline = 1;
			  include_stack_name[include_stack_ptr] = *curfile;
			  include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
			  tmp = strdup(string_buf);
			  curfile = &tmp;

			  dprintf("Switching to file %s\n",*curfile);

			  if (AddFiles(string_buf) != AUTH_SUCCEED)
			    {
			      return(_ERROR);
			    }

			  if ((yyin = fopen(string_buf,"r")) == NULL)
			    {
			      perror("fopen");
			      sprintf(bs_auth_extended,"Cannot open include file %s\n",string_buf);
			      return(_ERROR);
			    }

			  yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
			}
<<EOF>>			{
                          if (--include_stack_ptr < 0)
			    {
			      /* XXX - Is yyrestart a good idea? */
			      yyrestart(yyin);
			      yyterminate();
			    }
			  else
			    {
			      if (fclose(yyin))
				{
				  sprintf(bs_auth_extended,"Config file cannot be closed (%d)",errno);
				  return(AUTH_ERROR);
				}
			      yy_delete_buffer( YY_CURRENT_BUFFER );
			      yy_switch_to_buffer(include_stack[include_stack_ptr]);
			      free(*curfile);
			      curfile = &include_stack_name[include_stack_ptr];
			      newline = include_newline_stack[include_stack_ptr];

			      dprintf("Resuming file %s\n",*curfile);
			    }
			}


%{
/**********************************************************************
 * Series of statements to handle "quoted" strings                    *
 **********************************************************************/
%}
\"			string_buf_ptr = string_buf; BEGIN(zzstr);
<zzstr>\"		{ /* Saw closing quote -- all done */
			  BEGIN(INITIAL);
			  *string_buf_ptr = '\0';
			  dprintf("Matched _QuotedString [%s]\n",string_buf); return(_QuotedString);
			}
<zzstr>\n		{ sprintf(bs_auth_extended,"Unterminated string constant (%s)\n",string_buf);
			  return(_ERROR); }
<zzstr>[^\\\n\"]+	{ strncpy(string_buf_ptr,yytext,yyleng); string_buf_ptr+=yyleng; }


%{
/**********************************************************************
* Comments  (# to EOL)                                                *
 **********************************************************************/
%}
"#"[^\\\n]*$		dprintf("Found comment [%s]\n",yytext); /* Comment */


%{
/**********************************************************************
 * Series of statements to handle Days of the week                    *
 **********************************************************************/
%}
"Mon"			{ dprintf("Matched _Mon [%s]\n", yytext); return(_Mon); }
"Tue"			{ dprintf("Matched _Tue [%s]\n", yytext); return(_Tue); }
"Wed"			{ dprintf("Matched _Wed [%s]\n", yytext); return(_Wed); }
"Thu"			{ dprintf("Matched _Thu [%s]\n", yytext); return(_Thu); }
"Fri"			{ dprintf("Matched _Fri [%s]\n", yytext); return(_Fri); }
"Sat"			{ dprintf("Matched _Sat [%s]\n", yytext); return(_Sat); }
"Sun"			{ dprintf("Matched _Sun [%s]\n", yytext); return(_Sun); }


%{
/**********************************************************************
 * Series of statements to handle redefining # of time groups         *
 **********************************************************************/
%}
^"%timesize"[ \t]+	BEGIN(sosts);
<sosts>[^0-9]+		{ sprintf(bs_auth_extended,"%%timesize corrupt (%s)",yytext); return(_ERROR); }
<sosts>[0-9]+		{ BEGIN(INITIAL); TimeSize.ht_table_entries = atoi(yytext);return(_BOF);}


%{
/**********************************************************************
 * Series of statements to handle redefining # of date groups         *
 **********************************************************************/
%}
^"%datesize"[ \t]+	BEGIN(sosds);
<sosds>[^0-9]+		{ sprintf(bs_auth_extended,"%%datesize corrupt (%s)",yytext); return(_ERROR); }
<sosds>[0-9]+		{ BEGIN(INITIAL); DateSize.ht_table_entries = atoi(yytext);return(_BOF);}


%{
/**********************************************************************
 * Series of statements to handle redefining # of address groups      *
 **********************************************************************/
%}
^"%addrsize"[ \t]+	BEGIN(sosas);
<sosas>[^0-9]+		{ sprintf(bs_auth_extended,"%%addrsize corrupt (%s)",yytext); return(_ERROR); }
<sosas>[0-9]+		{ BEGIN(INITIAL); AddrSize.ht_table_entries = atoi(yytext);return(_BOF);}


%{
/**********************************************************************
 * Series of statements to handle redefining # of serv groups      *
 **********************************************************************/
%}
^"%servsize"[ \t]+	BEGIN(sosss);
<sosss>[^0-9]+		{ sprintf(bs_auth_extended,"%%servsize corrupt (%s)",yytext); return(_ERROR); }
<sosss>[0-9]+		{ BEGIN(INITIAL); ServSize.ht_table_entries = atoi(yytext);return(_BOF);}


%{
/**********************************************************************
 * Series of statements to handle redefining # of group groups      *
 **********************************************************************/
%}
^"%groupsize"[ \t]+	BEGIN(sosgs);
<sosgs>[^0-9]+		{ sprintf(bs_auth_extended,"%%groupsize corrupt (%s)",yytext); return(_ERROR); }
<sosgs>[0-9]+		{ BEGIN(INITIAL); GroupSize.ht_table_entries = atoi(yytext);return(_BOF); }


%{
/**********************************************************************
 * Series of statements to handle redefining # of users               *
 **********************************************************************/
%}
^"%usersize"[ \t]+	BEGIN(sosus);
<sosus>[^0-9]+		{ sprintf(bs_auth_extended,"%%usersize corrupt (%s)",yytext); return(_ERROR); }
<sosus>[0-9]+		{ BEGIN(INITIAL); UserSize.ht_table_entries = atoi(yytext);return(_BOF);}



%{
/**********************************************************************
 * Series of statements to match strings and numbers                  *
 **********************************************************************/
%}
[a-zA-Z][a-zA-Z0-9_]*	{ dprintf("Matched _String [%s]\n",yytext); return(_String); }
[0-9]+			{ dprintf("Matched _Number [%s]\n",yytext); return(_Number); }



%{
/**********************************************************************
 * Series of statements to handle special characters                  *
 **********************************************************************/
%}
":"			{ dprintf("Matched _Colon [%s]\n",yytext); return(_Colon); }
"("			{ dprintf("Matched _Leftp [%s]\n",yytext); return(_Leftp); }
")"			{ dprintf("Matched _Rightp [%s]\n",yytext); return(_Rightp); }
","			{ dprintf("Matched _Delim [%s]\n",yytext); return(_Delim); }
"."			{ dprintf("Matched _Dot [%s]\n",yytext); return(_Dot); }
"+"			{ dprintf("Matched _Plus [%s]\n",yytext); return(_Plus); }
"*"			{ dprintf("Matched _Deref [%s]\n",yytext); return(_Deref); }
"-"			{ dprintf("Matched _Minus [%s]\n",yytext); return(_Minus); }
"/"			{ dprintf("Matched _Slash [%s]\n",yytext); return(_Slash); }
"="			{ dprintf("Matched _Equal [%s]\n",yytext); return(_Equal); }
^"%%"			{ dprintf("Matched _MARK [%s]\n",yytext); return(_MARK); }
"\n"+			{ dprintf("Matched _EOL\n"); return(_EOL); }


%{
/**********************************************************************
 * Discard whitespace                                                 *
 **********************************************************************/
%}
[ \t]+			/* naught */

.			{ sprintf(bs_auth_extended,"Illegal character %s in file %s", yytext,*curfile); return(_ERROR); }
