📄 mangleappc.pl
字号:
if (($KEIL || $IAR) && m{(\w+) = (\d+)U}){ $enums{$1} = $2; } if (($KEIL || $IAR) && m{^\s*(typedef|volatile)\s+(\w+)\s+(\w+)\[(\w+)\];}) { my $type=$1; my $target_type = $2; my $identifier = $3; my $enum = $4; if ( defined($enums{$enum}) && ($enums{$enum} == 0) ) { $_ = "$type $target_type $identifier\[\];\n"; } } # # Array definitions without length are not allowed within typedef # struct # # # Replace varname[] with * varname; # if( ($KEIL || $IAR) && $typedef_struct_lines ) { # [] and * are _NOT_ the same inside a struct definition!! # [] means an array with a length that is up to the compiler to calculate # != * which is a regular pointer! # s{(\w+)\[\];}{\* $1; // Coverted from [] to * by mangleAppC.pl} my $quit = 0; if (m/\[\].*;/) { print STDERR "Structs with non-fixed length is not allowed in Keil\n"; $quit = 1; } if (m/struct.*{/) { print STDERR "You are not allowed to declare a struct inside a struct in Keil. Move it outside and give it a name.\n"; $quit = 1; } if ($quit) { print STDERR "Structure $typedef_struct_ident in $file line $line_no\n"; exit $quit; } }## Kill size_t# s{^\s*(typedef unsigned int size_t;)}{//$1};## Remove variable number of arguments for dbg_* functions# if ( $KEIL ) { s{#define dbg\(mode, format, ...\) \(\(void\)0\)}{#define dbg(mode, format) ((void)0)}; s{#define dbg_clear\(mode, format, ...\) \(\(void\)0\)}{#define dbg_clear(mode, format) ((void)0)};}if ( $KEIL ) { # hide debug enums that are out of range # s{^(.* 1ULL << (\d+).*)}{ ($2>=15) ? "//$1" : "$1" }e; # Hide all debug enums as 1ULL and 0ULL are unavailable in Keil # Alternatively this could be solved by including a new dbg_modes.h s{^(.*=.*\dULL.*)}{//$1}; s{^(.*DBG_DEFAULT.*=.*)}{//$1}; }## Replace keyword "data"# # replace keyword data with something else # Don't match xdata and __attribute((xdata)) if ($memory_att_match == 0) { s/(?!x)(.)data/$1_data/g; } $memory_att_match=0; # One line at a time...## disable file and line number preprocessor commands (sdcc/cw doesn't support it)# s{^(# \d+|#line)}{//$1};## Remove inline keywords (could be replaced by pragma on some compilers# (eg. cw, SDCC)# # MBD: Seems gcc sometimes do a __inline - no idea if it is the same! # ML: Let's stick to one syntax! SDCC does not seem to support __inline s{\b__inline\b}{ inline }; #s{^(.*\binline\b.*)}{ (my $t=$1) =~ s/\b(inline)\b/\/*$1*\//; "$t" }e; #s{^(.*\b__inline\b.*)}{ (my $t=$1) =~ s/\b(__inline)\b/\/*$1*\//; "$t" }e; # Keil does not support inline # SDCC from version 2.7.0 should but it does not seem to work for me! if ( $KEIL || $SDCC) { s{\b((?:__)?inline)\b}{ /*$1*/ } } # map gcc noinline attribute to hcs08 noinline pragma # Noinline does not exist in Keil/sdcc #s{^(.*)(__attribute\(\(noinline\)\))(.*)}{#pragma NO_INLINE\n$1/*$2*/$3}; ######################################################################### Convert datatypes ######################################################################### # /usr/include/stdint.h also contains a uint64_t definition. Lets kill it. # (if it is changed to int32_t we'll have a double definition) s{(__extension__)}{/*$1*/}; s/^typedef long long int int64_t;.*$//; s/^typedef unsigned long long int uint64_t;.*//; ## 64 bit integers are not implemented in sdcc so we kill them!!# # We assume the 32 bit version is already declared s/^\s*typedef\s*long\s*long\s*__nesc_nw_int64_t;\s*\n//; s/^\s*typedef\s*unsigned\s*long\s*long\s*__nesc_nw_uint64_t;\s*\n//; s/^\s*typedef\s*struct\s*nw_int64_t.*nw_int64_t;\s*\n//; s/^\s*typedef\s*struct\s*nw_uint64_t.*nw_uint64_t;\s*\n//;# # Remove implementation of __nesc_nw_uint64_t# $multi_match = 1 if /^.*static.*inline.*__nesc_nw_u{0,1}int64_t/; if ( $multi_match && /\}/ ) { $multi_match = 0; next; } next if $multi_match; s/^\s*typedef\s*long\s*long\s*int64_t;\s*\n//; s/^\s*typedef\s*unsigned\s*long\s*long\s*uint64_t;\s*\n//;# # Replace all uses of uint64_t# s/\suint64_t/ uint32_t/g; s/\sint64_t/ int32_t/g; s/long\s*long/long /g;## Drop empty structures (Keil doesn't seem to like that)# ## While dropping internal nesc structures such as the attribute tags# dropping the timer tags will never work. They are used to cascade a# bunch other types that will eventually fail =[..## So the big chunk of code bellow will probably never find an empty# struct to eliminate...# # It is important that these are run last - after any other # modyfications to the lines if no we might risk missing other # things that need to go - eg. #line # # Timer precision tags generates an empty typedef struct which are # bad, mkay. All typedefs are not generated the same way - some are # only one line, some have the identifier right after the ; some # don't. # # Unfortunately we can't match the offending structs based on the # name (nesc generates those) - we have to wait for the end and see # if this was an empty structure. It seems that all the empty # structures look a bit similar. So what we are looking for is this: # # The Timer precision tags (that we are looking for) look something like this # (when they get through nesC at least): # typedef sdf { # } # name; if ($typedef_struct_lines) { $typedef_struct_lines++; $typedef_struct = $typedef_struct . $_; #if (/^.*\}.*$/) { # Found the end } of the typedef if (/}/) { # Found the end } of the typedef $typedef_struct_closed = 1; if ( $typedef_struct_lines == 2) { $typedef_struct_empty = 1; } } # Reached last line i typedef # The ; might not be on the same line as the } if ($typedef_struct_closed && /^(.*);/ ) { my $identifyer = ""; # This fails if the identifier is right after ; fortunately it isn't # for our lines =] if ($1 ne "") { $identifyer = $1; } # Remember the name of the empty struct - we need this to # kill more lines that use this name later... if ($typedef_struct_empty){ $typedef_struct_empty_ident{$identifyer} = 1; my @list = split(/\n/, $typedef_struct); $_ = ""; # Comments in comments are bad mkay foreach my $line (@list) { if ($line =~ /\/\/.*/) { $_ = $_ . $line; } else { $_ = $_ . "//" . $line . "\n"; } } } else { # The struct was not empty... $_ = $typedef_struct; } $typedef_struct_closed = 0; $typedef_struct_lines = 0; $typedef_struct_empty = 0; # we are done - don't match any more! print $_; next; } else { # Output the whole structure at once! $_ = "";# $_ = "$typedef_struct_empty $typedef_struct_closed $typedef_struct_lines" . $_; } } # Match beginning of a "typedef struct" if( /^\s*(?:typedef\s+)(?:nx_)?struct ((?:\w|_)+) {/) { # we are not looking for one line typedef struct if (/\}.*;/) { } else { $typedef_struct = $_; $typedef_struct_ident = $1; $_ = ""; $typedef_struct_lines = 1; } } # After tossing the empty timer typedef stucts we need to toss these typedefs # as well: # typedef TMilli TimerTesterP$Timer$precision_tag; if (/^typedef\s+(\w+)\s+(.)+;.*/) { my $identifyer = $1; if (defined($typedef_struct_empty_ident{$identifyer})) { $_ = "//" . $_; } } # We know these are empty... if( /^struct __nesc_attr_atmostonce {/ || /^struct __nesc_attr_atleastonce {/ || /^struct __nesc_attr_exactlyonce {/ ) { $empty_struct=1; $_ = "/*" . $_; } if ( $empty_struct && /\}\;/) { $empty_struct = 0; chomp($_); $_ = $_ . "*/\n"; } print;} close(FILE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -