├── gcc ├── config.h ├── .gitignore └── Makefile ├── msvc ├── .gitignore └── xformat │ ├── xformat.sln │ └── xformattest │ └── xformattest.vcproj ├── eclipse ├── .gitignore ├── speed │ ├── config.h │ ├── .project │ └── .cproject ├── test │ ├── config.h │ ├── .project │ └── .cproject └── table │ ├── config.h │ ├── .project │ └── .cproject ├── .gitignore ├── README.md ├── src ├── xformatc.h ├── xformattable.c ├── xformatspeed.c ├── xformattest.c └── xformatc.c └── LICENSE /gcc/config.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /msvc/.gitignore: -------------------------------------------------------------------------------- 1 | x64 2 | win32 3 | *.suo 4 | *.ncb 5 | *.user 6 | -------------------------------------------------------------------------------- /eclipse/.gitignore: -------------------------------------------------------------------------------- 1 | Release/ 2 | Debug/ 3 | .metadata 4 | .settings 5 | 6 | -------------------------------------------------------------------------------- /eclipse/speed/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | #endif /* CONFIG_H */ 4 | -------------------------------------------------------------------------------- /eclipse/test/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | #endif /* CONFIG_H */ 4 | -------------------------------------------------------------------------------- /eclipse/table/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | 5 | 6 | #endif /* CONFIG_H */ 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | epsilon.ses 2 | x 3 | x.bat 4 | sdcc/ 5 | arm.bat 6 | *.lst 7 | *.o 8 | RemoteSystemsTempFiles/ 9 | -------------------------------------------------------------------------------- /gcc/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | xformattest 3 | xformattest.exe 4 | xformattable 5 | xformattable.exe 6 | xformatspeed 7 | xformatspeed.exe 8 | 9 | -------------------------------------------------------------------------------- /gcc/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | UFLAGS= 3 | CFLAGS=${UFLAGS} -DHAVE_CONFIG_H -I. -O3 -pedantic -Wall -Wextra -Wno-long-long 4 | 5 | 6 | all: xformattest xformattable xformatspeed 7 | 8 | 9 | xformattest: ../src/xformatc.c ../src/xformattest.c ../src/xformatc.h Makefile 10 | $(CC) $(CFLAGS) ../src/xformattest.c ../src/xformatc.c -o xformattest 11 | 12 | xformattable: ../src/xformatc.c ../src/xformattable.c Makefile 13 | $(CC) $(CFLAGS) ../src/xformattable.c -o xformattable 14 | 15 | xformatspeed: ../src/xformatc.c ../src/xformatspeed.c Makefile 16 | $(CC) $(CFLAGS) ../src/xformatspeed.c ../src/xformatc.c -o xformatspeed 17 | 18 | 19 | 20 | clean: 21 | rm -fr *.o *.exe xformattest xformattable xformatspeed 22 | -------------------------------------------------------------------------------- /msvc/xformat/xformat.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xformattest", "xformattest\xformattest.vcproj", "{C6AA20A0-86FB-428E-B30D-AC805DF2FBC7}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Release|Win32 = Release|Win32 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {C6AA20A0-86FB-428E-B30D-AC805DF2FBC7}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {C6AA20A0-86FB-428E-B30D-AC805DF2FBC7}.Debug|Win32.Build.0 = Debug|Win32 16 | {C6AA20A0-86FB-428E-B30D-AC805DF2FBC7}.Debug|x64.ActiveCfg = Debug|x64 17 | {C6AA20A0-86FB-428E-B30D-AC805DF2FBC7}.Debug|x64.Build.0 = Debug|x64 18 | {C6AA20A0-86FB-428E-B30D-AC805DF2FBC7}.Release|Win32.ActiveCfg = Release|Win32 19 | {C6AA20A0-86FB-428E-B30D-AC805DF2FBC7}.Release|Win32.Build.0 = Release|Win32 20 | {C6AA20A0-86FB-428E-B30D-AC805DF2FBC7}.Release|x64.ActiveCfg = Release|x64 21 | {C6AA20A0-86FB-428E-B30D-AC805DF2FBC7}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | xprintfc 2 | ======== 3 | 4 | Most completed and little printf like subsystem for embedded system. 5 | 6 | Example of code size now 2 architecture with all features enabled, compiled with -O3 : 7 | 8 | Embedded 32 bit ARM : 2268 bytes 9 | Linux X64 : 3690 bytes 10 | 11 | - Tested on microprocessor from 8 to 64 bit 12 | - Optional support for floating point number 13 | - Optional support for long long number 14 | - Support for binary number (%b) 15 | - Support for boolean value (%B) 16 | - Support for pointer in hex format (%p/%P) 17 | - Support for size_t C99 argument size 18 | - No library function required 19 | - Parametric function to emit single char 20 | - Configurable using config.h and -DHAVE_CONFIG_H 21 | - 10% fastest than libc functions. 22 | - And much more 23 | 24 | 25 | Configurable options 26 | ======================================================================== 27 | 28 | The option can be set directly on the compiler command line 29 | for example : 30 | gcc -DXCFG_FORMAT_LONGLONG=0 -c xformatc.c 31 | compile the function without floating point support or inserted 32 | in the file config.h and define the symbol HAVE_CONFIG_H on 33 | compilation time. 34 | 35 | 36 | XCFG_FORMAT_LONGLONG Set to 0 to exclude support for long long. 37 | 38 | XCFG_FORMAT_STATIC Set to static to reduce stack usage only 39 | for mono thread application. 40 | 41 | XCFG_FORMAT_FLOAT Set to 0 to exclude support for floating point. 42 | 43 | 44 | XCFG_FORMAT_FLOAT_PREC Set to 1 to make calculation using float instead of double. 45 | -------------------------------------------------------------------------------- /eclipse/test/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | test 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/test/Debug} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | full,incremental, 73 | 74 | 75 | 76 | 77 | 78 | org.eclipse.cdt.core.cnature 79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 80 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 81 | 82 | 83 | 84 | src 85 | 2 86 | PARENT-1-WORKSPACE_LOC/src 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /eclipse/speed/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | speed 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/test/Debug} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | full,incremental, 73 | 74 | 75 | 76 | 77 | 78 | org.eclipse.cdt.core.cnature 79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 80 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 81 | 82 | 83 | 84 | src 85 | 2 86 | PARENT-1-WORKSPACE_LOC/src 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /eclipse/table/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | table 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/table/Debug} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | full,incremental, 73 | 74 | 75 | 76 | 77 | 78 | org.eclipse.cdt.core.cnature 79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 80 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 81 | 82 | 83 | 84 | src 85 | 2 86 | PARENT-1-WORKSPACE_LOC/src 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /src/xformatc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file xformatc.h 3 | * 4 | * @brief Printf C declaration. 5 | * 6 | * @author Mario Viara 7 | * 8 | * @copyright Copyright Mario Viara 2014 - License Open Source (LGPL) 9 | * This is a free software and is opened for education, research and commercial 10 | * developments under license policy of following terms: 11 | * - This is a free software and there is NO WARRANTY. 12 | * - No restriction on use. You can use, modify and redistribute it for personal, 13 | * non-profit or commercial product UNDER YOUR RESPONSIBILITY. 14 | * - Redistributions of source code must retain the above copyright notice. 15 | * 16 | * To contact the author send an email to mario_at_viara.eu* 17 | */ 18 | #ifndef XFORMATC_H 19 | #define XFORMATC_H 20 | #include 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /** 26 | * MSVC use in x64 model IL32P64 architecture so the largest integer 27 | * is not a standard C integer. 28 | */ 29 | #if defined(_MSC_VER) && defined(_M_AMD64) 30 | #define LONG long long 31 | #define XCFG_FORMAT_LONG_ARE_LONGLONG 32 | #endif 33 | 34 | 35 | /** 36 | * SDCC support only float and for now do not support long long 37 | */ 38 | #ifdef __SDCC 39 | #define DOUBLE float 40 | #ifndef XCFG_FORMAT_LONGLONG 41 | #define XCFG_FORMAT_LONGLONG 0 42 | #endif 43 | #endif 44 | 45 | 46 | /** 47 | * Define internal parameters as volatile for 8 bit cpu define 48 | * XCFG_FORMAT_STATIC=static to reduce stack usage. 49 | */ 50 | #ifndef XCFG_FORMAT_STATIC 51 | #define XCFG_FORMAT_STATIC 52 | #endif 53 | 54 | 55 | /** 56 | * Define XCFG_FORMAT_FLOAT=0 to remove floating point support 57 | */ 58 | #ifndef XCFG_FORMAT_FLOAT 59 | #define XCFG_FORMAT_FLOAT 1 60 | #endif 61 | 62 | 63 | /** 64 | * Detect support for va_copy this macro must be called for example 65 | * in x86_64 machine to adjust the stack frame when an argument of va_list 66 | * is passed over functions. 67 | */ 68 | #ifndef XCFG_FORMAT_VA_COPY 69 | #if defined(__GNUC__) && defined(__x86_64__) 70 | #define XCFG_FORMAT_VA_COPY 1 71 | #endif 72 | 73 | 74 | #ifndef XCFG_FORMAT_VA_COPY 75 | #define XCFG_FORMAT_VA_COPY 0 76 | #endif 77 | 78 | #endif 79 | 80 | 81 | #ifndef XCFG_FORMAT_LONG 82 | #define XCFG_FORMAT_LONG 1 83 | #endif 84 | 85 | /** 86 | * Define to 0 to remove support for long long type (prefix ll) 87 | */ 88 | #ifndef XCFG_FORMAT_LONGLONG 89 | #define XCFG_FORMAT_LONGLONG XCFG_FORMAT_LONG 90 | #endif 91 | 92 | 93 | /** 94 | * Define to 1 to use internally float number instead of double. 95 | */ 96 | #ifndef XCFG_FORMAT_FLOAT_PREC 97 | #define XCFG_FORMAT_FLOAT_PREC 0 98 | #endif 99 | 100 | 101 | /** 102 | * Define to 1 to support floating point special value as nan and infinite the 103 | * default behavior is undefined if an invalid floating point number is used. 104 | * 105 | */ 106 | #ifndef XCFG_FORMAT_FLOAT_SPECIAL 107 | #define XCFG_FORMAT_FLOAT_SPECIAL 0 108 | #endif 109 | 110 | 111 | #if XCFG_FORMAT_FLOAT_SPECIAL 112 | #include 113 | #endif 114 | 115 | 116 | unsigned xformat(void (*outchar)(void *arg,char),void *arg,const char * fmt,...); 117 | 118 | unsigned xvformat(void (*outchar)(void *arg,char),void *arg,const char * fmt,va_list args); 119 | 120 | 121 | 122 | #ifdef __cplusplus 123 | } 124 | #endif 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /src/xformattable.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file xformattable.c 3 | * 4 | * @brief Table generator for xformatc.c 5 | * 6 | * 7 | * @author Mario Viara 8 | * 9 | * @version 1.00 10 | * 11 | * @copyright Copyright Mario Viara 2014 - License Open Source (LGPL) 12 | * This is a free software and is opened for education, research and commercial 13 | * developments under license policy of following terms: 14 | * - This is a free software and there is NO WARRANTY. 15 | * - No restriction on use. You can use, modify and redistribute it for personal, 16 | * non-profit or commercial product UNDER YOUR RESPONSIBILITY. 17 | * - Redistributions of source code must retain the above copyright notice. 18 | * 19 | */ 20 | #include 21 | 22 | #include "xformatc.c" 23 | 24 | static const unsigned states[] = 25 | { 26 | /* CHAR NORMAL PERCENT FLAG WIDTH DOT PRECIS SIZE TYPE*/ 27 | /* OTHER */ 0, 0, 0, 0, 0, 0, 0, 0, 28 | /* PERCENT */ 1, 0, 0, 0, 0, 0, 0, 1, 29 | /* DOT */ 0, 4, 4, 4, 4, 0, 0, 0, 30 | /* STAR */ 0, 3, 3, 0, 5, 6, 0, 0, 31 | /* ZERO */ 0, 2, 2, 3, 5, 5, 0, 0, 32 | /* DIGIT */ 0, 3, 3, 3, 5, 5, 0, 0, 33 | /* FLAG */ 0, 2, 2, 2, 2, 2, 2, 0, 34 | /* SIZE */ 0, 6, 6, 6, 6, 6, 6, 0, 35 | /* TYPE */ 0, 7, 7, 7, 7, 7, 7, 0, 36 | }; 37 | 38 | static unsigned table['z' - ' ' + 1]; 39 | #define N (int)((sizeof(table)/sizeof(unsigned))) 40 | 41 | 42 | void make(void) 43 | { 44 | int c,i; 45 | int cl; 46 | 47 | for (i = 0; i < N ; i++) 48 | { 49 | c = ' ' + i; 50 | switch (c) 51 | { 52 | case '.': 53 | cl = CH_DOT; 54 | break; 55 | 56 | case 'l': 57 | case 'h': 58 | case 'z': 59 | cl = CH_SIZE; 60 | break; 61 | case ' ': 62 | case '-': 63 | case '#': 64 | case '+': 65 | cl = CH_FLAG; 66 | break; 67 | 68 | case '0': 69 | cl = CH_ZERO; 70 | break; 71 | case '1': 72 | case '2': 73 | case '3': 74 | case '4': 75 | case '5': 76 | case '6': 77 | case '7': 78 | case '8': 79 | case '9': 80 | cl = CH_DIGIT; 81 | break; 82 | case '%': 83 | cl = CH_PERCENT; 84 | break; 85 | case '*': 86 | cl = CH_STAR; 87 | break; 88 | 89 | case 'd': 90 | case 'i': 91 | case 'S': 92 | case 's': 93 | case 'b': 94 | case 'x': 95 | case 'X': 96 | case 'o': 97 | case 'u': 98 | case 'c': 99 | case 'C': 100 | case 'p': 101 | case 'P': 102 | case 'f': 103 | case 'B': 104 | cl = CH_TYPE; 105 | break; 106 | 107 | default: 108 | cl = CH_OTHER; 109 | break; 110 | } 111 | 112 | table[i] = cl; 113 | 114 | if (i < (int)(sizeof(states)/sizeof(unsigned))) 115 | table[i] = table[i] | (states[i] << 4); 116 | } 117 | 118 | printf("static const unsigned char formatStates[] =\n{\n"); 119 | 120 | for (i = 0; i < N ; i++) 121 | { 122 | if (i % 8 == 0) 123 | printf("\t"); 124 | printf("0x%02X",table[i] & 0xff); 125 | if (i + 1 < N) 126 | printf(","); 127 | if ((i+1) % 8 == 0) 128 | printf("\n"); 129 | } 130 | printf("\n};\n\n"); 131 | } 132 | 133 | 134 | int main(int argc,char **argv) 135 | { 136 | (void)argc; 137 | (void)argv; 138 | 139 | make(); 140 | 141 | return 0; 142 | } 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /src/xformatspeed.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file xformattest.c 3 | * 4 | * @brief Test speed for xformatc.c 5 | * 6 | * 7 | * @author Mario Viara 8 | * 9 | * @version 1.00 10 | * 11 | * @copyright Copyright Mario Viara 2018 - License Open Source (LGPL) 12 | * This is a free software and is opened for education, research and commercial 13 | * developments under license policy of following terms: 14 | * - This is a free software and there is NO WARRANTY. 15 | * - No restriction on use. You can use, modify and redistribute it for personal, 16 | * non-profit or commercial product UNDER YOUR RESPONSIBILITY. 17 | * - Redistributions of source code must retain the above copyright notice. 18 | * 19 | */ 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "xformatc.h" 32 | 33 | 34 | static void myPutchar(void *arg,char c) 35 | { 36 | char ** s = (char **)arg; 37 | *(*s)++ = c; 38 | } 39 | 40 | static int myVsprintf(char *buf,const char *fmt,va_list args) 41 | { 42 | int result = xvformat(myPutchar,(void *)&buf,fmt,args); 43 | *buf = 0; 44 | return result; 45 | } 46 | 47 | 48 | static void testFormat(int (*format)(char *buffer,const char *format,va_list arg),const char * fmt,...) 49 | { 50 | char buffer[1024]; 51 | 52 | 53 | va_list list; 54 | #if XCFG_FORMAT_VA_COPY 55 | va_list args; 56 | 57 | va_start(args,fmt); 58 | va_copy(list,args); 59 | (*format)(buffer,fmt,list); 60 | va_end(list); 61 | va_end(args); 62 | #else 63 | va_start(list,fmt); 64 | (*format)(buffer,fmt,list); 65 | va_end(list); 66 | #endif 67 | 68 | 69 | 70 | } 71 | 72 | static void testspeed(const char * name,long count,int (*format)(char *buffer,const char * fmt,va_list args)) 73 | { 74 | long i; 75 | struct timeval start,now; 76 | double elapsed; 77 | 78 | printf("Starting test for %s ... ",name); 79 | fflush(stdout); 80 | gettimeofday(&start,0); 81 | 82 | for (i = 0 ; i < count ; i++) 83 | { 84 | testFormat(format,"Hello world {%u}",sizeof(unsigned long)); 85 | testFormat(format,"Hello %s","World"); 86 | testFormat(format,"String %4.4s","Large"); 87 | testFormat(format,"String %*.*s",4,4,"Hello"); 88 | testFormat(format,"integer %05d %+d %d %2d %5d",-7,7,-7,1234,1234); 89 | testFormat(format,"Integer %+05d %-5d % 5d %05d",1234,1234,1234,1234); 90 | testFormat(format,"Integer blank % d % d",1,-1); 91 | testFormat(format,"Unsigned %u %lu",123,123Lu); 92 | testFormat(format,"Hex with prefix %#x %#x %#X %#08x",0,1,2,12345678); 93 | testFormat(format,"Octal %o %lo",123,123456L); 94 | testFormat(format,"Octal with prefix %#o %#o",0,5); 95 | testFormat(format,"Hex %x %X %lX",0x1234,0xf0ad,0xf2345678L); 96 | testFormat(format,"Special char %%"); 97 | testFormat(format,"Size of void * %u(%u)",(size_t)sizeof(void *),(size_t)sizeof(void *)); 98 | testFormat(format,"Sizeof char=%d short=%d int=%d long=%d void*=%u size_t=%u", 99 | sizeof(char),sizeof(short),sizeof(int),sizeof(long),sizeof(void *),sizeof(size_t)); 100 | 101 | #if XCFG_FORMAT_FLOAT 102 | testFormat(format,"Floating %f",-0.6); 103 | testFormat(format,"Floating %6.2f",22.0/7.0); 104 | testFormat(format,"Floating %6.2f",-22.0/7.0); 105 | testFormat(format,"Floating %+6.1f %6.2f",3.999,-3.999); 106 | testFormat(format,"Floating %6.1f %6.0f",3.999,-3.999); 107 | testFormat(format,"Floating %5.0f",3.14); 108 | testFormat(format,"Floating %.0f",0.491); 109 | testFormat(format,"Floating %.0f",0.490); 110 | testFormat(format,"Floating %.0f",0.489); 111 | testFormat(format,"Floating %.0f",-0.491); 112 | testFormat(format,"Floating %.0f",-0.490); 113 | testFormat(format,"Floating %.0f",-0.489); 114 | #endif 115 | 116 | 117 | #if XCFG_FORMAT_LONG 118 | testFormat(format,"long %d %o %x",123456L,123456L,123456L); 119 | #endif 120 | 121 | #if XCFG_FORMAT_LONGLONG 122 | testFormat(format,"long long int %lld",(long long)123); 123 | testFormat(format,"long long int %lld",(long long)-123); 124 | testFormat(format,"long long hex %#llx",(long long)0x123456789abcdef); 125 | testFormat(format,"long long hex %#llX",(long long)0x123456789abcdef); 126 | testFormat(format,"Floating > 32 bit %f",pow(2.0,32.0)+1.0); 127 | testFormat(format,"Floating < 32 bit %f",-pow(2.0,32.0)-1.0); 128 | #endif 129 | } 130 | 131 | gettimeofday(&now,0); 132 | elapsed = ((double)now.tv_sec * 1000000.0 + now.tv_usec) - ((double)start.tv_sec * 1000000.0 + start.tv_usec); 133 | elapsed /= 1000000.0; 134 | 135 | printf(" Elapsed %.3f second(s)\n",elapsed); 136 | fflush(stdout); 137 | } 138 | 139 | int main(int argc,char **argv) 140 | { 141 | long count = 0; 142 | 143 | if (argc < 2) 144 | { 145 | printf("usage: xfprmatcspeed cycle\n"); 146 | exit(1); 147 | } 148 | else 149 | { 150 | 151 | count = atol(argv[1]); 152 | 153 | printf("Test speed for xprintfc using %lu cycle\n",count); 154 | testspeed("System ",count,vsprintf); 155 | testspeed("xformatc ",count,myVsprintf); 156 | } 157 | 158 | return 0; 159 | } 160 | 161 | 162 | -------------------------------------------------------------------------------- /src/xformattest.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file xformattest.c 3 | * 4 | * @brief Test pattern for xformatc.c 5 | * 6 | * 7 | * @author Mario Viara 8 | * 9 | * @version 1.00 10 | * 11 | * @copyright Copyright Mario Viara 2014 - License Open Source (LGPL) 12 | * This is a free software and is opened for education, research and commercial 13 | * developments under license policy of following terms: 14 | * - This is a free software and there is NO WARRANTY. 15 | * - No restriction on use. You can use, modify and redistribute it for personal, 16 | * non-profit or commercial product UNDER YOUR RESPONSIBILITY. 17 | * - Redistributions of source code must retain the above copyright notice. 18 | * 19 | */ 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "xformatc.h" 30 | 31 | 32 | static void myPutchar(void *arg,char c) 33 | { 34 | char ** s = (char **)arg; 35 | *(*s)++ = c; 36 | } 37 | 38 | static void myPrintf(char *buf,const char *fmt,va_list args) 39 | { 40 | xvformat(myPutchar,(void *)&buf,fmt,args); 41 | *buf = 0; 42 | } 43 | 44 | 45 | static void testFormat(const char * fmt,...) 46 | { 47 | char buf1[1024]; 48 | char buf2[1024]; 49 | 50 | va_list list; 51 | #if XCFG_FORMAT_VA_COPY 52 | va_list args; 53 | 54 | va_start(args,fmt); 55 | #else 56 | va_start(list,fmt); 57 | #endif 58 | 59 | #if XCFG_FORMAT_VA_COPY 60 | va_copy(list,args); 61 | #endif 62 | 63 | myPrintf(buf1,fmt,list); 64 | 65 | #if XCFG_FORMAT_VA_COPY 66 | va_end(list); 67 | #endif 68 | 69 | #if XCFG_FORMAT_VA_COPY 70 | va_copy(list,args); 71 | #endif 72 | 73 | vsprintf(buf2,fmt,list); 74 | 75 | #if XCFG_FORMAT_VA_COPY 76 | va_end(list); 77 | #endif 78 | 79 | 80 | if (*fmt != '*' && strcmp(buf1,buf2)) 81 | { 82 | fprintf(stderr,"XFormat : '%s'\nvsprintf: '%s'\nFormat : '%s' failed\n", 83 | buf1,buf2,fmt); 84 | exit(1); 85 | } 86 | else 87 | { 88 | printf("'%s'\n'%s'\n",buf1,buf2); 89 | 90 | } 91 | 92 | #if XCFG_FORMAT_VA_COPY 93 | va_end(args); 94 | (void)args; 95 | #else 96 | va_end(list); 97 | #endif 98 | 99 | } 100 | 101 | int main(void) 102 | { 103 | static int value; 104 | static void * ptr = &value; 105 | int stackValue; 106 | void * stackPtr = &stackValue; 107 | 108 | 109 | fprintf(stderr,"XFORMATC test\n\n"); 110 | testFormat("Hello world {%u}",sizeof(unsigned long)); 111 | testFormat("Hello %s","World"); 112 | testFormat("String %4.4s","Large"); 113 | testFormat("String %*.*s",4,4,"Hello"); 114 | testFormat("integer %05d %+d %d %2d %5d",-7,7,-7,1234,1234); 115 | testFormat("Integer %+05d %-5d % 5d %05d",1234,1234,1234,1234); 116 | testFormat("Integer blank % d % d",1,-1); 117 | testFormat("Unsigned %u %lu",123,123Lu); 118 | testFormat("Hex with prefix %#x %#x %#X %#08x",0,1,2,12345678); 119 | testFormat("Octal %o %lo",123,123456L); 120 | testFormat("Octal with prefix %#o %#o",0,5); 121 | testFormat("Hex %x %X %lX",0x1234,0xf0ad,0xf2345678L); 122 | testFormat("Special char %%"); 123 | testFormat("Size of void * %u(%u)",(size_t)sizeof(void *),(size_t)sizeof(void *)); 124 | testFormat("Sizeof char=%d short=%d int=%d long=%d void*=%u size_t=%u", 125 | sizeof(char),sizeof(short),sizeof(int),sizeof(long),sizeof(void *),sizeof(size_t)); 126 | 127 | #if XCFG_FORMAT_FLOAT 128 | testFormat("Floating %f",-0.6); 129 | testFormat("Floating %6.2f",22.0/7.0); 130 | testFormat("Floating %6.2f",-22.0/7.0); 131 | testFormat("Floating %+6.1f %6.2f",3.999,-3.999); 132 | testFormat("Floating %6.1f %6.0f",3.999,-3.999); 133 | testFormat("Floating %5.0f",3.14); 134 | testFormat("Floating %.0f",0.491); 135 | testFormat("Floating %.0f",0.490); 136 | testFormat("Floating %.0f",0.489); 137 | testFormat("Floating %.0f",-0.491); 138 | testFormat("Floating %.0f",-0.490); 139 | testFormat("Floating %.0f",-0.489); 140 | testFormat("Floating > 20 bit %f",pow(2.0,20.0)+1.0); 141 | testFormat("Floating < 20 bit %f",-pow(2.0,20.0)-1.0); 142 | #if XCFG_FORMAT_LONGLONG && XCFG_FORMAT_FLOAT_PREC == 0 143 | testFormat("Floating > 32 bit %f",pow(2.0,32.0)+1.0); 144 | testFormat("Floating < 32 bit %f",-pow(2.0,32.0)-1.0); 145 | #endif 146 | #endif 147 | 148 | testFormat("*Sizeof of void * %zu",sizeof(void *)); 149 | testFormat("*Binary number %b %#b",5,6); 150 | testFormat("*Stack ptr %p %P",stackPtr,stackPtr); 151 | testFormat("*Static ptr %p %P",ptr,ptr); 152 | testFormat("*Text ptr %p %P",xvformat,xvformat); 153 | testFormat("*boolean %B %B",1,0); 154 | testFormat("*Text pointer as sizeof %zX",xvformat); 155 | 156 | #if XCFG_FORMAT_LONG 157 | testFormat("long %d %o %x",123456L,123456L,123456L); 158 | testFormat("*long binary %b",123456L); 159 | #endif 160 | 161 | #if XCFG_FORMAT_LONGLONG 162 | testFormat("long long int %lld",(long long)123); 163 | testFormat("long long int %lld",(long long)-123); 164 | testFormat("long long hex %#llx",(long long)0x123456789abcdef); 165 | testFormat("long long hex %#llX",(long long)0x123456789abcdef); 166 | #endif 167 | fprintf(stderr,"\nTest completed successfully\n"); 168 | 169 | return 0; 170 | } 171 | 172 | 173 | -------------------------------------------------------------------------------- /msvc/xformat/xformattest/xformattest.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 18 | 19 | 20 | 21 | 22 | 29 | 32 | 35 | 38 | 41 | 44 | 55 | 58 | 61 | 64 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 93 | 100 | 103 | 106 | 109 | 112 | 116 | 127 | 130 | 133 | 136 | 143 | 146 | 149 | 152 | 155 | 158 | 161 | 164 | 165 | 173 | 176 | 179 | 182 | 185 | 188 | 199 | 202 | 205 | 208 | 217 | 220 | 223 | 226 | 229 | 232 | 235 | 238 | 239 | 247 | 250 | 253 | 256 | 259 | 263 | 274 | 277 | 280 | 283 | 292 | 295 | 298 | 301 | 304 | 307 | 310 | 313 | 314 | 315 | 316 | 317 | 318 | 323 | 326 | 327 | 330 | 331 | 332 | 337 | 340 | 341 | 342 | 347 | 348 | 349 | 350 | 351 | 352 | -------------------------------------------------------------------------------- /eclipse/table/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 80 | 81 | 86 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /eclipse/speed/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 36 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 83 | 84 | 89 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /eclipse/test/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 36 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 83 | 84 | 89 | 92 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /src/xformatc.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file xformatc.c 3 | * 4 | * @brief Printf C implementation. 5 | * 6 | * Tested with the following operating systems / compilers : 7 | * 8 | * - Visual studio 6 9 | * - Visual studio 2008 / Windows CE 10 | * - MinGw 32 11 | * - Linux i686 12 | * - Linux x86_64 13 | * - GCC with embedded ARM (M0+/M3/M4/M4F) 14 | * - Linux armel 15 | * - Linux armhf 16 | * - HCS08 with Freescale compiler. 17 | * 18 | * - SDCC (Z80 and 8051) 19 | * 20 | * @author Mario Viara 21 | * 22 | * 23 | * @copyright Copyright Mario Viara 2014 - License Open Source (LGPL) 24 | * This is a free software and is opened for education, research and commercial 25 | * developments under license policy of following terms: 26 | * 27 | * - This is a free software and there is NO WARRANTY. 28 | * - No restriction on use. You can use, modify and redistribute it for personal, 29 | * non-profit or commercial product UNDER YOUR RESPONSIBILITY. 30 | * - Redistributions of source code must retain the above copyright notice. 31 | * 32 | * To contact the author send an email to mario_at_viara.eu 33 | * 34 | */ 35 | #ifdef HAVE_CONFIG_H 36 | #include "config.h" 37 | #endif 38 | 39 | #include "xformatc.h" 40 | 41 | 42 | 43 | /** 44 | * Default largest int is long 45 | */ 46 | #ifndef LONG 47 | #if XCFG_FORMAT_LONG 48 | #define LONG long 49 | #else 50 | #define LONG int 51 | #endif 52 | #endif 53 | 54 | /** 55 | * Define the double type if not defined 56 | */ 57 | #ifndef DOUBLE 58 | #define DOUBLE double 59 | #endif 60 | 61 | 62 | /** 63 | * Default long long type 64 | */ 65 | #ifndef LONGLONG 66 | #define LONGLONG long long 67 | #endif 68 | 69 | 70 | /** 71 | * Definition to convert integer part of floating point 72 | * number if supported we use the long long type 73 | */ 74 | #if XCFG_FORMAT_LONGLONG 75 | #define FLOAT_LONG LONGLONG 76 | #define FLOAT_VALUE llvalue 77 | #define FLOAT_TYPE FLAG_TYPE_LONGLONG 78 | #else 79 | #define FLOAT_LONG LONG 80 | #define FLOAT_VALUE lvalue 81 | #define FLOAT_TYPE FLAG_TYPE_LONG 82 | #endif 83 | 84 | /** 85 | * Determine the precision of floating point number 86 | */ 87 | #if XCFG_FORMAT_FLOAT_PREC 88 | #ifdef DOUBLE 89 | #undef DOUBLE 90 | #endif 91 | #define DOUBLE float 92 | #define DOUBLE_ARGS double 93 | #else 94 | #define DOUBLE_ARGS DOUBLE 95 | #endif 96 | 97 | /** 98 | * Structure with all parameter used 99 | */ 100 | struct param_s 101 | { 102 | /** 103 | * Buffer for current integer value and for temporary 104 | * double value defined as union to save stack. 105 | */ 106 | union 107 | { 108 | unsigned LONG lvalue; 109 | #if XCFG_FORMAT_LONGLONG 110 | unsigned LONGLONG llvalue; 111 | #endif 112 | #if XCFG_FORMAT_FLOAT 113 | DOUBLE dvalue; 114 | #endif 115 | } values; 116 | 117 | /** 118 | * Pointer to the output buffer 119 | */ 120 | char* out; 121 | 122 | #if XCFG_FORMAT_FLOAT 123 | /** 124 | * Floating point argument 125 | */ 126 | DOUBLE dbl; 127 | 128 | /** 129 | * Integer part of floating point 130 | */ 131 | unsigned FLOAT_LONG iPart; 132 | 133 | #endif 134 | 135 | 136 | /** 137 | * Current length of the output buffer 138 | */ 139 | int length; 140 | 141 | /** 142 | * Field precision 143 | */ 144 | int prec; 145 | 146 | /** 147 | * Field width 148 | */ 149 | int width; 150 | 151 | 152 | /** 153 | * Count the number of char emitted 154 | */ 155 | unsigned count; 156 | 157 | 158 | /** 159 | * Parser flags 160 | */ 161 | unsigned flags; 162 | 163 | #define FLAG_TYPE_INT 0x0000 /* Argument is integer */ 164 | #define FLAG_TYPE_LONG 0x0001 /* Argument is long */ 165 | #define FLAG_TYPE_SIZEOF 0x0002 /* Argument is size_t */ 166 | #define FLAG_TYPE_LONGLONG 0x0003 /* Argument is long long */ 167 | #define FLAG_TYPE_MASK 0x0003 /* Mask for field type */ 168 | #define FLAG_PREC 0x0004 /* Precision set */ 169 | #define FLAG_LEFT 0x0008 /* Left alignment */ 170 | #define FLAG_BLANK 0x0010 /* Blank before positive integer number */ 171 | #define FLAG_PREFIX 0x0020 /* Prefix required */ 172 | #define FLAG_PLUS 0x0040 /* Force a + before positive number */ 173 | #define FLAG_UPPER 0x0080 /* Output in upper case letter */ 174 | #define FLAG_DECIMAL 0x0100 /* Decimal field */ 175 | #define FLAG_INTEGER 0x0200 /* Integer field */ 176 | #define FLAG_MINUS 0x0400 /* Field is negative */ 177 | #define FLAG_VALUE 0x0800 /* Value set */ 178 | #define FLAG_BUFFER 0x1000 /* Buffer set */ 179 | 180 | /** 181 | * Length of the prefix 182 | */ 183 | int prefixlen; 184 | 185 | /* Buffer to store the field prefix */ 186 | char prefix[2]; 187 | 188 | 189 | /** Buffer to store the biggest integer number in binary */ 190 | #if XCFG_FORMAT_LONGLONG 191 | char buffer[sizeof(LONGLONG)*8+1]; 192 | #else 193 | char buffer[sizeof(LONG)*8+1]; 194 | #endif 195 | 196 | /* Radix for ASCII integer conversion */ 197 | unsigned char radix; 198 | 199 | /* char used for padding */ 200 | char pad; 201 | 202 | 203 | /** 204 | * Current state 205 | */ 206 | char state; 207 | 208 | }; 209 | 210 | 211 | /** 212 | * Enum for the internal state machine 213 | */ 214 | enum State 215 | { 216 | /* Normal state outputting literal */ 217 | ST_NORMAL = 0, 218 | 219 | /* Just read % */ 220 | ST_PERCENT = 1, 221 | 222 | /* Just read flag */ 223 | ST_FLAG = 2, 224 | 225 | /* Just read the width */ 226 | ST_WIDTH = 3, 227 | 228 | /* Just read '.' */ 229 | ST_DOT= 4, 230 | 231 | /* Just read the precision */ 232 | ST_PRECIS = 5, 233 | 234 | /* Just read the size */ 235 | ST_SIZE = 6, 236 | 237 | /* Just read the type specifier */ 238 | ST_TYPE = 7 239 | }; 240 | 241 | /** 242 | * Enum for char class 243 | */ 244 | enum CharClass 245 | { 246 | /* Other char */ 247 | CH_OTHER = 0, 248 | /* The % char */ 249 | CH_PERCENT = 1, 250 | /* The . char */ 251 | CH_DOT = 2, 252 | /* The * char */ 253 | CH_STAR = 3, 254 | /* The 0 char */ 255 | CH_ZERO = 4, 256 | /* Digit 0-9 */ 257 | CH_DIGIT = 5, 258 | /* Flag chars */ 259 | CH_FLAG = 6, 260 | /* Size chars */ 261 | CH_SIZE = 7, 262 | /* Type chars */ 263 | CH_TYPE = 8 264 | }; 265 | 266 | 267 | 268 | /** 269 | * String used when %s is a null parameter 270 | */ 271 | static const char ms_null[] = "(null)"; 272 | /* 273 | * String for true value 274 | */ 275 | static const char ms_true[] = "True"; 276 | 277 | /** 278 | * String for false value 279 | */ 280 | static const char ms_false[]= "False"; 281 | 282 | 283 | #if XCFG_FORMAT_FLOAT 284 | static DOUBLE xpow10(int e) 285 | { 286 | DOUBLE result = 1.0; 287 | static const DOUBLE table[] = {10.0,100.0,1000.0,10000.0,100000.0,1000000.0}; 288 | static const int size = sizeof(table)/sizeof(table[0]); 289 | 290 | if (e > 0) 291 | { 292 | if (e > size) 293 | { 294 | result = table[size - 1]; 295 | for (e = e - size ; e ; e--) 296 | result *= (DOUBLE)10.0; 297 | } 298 | else 299 | result = table[e - 1]; 300 | } 301 | 302 | return result; 303 | } 304 | 305 | 306 | #if XCFG_FORMAT_FLOAT_SPECIAL 307 | static const char *checkFloat(DOUBLE value) 308 | { 309 | switch (fpclassify(value)) 310 | { 311 | case FP_NAN: 312 | return "nan"; 313 | 314 | case FP_INFINITE: 315 | return "inf"; 316 | 317 | case FP_SUBNORMAL: 318 | return "sub"; 319 | 320 | default: 321 | return 0; 322 | } 323 | } 324 | #endif 325 | 326 | #endif 327 | 328 | /* 329 | * This table contains the next state for all char and it will be 330 | * generate using xformattable.c 331 | */ 332 | 333 | static const unsigned char formatStates[] = 334 | { 335 | 0x06,0x00,0x00,0x06,0x00,0x01,0x00,0x00, 336 | 0x10,0x00,0x03,0x06,0x00,0x06,0x02,0x10, 337 | 0x04,0x45,0x45,0x45,0x45,0x05,0x05,0x05, 338 | 0x05,0x35,0x30,0x00,0x50,0x60,0x00,0x00, 339 | 0x00,0x20,0x28,0x38,0x50,0x50,0x00,0x00, 340 | 0x00,0x30,0x30,0x30,0x50,0x50,0x00,0x00, 341 | 0x08,0x20,0x20,0x28,0x20,0x20,0x20,0x00, 342 | 0x08,0x60,0x60,0x60,0x60,0x60,0x60,0x00, 343 | 0x00,0x70,0x78,0x78,0x78,0x70,0x78,0x00, 344 | 0x07,0x08,0x00,0x00,0x07,0x00,0x00,0x08, 345 | 0x08,0x00,0x00,0x08,0x00,0x08,0x00,0x00, 346 | 0x08,0x00,0x07 347 | }; 348 | 349 | 350 | static const char ms_digits[] = "0123456789abcdef"; 351 | 352 | #define U2A(name,type,value) \ 353 | static void name(struct param_s * param) \ 354 | { \ 355 | unsigned char digit; \ 356 | type val = param->values.value ; \ 357 | while (param->prec -- > 0 || val) \ 358 | { \ 359 | switch (param->radix) \ 360 | { \ 361 | case 2: \ 362 | digit = val & 0x01; \ 363 | val >>= 1; \ 364 | break; \ 365 | case 8: \ 366 | digit = val & 0x07; \ 367 | val >>= 3; \ 368 | break; \ 369 | case 16: \ 370 | digit = val & 0x0F;\ 371 | val >>= 4; \ 372 | break; \ 373 | default: \ 374 | case 10: \ 375 | digit = (unsigned char)(val % 10); \ 376 | val /= 10; \ 377 | break; \ 378 | } \ 379 | *param->out -- = ms_digits[digit]; \ 380 | param->length ++ ;\ 381 | } \ 382 | } 383 | 384 | 385 | 386 | 387 | /** 388 | * Convert an unsigned long value in one string 389 | * 390 | * All parameter are in the passed structure 391 | * 392 | * @param prec - Minimum precision 393 | * @param lvalue - Unsigned value 394 | * @param radix - Radix (Supported values 2/8/10/16) 395 | * 396 | * @param out - Buffer with the converted value. 397 | */ 398 | U2A(ulong2a,unsigned LONG,lvalue) 399 | #if XCFG_FORMAT_LONGLONG 400 | #ifdef XCFG_FORMAT_LONG_ARE_LONGLONG 401 | #define ullong2a ulong2a 402 | #else 403 | U2A(ullong2a,unsigned LONGLONG,llvalue) 404 | #endif 405 | #endif 406 | 407 | /** 408 | * Printf like using variable arguments. 409 | * 410 | * @param outchar - Pointer to the function to output one new char. 411 | * @param arg - Argument for the output function. 412 | * @param fmt - Format options for the list of parameters. 413 | * @param ... - Arguments 414 | * 415 | * @return The number of char emitted. 416 | * 417 | * @see xvformat 418 | */ 419 | unsigned xformat(void (*outchar)(void *,char),void *arg,const char * fmt,...) 420 | { 421 | va_list list; 422 | unsigned count; 423 | 424 | va_start(list,fmt); 425 | count = xvformat(outchar,arg,fmt,list); 426 | va_end(list); 427 | 428 | (void)list; 429 | 430 | return count; 431 | } 432 | 433 | 434 | /** 435 | * We do not want use any library function. 436 | * 437 | * @param s - C string 438 | * @return The length of the string 439 | */ 440 | static unsigned xstrlen(const char *s) 441 | { 442 | const char *i; 443 | 444 | for (i = s ; *i ; i++) 445 | { 446 | } 447 | 448 | return (unsigned)(i - s); 449 | } 450 | 451 | static unsigned outBuffer(void (*myoutchar)(void *arg,char),void *arg,const char *buffer,int len,unsigned toupper) 452 | { 453 | unsigned count = 0; 454 | int i; 455 | char c; 456 | 457 | for (i = 0; i < len ; i++) 458 | { 459 | c = buffer[i]; 460 | 461 | if (toupper && (c >= 'a' && c <= 'z')) 462 | { 463 | c = (char)(c - ('a' - 'A')); 464 | } 465 | 466 | (*myoutchar)(arg,c); 467 | count++; 468 | } 469 | 470 | 471 | return count; 472 | } 473 | 474 | 475 | static unsigned outChars(void (*myoutchar)(void *arg,char),void *arg,char ch,int len) 476 | { 477 | unsigned count= 0; 478 | 479 | while (len-- > 0) 480 | { 481 | (*myoutchar)(arg,ch); 482 | count++; 483 | } 484 | 485 | return count; 486 | } 487 | 488 | 489 | 490 | /* 491 | * Lint want declare list as const but list is an obscured pointer so 492 | * the warning is disabled. 493 | */ 494 | /*lint -save -e818 */ 495 | 496 | 497 | /** 498 | * Printf like format function. 499 | * 500 | * General format : 501 | * 502 | * %[width][.precision][flags]type 503 | * 504 | * - width Is the minimum size of the field. 505 | * 506 | * - precision Is the maximum size of the field. 507 | * 508 | * Supported flags : 509 | * 510 | * - l With integer number the argument will be of type long. 511 | * - ll With integer number the argument will be of type long long. 512 | * - Space for positive integer a space will be added before. 513 | * - z Compatible with C99 the argument is size_t (aka sizeof(void *)) 514 | * - + A + sign prefix positive number. 515 | * - # A prefix will be printed (o for octal,0x for hex,0b for binary) 516 | * - 0 Value will be padded with zero (default is spacwe) 517 | * - - Left justify as default filed have rigth justification. 518 | * 519 | * Supported type : 520 | * 521 | * - s Null terminated string of char. 522 | * - S Null terminated string of char in upper case. 523 | * - i Integer number. 524 | * - d Integer number. 525 | * - u Unsigned number. 526 | * - x Unsigned number in hex. 527 | * - X Unsigned number in hex upper case. 528 | * - b Binary number 529 | * - o Octal number 530 | * - p Pointer will be emitted with the prefix -> 531 | * - P Pointer in upper case letter. 532 | * - f Floating point number. 533 | * - B Boolean value printed as True / False. 534 | * 535 | * @param outchar - Pointer to the function to output one char. 536 | * @param arg - Argument for the output function. 537 | * @param fmt - Format options for the list of parameters. 538 | * @param args - List parameters. 539 | * 540 | * @return The number of char emitted. 541 | */ 542 | unsigned xvformat(void (*outchar)(void *,char),void *arg,const char * fmt,va_list _args) 543 | { 544 | XCFG_FORMAT_STATIC struct param_s param; 545 | int i; 546 | char c; 547 | 548 | #if XCFG_FORMAT_VA_COPY 549 | va_list args; 550 | 551 | va_copy(args,_args); 552 | #else 553 | #define args _args 554 | #endif 555 | 556 | param.count = 0; 557 | param.state = ST_NORMAL; 558 | 559 | while (*fmt) 560 | { 561 | c = *fmt++; 562 | 563 | if (c < ' ' || c > 'z') 564 | i = (int)CH_OTHER; 565 | else 566 | i = formatStates[c - ' '] & 0x0F; 567 | 568 | param.state = (char)(formatStates[(i << 3) + param.state] >> 4); 569 | 570 | 571 | switch (param.state) 572 | { 573 | default: 574 | case ST_NORMAL: 575 | (*outchar)(arg,c); 576 | param.count++; 577 | break; 578 | 579 | case ST_PERCENT: 580 | param.flags = param.length = param.prefixlen = param.width = param.prec = 0; 581 | param.pad = ' '; 582 | break; 583 | 584 | case ST_WIDTH: 585 | if (c == '*') 586 | param.width = (int)va_arg(args,int); 587 | else 588 | param.width = param.width * 10 + (c - '0'); 589 | break; 590 | 591 | case ST_DOT: 592 | break; 593 | 594 | case ST_PRECIS: 595 | param.flags |= FLAG_PREC; 596 | if (c == '*') 597 | param.prec = (int)va_arg(args,int); 598 | else 599 | param.prec = param.prec * 10 + (c - '0'); 600 | break; 601 | 602 | case ST_SIZE: 603 | switch (c) 604 | { 605 | default: 606 | break; 607 | case 'z': 608 | param.flags &= (unsigned)~FLAG_TYPE_MASK; 609 | param.flags |= FLAG_TYPE_SIZEOF; 610 | break; 611 | 612 | #if XCFG_FORMAT_LONG 613 | case 'l': 614 | #if XCFG_FORMAT_LONGLONG 615 | if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONG) 616 | { 617 | param.flags &= (unsigned)~FLAG_TYPE_MASK; 618 | param.flags |= FLAG_TYPE_LONGLONG; 619 | } 620 | else 621 | { 622 | param.flags &= (unsigned)~FLAG_TYPE_MASK; 623 | param.flags |= FLAG_TYPE_LONG; 624 | 625 | } 626 | #else 627 | param.flags &= ~FLAG_TYPE_MASK; 628 | param.flags |= FLAG_TYPE_LONG; 629 | #endif 630 | break; 631 | #endif 632 | 633 | } 634 | break; 635 | 636 | case ST_FLAG: 637 | switch (c) 638 | { 639 | default: 640 | break; 641 | case '-': 642 | param.flags |= FLAG_LEFT; 643 | break; 644 | case '0': 645 | param.pad = '0'; 646 | break; 647 | case ' ': 648 | param.flags |= FLAG_BLANK; 649 | break; 650 | case '#': 651 | param.flags |= FLAG_PREFIX; 652 | break; 653 | case '+': 654 | param.flags |= FLAG_PLUS; 655 | break; 656 | } 657 | break; 658 | 659 | case ST_TYPE: 660 | switch (c) 661 | { 662 | default: 663 | param.length = 0; 664 | break; 665 | 666 | /* 667 | * Pointer upper case 668 | */ 669 | case 'P': 670 | param.flags |= FLAG_UPPER; 671 | /* no break */ 672 | /* lint -fallthrough */ 673 | /* fall through */ 674 | 675 | /* 676 | * Pointer 677 | */ 678 | case 'p': 679 | param.flags &= (unsigned)~FLAG_TYPE_MASK; 680 | param.flags |= FLAG_INTEGER | FLAG_TYPE_SIZEOF; 681 | param.radix = 16; 682 | param.prec = sizeof(void *) * 2; 683 | param.prefix[0] = '-'; 684 | param.prefix[1] = '>'; 685 | param.prefixlen = 2; 686 | break; 687 | 688 | /* 689 | * Binary number 690 | */ 691 | case 'b': 692 | param.flags |= FLAG_INTEGER; 693 | param.radix = 2; 694 | if (param.flags & FLAG_PREFIX) 695 | { 696 | param.prefix[0] = '0'; 697 | param.prefix[1] = 'b'; 698 | param.prefixlen = 2; 699 | } 700 | break; 701 | 702 | /* 703 | * Octal number 704 | */ 705 | case 'o': 706 | param.flags |= FLAG_INTEGER; 707 | param.radix = 8; 708 | if (param.flags & FLAG_PREFIX) 709 | { 710 | param.prefix[0] = '0'; 711 | param.prefixlen = 1; 712 | } 713 | break; 714 | 715 | /* 716 | * Hex number upper case letter. 717 | */ 718 | case 'X': 719 | param.flags |= FLAG_UPPER; 720 | /* no break */ 721 | /* lint -fallthrough */ 722 | /* fall through */ 723 | 724 | /* 725 | * Hex number lower case 726 | */ 727 | case 'x': 728 | param.flags |= FLAG_INTEGER; 729 | param.radix = 16; 730 | if (param.flags & FLAG_PREFIX) 731 | { 732 | param.prefix[0] = '0'; 733 | param.prefix[1] = 'x'; 734 | param.prefixlen = 2; 735 | } 736 | break; 737 | 738 | /* 739 | * Integer number radix 10 740 | */ 741 | case 'd': 742 | case 'i': 743 | param.flags |= FLAG_DECIMAL; 744 | /* no break */ 745 | /* lint -fallthrough */ 746 | /* fall through */ 747 | 748 | /* 749 | * Unsigned number 750 | */ 751 | case 'u': 752 | param.flags |= FLAG_INTEGER; 753 | param.radix = 10; 754 | break; 755 | 756 | /* 757 | * Upper case string 758 | */ 759 | case 'S': 760 | param.flags |= FLAG_UPPER; 761 | /* no break */ 762 | /* lint -fallthrough */ 763 | /* fall through */ 764 | 765 | /* 766 | * Normal string 767 | */ 768 | case 's': 769 | param.out = va_arg(args,char *); 770 | if (param.out == 0) 771 | param.out = (char *)ms_null; 772 | param.length = (int)xstrlen(param.out); 773 | break; 774 | 775 | /* 776 | * Upper case char 777 | */ 778 | case 'C': 779 | param.flags |= FLAG_UPPER; 780 | /* no break */ 781 | /* lint -fallthrough */ 782 | /* fall through */ 783 | 784 | /* 785 | * Char 786 | */ 787 | case 'c': 788 | param.out = param.buffer; 789 | param.buffer[0] = (char)va_arg(args,int); 790 | param.length = 1; 791 | break; 792 | 793 | #if XCFG_FORMAT_FLOAT 794 | /** 795 | * Floating point number 796 | */ 797 | case 'f': 798 | if (!(param.flags & FLAG_PREC)) 799 | { 800 | param.prec = 6; 801 | } 802 | 803 | param.values.dvalue = xpow10(param.prec); 804 | param.dbl = (DOUBLE)va_arg(args,DOUBLE_ARGS); 805 | 806 | #if XCFG_FORMAT_FLOAT_SPECIAL 807 | param.out = (char *)checkFloat(param.dbl); 808 | if (param.out != 0) 809 | { 810 | param.length = (int)xstrlen(param.out); 811 | 812 | } 813 | else 814 | { 815 | #endif 816 | 817 | if (param.dbl < 0) 818 | { 819 | param.flags |= FLAG_MINUS; 820 | param.dbl -= (DOUBLE)0.5 / param.values.dvalue; 821 | param.iPart = (FLOAT_LONG)param.dbl; 822 | param.dbl -= (DOUBLE)(FLOAT_LONG)param.iPart; 823 | param.dbl = - param.dbl; 824 | } 825 | else 826 | { 827 | param.dbl += (DOUBLE)0.5 / param.values.dvalue; 828 | param.iPart = (FLOAT_LONG)param.dbl; 829 | param.dbl -= (DOUBLE)param.iPart; 830 | } 831 | 832 | param.dbl *= param.values.dvalue; 833 | 834 | param.values.lvalue = (unsigned LONG)param.dbl; 835 | 836 | param.out = param.buffer + sizeof(param.buffer) - 1; 837 | param.radix = 10; 838 | if (param.prec) 839 | { 840 | ulong2a(¶m); 841 | *param.out -- = '.'; 842 | param.length ++; 843 | } 844 | param.flags |= FLAG_INTEGER | FLAG_BUFFER | 845 | FLAG_DECIMAL | FLAG_VALUE | FLOAT_TYPE; 846 | 847 | param.prec = 0; 848 | param.values.FLOAT_VALUE = (unsigned FLOAT_LONG)param.iPart; 849 | 850 | #if XCFG_FORMAT_FLOAT_SPECIAL 851 | } 852 | #endif 853 | break; 854 | #endif 855 | 856 | /** 857 | * Boolean value 858 | */ 859 | case 'B': 860 | if (va_arg(args,int) != 0) 861 | param.out = (char*)ms_true; 862 | else 863 | param.out = (char*)ms_false; 864 | 865 | param.length = (int)xstrlen(param.out); 866 | break; 867 | 868 | 869 | } 870 | 871 | /* 872 | * Process integer number 873 | */ 874 | if (param.flags & FLAG_INTEGER) 875 | { 876 | if (param.prec == 0) 877 | param.prec = 1; 878 | 879 | if (!(param.flags & FLAG_VALUE)) 880 | { 881 | switch (param.flags & FLAG_TYPE_MASK) 882 | { 883 | case FLAG_TYPE_SIZEOF: 884 | param.values.lvalue = (unsigned LONG)va_arg(args,void *); 885 | break; 886 | case FLAG_TYPE_LONG: 887 | if (param.flags & FLAG_DECIMAL) 888 | param.values.lvalue = (LONG)va_arg(args,long); 889 | else 890 | param.values.lvalue = (unsigned LONG)va_arg(args,unsigned long); 891 | break; 892 | 893 | case FLAG_TYPE_INT: 894 | if (param.flags & FLAG_DECIMAL) 895 | param.values.lvalue = (LONG)va_arg(args,int); 896 | else 897 | param.values.lvalue = (unsigned LONG)va_arg(args,unsigned int); 898 | break; 899 | #if XCFG_FORMAT_LONGLONG 900 | case FLAG_TYPE_LONGLONG: 901 | param.values.llvalue = (LONGLONG)va_arg(args,long long); 902 | break; 903 | #endif 904 | } 905 | 906 | } 907 | 908 | if ((param.flags & FLAG_PREFIX) && param.values.lvalue == 0) 909 | { 910 | param.prefixlen = 0; 911 | } 912 | 913 | 914 | /* 915 | * Manage signed integer 916 | */ 917 | if (param.flags & FLAG_DECIMAL) 918 | { 919 | #if XCFG_FORMAT_LONGLONG 920 | if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONGLONG) 921 | { 922 | if ((LONGLONG)param.values.llvalue < 0) 923 | { 924 | param.values.llvalue = ~param.values.llvalue + 1; 925 | param.flags |= FLAG_MINUS; 926 | } 927 | } 928 | else 929 | { 930 | #endif 931 | if ((LONG)param.values.lvalue < 0) 932 | { 933 | param.values.lvalue = ~param.values.lvalue + 1; 934 | param.flags |= FLAG_MINUS; 935 | 936 | } 937 | #if XCFG_FORMAT_LONGLONG 938 | } 939 | #endif 940 | if (!(param.flags & FLAG_MINUS) && (param.flags & FLAG_BLANK)) 941 | { 942 | param.prefix[0] = ' '; 943 | param.prefixlen = 1; 944 | } 945 | } 946 | 947 | if ((param.flags & FLAG_BUFFER) == 0) 948 | { 949 | param.out = param.buffer + sizeof(param.buffer) - 1; 950 | } 951 | 952 | 953 | #if XCFG_FORMAT_LONGLONG 954 | if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONGLONG) 955 | ullong2a(¶m); 956 | else 957 | ulong2a(¶m); 958 | #else 959 | 960 | ulong2a(¶m); 961 | #endif 962 | param.out++; 963 | 964 | /* 965 | * Check if a sign is required 966 | */ 967 | if (param.flags & (FLAG_MINUS|FLAG_PLUS)) 968 | { 969 | c = param.flags & FLAG_MINUS ? '-' : '+'; 970 | 971 | if (param.pad == '0') 972 | { 973 | param.prefixlen = 1; 974 | param.prefix[0] = c; 975 | } 976 | else 977 | { 978 | *--param.out = c; 979 | param.length++; 980 | } 981 | } 982 | 983 | 984 | } 985 | else 986 | { 987 | if (param.width && param.length > param.width) 988 | { 989 | param.length = param.width; 990 | } 991 | 992 | } 993 | 994 | /* 995 | * Now width contain the size of the pad 996 | */ 997 | param.width -= (param.length + param.prefixlen); 998 | 999 | param.count += outBuffer(outchar,arg,param.prefix,param.prefixlen,param.flags & FLAG_UPPER); 1000 | if (!(param.flags & FLAG_LEFT)) 1001 | param.count += outChars(outchar,arg,param.pad,param.width); 1002 | param.count += outBuffer(outchar,arg,param.out,param.length,param.flags & FLAG_UPPER); 1003 | if (param.flags & FLAG_LEFT) 1004 | param.count += outChars(outchar,arg,param.pad,param.width); 1005 | 1006 | } 1007 | } 1008 | 1009 | #if XCFG_FORMAT_VA_COPY 1010 | va_end(args); 1011 | #endif 1012 | 1013 | return param.count; 1014 | } 1015 | 1016 | /*lint -restore */ 1017 | 1018 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | (This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.) 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | {description} 474 | Copyright (C) {year} {fullname} 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 489 | USA 490 | 491 | Also add information on how to contact you by electronic and paper mail. 492 | 493 | You should also get your employer (if you work as a programmer) or your 494 | school, if any, to sign a "copyright disclaimer" for the library, if 495 | necessary. Here is a sample; alter the names: 496 | 497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 498 | library `Frob' (a library for tweaking knobs) written by James Random 499 | Hacker. 500 | 501 | {signature of Ty Coon}, 1 April 1990 502 | Ty Coon, President of Vice 503 | 504 | That's all there is to it! 505 | 506 | --------------------------------------------------------------------------------