/* * FILE: scan_c.l * * DESCRIPTION: This is the lex file used to parse a C source code. */ %{ /* * freescope - Free source browser * Copyright (C) 2001 Olivier Deme * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifdef HAVE_CONFIG_H #include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include #include "parser.h" #ifndef MAP_FILE #define MAP_FILE 0 /* for systems other than 4.3+BSD */ #endif /* MAP_FILE */ #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) void scan_c (char*, size_t); static int strip_comments (register char*, register char*, off_t); static int is_native_type (register char*, size_t); size_t scope_length; char scope [255]; char file [255]; size_t file_length; int scope_level = 0; int call_level = 0; line_nbr_t lineno; %} WS [ \t\n] WS_PTR [ \t\n\*] TYPE char|double|float|int|long|short|signed|void|unsigned RESERVED auto|break|case|const|continue|default|do|default|do|else|enum|extern|for|goto|if|register|return|sizeof|static|struct|switch|typedef|union|volatile|while KWORD {TYPE}|{RESERVED} LETTER [a-zA-Z_] DIGIT [0-9] HEXDIGIT [a-fA-F0-9] SYMBOL {LETTER}({LETTER}|{DIGIT})* CHAR '.' VAR {SYMBOL}{WS}* ARRAY {SYMBOL}{WS}*(\[.*\]{WS}*)+ PREPROCESS #{SYMBOL} STRUCT struct{WS}+ VAR_DECL {SYMBOL}{WS_PTR}+{VAR}{WS}*; ARRAY_DECL {SYMBOL}{WS_PTR}+{ARRAY}{WS}*; VAR_MULTI_DECL {SYMBOL}{WS_PTR}+{VAR}{WS}*, VAR_MIDDLE_DECL {WS_PTR}*{SYMBOL}{WS}*, ARRAY_MULTI_DECL {SYMBOL}{WS_PTR}+{ARRAY}{WS}*, NEW_MULTI_DECL {WS_PTR}*{VAR}{WS}*, NEW_ARRAY_MULTI_DECL {WS_PTR}*{ARRAY}{WS}*, LAST_MULTI_DECL {WS_PTR}*{VAR}{WS}*\}?; LAST_ARRAY_MULTI_DECL {WS_PTR}*{ARRAY}{WS}*\}?; VAR_DECL_ASSIGN {SYMBOL}{WS_PTR}+{VAR}{WS}*=[^=]? ARRAY_DECL_ASSIGN {SYMBOL}{WS_PTR}+{ARRAY}=[^=]? MULTI_DECL_ASSIGN {SYMBOL}{WS_PTR}+{SYMBOL}{WS}*=[^=]?[^{]\+, NEW_MULTI_DECL_ASSIGN {WS_PTR}*{SYMBOL}{WS}*=[^=]?.*, LAST_MULTI_DECL_ASSIGN {WS_PTR}*{SYMBOL}{WS}*=[^=]?[^,]*\}?; FALSE_FUNC_DEF_1 {KWORD}{WS}*\([^\)]*\){WS}*\{ FALSE_FUNC_DEF_2 ({SYMBOL}|{KWORD}){WS_PTR}+{KWORD}{WS}*\([^\)]*\){WS}*\{ STRUCT_DECL struct{WS}+{SYMBOL}{WS}*\{ ANSI_FUNC_DEF_1 {SYMBOL}{WS}*\([^\)]*\){WS}*\{ ANSI_FUNC_DEF_2 {SYMBOL}{WS_PTR}+{SYMBOL}{WS}*\([^\)]*\){WS}*\{ KR_FUNC_DEF_1 {SYMBOL}{WS}*\([^\)]*\){WS}*([^\n]+;{WS}*)+\{ KR_FUNC_DEF_2 {SYMBOL}{WS_PTR}+{SYMBOL}{WS}*\([^\)]*\){WS}*([^\n]+;{WS}*)+\{ FUNC_CALL {SYMBOL}{WS}*\( FALSE_FUNC_CALL {KWORD}{WS}*\( FALSE_DECL1 {RESERVED}{WS}+{SYMBOL}{WS}*; FALSE_DECL2 {PREPROCESS}{WS}+{SYMBOL}{WS}*; DEFINITION #\ *define[ \t]+{SYMBOL} UNION_DECL union{WS}+{SYMBOL}{WS}*\{ ENUM_DECL enum{WS}+{SYMBOL}{WS}*\{ EXTERN_DECL extern\ + FALSE_STRUCT_UNION_DECL \}{WS_PTR}*{KWORD}{WS}*; STRUCT_UNION_DECL \}{WS_PTR}*(({VAR}|{ARRAY}),{WS_PTR}*)*({SYMBOL}|{ARRAY}){WS}*; %x FC %x MULTI_DECL %x FUNC_ARG %option stack %% {CHAR} { } \n { ++lineno; } \{ { ++scope_level; } \} { if ((scope_level != 0) && (--scope_level == 0)) { strcpy(scope, GLOBAL_SCOPE); scope_length = GLOBAL_SCOPE_LENGTH; } if (YYSTATE != INITIAL) yy_pop_state(); } ; { while (YYSTATE != INITIAL) yy_pop_state(); } {EXTERN_DECL} { /* extern ... */ yyless(6); yy_push_state(FUNC_ARG); } {RESERVED} { } {TYPE} { } \) { yy_pop_state(); } {SYMBOL} { add2db(ANY, yytext, yyleng, scope, scope_length, lineno); } 0x{HEXDIGIT}+ { } {FALSE_FUNC_DEF_1} { /* * This is something like if (...) { ... * We need to go back to the opening bracket since we might have a function * call inside (or something else). */ register size_t length = 0; /* Find the '(' */ while (yytext[length] != '(') { if (yytext[length] == '\n') ++lineno; ++length; } yyless(length); } {FALSE_FUNC_DEF_2} { /* * This is something like else if (...) { ... * We need to go back to the opening bracket since we might have a function * call inside (or something else). */ register size_t length = 0; /* Find the '(' */ while (yytext[length] != '(') { if (yytext[length] == '\n') ++lineno; ++length; } yyless(length); } {ANSI_FUNC_DEF_1} | {KR_FUNC_DEF_1} { /* * func (type1 arg1, type2 arg2, etc...) { */ register size_t length = 0; /* Get symbol length */ while ((yytext[length] != ' ') && (yytext[length] != '(') && (yytext[length] != '\n')) ++length; add2db(DEFINITION, yytext, length, scope, scope_length, lineno); strncpy(scope, yytext, length); scope[length] = '\0'; scope_length = length; yyless(length); yy_push_state(FUNC_ARG); } {ANSI_FUNC_DEF_2} | {KR_FUNC_DEF_2} { /* * symbol func (type1 arg1, type2 arg2, etc...) { * symbol ** func (type1 arg1, type2 arg2, etc...) { */ register size_t length = 0; register char* p = yytext; /* Get return type */ while ((*p != ' ') && (*p != '*') && (*p != '\n')) ++p; if (!is_native_type(yytext, p - yytext)) { add2db(ANY, yytext, p - yytext, scope, scope_length, lineno); } /* Skip '*' and spaces */ while ((*p == ' ') || (*p == '*') || (*p == '\n')) { if (*p == '\n') ++lineno; ++p; } /* Get function name */ while ((p[length] != ' ') && (p[length] != '(') && (p[length] != '\n')) ++length; add2db(DEFINITION, p, length, scope, scope_length, lineno); strncpy(scope, p, length); scope[length] = '\0'; scope_length = length; yyless(length + (p - yytext)); yy_push_state(FUNC_ARG); } {FALSE_FUNC_CALL} { /* * This is something like if (...) * We need to go back to the opening bracket since we might have a function * call inside (or something else). */ register size_t length = 0; /* Find the '(' */ while (yytext[length] != '(') { if (yytext[length] == '\n') ++lineno; ++length; } yyless(length); } {FUNC_CALL} { register size_t length = 0; /* Get symbol length */ while ((yytext[length] != ' ') && (yytext[length] != '(') && (yytext[length] != '\n')) ++length; if (strcmp(scope, GLOBAL_SCOPE) != 0) { add2db(FUNC_CALL, yytext, length, scope, scope_length, lineno); } else { add2db(ANY, yytext, length, scope, scope_length, lineno); } if (call_level == 0) yy_push_state(FC); ++call_level; yyless(length); } \) { if (--call_level == 0) yy_pop_state(); } {FALSE_DECL1} | /* "return a;", etc... are not var decl */ {FALSE_DECL2} { /* "#endif SYMBOL;", etc... are not var decl */ register size_t length = 0; /* Go to first space */ while ((yytext[length] != ' ') && (yytext[length] != '\n') && (yytext[length] != '*')) { ++length; } yyless(length); } {DEFINITION} { register char* p = yytext; /* skip "# define " */ p = strstr(yytext, "define") + 6; /* Go to first non-blank */ while ((*p == ' ') || (*p == '\n')) { if (*p == '\n') ++lineno; ++p; } /* Go to first space */ add2db(DEFINITION, p, yytext + yyleng - p, scope, scope_length, lineno); } {VAR_DECL} { /* TYPE ** var ; */ register int length = 0; register char* p; /* Add type in database */ while ((yytext[length] != ' ') && (yytext[length] != '\n') && (yytext[length] != '*')) { ++length; } if (!is_native_type(yytext, length)) { add2db(ANY, yytext, length, scope, scope_length, lineno); } p = yytext + length; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ length = 0; while ((p[length] != ' ') && (p[length] != ';') &&(p[length] != '\n')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); } {ARRAY_DECL} { /* TYPE ** var [arg1] [arg2] ... ; */ register int length = 0; register char* p; /* Add type in database */ while ((yytext[length] != ' ') && (yytext[length] != '\n') && (yytext[length] != '*')) { ++length; } if (!is_native_type(yytext, length)) { add2db(ANY, yytext, length, scope, scope_length, lineno); } p = yytext + length; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ length = 0; while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != '[')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); yyless(length + (p - yytext)); } {VAR_MULTI_DECL} { /* TYPE ** var1, */ register int length = 0; register char* p; /* Add type in database */ while ((yytext[length] != ' ') && (yytext[length] != '\n') && (yytext[length] != '*')) { ++length; } if (!is_native_type(yytext, length)) { add2db(ANY, yytext, length, scope, scope_length, lineno); } p = yytext + length; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ length = 0; while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != ',')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); yy_push_state(MULTI_DECL); yyless(length + (p - yytext)); } {NEW_MULTI_DECL} { /* ** var , */ register int length = 0; register char* p = yytext; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != ',')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); yyless(length + (p - yytext)); } {LAST_MULTI_DECL} { /* ** var ; */ /* ** var , */ register int length = 0; register char* p = yytext; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != ';')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); yyless(length + (p - yytext)); yy_pop_state(); } {ARRAY_MULTI_DECL} { /* TYPE ** var [arg1] [arg2] ... , */ register int length = 0; register char* p; /* Add type in database */ while ((yytext[length] != ' ') && (yytext[length] != '\n') && (yytext[length] != '*')) { ++length; } if (!is_native_type(yytext, length)) { add2db(ANY, yytext, length, scope, scope_length, lineno); } p = yytext + length; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ length = 0; while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != '[')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); yyless(length + (p - yytext)); yy_push_state(MULTI_DECL); } {NEW_ARRAY_MULTI_DECL} { /* ** var [arg1] [arg2] ... , */ register int length = 0; register char* p = yytext; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != '[')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); yyless(length + (p - yytext)); } {LAST_ARRAY_MULTI_DECL} { /* ** var [arg1] [arg2] ... ; */ register int length = 0; register char* p = yytext; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != '[')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); /* Skip blanks */ while ((*p == ' ') || (*p == '\n')) { if (*p == '\n') ++lineno; ++p; } yyless(length + (p - yytext)); yy_pop_state(); } {VAR_DECL_ASSIGN} | {ARRAY_DECL_ASSIGN} { /* * TYPE ** var = * TYPE ** var [arg1] [arg2] ... = */ register int length = 0; register char* p; /* Add type in database */ while ((yytext[length] != ' ') && (yytext[length] != '\n') && (yytext[length] != '*')) { ++length; } if (!is_native_type(yytext, length)) { add2db(ANY, yytext, length, scope, scope_length, lineno); } p = yytext + length; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ length = 0; while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != '[') && (p[length] != '=')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); yyless(length + (p - yytext)); } {MULTI_DECL_ASSIGN} { /* TYPE ** var = ... , */ register int length = 0; register int length2 = 0; register char* p; /* Add type in database */ while ((yytext[length] != ' ') && (yytext[length] != '\n') && (yytext[length] != '*')) { ++length; } if (!is_native_type(yytext, length)) { add2db(ANY, yytext, length, scope, scope_length, lineno); } p = yytext + length; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ length = 0; while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != ',')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); p += length; /* Skip blanks and '=' */ while ((*p == ' ') || (*p == '\n') || (*p == '=')) { if (*p == '\n') ++lineno; ++p; } length = 0; /* Get initialiser */ if ((*p != '"') && (*p != '\'') && (*p != '{') && (*p < 60 || *p > 71)) { while ((p[length2] != ' ') && (p[length2] != '\n') && (p[length2] != ',')) { ++length2; } add2db(ANY, p, length2, scope, scope_length, lineno); } else { yyless(length + (p - yytext)); } yy_push_state(MULTI_DECL); } {NEW_MULTI_DECL_ASSIGN} { /* ** arg = ... , */ register int length = 0; register int length2 = 0; register char* p = yytext; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ length = 0; while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != '=')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); p += length; /* Skip blanks and '=' */ while ((*p == ' ') || (*p == '\n') || (*p == '=')) { if (*p == '\n') ++lineno; ++p; } length2 = 0; /* Get initialiser */ if ((*p != '"') && (*p != '\'') && (*p != '{') && (*p < 60 || *p > 71)) { while ((p[length2] != ' ') && (p[length2] != '\n') && (p[length2] != ',')) { ++length2; } add2db(ANY, p, length2, scope, scope_length, lineno); } else { yyless(length + (p - yytext)); } } {LAST_MULTI_DECL_ASSIGN} { /* ** arg = ... ; */ register int length = 0; register char* p; /* Add type in database */ while ((yytext[length] != ' ') && (yytext[length] != '\n') && (yytext[length] != '*')) { ++length; } if (!is_native_type(yytext, length)) { add2db(ANY, yytext, length, scope, scope_length, lineno); } p = yytext + length; /* Skip blanks and pointers */ while ((*p == ' ') || (*p == '\n') || (*p == '*')) { if (*p == '\n') ++lineno; ++p; } /* Get variable */ length = 0; while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != '=')) { ++length; } add2db(DEFINITION, p, length, scope, scope_length, lineno); yyless(length + (p - yytext)); if (YYSTATE != INITIAL) yy_pop_state(); } {STRUCT_DECL} | {UNION_DECL} { /* * struct var { * union var { */ register int length = 0; register char* p = yytext; /* Go to first space */ while ((*p != ' ') && (*p != '\n')) ++p; /* Go to first character */ while ((*p == ' ') || (*p == '\n')) { if (*p == '\n') ++lineno; ++p; } /* Add type in database */ while ((p[length] != ' ') && (p[length] != '\n') && (p[length] != '{')) ++length; add2db(DEFINITION, p, length, scope, scope_length, lineno); yyless(length + (p - yytext)); } {FALSE_STRUCT_UNION_DECL} { /* } (break|else|...) ; */ if ((scope_level != 0) && (--scope_level == 0)) { strcpy(scope, GLOBAL_SCOPE); scope_length = GLOBAL_SCOPE_LENGTH; } yyless(1); } {STRUCT_UNION_DECL} { /* } ** var1, var2[arg1], ... ; */ yyless(1); if ((scope_level != 0) && (--scope_level == 0)) { strcpy(scope, GLOBAL_SCOPE); scope_length = GLOBAL_SCOPE_LENGTH; } yy_push_state(MULTI_DECL); } {ENUM_DECL} { /* enum var {...} */ register int length = 0; register char* p = yytext + 5; /* Go to var */ while ((*p == ' ') || (*p == '\n')) { if (*p == '\n') ++lineno; ++p; } /* Add type in database */ while ((p[length] != ' ') && (p[length] != '\n')) ++length; add2db(DEFINITION, p, length, scope, scope_length, lineno); yyless(length + (p - yytext)); yy_push_state(MULTI_DECL); } \ *if | \ *ifdef | \ *ifndef | \ *else | \ *elif | \ *endif | \ *pragma { } \ *include\ *\<[^\ ]+\> { /* #include <...> */ register char* p; register char* q; /* Get header file */ p = strchr(yytext, '<') + 1; while ((*p == ' ') || (*p == '\n')) { if (*p == '\n') ++lineno; ++p; } q = strchr(yytext, '>') - 1; add2db(INCLUDE, p, q - p + 1, scope, scope_length, lineno); parse_later(p, (size_t)(q - p) + 1); } \ *include\ *\"[^\ ]+\" { /* #include "..." */ register char* p; register char* q; /* Get header file */ p = strchr(yytext, '"'); q = p + 1; while (*q != '"') { if (*q == '\n') ++lineno; ++q; } add2db(INCLUDE, p + 1, q - p - 1, scope, scope_length, lineno); } %% /* * FUNCTION: scan_c * * DESCRIPTION: This is the entry point for the C file lexer * This function starts by creating a copy of the passed file * without any C comment. * It then run the lexer on this temporary file. * Once the file has been parsed, it is removed. * * IN: filename The file to scan * filename_length The number of charin the file name * IN-OUT: * RETURN CODE: */ void scan_c (char* filename, size_t filename_length) { char* src; static char* buf = NULL; int fdin; int length; int remaining; struct stat statbuf; YY_BUFFER_STATE yybuf; scope_level = 0; strncpy(file, filename, filename_length); file_length = filename_length; strcpy(scope, GLOBAL_SCOPE); scope_length = GLOBAL_SCOPE_LENGTH; /* Open input file */ if ((fdin = open(filename, O_RDONLY | O_NONBLOCK)) < 0) return; /* Get size */ if (fstat(fdin, &statbuf) < 0) { close(fdin); return; } /* Check if file is empty */ if (statbuf.st_size == 0) { close(fdin); return; } /* Allocate memory for stripped file */ if (buf == NULL) buf = (char*)calloc(statbuf.st_size, sizeof(char)); else buf = (char*)realloc(buf, statbuf.st_size); if (buf == NULL) { fprintf(stderr, "Out of memory!\n"); exit(-1); } /* Create a memory mapped region */ if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_FILE | MAP_SHARED, fdin, 0)) == 0) { close(fdin); return; } /* Read the whole file in the buffer */ remaining = statbuf.st_size; while (remaining != 0 && remaining >= SSIZE_MAX) { read(fdin, buf + statbuf.st_size - remaining, SSIZE_MAX); remaining -= SSIZE_MAX; } read(fdin, buf + statbuf.st_size - remaining, remaining); /* Remove all comments */ length = strip_comments(src, buf, statbuf.st_size); munmap(src, statbuf.st_size); /* close file */ close(fdin); if ((yyout = fopen("/dev/null", "rw")) == NULL) return; lineno = 1; /* Scan file */ yybuf = yy_scan_bytes(buf, length); yylex(); yy_delete_buffer(yybuf); fclose(yyout); } /* * FUNCTION: strip_comments * * DESCRIPTION: This functions takes as argument two memory mapped region and * copies one region to another stripping all C comments and * quoted strings. A C comment can start with "//". * * IN: src The source region * size The size of the src region * IN-OUT: dst The destination region * OUT: * RETURN CODE: The number of bytes written in the temporary file */ static int strip_comments (register char* src, register char* dst, off_t size) { int i = 0; int j = 0; int one_line_comment = 0; /* Copy everything except comments and quoted strings*/ while (i < size) { if ((src[i] == '/') && (i != size - 1) && ((src[i + 1] == '*') || (src[i + 1] == '/'))) { if (src[i + 1] == '/') { /* This is the start of a "//" comment */ one_line_comment = 1; } dst[j++] = ' '; i += 2; if (one_line_comment == 0) { /* Skip everything except new lines until end of comment */ while ((i != size - 1) && ((src[i] != '*') || (src[i+1] != '/'))) { if (src[i] == '\n') { dst[j++] = '\n'; } ++i; } i += 2; } else { /* One line comment */ while ((i != size - 1) && (src[i] != '\n')) { ++i; } if (i != size - 1) dst[j++] = '\n'; ++i; one_line_comment = 0; } /* Did we reach end of file? */ if (i == size - 1) break; } if ((i != size) && (src[i] == '"')) { /* * We need to go back and make sure that we haven't encountered an * include statement: # include "file.h" */ int pos = j--; while (dst[j] == ' ') --j; if (dst[j] == 'e') { j -= 6; if (strncmp(&dst[j], "include", 7) == 0) { j = pos; dst[j++] = src[i++]; do { if (i == size) break; /* This should not happen! */ dst[j++] = src[i++]; } while (dst[j-1] != '"'); continue; } } j = pos; dst[j++] = '"'; ++i; while ((i != size - 1) && (src[i] != '"')) { if (src[i] == '\n') { dst[j++] = '\n'; } ++i; } /* Did we reach end of file? */ if (i == size -1) break; } /* This is not the beginning of a comment */ if (src[i] != '\t') dst[j++] = src[i++]; else { dst[j++] = ' '; ++i; } } return j; } /* * FUNCTION: is_native_type * * DESCRIPTION: This function checks if a symbol is a native data type * * IN: symbol The symbol * length The symbol length * IN-OUT: * OUT: * RETURN CODE: 1 if the symbol is a native type. 0 otherwise. */ int is_native_type (register char* symbol, size_t length) { if ((strncmp(symbol, "char", length) == 0) || (strncmp(symbol, "int", length) == 0) || (strncmp(symbol, "unsigned", length) == 0) || (strncmp(symbol, "long", length) == 0) || (strncmp(symbol, "short", length) == 0) || (strncmp(symbol, "void", length) == 0) || (strncmp(symbol, "float", length) == 0) || (strncmp(symbol, "double", length) == 0) || (strncmp(symbol, "const", length) == 0) || (strncmp(symbol, "signed", length) == 0)) { return 1; } return 0; }