mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-23 00:18:23 +08:00
173 lines
7.2 KiB
Plaintext
173 lines
7.2 KiB
Plaintext
Better String library Porting Guide
|
|
-----------------------------------
|
|
|
|
by Paul Hsieh
|
|
|
|
The bstring library is an attempt to provide improved string processing
|
|
functionality to the C and C++ language. At the heart of the bstring library
|
|
is the management of "bstring"s which are a significant improvement over '\0'
|
|
terminated char buffers. See the accompanying documenation file bstrlib.txt
|
|
for more information.
|
|
|
|
===============================================================================
|
|
|
|
Identifying the Compiler
|
|
------------------------
|
|
|
|
Bstrlib has been tested on the following compilers:
|
|
|
|
Microsoft Visual C++
|
|
Watcom C/C++ (32 bit flat)
|
|
Intel's C/C++ compiler (on Windows)
|
|
The GNU C/C++ compiler (on Windows/Linux on x86 and PPC64)
|
|
Borland C++
|
|
Turbo C
|
|
|
|
There are slight differences in these compilers which requires slight
|
|
differences in the implementation of Bstrlib. These are accomodated in the
|
|
same sources using #ifdef/#if defined() on compiler specific macros. To
|
|
port Bstrlib to a new compiler not listed above, it is recommended that the
|
|
same strategy be followed. If you are unaware of the compiler specific
|
|
identifying preprocessor macro for your compiler you might find it here:
|
|
|
|
http://predef.sourceforge.net/precomp.html
|
|
|
|
Note that Intel C/C++ on Windows sets the Microsoft identifier: _MSC_VER.
|
|
|
|
16-bit vs. 32-bit vs. 64-bit Systems
|
|
------------------------------------
|
|
|
|
Bstrlib has been architected to deal with strings of length between 0 and
|
|
INT_MAX (inclusive). Since the values of int are never higher than size_t
|
|
there will be no issue here. Note that on most 64-bit systems int is 32-bit.
|
|
|
|
Dependency on The C-Library
|
|
---------------------------
|
|
|
|
Bstrlib uses the functions memcpy, memmove, malloc, realloc, free and
|
|
vsnprintf. Many free standing C compiler implementations that have a mode in
|
|
which the C library is not available will typically not include these
|
|
functions which will make porting Bstrlib to it onerous. Bstrlib is not
|
|
designed for such bare bones compiler environments. This usually includes
|
|
compilers that target ROM environments.
|
|
|
|
Porting Issues
|
|
--------------
|
|
|
|
Bstrlib has been written completely in ANSI/ISO C and ISO C++, however, there
|
|
are still a few porting issues. These are described below.
|
|
|
|
1. The vsnprintf () function.
|
|
|
|
Unfortunately, the earlier ANSI/ISO C standards did not include this function.
|
|
If the compiler of interest does not support this function then the
|
|
BSTRLIB_NOVSNP should be defined via something like:
|
|
|
|
#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
|
|
# if defined (__TURBOC__) || defined (__COMPILERVENDORSPECIFICMACRO__)
|
|
# define BSTRLIB_NOVSNP
|
|
# endif
|
|
#endif
|
|
|
|
which appears at the top of bstrlib.h. Note that the bformat(a) functions
|
|
will not be declared or implemented if the BSTRLIB_NOVSNP macro is set. If
|
|
the compiler has renamed vsnprintf() to some other named function, then
|
|
search for the definition of the exvsnprintf macro in bstrlib.c file and be
|
|
sure its defined appropriately:
|
|
|
|
#if defined (__COMPILERVENDORSPECIFICMACRO__)
|
|
# define exvsnprintf(r,b,n,f,a) {r=__compiler_specific_vsnprintf(b,n,f,a);}
|
|
#else
|
|
# define exvsnprintf(r,b,n,f,a) {r=vsnprintf(b,n,f,a);}
|
|
#endif
|
|
|
|
Take notice of the return value being captured in the variable r. It is
|
|
assumed that r exceeds n if and only if the underlying vsnprintf function has
|
|
determined what the true maximal output length would be for output if the
|
|
buffer were large enough to hold it. Non-modern implementations must output a
|
|
lesser number (the macro can and should be modified to ensure this).
|
|
|
|
2. Weak C++ compiler.
|
|
|
|
C++ is a much more complicated language to implement than C. This has lead
|
|
to varying quality of compiler implementations. The weaknesses isolated in
|
|
the initial ports are inclusion of the Standard Template Library,
|
|
std::iostream and exception handling. By default it is assumed that the C++
|
|
compiler supports all of these things correctly. If your compiler does not
|
|
support one or more of these define the corresponding macro:
|
|
|
|
BSTRLIB_CANNOT_USE_STL
|
|
BSTRLIB_CANNOT_USE_IOSTREAM
|
|
BSTRLIB_DOESNT_THROW_EXCEPTIONS
|
|
|
|
The compiler specific detected macro should be defined at the top of
|
|
bstrwrap.h in the Configuration defines section. Note that these disabling
|
|
macros can be overrided with the associated enabling macro if a subsequent
|
|
version of the compiler gains support. (For example, its possible to rig
|
|
up STLport to provide STL support for WATCOM C/C++, so -DBSTRLIB_CAN_USE_STL
|
|
can be passed in as a compiler option.)
|
|
|
|
3. The bsafe module, and reserved words.
|
|
|
|
The bsafe module is in gross violation of the ANSI/ISO C standard in the
|
|
sense that it redefines what could be implemented as reserved words on a
|
|
given compiler. The typical problem is that a compiler may inline some of the
|
|
functions and thus not be properly overridden by the definitions in the bsafe
|
|
module. It is also possible that a compiler may prohibit the redefinitions in
|
|
the bsafe module. Compiler specific action will be required to deal with
|
|
these situations.
|
|
|
|
Platform Specific Files
|
|
-----------------------
|
|
|
|
The makefiles for the examples are basically setup of for particular
|
|
environments for each platform. In general these makefiles are not portable
|
|
and should be constructed as necessary from scratch for each platform.
|
|
|
|
Testing a port
|
|
--------------
|
|
|
|
To test that a port compiles correctly do the following:
|
|
|
|
1. Build a sample project that includes the bstrlib, bstraux, bstrwrap, and
|
|
bsafe modules.
|
|
2. Compile bstest against the bstrlib module.
|
|
3. Run bstest and ensure that 0 errors are reported.
|
|
4. Compile test against the bstrlib and bstrwrap modules.
|
|
5. Run test and ensure that 0 errors are reported.
|
|
6. Compile each of the examples (except for the "re" example, which may be
|
|
complicated and is not a real test of bstrlib and except for the mfcbench
|
|
example which is Windows specific.)
|
|
7. Run each of the examples.
|
|
|
|
The builds must have 0 errors, and should have the absolute minimum number of
|
|
warnings (in most cases can be reduced to 0.) The result of execution should
|
|
be essentially identical on each platform.
|
|
|
|
Performance
|
|
-----------
|
|
|
|
Different CPU and compilers have different capabilities in terms of
|
|
performance. It is possible for Bstrlib to assume performance
|
|
characteristics that a platform doesn't have (since it was primarily
|
|
developed on just one platform). The goal of Bstrlib is to provide very good
|
|
performance on all platforms regardless of this but without resorting to
|
|
extreme measures (such as using assembly language, or non-portable intrinsics
|
|
or library extensions.)
|
|
|
|
There are two performance benchmarks that can be found in the example/
|
|
directory. They are: cbench.c and cppbench.cpp. These are variations and
|
|
expansions of a benchmark for another string library. They don't cover all
|
|
string functionality, but do include the most basic functions which will be
|
|
common in most string manipulation kernels.
|
|
|
|
...............................................................................
|
|
|
|
Feedback
|
|
--------
|
|
|
|
In all cases, you may email issues found to the primary author of Bstrlib at
|
|
the email address: websnarf@users.sourceforge.net
|
|
|
|
===============================================================================
|