Initial checkin
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@110 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
2c9313f7d1
commit
965d48350b
5 changed files with 2963 additions and 0 deletions
32
SWIG/Source/LParse/Makefile.in
Normal file
32
SWIG/Source/LParse/Makefile.in
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Generated automatically from Makefile.in by configure.
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
AR = @AR@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
RPATH = @RPATH@
|
||||||
|
SO = @SO@
|
||||||
|
CCSHARED = @CCSHARED@
|
||||||
|
LDSHARED = @LDSHARED@
|
||||||
|
INCLUDE = -I. -I../Swig -I../DOH/Include -I../Preprocessor
|
||||||
|
|
||||||
|
SRCS = cscanner.c type.c
|
||||||
|
OBJS = cscanner.o type.o
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CCSHARED) $(INCLUDE) $(CFLAGS) -c -o $*.o $<
|
||||||
|
|
||||||
|
all: parser.o $(OBJS)
|
||||||
|
|
||||||
|
parser.o: parser.c
|
||||||
|
$(CC) $(CCSHARED) $(INCLUDE) $(CFLAGS) -c -o $*.o $<
|
||||||
|
|
||||||
|
parser.c: parser.y
|
||||||
|
$(YACC) -d parser.y
|
||||||
|
@cp y.tab.h lyacc.h
|
||||||
|
@cp y.tab.c parser.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *~ core *.so *.a y.tab*
|
||||||
|
|
||||||
388
SWIG/Source/LParse/cscanner.c
Normal file
388
SWIG/Source/LParse/cscanner.c
Normal file
|
|
@ -0,0 +1,388 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Simplified Wrapper and Interface Generator (SWIG)
|
||||||
|
*
|
||||||
|
* Author : David Beazley
|
||||||
|
*
|
||||||
|
* Department of Computer Science
|
||||||
|
* University of Chicago
|
||||||
|
* 1100 E 58th Street
|
||||||
|
* Chicago, IL 60637
|
||||||
|
* beazley@cs.uchicago.edu
|
||||||
|
*
|
||||||
|
* Please read the file LICENSE for the copyright and terms by which SWIG
|
||||||
|
* can be used and distributed.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* $Header$
|
||||||
|
*
|
||||||
|
* scanner.c
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "lparse.h"
|
||||||
|
|
||||||
|
#define yylval lparse_yylval
|
||||||
|
|
||||||
|
#include "lyacc.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
static int map[][2] = {
|
||||||
|
{ SWIG_TOKEN_LPAREN, LPAREN },
|
||||||
|
{ SWIG_TOKEN_RPAREN, RPAREN },
|
||||||
|
{ SWIG_TOKEN_SEMI, SEMI },
|
||||||
|
{ SWIG_TOKEN_COMMA, COMMA },
|
||||||
|
{ SWIG_TOKEN_STAR, STAR },
|
||||||
|
{ SWIG_TOKEN_LBRACE, LBRACE },
|
||||||
|
{ SWIG_TOKEN_RBRACE, RBRACE },
|
||||||
|
{ SWIG_TOKEN_EQUAL, EQUAL },
|
||||||
|
{ SWIG_TOKEN_EQUALTO, EQUALTO },
|
||||||
|
{ SWIG_TOKEN_NOTEQUAL, NOTEQUAL },
|
||||||
|
{ SWIG_TOKEN_PLUS, PLUS },
|
||||||
|
{ SWIG_TOKEN_MINUS, MINUS },
|
||||||
|
{ SWIG_TOKEN_AND, AND },
|
||||||
|
{ SWIG_TOKEN_LAND, LAND },
|
||||||
|
{ SWIG_TOKEN_OR, OR},
|
||||||
|
{ SWIG_TOKEN_LOR, LOR},
|
||||||
|
{ SWIG_TOKEN_XOR, XOR},
|
||||||
|
{ SWIG_TOKEN_LESSTHAN, LESSTHAN },
|
||||||
|
{ SWIG_TOKEN_GREATERTHAN, GREATERTHAN },
|
||||||
|
{ SWIG_TOKEN_LTEQUAL, LTEQUAL},
|
||||||
|
{ SWIG_TOKEN_GTEQUAL, GTEQUAL},
|
||||||
|
{ SWIG_TOKEN_NOT, NOT },
|
||||||
|
{ SWIG_TOKEN_LNOT, LNOT },
|
||||||
|
{ SWIG_TOKEN_LBRACKET, LBRACKET },
|
||||||
|
{ SWIG_TOKEN_RBRACKET, RBRACKET },
|
||||||
|
{ SWIG_TOKEN_SLASH, SLASH },
|
||||||
|
{ SWIG_TOKEN_BACKSLASH, -1 },
|
||||||
|
{ SWIG_TOKEN_ENDLINE, -1},
|
||||||
|
{ SWIG_TOKEN_STRING, STRING },
|
||||||
|
{ SWIG_TOKEN_POUND, POUND },
|
||||||
|
{ SWIG_TOKEN_PERCENT, -1 },
|
||||||
|
{ SWIG_TOKEN_COLON, COLON },
|
||||||
|
{ SWIG_TOKEN_DCOLON, DCOLON },
|
||||||
|
{ SWIG_TOKEN_LSHIFT, LSHIFT },
|
||||||
|
{ SWIG_TOKEN_RSHIFT, RSHIFT },
|
||||||
|
{ SWIG_TOKEN_ID, ID},
|
||||||
|
{ SWIG_TOKEN_FLOAT, NUM_FLOAT},
|
||||||
|
{ SWIG_TOKEN_DOUBLE, NUM_FLOAT},
|
||||||
|
{ SWIG_TOKEN_INT, NUM_INT},
|
||||||
|
{ SWIG_TOKEN_UINT, NUM_UNSIGNED},
|
||||||
|
{ SWIG_TOKEN_LONG, NUM_LONG},
|
||||||
|
{ SWIG_TOKEN_ULONG, NUM_ULONG},
|
||||||
|
{ SWIG_TOKEN_CHAR, CHARCONST},
|
||||||
|
{ SWIG_TOKEN_PERIOD, PERIOD},
|
||||||
|
{ SWIG_TOKEN_AT, -1},
|
||||||
|
{ SWIG_TOKEN_DOLLAR, -1},
|
||||||
|
{ SWIG_TOKEN_CODEBLOCK, HBLOCK},
|
||||||
|
{ SWIG_TOKEN_ILLEGAL, SWIG_TOKEN_ILLEGAL},
|
||||||
|
{ SWIG_TOKEN_LAST, -1},
|
||||||
|
{0,0},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int remap[SWIG_MAXTOKENS];
|
||||||
|
static int cscan_init = 0;
|
||||||
|
static int cplusplus_mode = 0;
|
||||||
|
static int objc_mode = 0;
|
||||||
|
static SwigScanner *cscanner = 0;
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* void lparse_init()
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static void
|
||||||
|
lparse_init() {
|
||||||
|
int i = 0;
|
||||||
|
if (cscan_init) return;
|
||||||
|
while (map[i][0]) {
|
||||||
|
remap[map[i][0]] = map[i][1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
cscanner = NewSwigScanner();
|
||||||
|
SwigScanner_idstart(cscanner,"$%@");
|
||||||
|
cscan_init = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* LParse_push(DOH *str) - Initialize the scanner
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
LParse_push(DOH *str)
|
||||||
|
{
|
||||||
|
assert(str);
|
||||||
|
lparse_init();
|
||||||
|
SwigScanner_push(cscanner, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
DOH *LParse_file() {
|
||||||
|
return SwigScanner_get_file(cscanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LParse_line() {
|
||||||
|
return SwigScanner_get_line(cscanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LParse_set_location(DOH *file, int line) {
|
||||||
|
SwigScanner_set_location(cscanner,file,line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* LParse_cplusplus(int i) - Enable C++ scanning
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
int
|
||||||
|
LParse_cplusplus(int i) {
|
||||||
|
int old = cplusplus_mode;
|
||||||
|
cplusplus_mode = i;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* LParse_objc(int i) - Enable Objective-C scanning
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
int
|
||||||
|
LParse_objc(int i) {
|
||||||
|
int old = objc_mode;
|
||||||
|
objc_mode = i;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* LParse_error(DOH *file, int line, char *fmt, ...)
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static DOH *macro_name = 0;
|
||||||
|
static DOH *macro_file = 0;
|
||||||
|
static int macro_line = 0;
|
||||||
|
|
||||||
|
void LParse_macro_location(DOH *name, DOH *file, int line) {
|
||||||
|
macro_name = name;
|
||||||
|
macro_file = file;
|
||||||
|
macro_line = line;
|
||||||
|
}
|
||||||
|
void LParse_error(DOH *file, int line, char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap,fmt);
|
||||||
|
if (!file) {
|
||||||
|
file = SwigScanner_get_file(cscanner);
|
||||||
|
line = SwigScanner_get_line(cscanner);
|
||||||
|
}
|
||||||
|
if (macro_name) {
|
||||||
|
Printf(stderr,"%s:%d In macro %s at ", macro_file, macro_line, macro_name);
|
||||||
|
}
|
||||||
|
if (line > 0) {
|
||||||
|
Printf(stderr,"%s:%d ", file, line);
|
||||||
|
} else {
|
||||||
|
Printf(stderr,"%s:EOF ",file);
|
||||||
|
}
|
||||||
|
vPrintf(stderr,fmt,ap);
|
||||||
|
va_end(ap);
|
||||||
|
macro_name = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* LParse_skip_balanced() - Skip over some text
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
DOH *
|
||||||
|
LParse_skip_balanced(int startchar, int endchar)
|
||||||
|
{
|
||||||
|
DOH *file;
|
||||||
|
int line;
|
||||||
|
file = SwigScanner_get_file(cscanner);
|
||||||
|
line = SwigScanner_get_line(cscanner);
|
||||||
|
if (SwigScanner_skip_balanced(cscanner, startchar, endchar) == -1)
|
||||||
|
LParse_error(file,line,"Missing \'%c\'. Reached the end of input.\n", endchar);
|
||||||
|
return Copy(SwigScanner_text(cscanner));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* LParse_skip_semi() - Skip to the next semicolon
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
LParse_skip_semi() {
|
||||||
|
int t, line;
|
||||||
|
DOH *file;
|
||||||
|
int lparse_yylex();
|
||||||
|
|
||||||
|
line = SwigScanner_get_line(cscanner);
|
||||||
|
file = SwigScanner_get_file(cscanner);
|
||||||
|
while ((t = lparse_yylex())) {
|
||||||
|
if (t == SEMI) return;
|
||||||
|
}
|
||||||
|
LParse_error(file,line,"Missing semicolon. Reached the end of input.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LParse_skip_decl() {
|
||||||
|
int t, line, level = 0;
|
||||||
|
DOH *file;
|
||||||
|
int lparse_yylex();
|
||||||
|
|
||||||
|
line = SwigScanner_get_line(cscanner);
|
||||||
|
file = SwigScanner_get_file(cscanner);
|
||||||
|
while ((t = lparse_yylex())) {
|
||||||
|
if ((t == SEMI) && (level == 0)) return;
|
||||||
|
if (t == LBRACE) level++;
|
||||||
|
if (t == RBRACE) {
|
||||||
|
level--;
|
||||||
|
if (level <= 0) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (level) {
|
||||||
|
LParse_error(file,line,"Missing \'}\'. Reached the end of input.\n");
|
||||||
|
} else {
|
||||||
|
LParse_error(file,line,"Missing semicolon. Reached the end of input.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* int lparse_yylex() - Entry point called by the parser
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
static int
|
||||||
|
yylex1(void) {
|
||||||
|
int l, l1;
|
||||||
|
DOH *text;
|
||||||
|
char *yytext = 0;
|
||||||
|
int lparse_yylex();
|
||||||
|
|
||||||
|
assert(cscan_init);
|
||||||
|
l = SwigScanner_token(cscanner);
|
||||||
|
if (!l) return 0;
|
||||||
|
l1 = remap[l];
|
||||||
|
if (l1 == -1) return lparse_yylex();
|
||||||
|
|
||||||
|
text = SwigScanner_text(cscanner);
|
||||||
|
yylval.tok.line = Getline(text);
|
||||||
|
yylval.tok.filename = Getfile(text);
|
||||||
|
yylval.tok.data = 0;
|
||||||
|
yylval.tok.ivalue = 0;
|
||||||
|
yytext = Char(text);
|
||||||
|
if (l1 == SWIG_TOKEN_ILLEGAL) {
|
||||||
|
LParse_error(0,0,"Illegal character '%s'\n", text);
|
||||||
|
return yylex1();
|
||||||
|
}
|
||||||
|
if (l1 == STRING) {
|
||||||
|
yylval.tok.text = NewString(yytext+1);
|
||||||
|
Delitem(yylval.tok.text,DOH_END);
|
||||||
|
}
|
||||||
|
if ((l1 == HBLOCK) || (l1 == NUM_INT) || (l1 == NUM_FLOAT) || (l1 == NUM_UNSIGNED) || (l1 == NUM_LONG) || (l1 == NUM_ULONG)) {
|
||||||
|
yylval.tok.text = NewString(yytext);
|
||||||
|
}
|
||||||
|
if (l1 == ID) {
|
||||||
|
/* Look for keywords now */
|
||||||
|
if (strcmp(yytext,"int") == 0) return(TYPE_INT);
|
||||||
|
if (strcmp(yytext,"double") == 0) return(TYPE_DOUBLE);
|
||||||
|
if (strcmp(yytext,"void") == 0) return(TYPE_VOID);
|
||||||
|
if (strcmp(yytext,"char") == 0) return(TYPE_CHAR);
|
||||||
|
if (strcmp(yytext,"short") == 0) return(TYPE_SHORT);
|
||||||
|
if (strcmp(yytext,"long") == 0) return(TYPE_LONG);
|
||||||
|
if (strcmp(yytext,"float") == 0) return(TYPE_FLOAT);
|
||||||
|
if (strcmp(yytext,"signed") == 0) return(TYPE_SIGNED);
|
||||||
|
if (strcmp(yytext,"unsigned") == 0) return(TYPE_UNSIGNED);
|
||||||
|
if (strcmp(yytext,"bool") == 0) return(TYPE_BOOL);
|
||||||
|
|
||||||
|
/* C++ keywords */
|
||||||
|
|
||||||
|
if (1 || cplusplus_mode) {
|
||||||
|
if (strcmp(yytext,"class") == 0) {
|
||||||
|
yylval.tok.text = NewString(yytext);
|
||||||
|
return(CLASS);
|
||||||
|
}
|
||||||
|
if (strcmp(yytext,"private") == 0) return(PRIVATE);
|
||||||
|
if (strcmp(yytext,"public") == 0) return(PUBLIC);
|
||||||
|
if (strcmp(yytext,"protected") == 0) return(PROTECTED);
|
||||||
|
if (strcmp(yytext,"friend") == 0) return(FRIEND);
|
||||||
|
if (strcmp(yytext,"virtual") == 0) return(VIRTUAL);
|
||||||
|
if (strcmp(yytext,"operator") == 0) return(OPERATOR);
|
||||||
|
if (strcmp(yytext,"throw") == 0) return(THROW);
|
||||||
|
if (strcmp(yytext,"inline") == 0) return(lparse_yylex());
|
||||||
|
if (strcmp(yytext,"template") == 0) return(TEMPLATE);
|
||||||
|
}
|
||||||
|
/* Objective-C keywords */
|
||||||
|
|
||||||
|
if (objc_mode) {
|
||||||
|
if (strcmp(yytext,"@interface") == 0) return (OC_INTERFACE);
|
||||||
|
if (strcmp(yytext,"@end") == 0) return (OC_END);
|
||||||
|
if (strcmp(yytext,"@public") == 0) return (OC_PUBLIC);
|
||||||
|
if (strcmp(yytext,"@private") == 0) return (OC_PRIVATE);
|
||||||
|
if (strcmp(yytext,"@protected") == 0) return (OC_PROTECTED);
|
||||||
|
if (strcmp(yytext,"@class") == 0) return(OC_CLASS);
|
||||||
|
if (strcmp(yytext,"@implementation") == 0) return(OC_IMPLEMENT);
|
||||||
|
if (strcmp(yytext,"@protocol") == 0) return(OC_PROTOCOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Misc keywords */
|
||||||
|
if (strcmp(yytext,"static") == 0) return(STATIC);
|
||||||
|
if (strcmp(yytext,"extern") == 0) return(EXTERN);
|
||||||
|
if (strcmp(yytext,"const") == 0) return(CONST);
|
||||||
|
if (strcmp(yytext,"struct") == 0) {
|
||||||
|
yylval.tok.text = NewString(yytext);
|
||||||
|
return(STRUCT);
|
||||||
|
}
|
||||||
|
if (strcmp(yytext,"union") == 0) {
|
||||||
|
yylval.tok.text = NewString(yytext);
|
||||||
|
return(UNION);
|
||||||
|
}
|
||||||
|
if (strcmp(yytext,"enum") == 0) return(ENUM);
|
||||||
|
if (strcmp(yytext,"sizeof") == 0) return(SIZEOF);
|
||||||
|
if (strcmp(yytext,"defined") == 0) return(DEFINED);
|
||||||
|
|
||||||
|
/* Ignored keywords */
|
||||||
|
if (strcmp(yytext,"volatile") == 0) return(lparse_yylex());
|
||||||
|
|
||||||
|
/* SWIG directives */
|
||||||
|
if (strcmp(yytext,"%module") == 0) return(MODULE);
|
||||||
|
if (strcmp(yytext,"%constant") == 0) return (CONSTANT);
|
||||||
|
if (strcmp(yytext,"%type") == 0) return (TYPE);
|
||||||
|
if (strcmp(yytext,"%init") == 0) return(INIT);
|
||||||
|
if (strcmp(yytext,"%wrapper") == 0) return(WRAPPER);
|
||||||
|
if (strcmp(yytext,"%readonly") == 0) return(READONLY);
|
||||||
|
if (strcmp(yytext,"%readwrite") == 0) return(READWRITE);
|
||||||
|
if (strcmp(yytext,"%name") == 0) return(NAME);
|
||||||
|
if (strcmp(yytext,"%rename") == 0) return(RENAME);
|
||||||
|
if (strcmp(yytext,"%include") == 0) return(INCLUDE);
|
||||||
|
if (strcmp(yytext,"%extern") == 0) return(WEXTERN);
|
||||||
|
if (strcmp(yytext,"%checkout") == 0) return(CHECKOUT);
|
||||||
|
if (strcmp(yytext,"%macro") == 0) return(MACRO);
|
||||||
|
if (strcmp(yytext,"%section") == 0) return(SECTION);
|
||||||
|
if (strcmp(yytext,"%subsection") == 0) return(SUBSECTION);
|
||||||
|
if (strcmp(yytext,"%subsubsection") == 0) return(SUBSUBSECTION);
|
||||||
|
if (strcmp(yytext,"%title") == 0) return(TITLE);
|
||||||
|
if (strcmp(yytext,"%style") == 0) return(STYLE);
|
||||||
|
if (strcmp(yytext,"%localstyle") == 0) return(LOCALSTYLE);
|
||||||
|
if (strcmp(yytext,"%typedef") == 0) return(TYPEDEF);
|
||||||
|
if (strcmp(yytext,"typedef") == 0) return(TYPEDEF);
|
||||||
|
if (strcmp(yytext,"%alpha") == 0) return(ALPHA_MODE);
|
||||||
|
if (strcmp(yytext,"%raw") == 0) return(RAW_MODE);
|
||||||
|
if (strcmp(yytext,"%text") == 0) return(TEXT);
|
||||||
|
if (strcmp(yytext,"%native") == 0) return(NATIVE);
|
||||||
|
if (strcmp(yytext,"%disabledoc") == 0) return(DOC_DISABLE);
|
||||||
|
if (strcmp(yytext,"%enabledoc") == 0) return(DOC_ENABLE);
|
||||||
|
if (strcmp(yytext,"%pragma") == 0) return(PRAGMA);
|
||||||
|
if (strcmp(yytext,"%addmethods") == 0) return(ADDMETHODS);
|
||||||
|
if (strcmp(yytext,"%inline") == 0) return(INLINE);
|
||||||
|
if (strcmp(yytext,"%typemap") == 0) return(TYPEMAP);
|
||||||
|
if (strcmp(yytext,"%except") == 0) return(EXCEPT);
|
||||||
|
if (strcmp(yytext,"%import") == 0) return(IMPORT);
|
||||||
|
if (strcmp(yytext,"%echo") == 0) return(ECHO);
|
||||||
|
if (strcmp(yytext,"%new") == 0) return(NEW);
|
||||||
|
if (strcmp(yytext,"%apply") == 0) return(APPLY);
|
||||||
|
if (strcmp(yytext,"%clear") == 0) return(CLEAR);
|
||||||
|
if (strcmp(yytext,"%doconly") == 0) return(DOCONLY);
|
||||||
|
|
||||||
|
/* Have an unknown identifier, as a last step, we'll */
|
||||||
|
/* do a typedef lookup on it. */
|
||||||
|
yylval.tok.text = NewString(yytext);
|
||||||
|
if (LParse_typedef_check(yylval.tok.text)) {
|
||||||
|
return TYPE_TYPEDEF;
|
||||||
|
}
|
||||||
|
return(ID);
|
||||||
|
}
|
||||||
|
return(l1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lparse_yylex() {
|
||||||
|
int t;
|
||||||
|
t = yylex1();
|
||||||
|
/* printf("%d\n",t); */
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
98
SWIG/Source/LParse/lparse.h
Normal file
98
SWIG/Source/LParse/lparse.h
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* Simplified Wrapper and Interface Generator (SWIG)
|
||||||
|
*
|
||||||
|
* Author : David Beazley
|
||||||
|
*
|
||||||
|
* Department of Computer Science
|
||||||
|
* University of Chicago
|
||||||
|
* 1100 E 58th Street
|
||||||
|
* Chicago, IL 60637
|
||||||
|
* beazley@cs.uchicago.edu
|
||||||
|
*
|
||||||
|
* Please read the file LICENSE for the copyright and terms by which SWIG
|
||||||
|
* can be used and distributed.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _LPARSE_H
|
||||||
|
#define _LPARSE_H
|
||||||
|
|
||||||
|
#include "swig.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern void LParse_push(DOH *);
|
||||||
|
extern DOH *LParse_skip_balanced(int, int);
|
||||||
|
extern void LParse_skip_semi();
|
||||||
|
extern void LParse_skip_decl();
|
||||||
|
extern DOH *LParse_parse(DOH *str);
|
||||||
|
extern DOH *LParse_file();
|
||||||
|
extern int LParse_line();
|
||||||
|
extern void LParse_set_location(DOH *file, int line);
|
||||||
|
extern void LParse_error(DOH *file, int line, char *fmt, ...);
|
||||||
|
extern void LParse_macro_location(DOH *name, DOH *file, int line);
|
||||||
|
extern int LParse_cplusplus(int i);
|
||||||
|
extern int LParse_objc(int i);
|
||||||
|
|
||||||
|
#define LPARSE_T_INT 1
|
||||||
|
#define LPARSE_T_SHORT 2
|
||||||
|
#define LPARSE_T_LONG 3
|
||||||
|
#define LPARSE_T_UINT 4
|
||||||
|
#define LPARSE_T_USHORT 5
|
||||||
|
#define LPARSE_T_ULONG 6
|
||||||
|
#define LPARSE_T_UCHAR 7
|
||||||
|
#define LPARSE_T_SCHAR 8
|
||||||
|
#define LPARSE_T_BOOL 9
|
||||||
|
#define LPARSE_T_DOUBLE 10
|
||||||
|
#define LPARSE_T_FLOAT 11
|
||||||
|
#define LPARSE_T_CHAR 12
|
||||||
|
#define LPARSE_T_USER 13
|
||||||
|
#define LPARSE_T_VOID 14
|
||||||
|
#define LPARSE_T_ENUM 50
|
||||||
|
#define LPARSE_T_STRING 51
|
||||||
|
#define LPARSE_T_VARARGS 52
|
||||||
|
#define LPARSE_T_FUNCTION 53
|
||||||
|
#define LPARSE_T_SYMBOL 98
|
||||||
|
#define LPARSE_T_ERROR 99
|
||||||
|
|
||||||
|
/* This is the semi-bogus type structure from SWIG1.1. It will be replaced someday */
|
||||||
|
|
||||||
|
#define LPARSE_MAX_NAME 96
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DOHXCOMMON;
|
||||||
|
int type;
|
||||||
|
char *name;
|
||||||
|
char is_pointer;
|
||||||
|
char implicit_ptr;
|
||||||
|
char is_reference;
|
||||||
|
char status;
|
||||||
|
char *qualifier;
|
||||||
|
char *arraystr;
|
||||||
|
} LParseType;
|
||||||
|
|
||||||
|
extern LParseType *NewLParseType(int t);
|
||||||
|
extern void DelLParseType(DOH *t);
|
||||||
|
extern DOH *CopyLParseType(DOH *t);
|
||||||
|
extern int LParseType_check(DOH *t);
|
||||||
|
extern void LParse_typedef_add(LParseType *t, DOH *tname);
|
||||||
|
extern void LParse_typedef_resolve(LParseType *t, int level);
|
||||||
|
extern void LParse_typedef_replace(LParseType *t);
|
||||||
|
extern int LParse_typedef_check(DOH *tname);
|
||||||
|
extern void LParse_typedef_updatestatus(LParseType *t, int newstatus);
|
||||||
|
extern void LParse_merge_scope(DOH *h);
|
||||||
|
extern void LParse_new_scope(DOH *);
|
||||||
|
extern DOH *LParse_collapse_scope(DOH *prefix);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
2038
SWIG/Source/LParse/parser.y
Normal file
2038
SWIG/Source/LParse/parser.y
Normal file
File diff suppressed because it is too large
Load diff
407
SWIG/Source/LParse/type.c
Normal file
407
SWIG/Source/LParse/type.c
Normal file
|
|
@ -0,0 +1,407 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* Simplified Wrapper and Interface Generator (SWIG)
|
||||||
|
*
|
||||||
|
* Author : David Beazley
|
||||||
|
*
|
||||||
|
* Department of Computer Science
|
||||||
|
* University of Chicago
|
||||||
|
* 1100 E 58th Street
|
||||||
|
* Chicago, IL 60637
|
||||||
|
* beazley@cs.uchicago.edu
|
||||||
|
*
|
||||||
|
* Please read the file LICENSE for the copyright and terms by which SWIG
|
||||||
|
* can be used and distributed.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "lparse.h"
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* $Header$
|
||||||
|
*
|
||||||
|
* type.c
|
||||||
|
*
|
||||||
|
* Lame type structure for old SWIG parser
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
extern DOH *LParseTypeStr(DOH *to);
|
||||||
|
|
||||||
|
static DohObjInfo LParseTypeType = {
|
||||||
|
"LParseType", /* objname */
|
||||||
|
sizeof(LParseType), /* objsize */
|
||||||
|
DelLParseType, /* doh_del */
|
||||||
|
CopyLParseType, /* doh_copy */
|
||||||
|
0, /* doh_clear */
|
||||||
|
0, /* doh_scope */
|
||||||
|
LParseTypeStr, /* doh_str */
|
||||||
|
0, /* doh_data */
|
||||||
|
0, /* doh_dump */
|
||||||
|
0, /* doh_load */
|
||||||
|
0, /* doh_len */
|
||||||
|
0, /* doh_hash */
|
||||||
|
0, /* doh_cmp */
|
||||||
|
0, /* doh_mapping */
|
||||||
|
0, /* doh_sequence */
|
||||||
|
0, /* doh_file */
|
||||||
|
0, /* doh_string */
|
||||||
|
0, /* doh_callable */
|
||||||
|
0, /* doh_position */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* NewLParseType() - Create a new datatype
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
LParseType *
|
||||||
|
NewLParseType(int ty) {
|
||||||
|
LParseType *t = (LParseType *) DohObjMalloc(sizeof(LParseType));
|
||||||
|
t->objinfo = &LParseTypeType;
|
||||||
|
t->type = ty;
|
||||||
|
t->name = (char *) malloc(LPARSE_MAX_NAME);
|
||||||
|
t->name[0] = 0;
|
||||||
|
t->is_pointer = 0;
|
||||||
|
t->implicit_ptr = 0;
|
||||||
|
t->is_reference = 0;
|
||||||
|
t->status = 0;
|
||||||
|
t->qualifier = 0;
|
||||||
|
t->arraystr = 0;
|
||||||
|
switch(ty) {
|
||||||
|
case LPARSE_T_INT:
|
||||||
|
strcpy(t->name,"int");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_UINT:
|
||||||
|
strcpy(t->name,"unsigned");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_SHORT:
|
||||||
|
strcpy(t->name,"short");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_USHORT:
|
||||||
|
strcpy(t->name,"unsigned short");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_LONG:
|
||||||
|
strcpy(t->name,"long");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_ULONG:
|
||||||
|
strcpy(t->name,"unsigned long");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_FLOAT:
|
||||||
|
strcpy(t->name,"float");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_DOUBLE:
|
||||||
|
strcpy(t->name,"double");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_CHAR:
|
||||||
|
strcpy(t->name,"char");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_SCHAR:
|
||||||
|
strcpy(t->name,"signed char");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_UCHAR:
|
||||||
|
strcpy(t->name,"unsigned char");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_VOID:
|
||||||
|
strcpy(t->name,"void");
|
||||||
|
break;
|
||||||
|
case LPARSE_T_BOOL:
|
||||||
|
strcpy(t->name,"bool");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* DelLParseType() - Destroy a datatype
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
void DelLParseType(DOH *t) {
|
||||||
|
LParseType *ty = (LParseType *) t;
|
||||||
|
assert(ty->refcount <= 0);
|
||||||
|
free(ty->name);
|
||||||
|
if (ty->qualifier) free(ty->qualifier);
|
||||||
|
if (ty->arraystr) free(ty->arraystr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* CopyLParseType() - Copy a type
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
DOH *
|
||||||
|
CopyLParseType(DOH *co) {
|
||||||
|
LParseType *c;
|
||||||
|
LParseType *t = (LParseType *) DohObjMalloc(sizeof(LParseType));
|
||||||
|
c = (LParseType *) co;
|
||||||
|
t->objinfo = &LParseTypeType;
|
||||||
|
t->type = c->type;
|
||||||
|
t->name = (char *) malloc(LPARSE_MAX_NAME);
|
||||||
|
strcpy(t->name,c->name);
|
||||||
|
t->is_pointer = c->is_pointer;
|
||||||
|
t->implicit_ptr = c->implicit_ptr;
|
||||||
|
t->is_reference = c->is_reference;
|
||||||
|
t->status = c->status;
|
||||||
|
t->qualifier = copy_string(c->qualifier);
|
||||||
|
t->arraystr = copy_string(c->arraystr);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* LParseTypeStr() - Make a string of a datatype.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
DOH *
|
||||||
|
LParseTypeStr(DOH *to) {
|
||||||
|
DOH *s;
|
||||||
|
int i;
|
||||||
|
LParseType *t = (LParseType *) to;
|
||||||
|
s = NewString("");
|
||||||
|
Printf(s,"(%d) - ", t->type);
|
||||||
|
if (t->qualifier)
|
||||||
|
Printf(s,"%s ",t->qualifier);
|
||||||
|
Printf(s,"%s ",t->name);
|
||||||
|
if (t->is_reference || t->arraystr) t->is_pointer--;
|
||||||
|
for (i = 0; i < t->is_pointer; i++)
|
||||||
|
Putc('*',s);
|
||||||
|
if (t->is_reference || t->arraystr) t->is_pointer++;
|
||||||
|
if (t->is_reference)
|
||||||
|
Putc('&',s);
|
||||||
|
if (t->arraystr)
|
||||||
|
Printf(s,"%s", t->arraystr);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* --- typedef support ---
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define MAXSCOPE 256
|
||||||
|
static DOH *typedef_hash[MAXSCOPE];
|
||||||
|
static int scope = 0;
|
||||||
|
static int typedef_init = 0;
|
||||||
|
|
||||||
|
static void init_typedef() {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MAXSCOPE; i++)
|
||||||
|
typedef_hash[i] = 0;
|
||||||
|
scope = 0;
|
||||||
|
typedef_hash[scope] = NewHash();
|
||||||
|
typedef_init = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* void LParse_typedef_add(LParseType *t, DOH *tname)
|
||||||
|
*
|
||||||
|
* Create a new typedef.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void LParse_typedef_add(LParseType *t, DOH *tname) {
|
||||||
|
LParseType *nt;
|
||||||
|
|
||||||
|
if (!typedef_init) init_typedef();
|
||||||
|
/* Check to see if the type already exists */
|
||||||
|
if ((nt = (LParseType *) Getattr(typedef_hash[scope],tname))) {
|
||||||
|
Printf(stderr,"Warning. Datatype %s already defined (2nd definition ignored).\n", tname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nt = (LParseType *) CopyLParseType(t);
|
||||||
|
nt->implicit_ptr = (t->is_pointer-t->implicit_ptr); /* Record if mapped type is a pointer */
|
||||||
|
nt->is_pointer = (t->is_pointer-t->implicit_ptr); /* Adjust pointer value to be correct */
|
||||||
|
LParse_typedef_resolve(nt,0); /* Resolve any other mappings of this type */
|
||||||
|
|
||||||
|
/* Add this type to our hash table */
|
||||||
|
Setattr(typedef_hash[scope],tname, nt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* void LParse_typedef_resolve(LParseType *t, int level = 0)
|
||||||
|
*
|
||||||
|
* Checks to see if this datatype is in the typedef hash and
|
||||||
|
* resolves it if necessary. This will check all of the typedef
|
||||||
|
* hash tables we know about.
|
||||||
|
*
|
||||||
|
* level is an optional parameter that determines which scope to use.
|
||||||
|
* Usually this is only used with a bare :: operator in a datatype.
|
||||||
|
*
|
||||||
|
* The const headache :
|
||||||
|
*
|
||||||
|
* Normally SWIG will fail if a const variable is used in a typedef
|
||||||
|
* like this :
|
||||||
|
*
|
||||||
|
* typedef const char *String;
|
||||||
|
*
|
||||||
|
* This is because future occurrences of "String" will be treated like
|
||||||
|
* a char *, but without regard to the "constness". To work around
|
||||||
|
* this problem. The resolve() method checks to see if these original
|
||||||
|
* data type is const. If so, we'll substitute the name of the original
|
||||||
|
* datatype instead. Got it?
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void LParse_typedef_resolve(LParseType *t, int level) {
|
||||||
|
LParseType *td;
|
||||||
|
int s = scope - level;
|
||||||
|
|
||||||
|
if (!typedef_init) init_typedef();
|
||||||
|
while (s >= 0) {
|
||||||
|
if ((td = (LParseType *) Getattr(typedef_hash[s],t->name))) {
|
||||||
|
t->type = td->type;
|
||||||
|
t->is_pointer += td->is_pointer;
|
||||||
|
t->implicit_ptr += td->implicit_ptr;
|
||||||
|
t->status = t->status | td->status;
|
||||||
|
|
||||||
|
/* Check for constness, and replace type name if necessary */
|
||||||
|
|
||||||
|
if (td->qualifier) {
|
||||||
|
if (strcmp(td->qualifier,"const") == 0) {
|
||||||
|
strcpy(t->name,td->name);
|
||||||
|
t->qualifier = copy_string(td->qualifier);
|
||||||
|
t->implicit_ptr -= td->implicit_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
/* Not found, do nothing */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* void LParse_typedef_replace()
|
||||||
|
*
|
||||||
|
* Checks to see if this datatype is in the typedef hash and
|
||||||
|
* replaces it with the hash entry. Only applies to current scope.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void LParse_typedef_replace(LParseType *t) {
|
||||||
|
LParseType *td;
|
||||||
|
DOH *temp;
|
||||||
|
|
||||||
|
if (!typedef_init) init_typedef();
|
||||||
|
temp = NewString("");
|
||||||
|
if ((td = (LParseType *) Getattr(typedef_hash[scope],t->name))) {
|
||||||
|
t->type = td->type;
|
||||||
|
t->is_pointer = td->is_pointer;
|
||||||
|
t->implicit_ptr -= td->implicit_ptr;
|
||||||
|
strcpy(t->name, td->name);
|
||||||
|
if (td->arraystr) {
|
||||||
|
if (t->arraystr) {
|
||||||
|
Printf(temp,"%s", t->arraystr);
|
||||||
|
free(t->arraystr);
|
||||||
|
}
|
||||||
|
Printf(temp,"%s", td->arraystr);
|
||||||
|
t->arraystr = copy_string(Char(temp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Delete(temp);
|
||||||
|
/* Not found, do nothing */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* int LParse_typedef_check(DOH *tname)
|
||||||
|
*
|
||||||
|
* Checks to see whether tname is the name of a datatype we know
|
||||||
|
* about. Returns 1 if there's a match, 0 otherwise
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int LParse_typedef_check(DOH *tname) {
|
||||||
|
int s = scope;
|
||||||
|
if (!typedef_init) init_typedef();
|
||||||
|
while (s >= 0) {
|
||||||
|
if (Getattr(typedef_hash[s],tname)) return 1;
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* void LParse_typedef_updatestatus(LParseType *t, int newstatus)
|
||||||
|
*
|
||||||
|
* Checks to see if this datatype is in the hash table. If
|
||||||
|
* so, we'll update its status. This is sometimes used with
|
||||||
|
* typemap handling. Only applies to current scope.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
void LParse_typedef_updatestatus(LParseType *t, int newstatus) {
|
||||||
|
LParseType *td;
|
||||||
|
if (!typedef_init) init_typedef();
|
||||||
|
if ((td = (LParseType *) Getattr(typedef_hash[scope], t->name))) {
|
||||||
|
td->status = newstatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* void LParse_merge_scope(DOH *h)
|
||||||
|
*
|
||||||
|
* Copies all of the entries in scope h into the current scope. This is
|
||||||
|
* primarily done with C++ inheritance.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void LParse_merge_scope(DOH *h) {
|
||||||
|
DOH *key;
|
||||||
|
DOH *nt;
|
||||||
|
|
||||||
|
if (!typedef_init) init_typedef();
|
||||||
|
if (h) {
|
||||||
|
/* Copy all of the entries in the given hash table to this new one */
|
||||||
|
key = Firstkey(h);
|
||||||
|
while (key) {
|
||||||
|
nt = Copy(Getattr(h,key));
|
||||||
|
Setattr(typedef_hash[scope],key,nt);
|
||||||
|
key = Nextkey(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* void LParse_new_scope(DOH *h)
|
||||||
|
*
|
||||||
|
* Creates a new scope for handling typedefs. This is used in C++ handling
|
||||||
|
* to create typedef local to a class definition.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void LParse_new_scope(DOH *h) {
|
||||||
|
if (!typedef_init) init_typedef();
|
||||||
|
scope++;
|
||||||
|
typedef_hash[scope] = NewHash();
|
||||||
|
if (h) {
|
||||||
|
LParse_merge_scope(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* DOH *LParse_collapse_scope(DOH *prefix)
|
||||||
|
*
|
||||||
|
* Collapses the current scope into the previous one, but applies a prefix to
|
||||||
|
* all of the datatypes. This is done in order to properly handle C++ stuff.
|
||||||
|
* For example :
|
||||||
|
*
|
||||||
|
* class Foo {
|
||||||
|
* ...
|
||||||
|
* typedef double Real;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* will have a type mapping of "double --> Real" within the class itself.
|
||||||
|
* When we collapse the scope, this mapping will become "double --> Foo::Real"
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
DOH *LParse_collapse_scope(DOH *prefix) {
|
||||||
|
LParseType *nt;
|
||||||
|
DOH *key;
|
||||||
|
DOH *temp;
|
||||||
|
DOH *h;
|
||||||
|
|
||||||
|
if (!typedef_init) init_typedef();
|
||||||
|
if (scope > 0) {
|
||||||
|
if (prefix) {
|
||||||
|
key = Firstkey(typedef_hash[scope]);
|
||||||
|
while (key) {
|
||||||
|
nt = (LParseType *) Copy(Getattr(typedef_hash[scope],key));
|
||||||
|
temp = NewString("");
|
||||||
|
Printf(temp,"%s::%s", prefix,key);
|
||||||
|
Setattr(typedef_hash[scope-1],temp,nt);
|
||||||
|
key = Nextkey(typedef_hash[scope]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h = typedef_hash[scope];
|
||||||
|
typedef_hash[scope] = 0;
|
||||||
|
scope--;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue