1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef	_PARSEPROTO_H
28*7c478bd9Sstevel@tonic-gate #define	_PARSEPROTO_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
33*7c478bd9Sstevel@tonic-gate extern "C" {
34*7c478bd9Sstevel@tonic-gate #endif
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate /*
37*7c478bd9Sstevel@tonic-gate  * DECL - parse C type declarations.
38*7c478bd9Sstevel@tonic-gate  *
39*7c478bd9Sstevel@tonic-gate  * 1) Does not understand struct, union or enum definitions.
40*7c478bd9Sstevel@tonic-gate  * 2) Does not understand auto, static, extern or typedef storage class
41*7c478bd9Sstevel@tonic-gate  *    specifiers.
42*7c478bd9Sstevel@tonic-gate  * 3) Does not support initialization.
43*7c478bd9Sstevel@tonic-gate  * 4) Does not support type definition.
44*7c478bd9Sstevel@tonic-gate  * 5) Only understands array dimension specified as constant decimal
45*7c478bd9Sstevel@tonic-gate  *    integer or identifier.
46*7c478bd9Sstevel@tonic-gate  *
47*7c478bd9Sstevel@tonic-gate  * Supported Operations
48*7c478bd9Sstevel@tonic-gate  *
49*7c478bd9Sstevel@tonic-gate  *    decl_Parse        convert string to a decl_t.
50*7c478bd9Sstevel@tonic-gate  *    decl_Destroy      Free space associated with a (previously returned)
51*7c478bd9Sstevel@tonic-gate  *                      decl_t. The function follows the argument list.
52*7c478bd9Sstevel@tonic-gate  *    decl_SetName      set identifier.
53*7c478bd9Sstevel@tonic-gate  *    decl_GetName      return identifier.
54*7c478bd9Sstevel@tonic-gate  *    decl_ToString     convert a (previously returned) decl_t into a
55*7c478bd9Sstevel@tonic-gate  *                      printable representation.
56*7c478bd9Sstevel@tonic-gate  *    decl_GetArgLength return length of argument list.
57*7c478bd9Sstevel@tonic-gate  *    decl_GetNext      return the next decl_t associated with the given
58*7c478bd9Sstevel@tonic-gate  *                      decl_t.
59*7c478bd9Sstevel@tonic-gate  *    decl_GetDeclSpec	return the declaration specifier.
60*7c478bd9Sstevel@tonic-gate  *    decl_GetDSName    return identifier associated with a
61*7c478bd9Sstevel@tonic-gate  *			declaration specifier.
62*7c478bd9Sstevel@tonic-gate  *    decl_GetType      return the type_t associated with a decl_t.
63*7c478bd9Sstevel@tonic-gate  *    decl_IsVarargs    return true if the given decl_t is a varargs function.
64*7c478bd9Sstevel@tonic-gate  *    decl_IsFunction   return true if the given decl_t is a function.
65*7c478bd9Sstevel@tonic-gate  *
66*7c478bd9Sstevel@tonic-gate  *    type_GetNext      return the next type_t associated with a given type_t.
67*7c478bd9Sstevel@tonic-gate  *    type_IsArray      return true if the given type_t is an array.
68*7c478bd9Sstevel@tonic-gate  *    type_GetArraySize return size of array.
69*7c478bd9Sstevel@tonic-gate  *
70*7c478bd9Sstevel@tonic-gate  *    type_IsPtrTo      return true if the given type_t is a pointer to ... .
71*7c478bd9Sstevel@tonic-gate  *    type_GetPtrToTypeQual    return type qualifiers for a pointer to ... .
72*7c478bd9Sstevel@tonic-gate  *
73*7c478bd9Sstevel@tonic-gate  *    type_IsFunction   return true if the given type_t is a function.
74*7c478bd9Sstevel@tonic-gate  *    type_GetArgLength return length of argument list.
75*7c478bd9Sstevel@tonic-gate  *    type_IsVarargs    return true if function signature includes ... .
76*7c478bd9Sstevel@tonic-gate  *    type_GetArg       return the decl_t associated with a given type_t.
77*7c478bd9Sstevel@tonic-gate  *    type_IsPtrFun     return true if the given type_t is a pointer* to a
78*7c478bd9Sstevel@tonic-gate  *                      function.
79*7c478bd9Sstevel@tonic-gate  */
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate /* Include Files */
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate #include <stdio.h>
84*7c478bd9Sstevel@tonic-gate #include <ctype.h>
85*7c478bd9Sstevel@tonic-gate #include <string.h>
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate /* Macros and Constants */
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate #define	loop	for (;;)
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate #define	STT_isvoid(s)	((s) & (TS_VOID))
92*7c478bd9Sstevel@tonic-gate #define	STT_isfloat(s)	((s) & (TS_FLOAT | TS_DOUBLE))
93*7c478bd9Sstevel@tonic-gate #define	STT_ischar(s)	((s) & (TS_CHAR))
94*7c478bd9Sstevel@tonic-gate #define	STT_isint(s)	((s) & \
95*7c478bd9Sstevel@tonic-gate 			(TS_SHORT | TS_INT | TS_LONG | TS_LONGLONG | TS_CHAR))
96*7c478bd9Sstevel@tonic-gate #define	STT_isarith(s)	(STT_isfloat(s) || STT_isint(s))
97*7c478bd9Sstevel@tonic-gate #define	STT_isbasic(s)	(STT_isarith(s) || STT_isvoid(s))
98*7c478bd9Sstevel@tonic-gate #define	STT_isderived(s) ((s) & (TS_STRUCT | TS_UNION | TS_ENUM | TS_TYPEDEF))
99*7c478bd9Sstevel@tonic-gate #define	STT_has_explicit_sign(s)	((s) & (TS_SIGNED | TS_UNSIGNED))
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate /* Data Declarations */
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate /*
104*7c478bd9Sstevel@tonic-gate  * The overall type encoding is thus:
105*7c478bd9Sstevel@tonic-gate  *
106*7c478bd9Sstevel@tonic-gate  *    decl_t encodes a declaration which consists of:
107*7c478bd9Sstevel@tonic-gate  *        identifier
108*7c478bd9Sstevel@tonic-gate  *            declaration specifier (storage class specifier, type specifier,
109*7c478bd9Sstevel@tonic-gate  *              type qualifier)
110*7c478bd9Sstevel@tonic-gate  *            type modifiers (array, function, pointer to)
111*7c478bd9Sstevel@tonic-gate  *              ancillary (varargs?, argument list)
112*7c478bd9Sstevel@tonic-gate  *
113*7c478bd9Sstevel@tonic-gate  *    The argument list is an ordered, NULL terminated, linked list.
114*7c478bd9Sstevel@tonic-gate  *
115*7c478bd9Sstevel@tonic-gate  *    An empty argument list (== NULL) indicates an unknown argument
116*7c478bd9Sstevel@tonic-gate  *       list, i.e. "()".
117*7c478bd9Sstevel@tonic-gate  *
118*7c478bd9Sstevel@tonic-gate  *    declaration specifiers are encoded as bits in an enum (stt_t).
119*7c478bd9Sstevel@tonic-gate  *
120*7c478bd9Sstevel@tonic-gate  *    type modifiers are encoded as a linked list of variant records,
121*7c478bd9Sstevel@tonic-gate  *        i.e. "array of ..."
122*7c478bd9Sstevel@tonic-gate  *		"function returning ..." and "pointer to ...".
123*7c478bd9Sstevel@tonic-gate  *
124*7c478bd9Sstevel@tonic-gate  *    An empty list of type modifiers (== NULL) indicates a "plain" type.
125*7c478bd9Sstevel@tonic-gate  *
126*7c478bd9Sstevel@tonic-gate  *
127*7c478bd9Sstevel@tonic-gate  * OK, here goes some ASCII art...
128*7c478bd9Sstevel@tonic-gate  *
129*7c478bd9Sstevel@tonic-gate  *
130*7c478bd9Sstevel@tonic-gate  * base object
131*7c478bd9Sstevel@tonic-gate  *     |
132*7c478bd9Sstevel@tonic-gate  *     |
133*7c478bd9Sstevel@tonic-gate  *     V
134*7c478bd9Sstevel@tonic-gate  *
135*7c478bd9Sstevel@tonic-gate  * ----------      ----------      ----------       ----------
136*7c478bd9Sstevel@tonic-gate  * |        |      |        |      |        |       |        |
137*7c478bd9Sstevel@tonic-gate  * | decl_t |  --> | type_t |  --> | type_t |  ...  | type_t |  --> NULL
138*7c478bd9Sstevel@tonic-gate  * |        |      |        |      |(DD_FUN)|       |        |
139*7c478bd9Sstevel@tonic-gate  * ----------      ----------      ----------       ----------
140*7c478bd9Sstevel@tonic-gate  *     |                               |
141*7c478bd9Sstevel@tonic-gate  *     |                               |
142*7c478bd9Sstevel@tonic-gate  *     V                               V
143*7c478bd9Sstevel@tonic-gate  *                           A     ----------      ----------
144*7c478bd9Sstevel@tonic-gate  *    NULL                   r     |        |      |        |
145*7c478bd9Sstevel@tonic-gate  *                           g     | decl_t |  --> | type_t |  ... --> NULL
146*7c478bd9Sstevel@tonic-gate  *                           u     |        |      |        |
147*7c478bd9Sstevel@tonic-gate  *                           m     ----------      ----------
148*7c478bd9Sstevel@tonic-gate  *                           e         |
149*7c478bd9Sstevel@tonic-gate  *                           n         |
150*7c478bd9Sstevel@tonic-gate  *                           t         V
151*7c478bd9Sstevel@tonic-gate  *                                 ----------
152*7c478bd9Sstevel@tonic-gate  *                           L     |        |
153*7c478bd9Sstevel@tonic-gate  *                           i     | decl_t |  ... --> NULL
154*7c478bd9Sstevel@tonic-gate  *                           s     |        |
155*7c478bd9Sstevel@tonic-gate  *                           t     ----------
156*7c478bd9Sstevel@tonic-gate  *
157*7c478bd9Sstevel@tonic-gate  *                                    ...
158*7c478bd9Sstevel@tonic-gate  *
159*7c478bd9Sstevel@tonic-gate  *                                     |
160*7c478bd9Sstevel@tonic-gate  *	                               |
161*7c478bd9Sstevel@tonic-gate  *	                               V
162*7c478bd9Sstevel@tonic-gate  *
163*7c478bd9Sstevel@tonic-gate  *	                              NULL
164*7c478bd9Sstevel@tonic-gate  */
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate /*
167*7c478bd9Sstevel@tonic-gate  * The encoding of a declaration specifier is done primarily with an
168*7c478bd9Sstevel@tonic-gate  * stt_t type.
169*7c478bd9Sstevel@tonic-gate  * This type must support bit-wise operations.
170*7c478bd9Sstevel@tonic-gate  */
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate typedef enum {
173*7c478bd9Sstevel@tonic-gate 	SCS_MASK	= 0x000000ff,	/* storage class specifiers */
174*7c478bd9Sstevel@tonic-gate 	SCS_NONE	= 0x00000000,
175*7c478bd9Sstevel@tonic-gate 	SCS_REGISTER	= 0x00000001,
176*7c478bd9Sstevel@tonic-gate 	SCS_TYPEDEF	= 0x00000002,
177*7c478bd9Sstevel@tonic-gate 	SCS_EXTERN	= 0x00000004,
178*7c478bd9Sstevel@tonic-gate 	SCS_AUTO	= 0x00000008,
179*7c478bd9Sstevel@tonic-gate 	SCS_STATIC	= 0x00000010,
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate 	TS_MASK		= 0x00ffff00,	/* type specifiers */
182*7c478bd9Sstevel@tonic-gate 	TS_NO_TS	= 0x00000000,
183*7c478bd9Sstevel@tonic-gate 	TS_CHAR		= 0x00000100,
184*7c478bd9Sstevel@tonic-gate 	TS_SHORT	= 0x00000200,
185*7c478bd9Sstevel@tonic-gate 	TS_INT		= 0x00000400,
186*7c478bd9Sstevel@tonic-gate 	TS_LONG		= 0x00000800,
187*7c478bd9Sstevel@tonic-gate 	TS_SIGNED	= 0x00001000,
188*7c478bd9Sstevel@tonic-gate 	TS_UNSIGNED	= 0x00002000,
189*7c478bd9Sstevel@tonic-gate 	TS_ENUM		= 0x00004000,
190*7c478bd9Sstevel@tonic-gate 	TS_FLOAT	= 0x00010000,
191*7c478bd9Sstevel@tonic-gate 	TS_DOUBLE	= 0x00020000,
192*7c478bd9Sstevel@tonic-gate 	TS_STRUCT	= 0x00040000,
193*7c478bd9Sstevel@tonic-gate 	TS_UNION	= 0x00080000,
194*7c478bd9Sstevel@tonic-gate 	TS_TYPEDEF	= 0x00100000,
195*7c478bd9Sstevel@tonic-gate 	TS_VOID		= 0x00200000,
196*7c478bd9Sstevel@tonic-gate 	TS_LONGLONG	= 0x00400000,	/* non-ANSI type: long long */
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate 	TQ_MASK		= 0x0f000000,	/* type qualifiers */
199*7c478bd9Sstevel@tonic-gate 	TQ_NONE		= 0x00000000,
200*7c478bd9Sstevel@tonic-gate 	TQ_CONST	= 0x01000000,
201*7c478bd9Sstevel@tonic-gate 	TQ_VOLATILE	= 0x02000000,
202*7c478bd9Sstevel@tonic-gate 	TQ_RESTRICT	= 0x04000000,
203*7c478bd9Sstevel@tonic-gate 	TQ_RESTRICT_KYWD = 0x08000000
204*7c478bd9Sstevel@tonic-gate } stt_t;
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate typedef enum {			/* declarator options */
207*7c478bd9Sstevel@tonic-gate 	DD_NONE	= 0,
208*7c478bd9Sstevel@tonic-gate 	DD_ARY	= 1,		/* array of [size] ... */
209*7c478bd9Sstevel@tonic-gate 	DD_FUN	= 2,		/* function [taking and] returning ... */
210*7c478bd9Sstevel@tonic-gate 	DD_PTR	= 3		/* [tq] pointer to ... */
211*7c478bd9Sstevel@tonic-gate } decl_type_t;
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate typedef enum {
214*7c478bd9Sstevel@tonic-gate 	DTS_DECL = 0,
215*7c478bd9Sstevel@tonic-gate 	DTS_CAST = 1,
216*7c478bd9Sstevel@tonic-gate 	DTS_RET  = 3
217*7c478bd9Sstevel@tonic-gate } decl_dts_t;
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate typedef struct {
220*7c478bd9Sstevel@tonic-gate 	stt_t	 ds_stt;	/* scs|ts|tq */
221*7c478bd9Sstevel@tonic-gate 	char	*ds_id;		/* id for struct|union|enum|typedef */
222*7c478bd9Sstevel@tonic-gate } decl_spec_t;
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate typedef struct _declarator	decl_t;
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate typedef struct _type {
227*7c478bd9Sstevel@tonic-gate 	struct _type	*t_next;	/* next type_t or NULL */
228*7c478bd9Sstevel@tonic-gate 	decl_type_t	 t_dt;		/* oneof DD_* */
229*7c478bd9Sstevel@tonic-gate 	/* DD_FUN */
230*7c478bd9Sstevel@tonic-gate 	int		 t_nargs;	/* number of arguments */
231*7c478bd9Sstevel@tonic-gate 	int		 t_ellipsis;	/* a varargs? */
232*7c478bd9Sstevel@tonic-gate 	decl_t		*t_args;	/* list of arguments */
233*7c478bd9Sstevel@tonic-gate 	/* DD_PTR */
234*7c478bd9Sstevel@tonic-gate 	stt_t		 t_stt;		/* type qualifier, TQ_* */
235*7c478bd9Sstevel@tonic-gate 	/* DD_ARY */
236*7c478bd9Sstevel@tonic-gate 	char		*t_sizestr;	/* size as a string */
237*7c478bd9Sstevel@tonic-gate } type_t;
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate struct _declarator {
240*7c478bd9Sstevel@tonic-gate 	char		*d_name;	/* name of declarator */
241*7c478bd9Sstevel@tonic-gate 	decl_spec_t	*d_ds;		/* ts|scs|tq */
242*7c478bd9Sstevel@tonic-gate 	type_t		*d_type;	/* list of attributes or NULL */
243*7c478bd9Sstevel@tonic-gate 	int		 d_ellipsis;	/* a varargs? */
244*7c478bd9Sstevel@tonic-gate 	decl_t		*d_next;	/* next link in chain (arglist) */
245*7c478bd9Sstevel@tonic-gate };
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate /* External Declarations */
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate extern	char		*declspec_ToString(char *, decl_spec_t *);
250*7c478bd9Sstevel@tonic-gate 
251*7c478bd9Sstevel@tonic-gate extern	void		decl_Destroy(decl_t *);
252*7c478bd9Sstevel@tonic-gate extern	int		decl_GetArgLength(decl_t *);
253*7c478bd9Sstevel@tonic-gate extern	decl_t		*decl_SetName(decl_t *, char *);
254*7c478bd9Sstevel@tonic-gate extern	char		*decl_GetName(decl_t *);
255*7c478bd9Sstevel@tonic-gate extern	type_t		*decl_GetType(decl_t *);
256*7c478bd9Sstevel@tonic-gate extern	int		decl_IsVarargs(decl_t *dp);
257*7c478bd9Sstevel@tonic-gate extern	char		*decl_ToString(char *, decl_dts_t, decl_t *,
258*7c478bd9Sstevel@tonic-gate 			    const char *);
259*7c478bd9Sstevel@tonic-gate extern	const char	*decl_Parse(char *, decl_t **);
260*7c478bd9Sstevel@tonic-gate extern	void		decl_GetTraceInfo(decl_t *, char *, char *, decl_t **);
261*7c478bd9Sstevel@tonic-gate extern	char 		*decl_ToFormal(decl_t *);
262*7c478bd9Sstevel@tonic-gate extern	int		type_IsArray(type_t *);
263*7c478bd9Sstevel@tonic-gate extern	int		type_IsPtrTo(type_t *);
264*7c478bd9Sstevel@tonic-gate extern	int		type_IsFunction(type_t *);
265*7c478bd9Sstevel@tonic-gate extern	int		type_IsVarargs(type_t *);
266*7c478bd9Sstevel@tonic-gate extern	int		type_IsPtrFun(type_t *);
267*7c478bd9Sstevel@tonic-gate extern	decl_t		*decl_AddArgNames(decl_t *);
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
270*7c478bd9Sstevel@tonic-gate }
271*7c478bd9Sstevel@tonic-gate #endif
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate #endif	/* _PARSEPROTO_H */
274