bash 的解决方案。它通过命令使用来自目标文件的信息nm
。见man nm
。
要从源文件创建目标文件,您需要为每个源文件运行gcc
选项-c
(可能您已经拥有它们,由make
命令创建。然后,您可以跳过此步骤):
gcc -c one.c -o one.o
gcc -c two.c -o two.o
用法: ./convert.sh one.o two.o
#!/bin/bash
# store original function names to the variable.
orig_func_names=$(
# get list symbols from all object files
nm -f sysv "$@" |
# picks the functions and removes all information except names.
sed -n '/FUNC/s/\s.*//p' |
# selects only functions, which contain the uppercase letter in the name.
sed -n '/[A-Z]/p'
);
# convert camel case names to snake case names and store new names to the variable.
new_func_names=$(sed 's/[A-Z]/_\l&/g' <<< "$orig_func_names")
# create file, containing substitute commands for 'sed'.
# Example of commands from this file:
# s/\boneTwo\b/one_two/g
# s/\boneTwoThree\b/one_two_three/g
# etc. One line to the each function name.
paste -d'/' <(printf 's/\\b%s\\b\n' ${orig_func_names}) <(printf '%s/g\n' ${new_func_names}) > command_file.txt
# do converting
# change object file extenstions '.o' to C source - '.c' file extensions.
# were this filenames: one.o two.o three.o
# now they are: one.c two.c three.c
# this 'sed' command creates backup for the each file and change the source files.
sed -i_backup -f command_file.txt "${@/.o/.c}"
应该注意,在此解决方案中,执行时间呈指数增长。例如,如果我们有 70000 行和 1000 个函数,那么它需要进行 7000 万次检查(70000 行 * 1000 个函数)。知道需要多少时间会很有趣。
测试
输入
文件one.c
#include <stdio.h>
int one();
int oneTwo();
int oneTwoThree();
int oneTwoThreeFour();
int one() {
puts("");
return 0;
}
int oneTwo() {
printf("%s", "hello");
one();
return 0;
}
int oneTwoThree() {
oneTwo();
return 0;
}
int oneTwoThreeFour() {
oneTwoThree();
return 0;
}
int main() {
return 0;
}
文件two.c
#include <stdio.h>
int two() {
return 0;
}
int twoThree() {
two();
return 0;
}
int twoThreeFour() {
twoThree();
return 0;
}
输出
文件one.c
#include <stdio.h>
int one();
int one_two();
int one_two_three();
int one_two_three_four();
int one() {
puts("");
return 0;
}
int one_two() {
printf("%s", "hello");
one();
return 0;
}
int one_two_three() {
one_two();
return 0;
}
int one_two_three_four() {
one_two_three();
return 0;
}
int main() {
return 0;
}
文件two.c
#include <stdio.h>
int two() {
return 0;
}
int two_three() {
two();
return 0;
}
int two_three_four() {
two_three();
return 0;
}