/*
 * From: @(#)rpc_parse.c 1.8 89/02/22
 *
 * Copyright (c) 2010, Oracle America, Inc.
 * 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 the "Oracle America, 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.
 */

/*
 * 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"
#include "proto.h"

#define ARGNAME "arg"

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 (const 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 (const char **prefixp, const char **typep, defkind dkind);
static void unsigned_dec (const 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 *tcase; */
  case_list **tailp;
#if 0
  int flag;
#endif

  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 0
      flag = 0;
#endif
      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));
	}
#if 0
      else if (flag)
	{

	  *tailp = cases;
	  tailp = &cases->next;
	  cases = ALLOC (case_list);
	};
#endif

      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 const char *reserved_words[] =
{
  "array",
  "bytes",
  "destroy",
  "free",
  "getpos",
  "inline",
  "pointer",
  "reference",
  "setpos",
  "sizeof",
  "union",
  "vector",
  NULL
};

static const 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 (const 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 /* arg number */ )
{
  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 (const char **prefixp, const 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_LONG:
      *typep = "long";
      (void) peekscan (TOK_INT, &tok);
      break;
    case TOK_HYPER:
      *typep = "quad_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 (const 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_LONG:
      get_token (&tok);
      *typep = "u_long";
      (void) peekscan (TOK_INT, &tok);
      break;
    case TOK_HYPER:
      get_token (&tok);
      *typep = "u_quad_t";
      (void) peekscan(TOK_INT, &tok);
      break;
    case TOK_INT:
      get_token (&tok);
      *typep = "u_int";
      break;
    default:
      *typep = "u_int";
      break;
    }
}
