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