Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
f7315b84
Commit
f7315b84
authored
Dec 29, 2007
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Avoid hacky recompilation of files to namespacize, use hacky parser
instead!
parent
2040a0c4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
150 additions
and
78 deletions
+150
-78
ccan_tools/namespacize.c
ccan_tools/namespacize.c
+150
-78
No files found.
ccan_tools/namespacize.c
View file @
f7315b84
...
...
@@ -13,7 +13,10 @@
#include "talloc/talloc.h"
#define CFLAGS "-O3 -Wall -Wundef -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Werror -I. -Iccan_tools/libtap/src/"
#define CFLAGS_HDR "-Wall -Wundef -Wstrict-prototypes -Wold-style-definition -Werror -I."
#define IDENT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz" \
"01234567889_"
static
bool
verbose
=
false
;
static
int
indent
=
0
;
...
...
@@ -166,20 +169,6 @@ lines_from_cmd(const void *ctx, char *format, ...)
return
split
(
ctx
,
buffer
,
"
\n
"
,
NULL
);
}
static
char
*
build_obj
(
const
char
*
cfile
)
{
char
*
cmd
;
char
*
ofile
=
talloc_strdup
(
cfile
,
cfile
);
ofile
[
strlen
(
ofile
)
-
1
]
=
'c'
;
cmd
=
talloc_asprintf
(
ofile
,
"gcc "
CFLAGS
" -o %s -c %s"
,
ofile
,
cfile
);
if
(
system
(
cmd
)
!=
0
)
errx
(
1
,
"Failed to compile %s"
,
cfile
);
return
ofile
;
}
struct
replace
{
struct
replace
*
next
;
...
...
@@ -200,11 +189,12 @@ static void __attribute__((noreturn)) usage(void)
static
void
add_replace
(
struct
replace
**
repl
,
const
char
*
str
)
{
struct
replace
*
new
;
struct
replace
*
new
,
*
i
;
/* Don't replace things already CCAN-ized (eg. idempotent wrappers) */
if
(
strstarts
(
str
,
"CCAN_"
)
||
strstarts
(
str
,
"ccan_"
))
return
;
/* Avoid duplicates. */
for
(
i
=
*
repl
;
i
;
i
=
i
->
next
)
if
(
streq
(
i
->
string
,
str
))
return
;
new
=
talloc
(
*
repl
,
struct
replace
);
new
->
next
=
*
repl
;
...
...
@@ -212,6 +202,17 @@ static void add_replace(struct replace **repl, const char *str)
*
repl
=
new
;
}
static
void
add_replace_tok
(
struct
replace
**
repl
,
const
char
*
s
)
{
struct
replace
*
new
;
unsigned
int
len
=
strspn
(
s
,
IDENT_CHARS
);
new
=
talloc
(
*
repl
,
struct
replace
);
new
->
next
=
*
repl
;
new
->
string
=
talloc_strndup
(
new
,
s
,
len
);
*
repl
=
new
;
}
static
char
*
basename
(
const
void
*
ctx
,
const
char
*
dir
)
{
char
*
p
=
strrchr
(
dir
,
'/'
);
...
...
@@ -221,20 +222,11 @@ static char *basename(const void *ctx, const char *dir)
return
talloc_strdup
(
ctx
,
p
+
1
);
}
/* FIXME: Only does main header, should chase local includes. */
static
void
analyze_headers
(
const
char
*
dir
,
struct
replace
**
repl
)
static
void
look_for_macros
(
char
*
contents
,
struct
replace
**
repl
)
{
char
*
hdr
,
*
contents
,
*
p
;
char
*
p
;
enum
{
LINESTART
,
HASH
,
DEFINE
,
NONE
}
state
=
LINESTART
;
/* Get hold of header, assume that's it. */
hdr
=
talloc_asprintf
(
dir
,
"%s/%s.h"
,
dir
,
basename
(
dir
,
dir
));
contents
=
grab_file
(
dir
,
hdr
);
if
(
!
contents
)
err
(
1
,
"Reading %s"
,
hdr
);
verbose
(
"Looking in %s
\n
"
,
hdr
);
verbose_indent
();
/* Look for lines of form #define X */
for
(
p
=
contents
;
*
p
;
p
++
)
{
if
(
*
p
==
'\n'
)
...
...
@@ -248,79 +240,160 @@ static void analyze_headers(const char *dir, struct replace **repl)
}
else
if
(
state
==
DEFINE
)
{
unsigned
int
len
;
len
=
strspn
(
p
,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"01234567889_"
);
len
=
strspn
(
p
,
IDENT_CHARS
);
if
(
len
)
{
char
*
s
;
s
=
talloc_strndup
(
contents
,
p
,
len
);
verbose
(
"Found %s
\n
"
,
s
);
add_replace
(
repl
,
s
);
/* Don't wrap idempotent wrappers */
if
(
!
strstarts
(
s
,
"CCAN_"
))
{
verbose
(
"Found %s
\n
"
,
s
);
add_replace
(
repl
,
s
);
}
}
state
=
NONE
;
}
else
state
=
NONE
;
}
}
verbose_unindent
();
}
static
void
add_extern_symbols
(
const
char
*
ofile
,
struct
replace
**
repl
)
/* Blank out preprocessor lines, and eliminate \ */
static
void
preprocess
(
char
*
p
)
{
/* Should actually read the elf: this is a hack. */
char
**
line
;
char
*
s
;
line
=
lines_from_cmd
(
ofile
,
"nm --defined-only --extern %s"
,
ofile
);
/* We assume backslashes are only used for macros. */
while
((
s
=
strstr
(
p
,
"
\\\n
"
))
!=
NULL
)
s
[
0
]
=
s
[
1
]
=
' '
;
/* nm output is of form [hexaddr] [char] [name]\n */
for
(;
*
line
;
line
++
)
{
unsigned
int
cols
;
char
**
names
=
split
(
ofile
,
*
line
,
"
\t
"
,
&
cols
);
if
(
cols
!=
3
)
errx
(
1
,
"Unexpected nm line '%s' (%i cols)"
,
*
line
,
cols
);
/* Now eliminate # lines. */
if
(
p
[
0
]
==
'#'
)
{
unsigned
int
i
;
for
(
i
=
0
;
p
[
i
]
!=
'\n'
;
i
++
)
p
[
i
]
=
' '
;
}
while
((
s
=
strstr
(
p
,
"
\n
#"
))
!=
NULL
)
{
unsigned
int
i
;
for
(
i
=
1
;
s
[
i
]
!=
'\n'
;
i
++
)
s
[
i
]
=
' '
;
}
}
verbose
(
"Found %s
\n
"
,
names
[
2
]);
add_replace
(
repl
,
names
[
2
]);
static
char
*
get_statement
(
const
void
*
ctx
,
char
**
p
)
{
unsigned
brackets
=
0
;
bool
seen_brackets
=
false
;
char
*
answer
=
talloc_strdup
(
ctx
,
""
);
for
(;;)
{
if
((
*
p
)[
0
]
==
'/'
&&
(
*
p
)[
1
]
==
'/'
)
*
p
+=
strcspn
(
*
p
,
"
\n
"
);
else
if
((
*
p
)[
0
]
==
'/'
&&
(
*
p
)[
1
]
==
'*'
)
*
p
=
strstr
(
*
p
,
"*/"
)
+
1
;
else
{
char
c
=
**
p
;
if
(
c
==
';'
&&
!
brackets
)
{
(
*
p
)
++
;
return
answer
;
}
/* Compress whitespace into a single ' ' */
if
(
isspace
(
c
))
{
c
=
' '
;
while
(
isspace
((
*
p
)[
1
]))
(
*
p
)
++
;
}
else
if
(
c
==
'{'
||
c
==
'('
||
c
==
'['
)
{
if
(
c
==
'('
)
seen_brackets
=
true
;
brackets
++
;
}
else
if
(
c
==
'}'
||
c
==
')'
||
c
==
']'
)
brackets
--
;
if
(
answer
[
0
]
!=
'\0'
||
c
!=
' '
)
{
answer
=
talloc_realloc
(
NULL
,
answer
,
char
,
strlen
(
answer
)
+
2
);
answer
[
strlen
(
answer
)
+
1
]
=
'\0'
;
answer
[
strlen
(
answer
)]
=
c
;
}
if
(
c
==
'}'
&&
seen_brackets
&&
brackets
==
0
)
{
(
*
p
)
++
;
return
answer
;
}
}
(
*
p
)
++
;
if
(
**
p
==
'\0'
)
return
NULL
;
}
}
static
void
get_header_symbols
(
const
char
*
dir
,
struct
replace
**
repl
)
/* This hack should handle well-formatted code. */
static
void
look_for_definitions
(
char
*
contents
,
struct
replace
**
repl
)
{
char
*
cmd
;
char
*
hfile
=
talloc_asprintf
(
dir
,
"%s/%s.h"
,
dir
,
basename
(
dir
,
dir
));
char
*
ofile
=
talloc_asprintf
(
dir
,
"%s.o"
,
hfile
);
char
*
stmt
,
*
p
=
contents
;
/* Horrible hack to get static inlines. */
cmd
=
talloc_asprintf
(
dir
,
"gcc "
CFLAGS_HDR
" -Dstatic= -include %s -o %s -c -x c /dev/null"
,
hfile
,
ofile
);
if
(
system
(
cmd
)
!=
0
)
errx
(
1
,
"Failed to compile %s"
,
hfile
);
preprocess
(
contents
);
add_extern_symbols
(
ofile
,
repl
);
}
while
((
stmt
=
get_statement
(
contents
,
&
p
))
!=
NULL
)
{
int
i
,
len
;
/* FIXME: Better to analyse headers in more depth, rather than recompile.
*/
static
void
get_exposed_symbols
(
const
char
*
dir
,
struct
replace
**
repl
)
{
char
**
files
;
unsigned
int
i
;
/* Definition of struct/union?
*/
if
((
strncmp
(
stmt
,
"struct"
,
5
)
==
0
||
strncmp
(
stmt
,
"union"
,
5
)
==
0
)
&&
strchr
(
stmt
,
'{'
)
&&
stmt
[
7
]
!=
'{'
)
add_replace_tok
(
repl
,
stmt
+
7
)
;
files
=
get_dir
(
dir
);
for
(
i
=
0
;
files
[
i
];
i
++
)
{
char
*
ofile
;
if
(
!
strends
(
files
[
i
],
".c"
)
||
strends
(
files
[
i
],
"/_info.c"
))
/* Definition of var or typedef? */
for
(
i
=
strlen
(
stmt
)
-
1
;
i
>=
0
;
i
--
)
if
(
strspn
(
stmt
+
i
,
IDENT_CHARS
)
==
0
)
break
;
if
(
i
!=
strlen
(
stmt
)
-
1
)
{
add_replace_tok
(
repl
,
stmt
+
i
+
1
);
continue
;
}
/* This produces file.c -> file.o */
ofile
=
build_obj
(
files
[
i
]);
verbose
(
"Looking in %s
\n
"
,
ofile
);
verbose_indent
();
add_extern_symbols
(
ofile
,
repl
);
unlink
(
ofile
);
verbose_unindent
();
/* function or array declaration? */
len
=
strspn
(
stmt
,
IDENT_CHARS
"* "
);
if
(
len
>
0
&&
(
stmt
[
len
]
==
'('
||
stmt
[
len
]
==
'['
))
{
if
(
strspn
(
stmt
+
len
+
1
,
IDENT_CHARS
)
!=
0
)
{
for
(
i
=
len
-
1
;
i
>=
0
;
i
--
)
if
(
strspn
(
stmt
+
i
,
IDENT_CHARS
)
==
0
)
break
;
if
(
i
!=
len
-
1
)
{
add_replace_tok
(
repl
,
stmt
+
i
+
1
);
continue
;
}
}
else
{
/* Pointer to function? */
len
++
;
len
+=
strspn
(
stmt
+
len
,
" *"
);
i
=
strspn
(
stmt
+
len
,
IDENT_CHARS
);
if
(
i
>
0
&&
stmt
[
len
+
i
]
==
')'
)
add_replace_tok
(
repl
,
stmt
+
len
);
}
}
}
get_header_symbols
(
dir
,
repl
);
}
/* FIXME: Only does main header, should chase local includes. */
static
void
analyze_headers
(
const
char
*
dir
,
struct
replace
**
repl
)
{
char
*
hdr
,
*
contents
;
/* Get hold of header, assume that's it. */
hdr
=
talloc_asprintf
(
dir
,
"%s/%s.h"
,
dir
,
basename
(
dir
,
dir
));
contents
=
grab_file
(
dir
,
hdr
);
if
(
!
contents
)
err
(
1
,
"Reading %s"
,
hdr
);
verbose
(
"Looking in %s for macros
\n
"
,
hdr
);
verbose_indent
();
look_for_macros
(
contents
,
repl
);
verbose_unindent
();
verbose
(
"Looking in %s for symbols
\n
"
,
hdr
);
verbose_indent
();
look_for_definitions
(
contents
,
repl
);
verbose_unindent
();
}
static
void
write_replacement_file
(
const
char
*
dir
,
struct
replace
**
repl
)
...
...
@@ -472,7 +545,6 @@ static void convert_dir(const char *dir)
name
[
strlen
(
name
)
-
1
]
=
'\0'
;
analyze_headers
(
name
,
&
replace
);
get_exposed_symbols
(
name
,
&
replace
);
write_replacement_file
(
name
,
&
replace
);
setup_adjust_files
(
name
,
replace
,
&
adj
);
rename_files
(
adj
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment