The fix below will enable c code to be understood by any compiler supporting the C18 or C2x specifications. I've not (yet) had the opportunity to test with c++, so they may not fully comply with any of the C++ specifications.
Thank you to people such as @Antti Haapala, @Clifford, and @anastaciu who answered my related questions here and here and enabled this more complete answer.
The short long
type
First, the 24-bit short long
type was a problem, as no equivalent exists in the c-specifications, and because the two words of the type could not be addressed with a #define
. At first, I used Perl to simply modify the string short long
into long
of all the vendor-specific header files like this:
perl -pi -e "s/(short long)/long/g" .h
Note, for the Microchip MPLAB CX8 compiler on Windows the header files are located in the following folder and sub-folders: c:\Program Files (x86)\Microchip\xc8\v1.33\include
But then I realized that the short
type is never used on its own, so I decided to simply remove the short
part using a #define short
. Do note that this will affect anything using short
so I left both methods in this answer.
The register bit and byte addresses defined with @
@-signs were a specific problem, as they could not be redefined using #define
, so perl to the rescue again, this time using two passes to address the two different syntaxes:
perl -pi -e "s/@\s*([0-9a-fA-FxX]+)/AT($1)/g" .h
perl -pi -e "s/[@] ?+([^;]*)/AT($1)/g" .h
These essentially wrap anything following a @
in AT()
, allowing a normal define to operate on it.
The extra keywords
The final touch is to insert a macro header into each of the header files provided by the compiler vendor. I ended up with the following macro header:
// Hack to allow SourceTrail to be used on this source
#if defined __XC8
#define AT(address) @ address
#else
#define AT(address)
#define __bit _Bool
#define asm(assembly)
#define interrupt
#define short
#define high_priority
#define low_priority
#endif
As can be seen, anything non-standard is simply removed, except when the header files are used by the MPLAB XC8 compiler. The only exception is the __bit
type, which is redefined as a _Bool
type - it seems to work.
The full fix as a batch script to run on windows
As I'm running all of this on windows, Perl one-liners don't really work as on Linux, so in order to process each and every header file, I had to wrap the Perl command in a batch for-loop, which is pretty slow. To make up for it, I combined everything in a single batch called fix.cmd
, which is placed in the include folder (see path above):
:: Fix to allow SourceTrail to analyze MPLAB CX8 source code.
@echo off
setlocal enabledelayedexpansion
:: Run in the folder where the script exists.
pushd "%~dp0"
echo:Fixing MPLAB global include files to be used by SourceTrail and other analysis tools.
:: Loop each directory recrusively
set DirCounter=0
set FileCounter=0
for /r %%d in (.) do (
set /A DirCounter=DirCounter+1
pushd %%d
echo | set /p=Processing:
cd
for %%f in (*.h) do (
set /A FileCounter=FileCounter+1
set /A ModValue=FileCounter%%25
if !ModValue!==0 ( echo | set /p=* )
call :ProcessFile %%f
)
popd
echo *
)
echo:Processed %FileCounter% files in %DirCounter% folders.
echo Done
exit /b 0
:ProcessFile
:: filename is in %1
:: Remove short from short long. (Done with a define instead)
:: perl -pi -e "s/(short long)/long/g" %1
:: Replace the simple @ lines with AT().
perl -pi -e "s/@\s*([0-9a-fA-FxX]+)/AT($1)/g" %1
:: Exchange @ and wrap in parenthesis for any substring starting with @ and ending with ; in each header file.
perl -pi -e "s/[@] ?+([^;]*)/AT($1)/g" %1
:: Insert defines before first line in each header files:
perl -pi -e "print \"// Hack to allow SourceTrail to be used on this source\n#if defined __XC8\n #define AT(address) @ address\n#else\n #define AT(address)\n #define __bit _Bool\n #define asm(assembly)\n #define interrupt\n #define short\n#define high_priority\n #define low_priority\n#endif\n\n\" if $. == 1" %1
::Exit subroutine
exit /b
To perform the modification, open an elevated prompt, cd to the include files, and execute the fix.cmd
prerequisites
Perl must be installed on the Windows computer. I use StrawberryPerl
Edit:
Mostly fixed typos.
Clarified that there are two options for how to deal with the short long