Blame sunrpc/rpc_parse.c

Packit Service 82fcde
/*
Packit Service 82fcde
 * From: @(#)rpc_parse.c 1.8 89/02/22
Packit Service 82fcde
 *
Packit Service 82fcde
 * Copyright (c) 2010, Oracle America, Inc.
Packit Service 82fcde
 * Redistribution and use in source and binary forms, with or without
Packit Service 82fcde
 * modification, are permitted provided that the following conditions are
Packit Service 82fcde
 * met:
Packit Service 82fcde
 *
Packit Service 82fcde
 *     * Redistributions of source code must retain the above copyright
Packit Service 82fcde
 *       notice, this list of conditions and the following disclaimer.
Packit Service 82fcde
 *     * Redistributions in binary form must reproduce the above
Packit Service 82fcde
 *       copyright notice, this list of conditions and the following
Packit Service 82fcde
 *       disclaimer in the documentation and/or other materials
Packit Service 82fcde
 *       provided with the distribution.
Packit Service 82fcde
 *     * Neither the name of the "Oracle America, Inc." nor the names of its
Packit Service 82fcde
 *       contributors may be used to endorse or promote products derived
Packit Service 82fcde
 *       from this software without specific prior written permission.
Packit Service 82fcde
 *
Packit Service 82fcde
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit Service 82fcde
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit Service 82fcde
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
Packit Service 82fcde
 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
Packit Service 82fcde
 *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
Packit Service 82fcde
 *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit Service 82fcde
 *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
Packit Service 82fcde
 *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Packit Service 82fcde
 *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
Packit Service 82fcde
 *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Packit Service 82fcde
 *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit Service 82fcde
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * rpc_parse.c, Parser for the RPC protocol compiler
Packit Service 82fcde
 * Copyright (C) 1987 Sun Microsystems, Inc.
Packit Service 82fcde
 */
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include "rpc/types.h"
Packit Service 82fcde
#include "rpc_scan.h"
Packit Service 82fcde
#include "rpc_parse.h"
Packit Service 82fcde
#include "rpc_util.h"
Packit Service 82fcde
#include "proto.h"
Packit Service 82fcde
Packit Service 82fcde
#define ARGNAME "arg"
Packit Service 82fcde
Packit Service 82fcde
static void isdefined (definition * defp);
Packit Service 82fcde
static void def_struct (definition * defp);
Packit Service 82fcde
static void def_program (definition * defp);
Packit Service 82fcde
static void def_enum (definition * defp);
Packit Service 82fcde
static void def_const (definition * defp);
Packit Service 82fcde
static void def_union (definition * defp);
Packit Service 82fcde
static void check_type_name (const char *name, int new_type);
Packit Service 82fcde
static void def_typedef (definition * defp);
Packit Service 82fcde
static void get_declaration (declaration * dec, defkind dkind);
Packit Service 82fcde
static void get_prog_declaration (declaration * dec, defkind dkind, int num);
Packit Service 82fcde
static void get_type (const char **prefixp, const char **typep, defkind dkind);
Packit Service 82fcde
static void unsigned_dec (const char **typep);
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * return the next definition you see
Packit Service 82fcde
 */
Packit Service 82fcde
definition *
Packit Service 82fcde
get_definition (void)
Packit Service 82fcde
{
Packit Service 82fcde
  definition *defp;
Packit Service 82fcde
  token tok;
Packit Service 82fcde
Packit Service 82fcde
  defp = ALLOC (definition);
Packit Service 82fcde
  get_token (&tok;;
Packit Service 82fcde
  switch (tok.kind)
Packit Service 82fcde
    {
Packit Service 82fcde
    case TOK_STRUCT:
Packit Service 82fcde
      def_struct (defp);
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_UNION:
Packit Service 82fcde
      def_union (defp);
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_TYPEDEF:
Packit Service 82fcde
      def_typedef (defp);
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_ENUM:
Packit Service 82fcde
      def_enum (defp);
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_PROGRAM:
Packit Service 82fcde
      def_program (defp);
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_CONST:
Packit Service 82fcde
      def_const (defp);
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_EOF:
Packit Service 82fcde
      free (defp);
Packit Service 82fcde
      return (NULL);
Packit Service 82fcde
    default:
Packit Service 82fcde
      error ("definition keyword expected");
Packit Service 82fcde
    }
Packit Service 82fcde
  scan (TOK_SEMICOLON, &tok;;
Packit Service 82fcde
  isdefined (defp);
Packit Service 82fcde
  return (defp);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
isdefined (definition * defp)
Packit Service 82fcde
{
Packit Service 82fcde
  STOREVAL (&defined, defp);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
def_struct (definition * defp)
Packit Service 82fcde
{
Packit Service 82fcde
  token tok;
Packit Service 82fcde
  declaration dec;
Packit Service 82fcde
  decl_list *decls;
Packit Service 82fcde
  decl_list **tailp;
Packit Service 82fcde
Packit Service 82fcde
  defp->def_kind = DEF_STRUCT;
Packit Service 82fcde
Packit Service 82fcde
  scan (TOK_IDENT, &tok;;
Packit Service 82fcde
  defp->def_name = tok.str;
Packit Service 82fcde
  scan (TOK_LBRACE, &tok;;
Packit Service 82fcde
  tailp = &defp->def.st.decls;
Packit Service 82fcde
  do
Packit Service 82fcde
    {
Packit Service 82fcde
      get_declaration (&dec, DEF_STRUCT);
Packit Service 82fcde
      decls = ALLOC (decl_list);
Packit Service 82fcde
      decls->decl = dec;
Packit Service 82fcde
      *tailp = decls;
Packit Service 82fcde
      tailp = &decls->next;
Packit Service 82fcde
      scan (TOK_SEMICOLON, &tok;;
Packit Service 82fcde
      peek (&tok;;
Packit Service 82fcde
    }
Packit Service 82fcde
  while (tok.kind != TOK_RBRACE);
Packit Service 82fcde
  get_token (&tok;;
Packit Service 82fcde
  *tailp = NULL;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
def_program (definition * defp)
Packit Service 82fcde
{
Packit Service 82fcde
  token tok;
Packit Service 82fcde
  declaration dec;
Packit Service 82fcde
  decl_list *decls;
Packit Service 82fcde
  decl_list **tailp;
Packit Service 82fcde
  version_list *vlist;
Packit Service 82fcde
  version_list **vtailp;
Packit Service 82fcde
  proc_list *plist;
Packit Service 82fcde
  proc_list **ptailp;
Packit Service 82fcde
  int num_args;
Packit Service 82fcde
  bool_t isvoid = FALSE;	/* whether first argument is void */
Packit Service 82fcde
  defp->def_kind = DEF_PROGRAM;
Packit Service 82fcde
  scan (TOK_IDENT, &tok;;
Packit Service 82fcde
  defp->def_name = tok.str;
Packit Service 82fcde
  scan (TOK_LBRACE, &tok;;
Packit Service 82fcde
  vtailp = &defp->def.pr.versions;
Packit Service 82fcde
  tailp = &defp->def.st.decls;
Packit Service 82fcde
  scan (TOK_VERSION, &tok;;
Packit Service 82fcde
  do
Packit Service 82fcde
    {
Packit Service 82fcde
      scan (TOK_IDENT, &tok;;
Packit Service 82fcde
      vlist = ALLOC (version_list);
Packit Service 82fcde
      vlist->vers_name = tok.str;
Packit Service 82fcde
      scan (TOK_LBRACE, &tok;;
Packit Service 82fcde
      ptailp = &vlist->procs;
Packit Service 82fcde
      do
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* get result type */
Packit Service 82fcde
	  plist = ALLOC (proc_list);
Packit Service 82fcde
	  get_type (&plist->res_prefix, &plist->res_type,
Packit Service 82fcde
		    DEF_PROGRAM);
Packit Service 82fcde
	  if (streq (plist->res_type, "opaque"))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      error ("illegal result type");
Packit Service 82fcde
	    }
Packit Service 82fcde
	  scan (TOK_IDENT, &tok;;
Packit Service 82fcde
	  plist->proc_name = tok.str;
Packit Service 82fcde
	  scan (TOK_LPAREN, &tok;;
Packit Service 82fcde
	  /* get args - first one */
Packit Service 82fcde
	  num_args = 1;
Packit Service 82fcde
	  isvoid = FALSE;
Packit Service 82fcde
	  /* type of DEF_PROGRAM in the first
Packit Service 82fcde
	   * get_prog_declaration and DEF_STURCT in the next
Packit Service 82fcde
	   * allows void as argument if it is the only argument
Packit Service 82fcde
	   */
Packit Service 82fcde
	  get_prog_declaration (&dec, DEF_PROGRAM, num_args);
Packit Service 82fcde
	  if (streq (dec.type, "void"))
Packit Service 82fcde
	    isvoid = TRUE;
Packit Service 82fcde
	  decls = ALLOC (decl_list);
Packit Service 82fcde
	  plist->args.decls = decls;
Packit Service 82fcde
	  decls->decl = dec;
Packit Service 82fcde
	  tailp = &decls->next;
Packit Service 82fcde
	  /* get args */
Packit Service 82fcde
	  while (peekscan (TOK_COMMA, &tok))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      num_args++;
Packit Service 82fcde
	      get_prog_declaration (&dec, DEF_STRUCT,
Packit Service 82fcde
				    num_args);
Packit Service 82fcde
	      decls = ALLOC (decl_list);
Packit Service 82fcde
	      decls->decl = dec;
Packit Service 82fcde
	      *tailp = decls;
Packit Service 82fcde
	      if (streq (dec.type, "void"))
Packit Service 82fcde
		isvoid = TRUE;
Packit Service 82fcde
	      tailp = &decls->next;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  /* multiple arguments are only allowed in newstyle */
Packit Service 82fcde
	  if (!newstyle && num_args > 1)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      error ("only one argument is allowed");
Packit Service 82fcde
	    }
Packit Service 82fcde
	  if (isvoid && num_args > 1)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      error ("illegal use of void in program definition");
Packit Service 82fcde
	    }
Packit Service 82fcde
	  *tailp = NULL;
Packit Service 82fcde
	  scan (TOK_RPAREN, &tok;;
Packit Service 82fcde
	  scan (TOK_EQUAL, &tok;;
Packit Service 82fcde
	  scan_num (&tok;;
Packit Service 82fcde
	  scan (TOK_SEMICOLON, &tok;;
Packit Service 82fcde
	  plist->proc_num = tok.str;
Packit Service 82fcde
	  plist->arg_num = num_args;
Packit Service 82fcde
	  *ptailp = plist;
Packit Service 82fcde
	  ptailp = &plist->next;
Packit Service 82fcde
	  peek (&tok;;
Packit Service 82fcde
	}
Packit Service 82fcde
      while (tok.kind != TOK_RBRACE);
Packit Service 82fcde
      *ptailp = NULL;
Packit Service 82fcde
      *vtailp = vlist;
Packit Service 82fcde
      vtailp = &vlist->next;
Packit Service 82fcde
      scan (TOK_RBRACE, &tok;;
Packit Service 82fcde
      scan (TOK_EQUAL, &tok;;
Packit Service 82fcde
      scan_num (&tok;;
Packit Service 82fcde
      vlist->vers_num = tok.str;
Packit Service 82fcde
      /* make the argument structure name for each arg */
Packit Service 82fcde
      for (plist = vlist->procs; plist != NULL;
Packit Service 82fcde
	   plist = plist->next)
Packit Service 82fcde
	{
Packit Service 82fcde
	  plist->args.argname = make_argname (plist->proc_name,
Packit Service 82fcde
					      vlist->vers_num);
Packit Service 82fcde
	  /* free the memory ?? */
Packit Service 82fcde
	}
Packit Service 82fcde
      scan (TOK_SEMICOLON, &tok;;
Packit Service 82fcde
      scan2 (TOK_VERSION, TOK_RBRACE, &tok;;
Packit Service 82fcde
    }
Packit Service 82fcde
  while (tok.kind == TOK_VERSION);
Packit Service 82fcde
  scan (TOK_EQUAL, &tok;;
Packit Service 82fcde
  scan_num (&tok;;
Packit Service 82fcde
  defp->def.pr.prog_num = tok.str;
Packit Service 82fcde
  *vtailp = NULL;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
def_enum (definition * defp)
Packit Service 82fcde
{
Packit Service 82fcde
  token tok;
Packit Service 82fcde
  enumval_list *elist;
Packit Service 82fcde
  enumval_list **tailp;
Packit Service 82fcde
Packit Service 82fcde
  defp->def_kind = DEF_ENUM;
Packit Service 82fcde
  scan (TOK_IDENT, &tok;;
Packit Service 82fcde
  defp->def_name = tok.str;
Packit Service 82fcde
  scan (TOK_LBRACE, &tok;;
Packit Service 82fcde
  tailp = &defp->def.en.vals;
Packit Service 82fcde
  do
Packit Service 82fcde
    {
Packit Service 82fcde
      scan (TOK_IDENT, &tok;;
Packit Service 82fcde
      elist = ALLOC (enumval_list);
Packit Service 82fcde
      elist->name = tok.str;
Packit Service 82fcde
      elist->assignment = NULL;
Packit Service 82fcde
      scan3 (TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok;;
Packit Service 82fcde
      if (tok.kind == TOK_EQUAL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  scan_num (&tok;;
Packit Service 82fcde
	  elist->assignment = tok.str;
Packit Service 82fcde
	  scan2 (TOK_COMMA, TOK_RBRACE, &tok;;
Packit Service 82fcde
	}
Packit Service 82fcde
      *tailp = elist;
Packit Service 82fcde
      tailp = &elist->next;
Packit Service 82fcde
    }
Packit Service 82fcde
  while (tok.kind != TOK_RBRACE);
Packit Service 82fcde
  *tailp = NULL;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
def_const (definition * defp)
Packit Service 82fcde
{
Packit Service 82fcde
  token tok;
Packit Service 82fcde
Packit Service 82fcde
  defp->def_kind = DEF_CONST;
Packit Service 82fcde
  scan (TOK_IDENT, &tok;;
Packit Service 82fcde
  defp->def_name = tok.str;
Packit Service 82fcde
  scan (TOK_EQUAL, &tok;;
Packit Service 82fcde
  scan2 (TOK_IDENT, TOK_STRCONST, &tok;;
Packit Service 82fcde
  defp->def.co = tok.str;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
def_union (definition *defp)
Packit Service 82fcde
{
Packit Service 82fcde
  token tok;
Packit Service 82fcde
  declaration dec;
Packit Service 82fcde
  case_list *cases;
Packit Service 82fcde
/*  case_list *tcase; */
Packit Service 82fcde
  case_list **tailp;
Packit Service 82fcde
#if 0
Packit Service 82fcde
  int flag;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  defp->def_kind = DEF_UNION;
Packit Service 82fcde
  scan (TOK_IDENT, &tok;;
Packit Service 82fcde
  defp->def_name = tok.str;
Packit Service 82fcde
  scan (TOK_SWITCH, &tok;;
Packit Service 82fcde
  scan (TOK_LPAREN, &tok;;
Packit Service 82fcde
  get_declaration (&dec, DEF_UNION);
Packit Service 82fcde
  defp->def.un.enum_decl = dec;
Packit Service 82fcde
  tailp = &defp->def.un.cases;
Packit Service 82fcde
  scan (TOK_RPAREN, &tok;;
Packit Service 82fcde
  scan (TOK_LBRACE, &tok;;
Packit Service 82fcde
  scan (TOK_CASE, &tok;;
Packit Service 82fcde
  while (tok.kind == TOK_CASE)
Packit Service 82fcde
    {
Packit Service 82fcde
      scan2 (TOK_IDENT, TOK_CHARCONST, &tok;;
Packit Service 82fcde
      cases = ALLOC (case_list);
Packit Service 82fcde
      cases->case_name = tok.str;
Packit Service 82fcde
      scan (TOK_COLON, &tok;;
Packit Service 82fcde
      /* now peek at next token */
Packit Service 82fcde
#if 0
Packit Service 82fcde
      flag = 0;
Packit Service 82fcde
#endif
Packit Service 82fcde
      if (peekscan (TOK_CASE, &tok))
Packit Service 82fcde
	{
Packit Service 82fcde
Packit Service 82fcde
	  do
Packit Service 82fcde
	    {
Packit Service 82fcde
	      scan2 (TOK_IDENT, TOK_CHARCONST, &tok;;
Packit Service 82fcde
	      cases->contflag = 1;	/* continued case statement */
Packit Service 82fcde
	      *tailp = cases;
Packit Service 82fcde
	      tailp = &cases->next;
Packit Service 82fcde
	      cases = ALLOC (case_list);
Packit Service 82fcde
	      cases->case_name = tok.str;
Packit Service 82fcde
	      scan (TOK_COLON, &tok;;
Packit Service 82fcde
Packit Service 82fcde
	    }
Packit Service 82fcde
	  while (peekscan (TOK_CASE, &tok));
Packit Service 82fcde
	}
Packit Service 82fcde
#if 0
Packit Service 82fcde
      else if (flag)
Packit Service 82fcde
	{
Packit Service 82fcde
Packit Service 82fcde
	  *tailp = cases;
Packit Service 82fcde
	  tailp = &cases->next;
Packit Service 82fcde
	  cases = ALLOC (case_list);
Packit Service 82fcde
	};
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
      get_declaration (&dec, DEF_UNION);
Packit Service 82fcde
      cases->case_decl = dec;
Packit Service 82fcde
      cases->contflag = 0;	/* no continued case statement */
Packit Service 82fcde
      *tailp = cases;
Packit Service 82fcde
      tailp = &cases->next;
Packit Service 82fcde
      scan (TOK_SEMICOLON, &tok;;
Packit Service 82fcde
Packit Service 82fcde
      scan3 (TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok;;
Packit Service 82fcde
    }
Packit Service 82fcde
  *tailp = NULL;
Packit Service 82fcde
  if (tok.kind == TOK_DEFAULT)
Packit Service 82fcde
    {
Packit Service 82fcde
      scan (TOK_COLON, &tok;;
Packit Service 82fcde
      get_declaration (&dec, DEF_UNION);
Packit Service 82fcde
      defp->def.un.default_decl = ALLOC (declaration);
Packit Service 82fcde
      *defp->def.un.default_decl = dec;
Packit Service 82fcde
      scan (TOK_SEMICOLON, &tok;;
Packit Service 82fcde
      scan (TOK_RBRACE, &tok;;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      defp->def.un.default_decl = NULL;
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static const char *reserved_words[] =
Packit Service 82fcde
{
Packit Service 82fcde
  "array",
Packit Service 82fcde
  "bytes",
Packit Service 82fcde
  "destroy",
Packit Service 82fcde
  "free",
Packit Service 82fcde
  "getpos",
Packit Service 82fcde
  "inline",
Packit Service 82fcde
  "pointer",
Packit Service 82fcde
  "reference",
Packit Service 82fcde
  "setpos",
Packit Service 82fcde
  "sizeof",
Packit Service 82fcde
  "union",
Packit Service 82fcde
  "vector",
Packit Service 82fcde
  NULL
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
static const char *reserved_types[] =
Packit Service 82fcde
{
Packit Service 82fcde
  "opaque",
Packit Service 82fcde
  "string",
Packit Service 82fcde
  NULL
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * check that the given name is not one that would eventually result in
Packit Service 82fcde
 * xdr routines that would conflict with internal XDR routines.
Packit Service 82fcde
 */
Packit Service 82fcde
static void
Packit Service 82fcde
check_type_name (const char *name, int new_type)
Packit Service 82fcde
{
Packit Service 82fcde
  int i;
Packit Service 82fcde
  char tmp[100];
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; reserved_words[i] != NULL; i++)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (strcmp (name, reserved_words[i]) == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  sprintf (tmp,
Packit Service 82fcde
		"illegal (reserved) name :\'%s\' in type definition", name);
Packit Service 82fcde
	  error (tmp);
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  if (new_type)
Packit Service 82fcde
    {
Packit Service 82fcde
      for (i = 0; reserved_types[i] != NULL; i++)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (strcmp (name, reserved_types[i]) == 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      sprintf (tmp,
Packit Service 82fcde
		"illegal (reserved) name :\'%s\' in type definition", name);
Packit Service 82fcde
	      error (tmp);
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
def_typedef (definition * defp)
Packit Service 82fcde
{
Packit Service 82fcde
  declaration dec;
Packit Service 82fcde
Packit Service 82fcde
  defp->def_kind = DEF_TYPEDEF;
Packit Service 82fcde
  get_declaration (&dec, DEF_TYPEDEF);
Packit Service 82fcde
  defp->def_name = dec.name;
Packit Service 82fcde
  check_type_name (dec.name, 1);
Packit Service 82fcde
  defp->def.ty.old_prefix = dec.prefix;
Packit Service 82fcde
  defp->def.ty.old_type = dec.type;
Packit Service 82fcde
  defp->def.ty.rel = dec.rel;
Packit Service 82fcde
  defp->def.ty.array_max = dec.array_max;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
get_declaration (declaration * dec, defkind dkind)
Packit Service 82fcde
{
Packit Service 82fcde
  token tok;
Packit Service 82fcde
Packit Service 82fcde
  get_type (&dec->prefix, &dec->type, dkind);
Packit Service 82fcde
  dec->rel = REL_ALIAS;
Packit Service 82fcde
  if (streq (dec->type, "void"))
Packit Service 82fcde
    {
Packit Service 82fcde
      return;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  check_type_name (dec->type, 0);
Packit Service 82fcde
Packit Service 82fcde
  scan2 (TOK_STAR, TOK_IDENT, &tok;;
Packit Service 82fcde
  if (tok.kind == TOK_STAR)
Packit Service 82fcde
    {
Packit Service 82fcde
      dec->rel = REL_POINTER;
Packit Service 82fcde
      scan (TOK_IDENT, &tok;;
Packit Service 82fcde
    }
Packit Service 82fcde
  dec->name = tok.str;
Packit Service 82fcde
  if (peekscan (TOK_LBRACKET, &tok))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (dec->rel == REL_POINTER)
Packit Service 82fcde
	{
Packit Service 82fcde
	  error ("no array-of-pointer declarations -- use typedef");
Packit Service 82fcde
	}
Packit Service 82fcde
      dec->rel = REL_VECTOR;
Packit Service 82fcde
      scan_num (&tok;;
Packit Service 82fcde
      dec->array_max = tok.str;
Packit Service 82fcde
      scan (TOK_RBRACKET, &tok;;
Packit Service 82fcde
    }
Packit Service 82fcde
  else if (peekscan (TOK_LANGLE, &tok))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (dec->rel == REL_POINTER)
Packit Service 82fcde
	{
Packit Service 82fcde
	  error ("no array-of-pointer declarations -- use typedef");
Packit Service 82fcde
	}
Packit Service 82fcde
      dec->rel = REL_ARRAY;
Packit Service 82fcde
      if (peekscan (TOK_RANGLE, &tok))
Packit Service 82fcde
	{
Packit Service 82fcde
	  dec->array_max = "~0";	/* unspecified size, use max */
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  scan_num (&tok;;
Packit Service 82fcde
	  dec->array_max = tok.str;
Packit Service 82fcde
	  scan (TOK_RANGLE, &tok;;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  if (streq (dec->type, "opaque"))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR)
Packit Service 82fcde
	{
Packit Service 82fcde
	  error ("array declaration expected");
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  else if (streq (dec->type, "string"))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (dec->rel != REL_ARRAY)
Packit Service 82fcde
	{
Packit Service 82fcde
	  error ("variable-length array declaration expected");
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
get_prog_declaration (declaration * dec, defkind dkind, int num /* arg number */ )
Packit Service 82fcde
{
Packit Service 82fcde
  token tok;
Packit Service 82fcde
  char name[MAXLINESIZE];		/* argument name */
Packit Service 82fcde
Packit Service 82fcde
  if (dkind == DEF_PROGRAM)
Packit Service 82fcde
    {
Packit Service 82fcde
      peek (&tok;;
Packit Service 82fcde
      if (tok.kind == TOK_RPAREN)
Packit Service 82fcde
	{			/* no arguments */
Packit Service 82fcde
	  dec->rel = REL_ALIAS;
Packit Service 82fcde
	  dec->type = "void";
Packit Service 82fcde
	  dec->prefix = NULL;
Packit Service 82fcde
	  dec->name = NULL;
Packit Service 82fcde
	  return;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  get_type (&dec->prefix, &dec->type, dkind);
Packit Service 82fcde
  dec->rel = REL_ALIAS;
Packit Service 82fcde
  if (peekscan (TOK_IDENT, &tok))	/* optional name of argument */
Packit Service 82fcde
    strcpy (name, tok.str);
Packit Service 82fcde
  else
Packit Service 82fcde
    sprintf (name, "%s%d", ARGNAME, num);	/* default name of argument */
Packit Service 82fcde
Packit Service 82fcde
  dec->name = (char *) strdup (name);
Packit Service 82fcde
Packit Service 82fcde
  if (streq (dec->type, "void"))
Packit Service 82fcde
    {
Packit Service 82fcde
      return;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (streq (dec->type, "opaque"))
Packit Service 82fcde
    {
Packit Service 82fcde
      error ("opaque -- illegal argument type");
Packit Service 82fcde
    }
Packit Service 82fcde
  if (peekscan (TOK_STAR, &tok))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (streq (dec->type, "string"))
Packit Service 82fcde
	{
Packit Service 82fcde
	  error ("pointer to string not allowed in program arguments\n");
Packit Service 82fcde
	}
Packit Service 82fcde
      dec->rel = REL_POINTER;
Packit Service 82fcde
      if (peekscan (TOK_IDENT, &tok))	/* optional name of argument */
Packit Service 82fcde
	dec->name = strdup (tok.str);
Packit Service 82fcde
    }
Packit Service 82fcde
  if (peekscan (TOK_LANGLE, &tok))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (!streq (dec->type, "string"))
Packit Service 82fcde
	{
Packit Service 82fcde
	  error ("arrays cannot be declared as arguments to procedures -- use typedef");
Packit Service 82fcde
	}
Packit Service 82fcde
      dec->rel = REL_ARRAY;
Packit Service 82fcde
      if (peekscan (TOK_RANGLE, &tok))
Packit Service 82fcde
	{
Packit Service 82fcde
	  dec->array_max = "~0";	/* unspecified size, use max */
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  scan_num (&tok;;
Packit Service 82fcde
	  dec->array_max = tok.str;
Packit Service 82fcde
	  scan (TOK_RANGLE, &tok;;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  if (streq (dec->type, "string"))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (dec->rel != REL_ARRAY)
Packit Service 82fcde
	{			/* .x specifies just string as
Packit Service 82fcde
				 * type of argument
Packit Service 82fcde
				 * - make it string<>
Packit Service 82fcde
				 */
Packit Service 82fcde
	  dec->rel = REL_ARRAY;
Packit Service 82fcde
	  dec->array_max = "~0";	/* unspecified size, use max */
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
get_type (const char **prefixp, const char **typep, defkind dkind)
Packit Service 82fcde
{
Packit Service 82fcde
  token tok;
Packit Service 82fcde
Packit Service 82fcde
  *prefixp = NULL;
Packit Service 82fcde
  get_token (&tok;;
Packit Service 82fcde
  switch (tok.kind)
Packit Service 82fcde
    {
Packit Service 82fcde
    case TOK_IDENT:
Packit Service 82fcde
      *typep = tok.str;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_STRUCT:
Packit Service 82fcde
    case TOK_ENUM:
Packit Service 82fcde
    case TOK_UNION:
Packit Service 82fcde
      *prefixp = tok.str;
Packit Service 82fcde
      scan (TOK_IDENT, &tok;;
Packit Service 82fcde
      *typep = tok.str;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_UNSIGNED:
Packit Service 82fcde
      unsigned_dec (typep);
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_SHORT:
Packit Service 82fcde
      *typep = "short";
Packit Service 82fcde
      (void) peekscan (TOK_INT, &tok;;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_LONG:
Packit Service 82fcde
      *typep = "long";
Packit Service 82fcde
      (void) peekscan (TOK_INT, &tok;;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_HYPER:
Packit Service 82fcde
      *typep = "quad_t";
Packit Service 82fcde
      (void) peekscan(TOK_INT, &tok;;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_VOID:
Packit Service 82fcde
      if (dkind != DEF_UNION && dkind != DEF_PROGRAM)
Packit Service 82fcde
	{
Packit Service 82fcde
	  error ("voids allowed only inside union and program definitions with one argument");
Packit Service 82fcde
	}
Packit Service 82fcde
      *typep = tok.str;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_STRING:
Packit Service 82fcde
    case TOK_OPAQUE:
Packit Service 82fcde
    case TOK_CHAR:
Packit Service 82fcde
    case TOK_INT:
Packit Service 82fcde
    case TOK_FLOAT:
Packit Service 82fcde
    case TOK_DOUBLE:
Packit Service 82fcde
    case TOK_BOOL:
Packit Service 82fcde
      *typep = tok.str;
Packit Service 82fcde
      break;
Packit Service 82fcde
    default:
Packit Service 82fcde
      error ("expected type specifier");
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
unsigned_dec (const char **typep)
Packit Service 82fcde
{
Packit Service 82fcde
  token tok;
Packit Service 82fcde
Packit Service 82fcde
  peek (&tok;;
Packit Service 82fcde
  switch (tok.kind)
Packit Service 82fcde
    {
Packit Service 82fcde
    case TOK_CHAR:
Packit Service 82fcde
      get_token (&tok;;
Packit Service 82fcde
      *typep = "u_char";
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_SHORT:
Packit Service 82fcde
      get_token (&tok;;
Packit Service 82fcde
      *typep = "u_short";
Packit Service 82fcde
      (void) peekscan (TOK_INT, &tok;;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_LONG:
Packit Service 82fcde
      get_token (&tok;;
Packit Service 82fcde
      *typep = "u_long";
Packit Service 82fcde
      (void) peekscan (TOK_INT, &tok;;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_HYPER:
Packit Service 82fcde
      get_token (&tok;;
Packit Service 82fcde
      *typep = "u_quad_t";
Packit Service 82fcde
      (void) peekscan(TOK_INT, &tok;;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case TOK_INT:
Packit Service 82fcde
      get_token (&tok;;
Packit Service 82fcde
      *typep = "u_int";
Packit Service 82fcde
      break;
Packit Service 82fcde
    default:
Packit Service 82fcde
      *typep = "u_int";
Packit Service 82fcde
      break;
Packit Service 82fcde
    }
Packit Service 82fcde
}