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