mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 06:34:12 +08:00
Merge branch 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6
* 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6: kbuild: Make DEBUG_SECTION_MISMATCH selectable, but not on by default genksyms: Regenerate lexer and parser genksyms: Track changes to enum constants genksyms: simplify usage of find_symbol() genksyms: Add helpers for building string lists genksyms: Simplify printing of symbol types genksyms: Simplify lexer genksyms: Do not paste the bison header file to lex.c modpost: fix trailing comma KBuild: silence "'scripts/unifdef' is up to date." kbuild: Add extra gcc checks kbuild: reenable section mismatch analysis unifdef: update to upstream version 2.5
This commit is contained in:
commit
eddecbb601
@ -196,3 +196,8 @@ to be included in the databases, separated by blank space. E.g.:
|
||||
To get all available archs you can also specify all. E.g.:
|
||||
|
||||
$ make ALLSOURCE_ARCHS=all tags
|
||||
|
||||
KBUILD_ENABLE_EXTRA_GCC_CHECKS
|
||||
--------------------------------------------------
|
||||
If enabled over the make command line with "W=1", it turns on additional
|
||||
gcc -W... options for more extensive build-time checking.
|
||||
|
7
Makefile
7
Makefile
@ -102,6 +102,10 @@ ifeq ("$(origin O)", "command line")
|
||||
KBUILD_OUTPUT := $(O)
|
||||
endif
|
||||
|
||||
ifeq ("$(origin W)", "command line")
|
||||
export KBUILD_ENABLE_EXTRA_GCC_CHECKS := 1
|
||||
endif
|
||||
|
||||
# That's our default target when none is given on the command line
|
||||
PHONY := _all
|
||||
_all:
|
||||
@ -1018,7 +1022,7 @@ hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm)
|
||||
|
||||
PHONY += __headers
|
||||
__headers: include/linux/version.h scripts_basic FORCE
|
||||
$(Q)$(MAKE) $(build)=scripts scripts/unifdef
|
||||
$(Q)$(MAKE) $(build)=scripts build_unifdef
|
||||
|
||||
PHONY += headers_install_all
|
||||
headers_install_all:
|
||||
@ -1263,6 +1267,7 @@ help:
|
||||
@echo ' make O=dir [targets] Locate all output files in "dir", including .config'
|
||||
@echo ' make C=1 [targets] Check all c source with $$CHECK (sparse by default)'
|
||||
@echo ' make C=2 [targets] Force check of all c source with $$CHECK'
|
||||
@echo ' make W=1 [targets] Enable extra gcc checks'
|
||||
@echo ''
|
||||
@echo 'Execute "make" or "make all" to build all targets marked with [*] '
|
||||
@echo 'For further info see the ./README file'
|
||||
|
@ -102,11 +102,6 @@ config HEADERS_CHECK
|
||||
|
||||
config DEBUG_SECTION_MISMATCH
|
||||
bool "Enable full Section mismatch analysis"
|
||||
depends on UNDEFINED || (BLACKFIN)
|
||||
default y
|
||||
# This option is on purpose disabled for now.
|
||||
# It will be enabled when we are down to a reasonable number
|
||||
# of section mismatch warnings (< 10 for an allyesconfig build)
|
||||
help
|
||||
The section mismatch analysis checks if there are illegal
|
||||
references from one section to another section.
|
||||
|
@ -18,6 +18,11 @@ always := $(hostprogs-y) $(hostprogs-m)
|
||||
# The following hostprogs-y programs are only build on demand
|
||||
hostprogs-y += unifdef
|
||||
|
||||
# This target is used internally to avoid "is up to date" messages
|
||||
PHONY += build_unifdef
|
||||
build_unifdef: scripts/unifdef FORCE
|
||||
@:
|
||||
|
||||
subdir-$(CONFIG_MODVERSIONS) += genksyms
|
||||
subdir-y += mod
|
||||
subdir-$(CONFIG_SECURITY_SELINUX) += selinux
|
||||
|
@ -49,6 +49,40 @@ ifeq ($(KBUILD_NOPEDANTIC),)
|
||||
$(error CFLAGS was changed in "$(kbuild-file)". Fix it to use EXTRA_CFLAGS)
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# make W=1 settings
|
||||
#
|
||||
# $(call cc-option... ) handles gcc -W.. options which
|
||||
# are not supported by all versions of the compiler
|
||||
ifdef KBUILD_ENABLE_EXTRA_GCC_CHECKS
|
||||
KBUILD_EXTRA_WARNINGS := -Wextra
|
||||
KBUILD_EXTRA_WARNINGS += -Wunused -Wno-unused-parameter
|
||||
KBUILD_EXTRA_WARNINGS += -Waggregate-return
|
||||
KBUILD_EXTRA_WARNINGS += -Wbad-function-cast
|
||||
KBUILD_EXTRA_WARNINGS += -Wcast-qual
|
||||
KBUILD_EXTRA_WARNINGS += -Wcast-align
|
||||
KBUILD_EXTRA_WARNINGS += -Wconversion
|
||||
KBUILD_EXTRA_WARNINGS += -Wdisabled-optimization
|
||||
KBUILD_EXTRA_WARNINGS += -Wlogical-op
|
||||
KBUILD_EXTRA_WARNINGS += -Wmissing-declarations
|
||||
KBUILD_EXTRA_WARNINGS += -Wmissing-format-attribute
|
||||
KBUILD_EXTRA_WARNINGS += $(call cc-option, -Wmissing-include-dirs,)
|
||||
KBUILD_EXTRA_WARNINGS += -Wmissing-prototypes
|
||||
KBUILD_EXTRA_WARNINGS += -Wnested-externs
|
||||
KBUILD_EXTRA_WARNINGS += -Wold-style-definition
|
||||
KBUILD_EXTRA_WARNINGS += $(call cc-option, -Woverlength-strings,)
|
||||
KBUILD_EXTRA_WARNINGS += -Wpacked
|
||||
KBUILD_EXTRA_WARNINGS += -Wpacked-bitfield-compat
|
||||
KBUILD_EXTRA_WARNINGS += -Wpadded
|
||||
KBUILD_EXTRA_WARNINGS += -Wpointer-arith
|
||||
KBUILD_EXTRA_WARNINGS += -Wredundant-decls
|
||||
KBUILD_EXTRA_WARNINGS += -Wshadow
|
||||
KBUILD_EXTRA_WARNINGS += -Wswitch-default
|
||||
KBUILD_EXTRA_WARNINGS += $(call cc-option, -Wvla,)
|
||||
KBUILD_CFLAGS += $(KBUILD_EXTRA_WARNINGS)
|
||||
endif
|
||||
|
||||
include scripts/Makefile.lib
|
||||
|
||||
ifdef host-progs
|
||||
@ -403,7 +437,6 @@ ifneq ($(cmd_files),)
|
||||
include $(cmd_files)
|
||||
endif
|
||||
|
||||
|
||||
# Declare the contents of the .PHONY variable as phony. We keep that
|
||||
# information in a variable se we can use it in if_changed and friends.
|
||||
|
||||
|
@ -28,9 +28,9 @@ $(obj)/keywords.c: $(obj)/keywords.gperf FORCE
|
||||
# flex
|
||||
|
||||
quiet_cmd_lex.c = FLEX $@
|
||||
cmd_lex.c = flex -o$@ -d $< $(obj)/parse.h
|
||||
cmd_lex.c = flex -o$@ -d $<
|
||||
|
||||
$(obj)/lex.c: $(obj)/lex.l $(obj)/parse.h $(obj)/keywords.c FORCE
|
||||
$(obj)/lex.c: $(obj)/lex.l $(obj)/keywords.c FORCE
|
||||
$(call if_changed,lex.c)
|
||||
cp $@ $@_shipped
|
||||
|
||||
|
@ -53,12 +53,22 @@ static int nsyms;
|
||||
static struct symbol *expansion_trail;
|
||||
static struct symbol *visited_symbols;
|
||||
|
||||
static const char *const symbol_type_name[] = {
|
||||
"normal", "typedef", "enum", "struct", "union"
|
||||
static const struct {
|
||||
int n;
|
||||
const char *name;
|
||||
} symbol_types[] = {
|
||||
[SYM_NORMAL] = { 0, NULL},
|
||||
[SYM_TYPEDEF] = {'t', "typedef"},
|
||||
[SYM_ENUM] = {'e', "enum"},
|
||||
[SYM_STRUCT] = {'s', "struct"},
|
||||
[SYM_UNION] = {'u', "union"},
|
||||
[SYM_ENUM_CONST] = {'E', "enum constant"},
|
||||
};
|
||||
|
||||
static int equal_list(struct string_list *a, struct string_list *b);
|
||||
static void print_list(FILE * f, struct string_list *list);
|
||||
static struct string_list *concat_list(struct string_list *start, ...);
|
||||
static struct string_list *mk_node(const char *string);
|
||||
static void print_location(void);
|
||||
static void print_type_name(enum symbol_type type, const char *name);
|
||||
|
||||
@ -140,14 +150,20 @@ static unsigned long crc32(const char *s)
|
||||
|
||||
static enum symbol_type map_to_ns(enum symbol_type t)
|
||||
{
|
||||
if (t == SYM_TYPEDEF)
|
||||
t = SYM_NORMAL;
|
||||
else if (t == SYM_UNION)
|
||||
t = SYM_STRUCT;
|
||||
switch (t) {
|
||||
case SYM_ENUM_CONST:
|
||||
case SYM_NORMAL:
|
||||
case SYM_TYPEDEF:
|
||||
return SYM_NORMAL;
|
||||
case SYM_ENUM:
|
||||
case SYM_STRUCT:
|
||||
case SYM_UNION:
|
||||
return SYM_STRUCT;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
struct symbol *find_symbol(const char *name, enum symbol_type ns)
|
||||
struct symbol *find_symbol(const char *name, enum symbol_type ns, int exact)
|
||||
{
|
||||
unsigned long h = crc32(name) % HASH_BUCKETS;
|
||||
struct symbol *sym;
|
||||
@ -158,6 +174,8 @@ struct symbol *find_symbol(const char *name, enum symbol_type ns)
|
||||
sym->is_declared)
|
||||
break;
|
||||
|
||||
if (exact && sym && sym->type != ns)
|
||||
return NULL;
|
||||
return sym;
|
||||
}
|
||||
|
||||
@ -180,10 +198,47 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type,
|
||||
struct string_list *defn, int is_extern,
|
||||
int is_reference)
|
||||
{
|
||||
unsigned long h = crc32(name) % HASH_BUCKETS;
|
||||
unsigned long h;
|
||||
struct symbol *sym;
|
||||
enum symbol_status status = STATUS_UNCHANGED;
|
||||
/* The parser adds symbols in the order their declaration completes,
|
||||
* so it is safe to store the value of the previous enum constant in
|
||||
* a static variable.
|
||||
*/
|
||||
static int enum_counter;
|
||||
static struct string_list *last_enum_expr;
|
||||
|
||||
if (type == SYM_ENUM_CONST) {
|
||||
if (defn) {
|
||||
free_list(last_enum_expr, NULL);
|
||||
last_enum_expr = copy_list_range(defn, NULL);
|
||||
enum_counter = 1;
|
||||
} else {
|
||||
struct string_list *expr;
|
||||
char buf[20];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%d", enum_counter++);
|
||||
if (last_enum_expr) {
|
||||
expr = copy_list_range(last_enum_expr, NULL);
|
||||
defn = concat_list(mk_node("("),
|
||||
expr,
|
||||
mk_node(")"),
|
||||
mk_node("+"),
|
||||
mk_node(buf), NULL);
|
||||
} else {
|
||||
defn = mk_node(buf);
|
||||
}
|
||||
}
|
||||
} else if (type == SYM_ENUM) {
|
||||
free_list(last_enum_expr, NULL);
|
||||
last_enum_expr = NULL;
|
||||
enum_counter = 0;
|
||||
if (!name)
|
||||
/* Anonymous enum definition, nothing more to do */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
h = crc32(name) % HASH_BUCKETS;
|
||||
for (sym = symtab[h]; sym; sym = sym->hash_next) {
|
||||
if (map_to_ns(sym->type) == map_to_ns(type) &&
|
||||
strcmp(name, sym->name) == 0) {
|
||||
@ -247,8 +302,12 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type,
|
||||
sym->is_override = 0;
|
||||
|
||||
if (flag_debug) {
|
||||
fprintf(debugfile, "Defn for %s %s == <",
|
||||
symbol_type_name[type], name);
|
||||
if (symbol_types[type].name)
|
||||
fprintf(debugfile, "Defn for %s %s == <",
|
||||
symbol_types[type].name, name);
|
||||
else
|
||||
fprintf(debugfile, "Defn for type%d %s == <",
|
||||
type, name);
|
||||
if (is_extern)
|
||||
fputs("extern ", debugfile);
|
||||
print_list(debugfile, defn);
|
||||
@ -288,6 +347,35 @@ void free_list(struct string_list *s, struct string_list *e)
|
||||
}
|
||||
}
|
||||
|
||||
static struct string_list *mk_node(const char *string)
|
||||
{
|
||||
struct string_list *newnode;
|
||||
|
||||
newnode = xmalloc(sizeof(*newnode));
|
||||
newnode->string = xstrdup(string);
|
||||
newnode->tag = SYM_NORMAL;
|
||||
newnode->next = NULL;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static struct string_list *concat_list(struct string_list *start, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct string_list *n, *n2;
|
||||
|
||||
if (!start)
|
||||
return NULL;
|
||||
for (va_start(ap, start); (n = va_arg(ap, struct string_list *));) {
|
||||
for (n2 = n; n2->next; n2 = n2->next)
|
||||
;
|
||||
n2->next = start;
|
||||
start = n;
|
||||
}
|
||||
va_end(ap);
|
||||
return start;
|
||||
}
|
||||
|
||||
struct string_list *copy_node(struct string_list *node)
|
||||
{
|
||||
struct string_list *newnode;
|
||||
@ -299,6 +387,22 @@ struct string_list *copy_node(struct string_list *node)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
struct string_list *copy_list_range(struct string_list *start,
|
||||
struct string_list *end)
|
||||
{
|
||||
struct string_list *res, *n;
|
||||
|
||||
if (start == end)
|
||||
return NULL;
|
||||
n = res = copy_node(start);
|
||||
for (start = start->next; start != end; start = start->next) {
|
||||
n->next = copy_node(start);
|
||||
n = n->next;
|
||||
}
|
||||
n->next = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int equal_list(struct string_list *a, struct string_list *b)
|
||||
{
|
||||
while (a && b) {
|
||||
@ -346,8 +450,8 @@ static struct string_list *read_node(FILE *f)
|
||||
if (node.string[1] == '#') {
|
||||
int n;
|
||||
|
||||
for (n = 0; n < ARRAY_SIZE(symbol_type_name); n++) {
|
||||
if (node.string[0] == symbol_type_name[n][0]) {
|
||||
for (n = 0; n < ARRAY_SIZE(symbol_types); n++) {
|
||||
if (node.string[0] == symbol_types[n].n) {
|
||||
node.tag = n;
|
||||
node.string += 2;
|
||||
return copy_node(&node);
|
||||
@ -397,8 +501,8 @@ static void read_reference(FILE *f)
|
||||
|
||||
static void print_node(FILE * f, struct string_list *list)
|
||||
{
|
||||
if (list->tag != SYM_NORMAL) {
|
||||
putc(symbol_type_name[list->tag][0], f);
|
||||
if (symbol_types[list->tag].n) {
|
||||
putc(symbol_types[list->tag].n, f);
|
||||
putc('#', f);
|
||||
}
|
||||
fputs(list->string, f);
|
||||
@ -468,8 +572,9 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
|
||||
crc = partial_crc32_one(' ', crc);
|
||||
break;
|
||||
|
||||
case SYM_ENUM_CONST:
|
||||
case SYM_TYPEDEF:
|
||||
subsym = find_symbol(cur->string, cur->tag);
|
||||
subsym = find_symbol(cur->string, cur->tag, 0);
|
||||
/* FIXME: Bad reference files can segfault here. */
|
||||
if (subsym->expansion_trail) {
|
||||
if (flag_dump_defs)
|
||||
@ -486,55 +591,30 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
|
||||
case SYM_STRUCT:
|
||||
case SYM_UNION:
|
||||
case SYM_ENUM:
|
||||
subsym = find_symbol(cur->string, cur->tag);
|
||||
subsym = find_symbol(cur->string, cur->tag, 0);
|
||||
if (!subsym) {
|
||||
struct string_list *n, *t = NULL;
|
||||
struct string_list *n;
|
||||
|
||||
error_with_pos("expand undefined %s %s",
|
||||
symbol_type_name[cur->tag],
|
||||
symbol_types[cur->tag].name,
|
||||
cur->string);
|
||||
|
||||
n = xmalloc(sizeof(*n));
|
||||
n->string = xstrdup(symbol_type_name[cur->tag]);
|
||||
n->tag = SYM_NORMAL;
|
||||
n->next = t;
|
||||
t = n;
|
||||
|
||||
n = xmalloc(sizeof(*n));
|
||||
n->string = xstrdup(cur->string);
|
||||
n->tag = SYM_NORMAL;
|
||||
n->next = t;
|
||||
t = n;
|
||||
|
||||
n = xmalloc(sizeof(*n));
|
||||
n->string = xstrdup("{");
|
||||
n->tag = SYM_NORMAL;
|
||||
n->next = t;
|
||||
t = n;
|
||||
|
||||
n = xmalloc(sizeof(*n));
|
||||
n->string = xstrdup("UNKNOWN");
|
||||
n->tag = SYM_NORMAL;
|
||||
n->next = t;
|
||||
t = n;
|
||||
|
||||
n = xmalloc(sizeof(*n));
|
||||
n->string = xstrdup("}");
|
||||
n->tag = SYM_NORMAL;
|
||||
n->next = t;
|
||||
t = n;
|
||||
|
||||
n = concat_list(mk_node
|
||||
(symbol_types[cur->tag].name),
|
||||
mk_node(cur->string),
|
||||
mk_node("{"),
|
||||
mk_node("UNKNOWN"),
|
||||
mk_node("}"), NULL);
|
||||
subsym =
|
||||
add_symbol(cur->string, cur->tag, n, 0);
|
||||
}
|
||||
if (subsym->expansion_trail) {
|
||||
if (flag_dump_defs) {
|
||||
fprintf(debugfile, "%s %s ",
|
||||
symbol_type_name[cur->tag],
|
||||
symbol_types[cur->tag].name,
|
||||
cur->string);
|
||||
}
|
||||
|
||||
crc = partial_crc32(symbol_type_name[cur->tag],
|
||||
crc = partial_crc32(symbol_types[cur->tag].name,
|
||||
crc);
|
||||
crc = partial_crc32_one(' ', crc);
|
||||
crc = partial_crc32(cur->string, crc);
|
||||
@ -565,7 +645,7 @@ void export_symbol(const char *name)
|
||||
{
|
||||
struct symbol *sym;
|
||||
|
||||
sym = find_symbol(name, SYM_NORMAL);
|
||||
sym = find_symbol(name, SYM_NORMAL, 0);
|
||||
if (!sym)
|
||||
error_with_pos("export undefined symbol %s", name);
|
||||
else {
|
||||
@ -624,8 +704,8 @@ static void print_location(void)
|
||||
|
||||
static void print_type_name(enum symbol_type type, const char *name)
|
||||
{
|
||||
if (type != SYM_NORMAL)
|
||||
fprintf(stderr, "%s %s", symbol_type_name[type], name);
|
||||
if (symbol_types[type].name)
|
||||
fprintf(stderr, "%s %s", symbol_types[type].name, name);
|
||||
else
|
||||
fprintf(stderr, "%s", name);
|
||||
}
|
||||
@ -771,8 +851,8 @@ int main(int argc, char **argv)
|
||||
|
||||
if (sym->is_override)
|
||||
fputs("override ", dumpfile);
|
||||
if (sym->type != SYM_NORMAL) {
|
||||
putc(symbol_type_name[sym->type][0], dumpfile);
|
||||
if (symbol_types[sym->type].n) {
|
||||
putc(symbol_types[sym->type].n, dumpfile);
|
||||
putc('#', dumpfile);
|
||||
}
|
||||
fputs(sym->name, dumpfile);
|
||||
|
@ -26,7 +26,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
enum symbol_type {
|
||||
SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION
|
||||
SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION,
|
||||
SYM_ENUM_CONST
|
||||
};
|
||||
|
||||
enum symbol_status {
|
||||
@ -58,7 +59,7 @@ typedef struct string_list **yystype;
|
||||
extern int cur_line;
|
||||
extern char *cur_filename;
|
||||
|
||||
struct symbol *find_symbol(const char *name, enum symbol_type ns);
|
||||
struct symbol *find_symbol(const char *name, enum symbol_type ns, int exact);
|
||||
struct symbol *add_symbol(const char *name, enum symbol_type type,
|
||||
struct string_list *defn, int is_extern);
|
||||
void export_symbol(const char *);
|
||||
@ -66,6 +67,8 @@ void export_symbol(const char *);
|
||||
void free_node(struct string_list *list);
|
||||
void free_list(struct string_list *s, struct string_list *e);
|
||||
struct string_list *copy_node(struct string_list *);
|
||||
struct string_list *copy_list_range(struct string_list *start,
|
||||
struct string_list *end);
|
||||
|
||||
int yylex(void);
|
||||
int yyparse(void);
|
||||
|
@ -79,6 +79,7 @@ typedef int flex_int32_t;
|
||||
typedef unsigned char flex_uint8_t;
|
||||
typedef unsigned short int flex_uint16_t;
|
||||
typedef unsigned int flex_uint32_t;
|
||||
#endif /* ! C99 */
|
||||
|
||||
/* Limits of integral types. */
|
||||
#ifndef INT8_MIN
|
||||
@ -109,8 +110,6 @@ typedef unsigned int flex_uint32_t;
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#endif /* ! C99 */
|
||||
|
||||
#endif /* ! FLEXINT_H */
|
||||
|
||||
/* %endif */
|
||||
@ -456,16 +455,16 @@ struct yy_trans_info
|
||||
flex_int32_t yy_verify;
|
||||
flex_int32_t yy_nxt;
|
||||
};
|
||||
static yyconst flex_int16_t yy_accept[76] =
|
||||
static yyconst flex_int16_t yy_accept[73] =
|
||||
{ 0,
|
||||
0, 0, 0, 0, 14, 12, 4, 3, 12, 7,
|
||||
12, 12, 7, 12, 12, 12, 12, 12, 9, 9,
|
||||
12, 12, 12, 4, 0, 5, 0, 7, 0, 6,
|
||||
0, 0, 0, 0, 0, 0, 2, 8, 10, 10,
|
||||
9, 0, 0, 9, 9, 0, 9, 0, 0, 11,
|
||||
0, 0, 0, 10, 0, 10, 9, 9, 0, 0,
|
||||
0, 0, 0, 0, 0, 10, 10, 0, 0, 0,
|
||||
0, 0, 0, 1, 0
|
||||
0, 0, 14, 12, 4, 3, 12, 7, 12, 12,
|
||||
12, 12, 12, 9, 9, 12, 12, 7, 12, 12,
|
||||
4, 0, 5, 0, 7, 8, 0, 6, 0, 0,
|
||||
10, 10, 9, 0, 0, 9, 9, 0, 9, 0,
|
||||
0, 0, 0, 2, 0, 0, 11, 0, 10, 0,
|
||||
10, 9, 9, 0, 0, 0, 10, 10, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 0
|
||||
} ;
|
||||
|
||||
static yyconst flex_int32_t yy_ec[256] =
|
||||
@ -507,108 +506,104 @@ static yyconst flex_int32_t yy_meta[29] =
|
||||
8, 7, 3, 3, 3, 1, 3, 1
|
||||
} ;
|
||||
|
||||
static yyconst flex_int16_t yy_base[88] =
|
||||
static yyconst flex_int16_t yy_base[85] =
|
||||
{ 0,
|
||||
0, 147, 21, 140, 145, 284, 39, 284, 26, 0,
|
||||
32, 126, 40, 44, 115, 35, 36, 46, 50, 53,
|
||||
39, 61, 54, 79, 65, 284, 0, 0, 66, 284,
|
||||
0, 119, 79, 75, 123, 104, 284, 284, 107, 0,
|
||||
79, 73, 76, 76, 66, 0, 0, 85, 86, 284,
|
||||
133, 83, 91, 284, 99, 147, 284, 114, 122, 70,
|
||||
107, 141, 172, 151, 135, 181, 284, 137, 114, 157,
|
||||
149, 48, 45, 284, 284, 208, 214, 222, 230, 238,
|
||||
246, 250, 255, 256, 261, 267, 275
|
||||
0, 145, 150, 266, 27, 266, 25, 0, 131, 23,
|
||||
23, 16, 23, 39, 31, 25, 39, 60, 22, 65,
|
||||
57, 43, 266, 0, 0, 266, 61, 266, 0, 128,
|
||||
74, 0, 113, 59, 62, 113, 52, 0, 0, 72,
|
||||
66, 110, 100, 266, 73, 74, 266, 70, 266, 90,
|
||||
103, 266, 84, 129, 108, 113, 143, 266, 107, 66,
|
||||
118, 137, 168, 120, 80, 91, 145, 143, 83, 41,
|
||||
266, 266, 190, 196, 204, 212, 220, 228, 232, 237,
|
||||
238, 243, 249, 257
|
||||
} ;
|
||||
|
||||
static yyconst flex_int16_t yy_def[88] =
|
||||
static yyconst flex_int16_t yy_def[85] =
|
||||
{ 0,
|
||||
75, 1, 1, 3, 75, 75, 75, 75, 76, 77,
|
||||
78, 75, 77, 79, 75, 75, 75, 75, 75, 19,
|
||||
75, 75, 75, 75, 76, 75, 80, 77, 78, 75,
|
||||
81, 75, 76, 78, 79, 79, 75, 75, 75, 39,
|
||||
19, 82, 83, 75, 75, 84, 20, 76, 78, 75,
|
||||
79, 51, 85, 75, 75, 75, 75, 84, 79, 51,
|
||||
79, 79, 79, 51, 75, 75, 75, 86, 79, 63,
|
||||
86, 87, 87, 75, 0, 75, 75, 75, 75, 75,
|
||||
75, 75, 75, 75, 75, 75, 75
|
||||
72, 1, 72, 72, 72, 72, 73, 74, 72, 72,
|
||||
75, 72, 72, 72, 14, 72, 72, 74, 72, 76,
|
||||
72, 73, 72, 77, 74, 72, 75, 72, 78, 72,
|
||||
72, 31, 14, 79, 80, 72, 72, 81, 15, 73,
|
||||
75, 76, 76, 72, 73, 75, 72, 82, 72, 72,
|
||||
72, 72, 81, 76, 54, 72, 72, 72, 76, 54,
|
||||
76, 76, 76, 54, 83, 76, 63, 83, 84, 84,
|
||||
72, 0, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72
|
||||
} ;
|
||||
|
||||
static yyconst flex_int16_t yy_nxt[313] =
|
||||
static yyconst flex_int16_t yy_nxt[295] =
|
||||
{ 0,
|
||||
6, 7, 8, 7, 9, 6, 10, 6, 6, 11,
|
||||
6, 6, 12, 6, 6, 6, 6, 6, 6, 10,
|
||||
10, 10, 13, 10, 10, 6, 10, 6, 15, 16,
|
||||
26, 15, 17, 18, 19, 20, 20, 21, 15, 22,
|
||||
24, 30, 24, 38, 33, 36, 37, 74, 23, 34,
|
||||
74, 27, 38, 38, 38, 38, 38, 31, 32, 39,
|
||||
39, 39, 40, 41, 41, 42, 47, 47, 47, 26,
|
||||
43, 38, 44, 45, 46, 30, 44, 75, 38, 38,
|
||||
24, 38, 24, 26, 30, 40, 55, 55, 57, 26,
|
||||
27, 31, 57, 43, 35, 30, 64, 64, 64, 57,
|
||||
4, 5, 6, 5, 7, 4, 8, 9, 10, 11,
|
||||
9, 12, 13, 14, 15, 15, 16, 9, 17, 8,
|
||||
8, 8, 18, 8, 8, 4, 8, 19, 21, 23,
|
||||
21, 26, 28, 26, 26, 30, 31, 31, 31, 26,
|
||||
26, 26, 26, 71, 39, 39, 39, 23, 29, 26,
|
||||
24, 32, 33, 33, 34, 72, 26, 26, 21, 35,
|
||||
21, 36, 37, 38, 40, 36, 43, 44, 24, 41,
|
||||
28, 32, 50, 50, 52, 28, 23, 23, 52, 35,
|
||||
56, 56, 44, 28, 42, 71, 29, 31, 31, 31,
|
||||
42, 29, 59, 44, 48, 49, 49, 24, 24, 29,
|
||||
|
||||
31, 65, 65, 75, 27, 36, 37, 35, 59, 37,
|
||||
27, 31, 56, 56, 56, 59, 37, 51, 52, 52,
|
||||
39, 39, 39, 59, 37, 37, 68, 53, 54, 54,
|
||||
69, 50, 38, 54, 59, 37, 44, 45, 32, 37,
|
||||
44, 35, 59, 37, 75, 14, 60, 60, 66, 66,
|
||||
66, 37, 14, 72, 75, 61, 62, 63, 59, 61,
|
||||
56, 56, 56, 69, 64, 64, 64, 69, 67, 67,
|
||||
75, 75, 75, 67, 37, 35, 75, 75, 75, 61,
|
||||
62, 75, 75, 61, 75, 70, 70, 70, 75, 75,
|
||||
75, 70, 70, 70, 66, 66, 66, 75, 75, 75,
|
||||
49, 43, 44, 51, 51, 51, 36, 37, 59, 44,
|
||||
36, 65, 44, 54, 55, 55, 51, 51, 51, 59,
|
||||
44, 64, 64, 64, 58, 58, 57, 57, 57, 58,
|
||||
59, 44, 42, 64, 64, 64, 52, 72, 59, 44,
|
||||
47, 66, 60, 60, 42, 44, 59, 69, 26, 72,
|
||||
20, 61, 62, 63, 72, 61, 57, 57, 57, 66,
|
||||
72, 72, 72, 66, 49, 49, 72, 61, 62, 49,
|
||||
44, 61, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 67, 67, 67, 72, 72, 72, 67, 67, 67,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 25, 72,
|
||||
|
||||
75, 75, 54, 54, 75, 75, 75, 54, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 28, 75, 75, 28,
|
||||
28, 28, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
35, 35, 35, 35, 35, 35, 35, 35, 48, 75,
|
||||
48, 48, 48, 48, 48, 48, 49, 75, 49, 49,
|
||||
49, 49, 49, 49, 42, 42, 75, 42, 56, 75,
|
||||
56, 58, 58, 58, 66, 75, 66, 71, 71, 71,
|
||||
71, 71, 71, 71, 71, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 5, 75, 75, 75, 75, 75, 75,
|
||||
75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
|
||||
72, 25, 25, 25, 27, 27, 27, 27, 27, 27,
|
||||
27, 27, 42, 42, 42, 42, 42, 42, 42, 42,
|
||||
45, 72, 45, 45, 45, 45, 45, 45, 46, 72,
|
||||
46, 46, 46, 46, 46, 46, 34, 34, 72, 34,
|
||||
51, 72, 51, 53, 53, 53, 57, 72, 57, 68,
|
||||
68, 68, 68, 68, 68, 68, 68, 70, 70, 70,
|
||||
70, 70, 70, 70, 70, 3, 72, 72, 72, 72,
|
||||
72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72
|
||||
|
||||
75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
|
||||
75, 75
|
||||
} ;
|
||||
|
||||
static yyconst flex_int16_t yy_chk[313] =
|
||||
static yyconst flex_int16_t yy_chk[295] =
|
||||
{ 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
|
||||
9, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
7, 11, 7, 16, 13, 14, 14, 73, 3, 13,
|
||||
72, 9, 16, 17, 17, 21, 21, 11, 18, 18,
|
||||
18, 18, 19, 19, 19, 19, 20, 20, 20, 25,
|
||||
19, 23, 19, 19, 19, 29, 19, 20, 22, 22,
|
||||
24, 23, 24, 33, 34, 42, 43, 43, 45, 48,
|
||||
25, 29, 45, 42, 60, 49, 52, 52, 52, 44,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 5, 7,
|
||||
5, 10, 11, 12, 12, 13, 13, 13, 13, 19,
|
||||
10, 16, 16, 70, 15, 15, 15, 22, 11, 19,
|
||||
7, 14, 14, 14, 14, 15, 17, 17, 21, 14,
|
||||
21, 14, 14, 14, 18, 14, 20, 20, 22, 18,
|
||||
27, 34, 35, 35, 37, 41, 40, 45, 37, 34,
|
||||
48, 48, 65, 46, 65, 69, 27, 31, 31, 31,
|
||||
60, 41, 66, 66, 31, 31, 31, 40, 45, 46,
|
||||
|
||||
34, 53, 53, 41, 33, 36, 36, 52, 61, 61,
|
||||
48, 49, 55, 55, 55, 69, 69, 36, 36, 36,
|
||||
39, 39, 39, 59, 59, 35, 59, 39, 39, 39,
|
||||
61, 32, 15, 39, 51, 51, 58, 58, 12, 68,
|
||||
58, 68, 62, 62, 5, 4, 51, 51, 65, 65,
|
||||
65, 71, 2, 71, 0, 51, 51, 51, 70, 51,
|
||||
56, 56, 56, 62, 64, 64, 64, 62, 56, 56,
|
||||
0, 0, 0, 56, 63, 64, 0, 0, 0, 70,
|
||||
70, 0, 0, 70, 0, 63, 63, 63, 0, 0,
|
||||
0, 63, 63, 63, 66, 66, 66, 0, 0, 0,
|
||||
31, 43, 43, 50, 50, 50, 53, 53, 59, 59,
|
||||
53, 59, 42, 43, 43, 43, 51, 51, 51, 61,
|
||||
61, 55, 55, 55, 51, 51, 56, 56, 56, 51,
|
||||
54, 54, 55, 64, 64, 64, 36, 33, 62, 62,
|
||||
30, 61, 54, 54, 64, 68, 67, 68, 9, 3,
|
||||
2, 54, 54, 54, 0, 54, 57, 57, 57, 62,
|
||||
0, 0, 0, 62, 57, 57, 0, 67, 67, 57,
|
||||
63, 67, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 63, 63, 63, 0, 0, 0, 63, 63, 63,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 74, 0,
|
||||
|
||||
0, 0, 66, 66, 0, 0, 0, 66, 76, 76,
|
||||
76, 76, 76, 76, 76, 76, 77, 0, 0, 77,
|
||||
77, 77, 78, 78, 78, 78, 78, 78, 78, 78,
|
||||
79, 79, 79, 79, 79, 79, 79, 79, 80, 0,
|
||||
80, 80, 80, 80, 80, 80, 81, 0, 81, 81,
|
||||
81, 81, 81, 81, 82, 82, 0, 82, 83, 0,
|
||||
83, 84, 84, 84, 85, 0, 85, 86, 86, 86,
|
||||
86, 86, 86, 86, 86, 87, 87, 87, 87, 87,
|
||||
87, 87, 87, 75, 75, 75, 75, 75, 75, 75,
|
||||
75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
|
||||
0, 74, 74, 74, 75, 75, 75, 75, 75, 75,
|
||||
75, 75, 76, 76, 76, 76, 76, 76, 76, 76,
|
||||
77, 0, 77, 77, 77, 77, 77, 77, 78, 0,
|
||||
78, 78, 78, 78, 78, 78, 79, 79, 0, 79,
|
||||
80, 0, 80, 81, 81, 81, 82, 0, 82, 83,
|
||||
83, 83, 83, 83, 83, 83, 83, 84, 84, 84,
|
||||
84, 84, 84, 84, 84, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72
|
||||
|
||||
75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
|
||||
75, 75
|
||||
} ;
|
||||
|
||||
static yy_state_type yy_last_accepting_state;
|
||||
@ -619,8 +614,8 @@ int yy_flex_debug = 1;
|
||||
|
||||
static yyconst flex_int16_t yy_rule_linenum[13] =
|
||||
{ 0,
|
||||
71, 72, 73, 76, 79, 80, 81, 87, 88, 89,
|
||||
91, 94
|
||||
67, 68, 69, 72, 75, 76, 77, 83, 84, 85,
|
||||
87, 90
|
||||
} ;
|
||||
|
||||
/* The intent behind this definition is that it'll catch
|
||||
@ -667,15 +662,11 @@ char *yytext;
|
||||
and then we categorize those basic tokens in the second stage. */
|
||||
#define YY_DECL static int yylex1(void)
|
||||
|
||||
/* Version 2 checksumming does proper tokenization; version 1 wasn't
|
||||
quite so pedantic. */
|
||||
|
||||
/* We don't do multiple input files. */
|
||||
#define YY_NO_INPUT 1
|
||||
#line 676 "scripts/genksyms/lex.c"
|
||||
#line 668 "scripts/genksyms/lex.c"
|
||||
|
||||
#define INITIAL 0
|
||||
#define V2_TOKENS 1
|
||||
|
||||
#ifndef YY_NO_UNISTD_H
|
||||
/* Special case for "unistd.h", since it is non-ANSI. We include it way
|
||||
@ -808,7 +799,7 @@ static int input (void );
|
||||
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
|
||||
{ \
|
||||
int c = '*'; \
|
||||
size_t n; \
|
||||
int n; \
|
||||
for ( n = 0; n < max_size && \
|
||||
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
|
||||
buf[n] = (char) c; \
|
||||
@ -918,12 +909,12 @@ YY_DECL
|
||||
register int yy_act;
|
||||
|
||||
/* %% [7.0] user's declarations go here */
|
||||
#line 67 "scripts/genksyms/lex.l"
|
||||
#line 63 "scripts/genksyms/lex.l"
|
||||
|
||||
|
||||
|
||||
/* Keep track of our location in the original source files. */
|
||||
#line 927 "scripts/genksyms/lex.c"
|
||||
#line 918 "scripts/genksyms/lex.c"
|
||||
|
||||
if ( !(yy_init) )
|
||||
{
|
||||
@ -987,13 +978,13 @@ yy_match:
|
||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
|
||||
{
|
||||
yy_current_state = (int) yy_def[yy_current_state];
|
||||
if ( yy_current_state >= 76 )
|
||||
if ( yy_current_state >= 73 )
|
||||
yy_c = yy_meta[(unsigned int) yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
|
||||
++yy_cp;
|
||||
}
|
||||
while ( yy_base[yy_current_state] != 284 );
|
||||
while ( yy_base[yy_current_state] != 266 );
|
||||
|
||||
yy_find_action:
|
||||
/* %% [10.0] code to find the action number goes here */
|
||||
@ -1041,42 +1032,42 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
case 1:
|
||||
/* rule 1 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 71 "scripts/genksyms/lex.l"
|
||||
#line 67 "scripts/genksyms/lex.l"
|
||||
return FILENAME;
|
||||
YY_BREAK
|
||||
case 2:
|
||||
/* rule 2 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 72 "scripts/genksyms/lex.l"
|
||||
#line 68 "scripts/genksyms/lex.l"
|
||||
cur_line++;
|
||||
YY_BREAK
|
||||
case 3:
|
||||
/* rule 3 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 73 "scripts/genksyms/lex.l"
|
||||
#line 69 "scripts/genksyms/lex.l"
|
||||
cur_line++;
|
||||
YY_BREAK
|
||||
/* Ignore all other whitespace. */
|
||||
case 4:
|
||||
YY_RULE_SETUP
|
||||
#line 76 "scripts/genksyms/lex.l"
|
||||
#line 72 "scripts/genksyms/lex.l"
|
||||
;
|
||||
YY_BREAK
|
||||
case 5:
|
||||
/* rule 5 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 79 "scripts/genksyms/lex.l"
|
||||
#line 75 "scripts/genksyms/lex.l"
|
||||
return STRING;
|
||||
YY_BREAK
|
||||
case 6:
|
||||
/* rule 6 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 80 "scripts/genksyms/lex.l"
|
||||
#line 76 "scripts/genksyms/lex.l"
|
||||
return CHAR;
|
||||
YY_BREAK
|
||||
case 7:
|
||||
YY_RULE_SETUP
|
||||
#line 81 "scripts/genksyms/lex.l"
|
||||
#line 77 "scripts/genksyms/lex.l"
|
||||
return IDENT;
|
||||
YY_BREAK
|
||||
/* The Pedant requires that the other C multi-character tokens be
|
||||
@ -1085,38 +1076,37 @@ return IDENT;
|
||||
around them properly. */
|
||||
case 8:
|
||||
YY_RULE_SETUP
|
||||
#line 87 "scripts/genksyms/lex.l"
|
||||
#line 83 "scripts/genksyms/lex.l"
|
||||
return OTHER;
|
||||
YY_BREAK
|
||||
case 9:
|
||||
YY_RULE_SETUP
|
||||
#line 88 "scripts/genksyms/lex.l"
|
||||
#line 84 "scripts/genksyms/lex.l"
|
||||
return INT;
|
||||
YY_BREAK
|
||||
case 10:
|
||||
YY_RULE_SETUP
|
||||
#line 89 "scripts/genksyms/lex.l"
|
||||
#line 85 "scripts/genksyms/lex.l"
|
||||
return REAL;
|
||||
YY_BREAK
|
||||
case 11:
|
||||
YY_RULE_SETUP
|
||||
#line 91 "scripts/genksyms/lex.l"
|
||||
#line 87 "scripts/genksyms/lex.l"
|
||||
return DOTS;
|
||||
YY_BREAK
|
||||
/* All other tokens are single characters. */
|
||||
case 12:
|
||||
YY_RULE_SETUP
|
||||
#line 94 "scripts/genksyms/lex.l"
|
||||
#line 90 "scripts/genksyms/lex.l"
|
||||
return yytext[0];
|
||||
YY_BREAK
|
||||
case 13:
|
||||
YY_RULE_SETUP
|
||||
#line 97 "scripts/genksyms/lex.l"
|
||||
#line 93 "scripts/genksyms/lex.l"
|
||||
ECHO;
|
||||
YY_BREAK
|
||||
#line 1118 "scripts/genksyms/lex.c"
|
||||
#line 1109 "scripts/genksyms/lex.c"
|
||||
case YY_STATE_EOF(INITIAL):
|
||||
case YY_STATE_EOF(V2_TOKENS):
|
||||
yyterminate();
|
||||
|
||||
case YY_END_OF_BUFFER:
|
||||
@ -1429,7 +1419,7 @@ static int yy_get_next_buffer (void)
|
||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
|
||||
{
|
||||
yy_current_state = (int) yy_def[yy_current_state];
|
||||
if ( yy_current_state >= 76 )
|
||||
if ( yy_current_state >= 73 )
|
||||
yy_c = yy_meta[(unsigned int) yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
|
||||
@ -1462,11 +1452,11 @@ static int yy_get_next_buffer (void)
|
||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
|
||||
{
|
||||
yy_current_state = (int) yy_def[yy_current_state];
|
||||
if ( yy_current_state >= 76 )
|
||||
if ( yy_current_state >= 73 )
|
||||
yy_c = yy_meta[(unsigned int) yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
|
||||
yy_is_jam = (yy_current_state == 75);
|
||||
yy_is_jam = (yy_current_state == 72);
|
||||
|
||||
return yy_is_jam ? 0 : yy_current_state;
|
||||
}
|
||||
@ -2252,7 +2242,7 @@ void yyfree (void * ptr )
|
||||
|
||||
/* %ok-for-header */
|
||||
|
||||
#line 97 "scripts/genksyms/lex.l"
|
||||
#line 93 "scripts/genksyms/lex.l"
|
||||
|
||||
|
||||
|
||||
@ -2263,12 +2253,23 @@ void yyfree (void * ptr )
|
||||
|
||||
/* Macros to append to our phrase collection list. */
|
||||
|
||||
/*
|
||||
* We mark any token, that that equals to a known enumerator, as
|
||||
* SYM_ENUM_CONST. The parser will change this for struct and union tags later,
|
||||
* the only problem is struct and union members:
|
||||
* enum e { a, b }; struct s { int a, b; }
|
||||
* but in this case, the only effect will be, that the ABI checksums become
|
||||
* more volatile, which is acceptable. Also, such collisions are quite rare,
|
||||
* so far it was only observed in include/linux/telephony.h.
|
||||
*/
|
||||
#define _APP(T,L) do { \
|
||||
cur_node = next_node; \
|
||||
next_node = xmalloc(sizeof(*next_node)); \
|
||||
next_node->next = cur_node; \
|
||||
cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
|
||||
cur_node->tag = SYM_NORMAL; \
|
||||
cur_node->tag = \
|
||||
find_symbol(cur_node->string, SYM_ENUM_CONST, 1)?\
|
||||
SYM_ENUM_CONST : SYM_NORMAL ; \
|
||||
} while (0)
|
||||
|
||||
#define APP _APP(yytext, yyleng)
|
||||
@ -2294,7 +2295,6 @@ yylex(void)
|
||||
|
||||
if (lexstate == ST_NOTSTARTED)
|
||||
{
|
||||
BEGIN(V2_TOKENS);
|
||||
next_node = xmalloc(sizeof(*next_node));
|
||||
next_node->next = NULL;
|
||||
lexstate = ST_NORMAL;
|
||||
@ -2347,8 +2347,8 @@ repeat:
|
||||
|
||||
case STRUCT_KEYW:
|
||||
case UNION_KEYW:
|
||||
dont_want_brace_phrase = 3;
|
||||
case ENUM_KEYW:
|
||||
dont_want_brace_phrase = 3;
|
||||
suppress_type_lookup = 2;
|
||||
goto fini;
|
||||
|
||||
@ -2358,8 +2358,7 @@ repeat:
|
||||
}
|
||||
if (!suppress_type_lookup)
|
||||
{
|
||||
struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF);
|
||||
if (sym && sym->type == SYM_TYPEDEF)
|
||||
if (find_symbol(yytext, SYM_TYPEDEF, 1))
|
||||
token = TYPE;
|
||||
}
|
||||
}
|
||||
@ -2478,7 +2477,20 @@ repeat:
|
||||
++count;
|
||||
APP;
|
||||
goto repeat;
|
||||
case ')': case ']': case '}':
|
||||
case '}':
|
||||
/* is this the last line of an enum declaration? */
|
||||
if (count == 0)
|
||||
{
|
||||
/* Put back the token we just read so's we can find it again
|
||||
after registering the expression. */
|
||||
unput(token);
|
||||
|
||||
lexstate = ST_NORMAL;
|
||||
token = EXPRESSION_PHRASE;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case ')': case ']':
|
||||
--count;
|
||||
APP;
|
||||
goto repeat;
|
||||
@ -2567,143 +2579,4 @@ fini:
|
||||
|
||||
return token;
|
||||
}
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
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, 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., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
ASM_KEYW = 258,
|
||||
ATTRIBUTE_KEYW = 259,
|
||||
AUTO_KEYW = 260,
|
||||
BOOL_KEYW = 261,
|
||||
CHAR_KEYW = 262,
|
||||
CONST_KEYW = 263,
|
||||
DOUBLE_KEYW = 264,
|
||||
ENUM_KEYW = 265,
|
||||
EXTERN_KEYW = 266,
|
||||
EXTENSION_KEYW = 267,
|
||||
FLOAT_KEYW = 268,
|
||||
INLINE_KEYW = 269,
|
||||
INT_KEYW = 270,
|
||||
LONG_KEYW = 271,
|
||||
REGISTER_KEYW = 272,
|
||||
RESTRICT_KEYW = 273,
|
||||
SHORT_KEYW = 274,
|
||||
SIGNED_KEYW = 275,
|
||||
STATIC_KEYW = 276,
|
||||
STRUCT_KEYW = 277,
|
||||
TYPEDEF_KEYW = 278,
|
||||
UNION_KEYW = 279,
|
||||
UNSIGNED_KEYW = 280,
|
||||
VOID_KEYW = 281,
|
||||
VOLATILE_KEYW = 282,
|
||||
TYPEOF_KEYW = 283,
|
||||
EXPORT_SYMBOL_KEYW = 284,
|
||||
ASM_PHRASE = 285,
|
||||
ATTRIBUTE_PHRASE = 286,
|
||||
BRACE_PHRASE = 287,
|
||||
BRACKET_PHRASE = 288,
|
||||
EXPRESSION_PHRASE = 289,
|
||||
CHAR = 290,
|
||||
DOTS = 291,
|
||||
IDENT = 292,
|
||||
INT = 293,
|
||||
REAL = 294,
|
||||
STRING = 295,
|
||||
TYPE = 296,
|
||||
OTHER = 297,
|
||||
FILENAME = 298
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define ASM_KEYW 258
|
||||
#define ATTRIBUTE_KEYW 259
|
||||
#define AUTO_KEYW 260
|
||||
#define BOOL_KEYW 261
|
||||
#define CHAR_KEYW 262
|
||||
#define CONST_KEYW 263
|
||||
#define DOUBLE_KEYW 264
|
||||
#define ENUM_KEYW 265
|
||||
#define EXTERN_KEYW 266
|
||||
#define EXTENSION_KEYW 267
|
||||
#define FLOAT_KEYW 268
|
||||
#define INLINE_KEYW 269
|
||||
#define INT_KEYW 270
|
||||
#define LONG_KEYW 271
|
||||
#define REGISTER_KEYW 272
|
||||
#define RESTRICT_KEYW 273
|
||||
#define SHORT_KEYW 274
|
||||
#define SIGNED_KEYW 275
|
||||
#define STATIC_KEYW 276
|
||||
#define STRUCT_KEYW 277
|
||||
#define TYPEDEF_KEYW 278
|
||||
#define UNION_KEYW 279
|
||||
#define UNSIGNED_KEYW 280
|
||||
#define VOID_KEYW 281
|
||||
#define VOLATILE_KEYW 282
|
||||
#define TYPEOF_KEYW 283
|
||||
#define EXPORT_SYMBOL_KEYW 284
|
||||
#define ASM_PHRASE 285
|
||||
#define ATTRIBUTE_PHRASE 286
|
||||
#define BRACE_PHRASE 287
|
||||
#define BRACKET_PHRASE 288
|
||||
#define EXPRESSION_PHRASE 289
|
||||
#define CHAR 290
|
||||
#define DOTS 291
|
||||
#define IDENT 292
|
||||
#define INT 293
|
||||
#define REAL 294
|
||||
#define STRING 295
|
||||
#define TYPE 296
|
||||
#define OTHER 297
|
||||
#define FILENAME 298
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef int YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
|
||||
|
@ -55,10 +55,6 @@ CHAR L?\'([^\\\']*\\.)*[^\\\']*\'
|
||||
|
||||
MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
|
||||
|
||||
/* Version 2 checksumming does proper tokenization; version 1 wasn't
|
||||
quite so pedantic. */
|
||||
%s V2_TOKENS
|
||||
|
||||
/* We don't do multiple input files. */
|
||||
%option noyywrap
|
||||
|
||||
@ -84,9 +80,9 @@ MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
|
||||
recognized as tokens. We don't actually use them since we don't
|
||||
parse expressions, but we do want whitespace to be arranged
|
||||
around them properly. */
|
||||
<V2_TOKENS>{MC_TOKEN} return OTHER;
|
||||
<V2_TOKENS>{INT} return INT;
|
||||
<V2_TOKENS>{REAL} return REAL;
|
||||
{MC_TOKEN} return OTHER;
|
||||
{INT} return INT;
|
||||
{REAL} return REAL;
|
||||
|
||||
"..." return DOTS;
|
||||
|
||||
@ -103,12 +99,23 @@ MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
|
||||
|
||||
/* Macros to append to our phrase collection list. */
|
||||
|
||||
/*
|
||||
* We mark any token, that that equals to a known enumerator, as
|
||||
* SYM_ENUM_CONST. The parser will change this for struct and union tags later,
|
||||
* the only problem is struct and union members:
|
||||
* enum e { a, b }; struct s { int a, b; }
|
||||
* but in this case, the only effect will be, that the ABI checksums become
|
||||
* more volatile, which is acceptable. Also, such collisions are quite rare,
|
||||
* so far it was only observed in include/linux/telephony.h.
|
||||
*/
|
||||
#define _APP(T,L) do { \
|
||||
cur_node = next_node; \
|
||||
next_node = xmalloc(sizeof(*next_node)); \
|
||||
next_node->next = cur_node; \
|
||||
cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
|
||||
cur_node->tag = SYM_NORMAL; \
|
||||
cur_node->tag = \
|
||||
find_symbol(cur_node->string, SYM_ENUM_CONST, 1)?\
|
||||
SYM_ENUM_CONST : SYM_NORMAL ; \
|
||||
} while (0)
|
||||
|
||||
#define APP _APP(yytext, yyleng)
|
||||
@ -134,7 +141,6 @@ yylex(void)
|
||||
|
||||
if (lexstate == ST_NOTSTARTED)
|
||||
{
|
||||
BEGIN(V2_TOKENS);
|
||||
next_node = xmalloc(sizeof(*next_node));
|
||||
next_node->next = NULL;
|
||||
lexstate = ST_NORMAL;
|
||||
@ -187,8 +193,8 @@ repeat:
|
||||
|
||||
case STRUCT_KEYW:
|
||||
case UNION_KEYW:
|
||||
dont_want_brace_phrase = 3;
|
||||
case ENUM_KEYW:
|
||||
dont_want_brace_phrase = 3;
|
||||
suppress_type_lookup = 2;
|
||||
goto fini;
|
||||
|
||||
@ -198,8 +204,7 @@ repeat:
|
||||
}
|
||||
if (!suppress_type_lookup)
|
||||
{
|
||||
struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF);
|
||||
if (sym && sym->type == SYM_TYPEDEF)
|
||||
if (find_symbol(yytext, SYM_TYPEDEF, 1))
|
||||
token = TYPE;
|
||||
}
|
||||
}
|
||||
@ -318,7 +323,20 @@ repeat:
|
||||
++count;
|
||||
APP;
|
||||
goto repeat;
|
||||
case ')': case ']': case '}':
|
||||
case '}':
|
||||
/* is this the last line of an enum declaration? */
|
||||
if (count == 0)
|
||||
{
|
||||
/* Put back the token we just read so's we can find it again
|
||||
after registering the expression. */
|
||||
unput(token);
|
||||
|
||||
lexstate = ST_NORMAL;
|
||||
token = EXPRESSION_PHRASE;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case ')': case ']':
|
||||
--count;
|
||||
APP;
|
||||
goto repeat;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,24 +1,23 @@
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
|
||||
/* A Bison parser, made by GNU Bison 2.4.1. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
||||
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, or (at your option)
|
||||
any later version.
|
||||
|
||||
the Free Software Foundation, either version 3 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., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
@ -29,10 +28,11 @@
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
@ -82,58 +82,16 @@
|
||||
FILENAME = 298
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define ASM_KEYW 258
|
||||
#define ATTRIBUTE_KEYW 259
|
||||
#define AUTO_KEYW 260
|
||||
#define BOOL_KEYW 261
|
||||
#define CHAR_KEYW 262
|
||||
#define CONST_KEYW 263
|
||||
#define DOUBLE_KEYW 264
|
||||
#define ENUM_KEYW 265
|
||||
#define EXTERN_KEYW 266
|
||||
#define EXTENSION_KEYW 267
|
||||
#define FLOAT_KEYW 268
|
||||
#define INLINE_KEYW 269
|
||||
#define INT_KEYW 270
|
||||
#define LONG_KEYW 271
|
||||
#define REGISTER_KEYW 272
|
||||
#define RESTRICT_KEYW 273
|
||||
#define SHORT_KEYW 274
|
||||
#define SIGNED_KEYW 275
|
||||
#define STATIC_KEYW 276
|
||||
#define STRUCT_KEYW 277
|
||||
#define TYPEDEF_KEYW 278
|
||||
#define UNION_KEYW 279
|
||||
#define UNSIGNED_KEYW 280
|
||||
#define VOID_KEYW 281
|
||||
#define VOLATILE_KEYW 282
|
||||
#define TYPEOF_KEYW 283
|
||||
#define EXPORT_SYMBOL_KEYW 284
|
||||
#define ASM_PHRASE 285
|
||||
#define ATTRIBUTE_PHRASE 286
|
||||
#define BRACE_PHRASE 287
|
||||
#define BRACKET_PHRASE 288
|
||||
#define EXPRESSION_PHRASE 289
|
||||
#define CHAR 290
|
||||
#define DOTS 291
|
||||
#define IDENT 292
|
||||
#define INT 293
|
||||
#define REAL 294
|
||||
#define STRING 295
|
||||
#define TYPE 296
|
||||
#define OTHER 297
|
||||
#define FILENAME 298
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef int YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "genksyms.h"
|
||||
|
||||
static int is_typedef;
|
||||
@ -227,16 +228,19 @@ type_specifier:
|
||||
add_symbol(i->string, SYM_UNION, s, is_extern);
|
||||
$$ = $3;
|
||||
}
|
||||
| ENUM_KEYW IDENT BRACE_PHRASE
|
||||
| ENUM_KEYW IDENT enum_body
|
||||
{ struct string_list *s = *$3, *i = *$2, *r;
|
||||
r = copy_node(i); r->tag = SYM_ENUM;
|
||||
r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
|
||||
add_symbol(i->string, SYM_ENUM, s, is_extern);
|
||||
$$ = $3;
|
||||
}
|
||||
|
||||
/* Anonymous s/u/e definitions. Nothing needs doing. */
|
||||
| ENUM_KEYW BRACE_PHRASE { $$ = $2; }
|
||||
/*
|
||||
* Anonymous enum definition. Tell add_symbol() to restart its counter.
|
||||
*/
|
||||
| ENUM_KEYW enum_body
|
||||
{ add_symbol(NULL, SYM_ENUM, NULL, 0); $$ = $2; }
|
||||
/* Anonymous s/u definitions. Nothing needs doing. */
|
||||
| STRUCT_KEYW class_body { $$ = $2; }
|
||||
| UNION_KEYW class_body { $$ = $2; }
|
||||
;
|
||||
@ -449,6 +453,28 @@ attribute_opt:
|
||||
| attribute_opt ATTRIBUTE_PHRASE
|
||||
;
|
||||
|
||||
enum_body:
|
||||
'{' enumerator_list '}' { $$ = $3; }
|
||||
| '{' enumerator_list ',' '}' { $$ = $4; }
|
||||
;
|
||||
|
||||
enumerator_list:
|
||||
enumerator
|
||||
| enumerator_list ',' enumerator
|
||||
|
||||
enumerator:
|
||||
IDENT
|
||||
{
|
||||
const char *name = strdup((*$1)->string);
|
||||
add_symbol(name, SYM_ENUM_CONST, NULL, 0);
|
||||
}
|
||||
| IDENT '=' EXPRESSION_PHRASE
|
||||
{
|
||||
const char *name = strdup((*$1)->string);
|
||||
struct string_list *expr = copy_list_range(*$3, *$2);
|
||||
add_symbol(name, SYM_ENUM_CONST, expr, 0);
|
||||
}
|
||||
|
||||
asm_definition:
|
||||
ASM_PHRASE ';' { $$ = $2; }
|
||||
;
|
||||
|
@ -1248,6 +1248,19 @@ static int is_function(Elf_Sym *sym)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void print_section_list(const char * const list[20])
|
||||
{
|
||||
const char *const *s = list;
|
||||
|
||||
while (*s) {
|
||||
fprintf(stderr, "%s", *s);
|
||||
s++;
|
||||
if (*s)
|
||||
fprintf(stderr, ", ");
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a warning about a section mismatch.
|
||||
* Try to find symbols near it so user can find it.
|
||||
@ -1304,7 +1317,6 @@ static void report_sec_mismatch(const char *modname,
|
||||
break;
|
||||
case DATA_TO_ANY_INIT: {
|
||||
prl_to = sec2annotation(tosec);
|
||||
const char *const *s = mismatch->symbol_white_list;
|
||||
fprintf(stderr,
|
||||
"The variable %s references\n"
|
||||
"the %s %s%s%s\n"
|
||||
@ -1312,9 +1324,7 @@ static void report_sec_mismatch(const char *modname,
|
||||
"variable with __init* or __refdata (see linux/init.h) "
|
||||
"or name the variable:\n",
|
||||
fromsym, to, prl_to, tosym, to_p);
|
||||
while (*s)
|
||||
fprintf(stderr, "%s, ", *s++);
|
||||
fprintf(stderr, "\n");
|
||||
print_section_list(mismatch->symbol_white_list);
|
||||
free(prl_to);
|
||||
break;
|
||||
}
|
||||
@ -1329,7 +1339,6 @@ static void report_sec_mismatch(const char *modname,
|
||||
break;
|
||||
case DATA_TO_ANY_EXIT: {
|
||||
prl_to = sec2annotation(tosec);
|
||||
const char *const *s = mismatch->symbol_white_list;
|
||||
fprintf(stderr,
|
||||
"The variable %s references\n"
|
||||
"the %s %s%s%s\n"
|
||||
@ -1337,9 +1346,7 @@ static void report_sec_mismatch(const char *modname,
|
||||
"variable with __exit* (see linux/init.h) or "
|
||||
"name the variable:\n",
|
||||
fromsym, to, prl_to, tosym, to_p);
|
||||
while (*s)
|
||||
fprintf(stderr, "%s, ", *s++);
|
||||
fprintf(stderr, "\n");
|
||||
print_section_list(mismatch->symbol_white_list);
|
||||
free(prl_to);
|
||||
break;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002 - 2009 Tony Finch <dot@dotat.at>
|
||||
* Copyright (c) 2002 - 2011 Tony Finch <dot@dotat.at>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -24,23 +24,14 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* unifdef - remove ifdef'ed lines
|
||||
*
|
||||
* This code was derived from software contributed to Berkeley by Dave Yost.
|
||||
* It was rewritten to support ANSI C by Tony Finch. The original version
|
||||
* of unifdef carried the 4-clause BSD copyright licence. None of its code
|
||||
* remains in this version (though some of the names remain) so it now
|
||||
* carries a more liberal licence.
|
||||
*
|
||||
* The latest version is available from http://dotat.at/prog/unifdef
|
||||
*/
|
||||
|
||||
static const char * const copyright[] = {
|
||||
"@(#) Copyright (c) 2002 - 2009 Tony Finch <dot@dotat.at>\n",
|
||||
"$dotat: unifdef/unifdef.c,v 1.190 2009/11/27 17:21:26 fanf2 Exp $",
|
||||
};
|
||||
|
||||
/*
|
||||
* unifdef - remove ifdef'ed lines
|
||||
*
|
||||
* Wishlist:
|
||||
* provide an option which will append the name of the
|
||||
* appropriate symbol after #else's and #endif's
|
||||
@ -48,12 +39,16 @@ static const char * const copyright[] = {
|
||||
* #else's and #endif's to see that they match their
|
||||
* corresponding #ifdef or #ifndef
|
||||
*
|
||||
* The first two items above require better buffer handling, which would
|
||||
* also make it possible to handle all "dodgy" directives correctly.
|
||||
* These require better buffer handling, which would also make
|
||||
* it possible to handle all "dodgy" directives correctly.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
@ -61,6 +56,12 @@ static const char * const copyright[] = {
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const char copyright[] =
|
||||
"@(#) $Version: unifdef-2.5 $\n"
|
||||
"@(#) $Author: Tony Finch (dot@dotat.at) $\n"
|
||||
"@(#) $URL: http://dotat.at/prog/unifdef $\n"
|
||||
;
|
||||
|
||||
/* types of input lines: */
|
||||
typedef enum {
|
||||
LT_TRUEI, /* a true #if with ignore flag */
|
||||
@ -152,6 +153,11 @@ static char const * const linestate_name[] = {
|
||||
*/
|
||||
#define EDITSLOP 10
|
||||
|
||||
/*
|
||||
* For temporary filenames
|
||||
*/
|
||||
#define TEMPLATE "unifdef.XXXXXX"
|
||||
|
||||
/*
|
||||
* Globals.
|
||||
*/
|
||||
@ -165,6 +171,7 @@ static bool strictlogic; /* -K: keep ambiguous #ifs */
|
||||
static bool killconsts; /* -k: eval constant #ifs */
|
||||
static bool lnnum; /* -n: add #line directives */
|
||||
static bool symlist; /* -s: output symbol list */
|
||||
static bool symdepth; /* -S: output symbol depth */
|
||||
static bool text; /* -t: this is a text file */
|
||||
|
||||
static const char *symname[MAXSYMS]; /* symbol name */
|
||||
@ -175,10 +182,18 @@ static int nsyms; /* number of symbols */
|
||||
static FILE *input; /* input file pointer */
|
||||
static const char *filename; /* input file name */
|
||||
static int linenum; /* current line number */
|
||||
static FILE *output; /* output file pointer */
|
||||
static const char *ofilename; /* output file name */
|
||||
static bool overwriting; /* output overwrites input */
|
||||
static char tempname[FILENAME_MAX]; /* used when overwriting */
|
||||
|
||||
static char tline[MAXLINE+EDITSLOP];/* input buffer plus space */
|
||||
static char *keyword; /* used for editing #elif's */
|
||||
|
||||
static const char *newline; /* input file format */
|
||||
static const char newline_unix[] = "\n";
|
||||
static const char newline_crlf[] = "\r\n";
|
||||
|
||||
static Comment_state incomment; /* comment parser state */
|
||||
static Line_state linestate; /* #if line parser state */
|
||||
static Ifstate ifstate[MAXDEPTH]; /* #if processor state */
|
||||
@ -189,10 +204,13 @@ static int delcount; /* count of deleted lines */
|
||||
static unsigned blankcount; /* count of blank lines */
|
||||
static unsigned blankmax; /* maximum recent blankcount */
|
||||
static bool constexpr; /* constant #if expression */
|
||||
static bool zerosyms = true; /* to format symdepth output */
|
||||
static bool firstsym; /* ditto */
|
||||
|
||||
static int exitstat; /* program exit status */
|
||||
|
||||
static void addsym(bool, bool, char *);
|
||||
static void closeout(void);
|
||||
static void debug(const char *, ...);
|
||||
static void done(void);
|
||||
static void error(const char *);
|
||||
@ -212,6 +230,7 @@ static void state(Ifstate);
|
||||
static int strlcmp(const char *, const char *, size_t);
|
||||
static void unnest(void);
|
||||
static void usage(void);
|
||||
static void version(void);
|
||||
|
||||
#define endsym(c) (!isalnum((unsigned char)c) && c != '_')
|
||||
|
||||
@ -223,7 +242,7 @@ main(int argc, char *argv[])
|
||||
{
|
||||
int opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, "i:D:U:I:BbcdeKklnst")) != -1)
|
||||
while ((opt = getopt(argc, argv, "i:D:U:I:o:bBcdeKklnsStV")) != -1)
|
||||
switch (opt) {
|
||||
case 'i': /* treat stuff controlled by these symbols as text */
|
||||
/*
|
||||
@ -245,16 +264,15 @@ main(int argc, char *argv[])
|
||||
case 'U': /* undef a symbol */
|
||||
addsym(false, false, optarg);
|
||||
break;
|
||||
case 'I':
|
||||
/* no-op for compatibility with cpp */
|
||||
break;
|
||||
case 'B': /* compress blank lines around removed section */
|
||||
compblank = true;
|
||||
case 'I': /* no-op for compatibility with cpp */
|
||||
break;
|
||||
case 'b': /* blank deleted lines instead of omitting them */
|
||||
case 'l': /* backwards compatibility */
|
||||
lnblank = true;
|
||||
break;
|
||||
case 'B': /* compress blank lines around removed section */
|
||||
compblank = true;
|
||||
break;
|
||||
case 'c': /* treat -D as -U and vice versa */
|
||||
complement = true;
|
||||
break;
|
||||
@ -273,12 +291,20 @@ main(int argc, char *argv[])
|
||||
case 'n': /* add #line directive after deleted lines */
|
||||
lnnum = true;
|
||||
break;
|
||||
case 'o': /* output to a file */
|
||||
ofilename = optarg;
|
||||
break;
|
||||
case 's': /* only output list of symbols that control #ifs */
|
||||
symlist = true;
|
||||
break;
|
||||
case 'S': /* list symbols with their nesting depth */
|
||||
symlist = symdepth = true;
|
||||
break;
|
||||
case 't': /* don't parse C comments */
|
||||
text = true;
|
||||
break;
|
||||
case 'V': /* print version */
|
||||
version();
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
@ -290,21 +316,68 @@ main(int argc, char *argv[])
|
||||
errx(2, "can only do one file");
|
||||
} else if (argc == 1 && strcmp(*argv, "-") != 0) {
|
||||
filename = *argv;
|
||||
input = fopen(filename, "r");
|
||||
input = fopen(filename, "rb");
|
||||
if (input == NULL)
|
||||
err(2, "can't open %s", filename);
|
||||
} else {
|
||||
filename = "[stdin]";
|
||||
input = stdin;
|
||||
}
|
||||
if (ofilename == NULL) {
|
||||
ofilename = "[stdout]";
|
||||
output = stdout;
|
||||
} else {
|
||||
struct stat ist, ost;
|
||||
if (stat(ofilename, &ost) == 0 &&
|
||||
fstat(fileno(input), &ist) == 0)
|
||||
overwriting = (ist.st_dev == ost.st_dev
|
||||
&& ist.st_ino == ost.st_ino);
|
||||
if (overwriting) {
|
||||
const char *dirsep;
|
||||
int ofd;
|
||||
|
||||
dirsep = strrchr(ofilename, '/');
|
||||
if (dirsep != NULL)
|
||||
snprintf(tempname, sizeof(tempname),
|
||||
"%.*s/" TEMPLATE,
|
||||
(int)(dirsep - ofilename), ofilename);
|
||||
else
|
||||
snprintf(tempname, sizeof(tempname),
|
||||
TEMPLATE);
|
||||
ofd = mkstemp(tempname);
|
||||
if (ofd != -1)
|
||||
output = fdopen(ofd, "wb+");
|
||||
if (output == NULL)
|
||||
err(2, "can't create temporary file");
|
||||
fchmod(ofd, ist.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO));
|
||||
} else {
|
||||
output = fopen(ofilename, "wb");
|
||||
if (output == NULL)
|
||||
err(2, "can't open %s", ofilename);
|
||||
}
|
||||
}
|
||||
process();
|
||||
abort(); /* bug */
|
||||
}
|
||||
|
||||
static void
|
||||
version(void)
|
||||
{
|
||||
const char *c = copyright;
|
||||
for (;;) {
|
||||
while (*++c != '$')
|
||||
if (*c == '\0')
|
||||
exit(0);
|
||||
while (*++c != '$')
|
||||
putc(*c, stderr);
|
||||
putc('\n', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]"
|
||||
fprintf(stderr, "usage: unifdef [-bBcdeKknsStV] [-Ipath]"
|
||||
" [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");
|
||||
exit(2);
|
||||
}
|
||||
@ -322,7 +395,8 @@ usage(void)
|
||||
* When we have processed a group that starts off with a known-false
|
||||
* #if/#elif sequence (which has therefore been deleted) followed by a
|
||||
* #elif that we don't understand and therefore must keep, we edit the
|
||||
* latter into a #if to keep the nesting correct.
|
||||
* latter into a #if to keep the nesting correct. We use strncpy() to
|
||||
* overwrite the 4 byte token "elif" with "if " without a '\0' byte.
|
||||
*
|
||||
* When we find a true #elif in a group, the following block will
|
||||
* always be kept and the rest of the sequence after the next #elif or
|
||||
@ -375,11 +449,11 @@ static void Oelif (void) { if (!iocccok) Eioccc(); Pelif(); }
|
||||
static void Idrop (void) { Fdrop(); ignoreon(); }
|
||||
static void Itrue (void) { Ftrue(); ignoreon(); }
|
||||
static void Ifalse(void) { Ffalse(); ignoreon(); }
|
||||
/* edit this line */
|
||||
/* modify this line */
|
||||
static void Mpass (void) { strncpy(keyword, "if ", 4); Pelif(); }
|
||||
static void Mtrue (void) { keywordedit("else\n"); state(IS_TRUE_MIDDLE); }
|
||||
static void Melif (void) { keywordedit("endif\n"); state(IS_FALSE_TRAILER); }
|
||||
static void Melse (void) { keywordedit("endif\n"); state(IS_FALSE_ELSE); }
|
||||
static void Mtrue (void) { keywordedit("else"); state(IS_TRUE_MIDDLE); }
|
||||
static void Melif (void) { keywordedit("endif"); state(IS_FALSE_TRAILER); }
|
||||
static void Melse (void) { keywordedit("endif"); state(IS_FALSE_ELSE); }
|
||||
|
||||
static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
|
||||
/* IS_OUTSIDE */
|
||||
@ -431,13 +505,6 @@ static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
|
||||
* State machine utility functions
|
||||
*/
|
||||
static void
|
||||
done(void)
|
||||
{
|
||||
if (incomment)
|
||||
error("EOF in comment");
|
||||
exit(exitstat);
|
||||
}
|
||||
static void
|
||||
ignoreoff(void)
|
||||
{
|
||||
if (depth == 0)
|
||||
@ -452,14 +519,8 @@ ignoreon(void)
|
||||
static void
|
||||
keywordedit(const char *replacement)
|
||||
{
|
||||
size_t size = tline + sizeof(tline) - keyword;
|
||||
char *dst = keyword;
|
||||
const char *src = replacement;
|
||||
if (size != 0) {
|
||||
while ((--size != 0) && (*src != '\0'))
|
||||
*dst++ = *src++;
|
||||
*dst = '\0';
|
||||
}
|
||||
snprintf(keyword, tline + sizeof(tline) - keyword,
|
||||
"%s%s", replacement, newline);
|
||||
print();
|
||||
}
|
||||
static void
|
||||
@ -494,24 +555,26 @@ flushline(bool keep)
|
||||
if (symlist)
|
||||
return;
|
||||
if (keep ^ complement) {
|
||||
bool blankline = tline[strspn(tline, " \t\n")] == '\0';
|
||||
bool blankline = tline[strspn(tline, " \t\r\n")] == '\0';
|
||||
if (blankline && compblank && blankcount != blankmax) {
|
||||
delcount += 1;
|
||||
blankcount += 1;
|
||||
} else {
|
||||
if (lnnum && delcount > 0)
|
||||
printf("#line %d\n", linenum);
|
||||
fputs(tline, stdout);
|
||||
printf("#line %d%s", linenum, newline);
|
||||
fputs(tline, output);
|
||||
delcount = 0;
|
||||
blankmax = blankcount = blankline ? blankcount + 1 : 0;
|
||||
}
|
||||
} else {
|
||||
if (lnblank)
|
||||
putc('\n', stdout);
|
||||
fputs(newline, output);
|
||||
exitstat = 1;
|
||||
delcount += 1;
|
||||
blankcount = 0;
|
||||
}
|
||||
if (debugging)
|
||||
fflush(output);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -520,21 +583,54 @@ flushline(bool keep)
|
||||
static void
|
||||
process(void)
|
||||
{
|
||||
Linetype lineval;
|
||||
|
||||
/* When compressing blank lines, act as if the file
|
||||
is preceded by a large number of blank lines. */
|
||||
blankmax = blankcount = 1000;
|
||||
for (;;) {
|
||||
linenum++;
|
||||
lineval = parseline();
|
||||
Linetype lineval = parseline();
|
||||
trans_table[ifstate[depth]][lineval]();
|
||||
debug("process %s -> %s depth %d",
|
||||
linetype_name[lineval],
|
||||
debug("process line %d %s -> %s depth %d",
|
||||
linenum, linetype_name[lineval],
|
||||
ifstate_name[ifstate[depth]], depth);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the output and handle errors.
|
||||
*/
|
||||
static void
|
||||
closeout(void)
|
||||
{
|
||||
if (symdepth && !zerosyms)
|
||||
printf("\n");
|
||||
if (fclose(output) == EOF) {
|
||||
warn("couldn't write to %s", ofilename);
|
||||
if (overwriting) {
|
||||
unlink(tempname);
|
||||
errx(2, "%s unchanged", filename);
|
||||
} else {
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up and exit.
|
||||
*/
|
||||
static void
|
||||
done(void)
|
||||
{
|
||||
if (incomment)
|
||||
error("EOF in comment");
|
||||
closeout();
|
||||
if (overwriting && rename(tempname, ofilename) == -1) {
|
||||
warn("couldn't rename temporary file");
|
||||
unlink(tempname);
|
||||
errx(2, "%s unchanged", ofilename);
|
||||
}
|
||||
exit(exitstat);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a line and determine its type. We keep the preprocessor line
|
||||
* parser state between calls in the global variable linestate, with
|
||||
@ -549,14 +645,22 @@ parseline(void)
|
||||
Linetype retval;
|
||||
Comment_state wascomment;
|
||||
|
||||
linenum++;
|
||||
if (fgets(tline, MAXLINE, input) == NULL)
|
||||
return (LT_EOF);
|
||||
if (newline == NULL) {
|
||||
if (strrchr(tline, '\n') == strrchr(tline, '\r') + 1)
|
||||
newline = newline_crlf;
|
||||
else
|
||||
newline = newline_unix;
|
||||
}
|
||||
retval = LT_PLAIN;
|
||||
wascomment = incomment;
|
||||
cp = skipcomment(tline);
|
||||
if (linestate == LS_START) {
|
||||
if (*cp == '#') {
|
||||
linestate = LS_HASH;
|
||||
firstsym = true;
|
||||
cp = skipcomment(cp + 1);
|
||||
} else if (*cp != '\0')
|
||||
linestate = LS_DIRTY;
|
||||
@ -566,7 +670,8 @@ parseline(void)
|
||||
cp = skipsym(cp);
|
||||
kwlen = cp - keyword;
|
||||
/* no way can we deal with a continuation inside a keyword */
|
||||
if (strncmp(cp, "\\\n", 2) == 0)
|
||||
if (strncmp(cp, "\\\r\n", 3) == 0 ||
|
||||
strncmp(cp, "\\\n", 2) == 0)
|
||||
Eioccc();
|
||||
if (strlcmp("ifdef", keyword, kwlen) == 0 ||
|
||||
strlcmp("ifndef", keyword, kwlen) == 0) {
|
||||
@ -617,9 +722,8 @@ parseline(void)
|
||||
size_t len = cp - tline;
|
||||
if (fgets(tline + len, MAXLINE - len, input) == NULL) {
|
||||
/* append the missing newline */
|
||||
tline[len+0] = '\n';
|
||||
tline[len+1] = '\0';
|
||||
cp++;
|
||||
strcpy(tline + len, newline);
|
||||
cp += strlen(newline);
|
||||
linestate = LS_START;
|
||||
} else {
|
||||
linestate = LS_DIRTY;
|
||||
@ -630,7 +734,7 @@ parseline(void)
|
||||
while (*cp != '\0')
|
||||
cp = skipcomment(cp + 1);
|
||||
}
|
||||
debug("parser %s comment %s line",
|
||||
debug("parser line %d state %s comment %s line", linenum,
|
||||
comment_name[incomment], linestate_name[linestate]);
|
||||
return (retval);
|
||||
}
|
||||
@ -875,11 +979,16 @@ skipcomment(const char *cp)
|
||||
}
|
||||
while (*cp != '\0')
|
||||
/* don't reset to LS_START after a line continuation */
|
||||
if (strncmp(cp, "\\\n", 2) == 0)
|
||||
if (strncmp(cp, "\\\r\n", 3) == 0)
|
||||
cp += 3;
|
||||
else if (strncmp(cp, "\\\n", 2) == 0)
|
||||
cp += 2;
|
||||
else switch (incomment) {
|
||||
case NO_COMMENT:
|
||||
if (strncmp(cp, "/\\\n", 3) == 0) {
|
||||
if (strncmp(cp, "/\\\r\n", 4) == 0) {
|
||||
incomment = STARTING_COMMENT;
|
||||
cp += 4;
|
||||
} else if (strncmp(cp, "/\\\n", 3) == 0) {
|
||||
incomment = STARTING_COMMENT;
|
||||
cp += 3;
|
||||
} else if (strncmp(cp, "/*", 2) == 0) {
|
||||
@ -899,7 +1008,7 @@ skipcomment(const char *cp)
|
||||
} else if (strncmp(cp, "\n", 1) == 0) {
|
||||
linestate = LS_START;
|
||||
cp += 1;
|
||||
} else if (strchr(" \t", *cp) != NULL) {
|
||||
} else if (strchr(" \r\t", *cp) != NULL) {
|
||||
cp += 1;
|
||||
} else
|
||||
return (cp);
|
||||
@ -931,7 +1040,10 @@ skipcomment(const char *cp)
|
||||
cp += 1;
|
||||
continue;
|
||||
case C_COMMENT:
|
||||
if (strncmp(cp, "*\\\n", 3) == 0) {
|
||||
if (strncmp(cp, "*\\\r\n", 4) == 0) {
|
||||
incomment = FINISHING_COMMENT;
|
||||
cp += 4;
|
||||
} else if (strncmp(cp, "*\\\n", 3) == 0) {
|
||||
incomment = FINISHING_COMMENT;
|
||||
cp += 3;
|
||||
} else if (strncmp(cp, "*/", 2) == 0) {
|
||||
@ -1015,7 +1127,13 @@ findsym(const char *str)
|
||||
if (cp == str)
|
||||
return (-1);
|
||||
if (symlist) {
|
||||
printf("%.*s\n", (int)(cp-str), str);
|
||||
if (symdepth && firstsym)
|
||||
printf("%s%3d", zerosyms ? "" : "\n", depth);
|
||||
firstsym = zerosyms = false;
|
||||
printf("%s%.*s%s",
|
||||
symdepth ? " " : "",
|
||||
(int)(cp-str), str,
|
||||
symdepth ? "" : "\n");
|
||||
/* we don't care about the value of the symbol */
|
||||
return (0);
|
||||
}
|
||||
@ -1052,7 +1170,7 @@ addsym(bool ignorethis, bool definethis, char *sym)
|
||||
value[symind] = val+1;
|
||||
*val = '\0';
|
||||
} else if (*val == '\0')
|
||||
value[symind] = "";
|
||||
value[symind] = "1";
|
||||
else
|
||||
usage();
|
||||
} else {
|
||||
@ -1060,6 +1178,8 @@ addsym(bool ignorethis, bool definethis, char *sym)
|
||||
usage();
|
||||
value[symind] = NULL;
|
||||
}
|
||||
debug("addsym %s=%s", symname[symind],
|
||||
value[symind] ? value[symind] : "undef");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1100,5 +1220,6 @@ error(const char *msg)
|
||||
else
|
||||
warnx("%s: %d: %s (#if line %d depth %d)",
|
||||
filename, linenum, msg, stifline[depth], depth);
|
||||
closeout();
|
||||
errx(2, "output may be truncated");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user