/*
 * Copyright (c) 2009, Sun Microsystems, Inc.
 * 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 Sun Microsystems, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#if 0
static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
#endif

/*
 * rpc_parse.c, Parser for the RPC protocol compiler 
 * Copyright (C) 1987 Sun Microsystems, Inc.
 */
#include <stdio.h>
#include <string.h>
#include "rpc/types.h"
#include "rpc_scan.h"
#include "rpc_parse.h"
#include "rpc_util.h"

#define ARGNAME "arg"

/*
extern char *make_argname();
extern char *strdup();
 */

static void	isdefined(definition *defp);
static void	def_struct(definition *defp);
static void	def_program(definition *defp);
static void	def_enum(definition *defp);
static void	def_const(definition *defp);
static void	def_union(definition *defp);
static void	check_type_name(char *name, int new_type);
static void	def_typedef(definition *defp);
static void	get_declaration(declaration *dec, defkind dkind);
static void	get_prog_declaration(declaration *dec, defkind dkind, int num);
static void	get_type(char **prefixp, char **typep, defkind dkind);
static void	unsigned_dec(char **typep);

/*
 * return the next definition you see
 */
definition *
get_definition(void)
{
	definition *defp;
	token tok;

	defp = ALLOC(definition);
	get_token(&tok);
	switch (tok.kind) {
	case TOK_STRUCT:
		def_struct(defp);
		break;
	case TOK_UNION:
		def_union(defp);
		break;
	case TOK_TYPEDEF:
		def_typedef(defp);
		break;
	case TOK_ENUM:
		def_enum(defp);
		break;
	case TOK_PROGRAM:
		def_program(defp);
		break;
	case TOK_CONST:
		def_const(defp);
		break;
	case TOK_EOF:
		free(defp);
		return (NULL);
	default:
		error("definition keyword expected");
	}
	scan(TOK_SEMICOLON, &tok);
	isdefined(defp);
	return (defp);
}

static void
isdefined(definition *defp)
{
	STOREVAL(&defined, defp);
}

static void
def_struct(definition *defp)
{
	token tok;
	declaration dec;
	decl_list *decls;
	decl_list **tailp;

	defp->def_kind = DEF_STRUCT;

	scan(TOK_IDENT, &tok);
	defp->def_name = tok.str;
	scan(TOK_LBRACE, &tok);
	tailp = &defp->def.st.decls;
	do {
		get_declaration(&dec, DEF_STRUCT);
		decls = ALLOC(decl_list);
		decls->decl = dec;
		*tailp = decls;
		tailp = &decls->next;
		scan(TOK_SEMICOLON, &tok);
		peek(&tok);
	} while (tok.kind != TOK_RBRACE);
	get_token(&tok);
	*tailp = NULL;
}

static void
def_program(definition *defp)
{
	token tok;
	declaration dec;
	decl_list *decls;
	decl_list **tailp;
	version_list *vlist;
	version_list **vtailp;
	proc_list *plist;
	proc_list **ptailp;
	int num_args;
	bool_t isvoid = FALSE; /* whether first argument is void */
	defp->def_kind = DEF_PROGRAM;
	scan(TOK_IDENT, &tok);
	defp->def_name = tok.str;
	scan(TOK_LBRACE, &tok);
	vtailp = &defp->def.pr.versions;
	tailp = &defp->def.st.decls;
	scan(TOK_VERSION, &tok);
	do {
		scan(TOK_IDENT, &tok);
		vlist = ALLOC(version_list);
		vlist->vers_name = tok.str;
		scan(TOK_LBRACE, &tok);
		ptailp = &vlist->procs;
		do {
			/* get result type */
			plist = ALLOC(proc_list);
			get_type(&plist->res_prefix, &plist->res_type, 
				 DEF_PROGRAM);
			if (streq(plist->res_type, "opaque")) {
				error("illegal result type");
			}
			scan(TOK_IDENT, &tok);
			plist->proc_name = tok.str;
			scan(TOK_LPAREN, &tok);
			/* get args - first one*/
			num_args = 1;
			isvoid = FALSE;
			/* type of DEF_PROGRAM in the first 
			 * get_prog_declaration and DEF_STURCT in the next
			 * allows void as argument if it is the only argument
			 */
			get_prog_declaration(&dec, DEF_PROGRAM, num_args);
			if (streq(dec.type, "void"))
			  isvoid = TRUE;
			decls = ALLOC(decl_list);
			plist->args.decls = decls;
			decls->decl = dec;
			tailp = &decls->next;
			/* get args */
			while(peekscan(TOK_COMMA, &tok)) {
			  num_args++;
			  get_prog_declaration(&dec, DEF_STRUCT, 
					       num_args);
			  decls = ALLOC(decl_list);
			  decls->decl = dec;
			  *tailp = decls;
			  if (streq(dec.type, "void"))
			    isvoid = TRUE;
			  tailp = &decls->next;
			}
			/* multiple arguments are only allowed in newstyle */
			if( !newstyle && num_args > 1 ) {
			  error("only one argument is allowed" );
			}
			if (isvoid && num_args > 1) { 
			  error("illegal use of void in program definition");
			}
			*tailp = NULL;
			scan(TOK_RPAREN, &tok);
			scan(TOK_EQUAL, &tok);
			scan_num(&tok);
			scan(TOK_SEMICOLON, &tok);
			plist->proc_num = tok.str;
			plist->arg_num = num_args;
			*ptailp = plist;
			ptailp = &plist->next;
			peek(&tok);
		} while (tok.kind != TOK_RBRACE);
		*ptailp = NULL;
		*vtailp = vlist;
		vtailp = &vlist->next;
		scan(TOK_RBRACE, &tok);
		scan(TOK_EQUAL, &tok);
		scan_num(&tok);
		vlist->vers_num = tok.str;
		/* make the argument structure name for each arg*/
		for(plist = vlist->procs; plist != NULL; 
		    plist = plist->next) {
			plist->args.argname = make_argname(plist->proc_name,
							   vlist->vers_num); 
			/* free the memory ??*/
		}
		scan(TOK_SEMICOLON, &tok);
		scan2(TOK_VERSION, TOK_RBRACE, &tok);
	} while (tok.kind == TOK_VERSION);
	scan(TOK_EQUAL, &tok);
	scan_num(&tok);
	defp->def.pr.prog_num = tok.str;
	*vtailp = NULL;
}


static void
def_enum(definition *defp)
{
	token tok;
	enumval_list *elist;
	enumval_list **tailp;

	defp->def_kind = DEF_ENUM;
	scan(TOK_IDENT, &tok);
	defp->def_name = tok.str;
	scan(TOK_LBRACE, &tok);
	tailp = &defp->def.en.vals;
	do {
		scan(TOK_IDENT, &tok);
		elist = ALLOC(enumval_list);
		elist->name = tok.str;
		elist->assignment = NULL;
		scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
		if (tok.kind == TOK_EQUAL) {
			scan_num(&tok);
			elist->assignment = tok.str;
			scan2(TOK_COMMA, TOK_RBRACE, &tok);
		}
		*tailp = elist;
		tailp = &elist->next;
	} while (tok.kind != TOK_RBRACE);
	*tailp = NULL;
}

static void
def_const(definition *defp)
{
	token tok;

	defp->def_kind = DEF_CONST;
	scan(TOK_IDENT, &tok);
	defp->def_name = tok.str;
	scan(TOK_EQUAL, &tok);
	scan2(TOK_IDENT, TOK_STRCONST, &tok);
	defp->def.co = tok.str;
}

static void
def_union(definition *defp)
{
  token tok;
  declaration dec;
  case_list *cases;
  case_list **tailp;

  defp->def_kind = DEF_UNION;
  scan(TOK_IDENT, &tok);
  defp->def_name = tok.str;
  scan(TOK_SWITCH, &tok);
  scan(TOK_LPAREN, &tok);
  get_declaration(&dec, DEF_UNION);
  defp->def.un.enum_decl = dec;
  tailp = &defp->def.un.cases;
  scan(TOK_RPAREN, &tok);
  scan(TOK_LBRACE, &tok);
  scan(TOK_CASE, &tok);
  while (tok.kind == TOK_CASE) {
    scan2(TOK_IDENT, TOK_CHARCONST, &tok);
    cases = ALLOC(case_list);
    cases->case_name = tok.str;
    scan(TOK_COLON, &tok);
    /* now peek at next token */
    if(peekscan(TOK_CASE,&tok))
      {

	do 
	  {
	    scan2(TOK_IDENT, TOK_CHARCONST, &tok);
	    cases->contflag=1;	/* continued case statement */
	    *tailp = cases;
	    tailp = &cases->next;
	    cases = ALLOC(case_list);
	    cases->case_name = tok.str;
	    scan(TOK_COLON, &tok);
      
	  }while(peekscan(TOK_CASE,&tok));
      }

    get_declaration(&dec, DEF_UNION);
    cases->case_decl = dec;
    cases->contflag=0;		/* no continued case statement */
    *tailp = cases;
    tailp = &cases->next;
    scan(TOK_SEMICOLON, &tok);

    scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
  }
  *tailp = NULL;
  if (tok.kind == TOK_DEFAULT) {
    scan(TOK_COLON, &tok);
    get_declaration(&dec, DEF_UNION);
    defp->def.un.default_decl = ALLOC(declaration);
    *defp->def.un.default_decl = dec;
    scan(TOK_SEMICOLON, &tok);
    scan(TOK_RBRACE, &tok);
  } else {
    defp->def.un.default_decl = NULL;
  }
}

static char* reserved_words[] =
{
  "array",
  "bytes",
  "destroy",
  "free",
  "getpos",
  "inline",
  "pointer",
  "reference",
  "setpos",
  "sizeof",
  "union",
  "vector",
  NULL
  };

static char* reserved_types[] =
{
  "opaque",
  "string",
  NULL
  };

/* check that the given name is not one that would eventually result in
   xdr routines that would conflict with internal XDR routines. */
static void
check_type_name(char *name, int new_type)
{
  int i;
  char tmp[100];

  for( i = 0; reserved_words[i] != NULL; i++ ) {
    if( strcmp( name, reserved_words[i] ) == 0 ) {
      sprintf(tmp, 
	      "illegal (reserved) name :\'%s\' in type definition", name );
      error(tmp);
    }
  }
  if( new_type ) {
    for( i = 0; reserved_types[i] != NULL; i++ ) {
      if( strcmp( name, reserved_types[i] ) == 0 ) {
	sprintf(tmp, 
		"illegal (reserved) name :\'%s\' in type definition", name );
	error(tmp);
      }
    }
  }
}

static void
def_typedef(definition *defp)
{
	declaration dec;

	defp->def_kind = DEF_TYPEDEF;
	get_declaration(&dec, DEF_TYPEDEF);
	defp->def_name = dec.name;
	check_type_name( dec.name, 1 );
	defp->def.ty.old_prefix = dec.prefix;
	defp->def.ty.old_type = dec.type;
	defp->def.ty.rel = dec.rel;
	defp->def.ty.array_max = dec.array_max;
}

static void
get_declaration(declaration *dec, defkind dkind)
{
	token tok;

	get_type(&dec->prefix, &dec->type, dkind);
	dec->rel = REL_ALIAS;
	if (streq(dec->type, "void")) {
		return;
	}

	check_type_name( dec->type, 0 );

	scan2(TOK_STAR, TOK_IDENT, &tok);
	if (tok.kind == TOK_STAR) {
		dec->rel = REL_POINTER;
		scan(TOK_IDENT, &tok);
	}
	dec->name = tok.str;
	if (peekscan(TOK_LBRACKET, &tok)) {
		if (dec->rel == REL_POINTER) {
			error("no array-of-pointer declarations -- use typedef");
		}
		dec->rel = REL_VECTOR;
		scan_num(&tok);
		dec->array_max = tok.str;
		scan(TOK_RBRACKET, &tok);
	} else if (peekscan(TOK_LANGLE, &tok)) {
		if (dec->rel == REL_POINTER) {
			error("no array-of-pointer declarations -- use typedef");
		}
		dec->rel = REL_ARRAY;
		if (peekscan(TOK_RANGLE, &tok)) {
			dec->array_max = "~0";	/* unspecified size, use max */
		} else {
			scan_num(&tok);
			dec->array_max = tok.str;
			scan(TOK_RANGLE, &tok);
		}
	}
	if (streq(dec->type, "opaque")) {
		if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
			error("array declaration expected");
		}
	} else if (streq(dec->type, "string")) {
		if (dec->rel != REL_ARRAY) {
			error("variable-length array declaration expected");
		}
	}
}


static void
get_prog_declaration(declaration *dec, defkind dkind, int num)
{
	token tok;
	char name[10]; /* argument name */

	if (dkind == DEF_PROGRAM) { 
	  peek(&tok);
	  if (tok.kind == TOK_RPAREN) { /* no arguments */
	    	dec->rel = REL_ALIAS;
		dec->type = "void";
		dec->prefix = NULL;
		dec->name = NULL;
		return;
	      }
	}
	get_type(&dec->prefix, &dec->type, dkind);
	dec->rel = REL_ALIAS;
	if (peekscan(TOK_IDENT, &tok))  /* optional name of argument */
		strcpy(name, tok.str);
	else 
		sprintf(name, "%s%d", ARGNAME, num); /* default name of argument */

	dec->name = (char *) strdup(name); 
	
	if (streq(dec->type, "void")) {
		return;
	}

	if (streq(dec->type, "opaque")) {
		error("opaque -- illegal argument type");
	}
	if (peekscan(TOK_STAR, &tok)) { 
	  if (streq(dec->type, "string")) {
	    error("pointer to string not allowed in program arguments\n");
	  }
		dec->rel = REL_POINTER;
		if (peekscan(TOK_IDENT, &tok))  /* optional name of argument */
		  dec->name = strdup(tok.str);
      }
	  if (peekscan(TOK_LANGLE, &tok)) {
	    if (!streq(dec->type, "string")) {
	      error("arrays cannot be declared as arguments to procedures -- use typedef");
	    }
		dec->rel = REL_ARRAY;
		if (peekscan(TOK_RANGLE, &tok)) {
			dec->array_max = "~0";/* unspecified size, use max */
		} else {
			scan_num(&tok);
			dec->array_max = tok.str;
			scan(TOK_RANGLE, &tok);
		}
	}
	if (streq(dec->type, "string")) {
		if (dec->rel != REL_ARRAY) {  /* .x specifies just string as
					       * type of argument 
					       * - make it string<>
					       */
			dec->rel = REL_ARRAY;
			dec->array_max = "~0";/* unspecified size, use max */
		}
	}
}



static void
get_type(char **prefixp, char **typep, defkind dkind)
{
	token tok;

	*prefixp = NULL;
	get_token(&tok);
	switch (tok.kind) {
	case TOK_IDENT:
		*typep = tok.str;
		break;
	case TOK_STRUCT:
	case TOK_ENUM:
	case TOK_UNION:
		*prefixp = tok.str;
		scan(TOK_IDENT, &tok);
		*typep = tok.str;
		break;
	case TOK_UNSIGNED:
		unsigned_dec(typep);
		break;
	case TOK_SHORT:
		*typep = "short";
		(void) peekscan(TOK_INT, &tok);
		break;
	case TOK_INT32:
		*typep = "int32_t";
		(void) peekscan(TOK_INT, &tok);
		break;
	case TOK_VOID:
		if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
			error("voids allowed only inside union and program definitions with one argument");
		}
		*typep = tok.str;
		break;
	case TOK_STRING:
	case TOK_OPAQUE:
	case TOK_CHAR:
	case TOK_INT:
	case TOK_FLOAT:
	case TOK_DOUBLE:
	case TOK_BOOL:
		*typep = tok.str;
		break;
	default:
		error("expected type specifier");
	}
}

static void
unsigned_dec(char **typep)
{
	token tok;

	peek(&tok);
	switch (tok.kind) {
	case TOK_CHAR:
		get_token(&tok);
		*typep = "u_char";
		break;
	case TOK_SHORT:
		get_token(&tok);
		*typep = "u_short";
		(void) peekscan(TOK_INT, &tok);
		break;
	case TOK_INT32:
		get_token(&tok);
		*typep = "u_int32_";
		(void) peekscan(TOK_INT, &tok);
		break;
	case TOK_INT:
		get_token(&tok);
		*typep = "u_int";
		break;
	default:
		*typep = "u_int";
		break;
	}
}
