├── .gitignore ├── CMakeFiles ├── 3.10.2 │ ├── CMakeCCompiler.cmake │ ├── CMakeDetermineCompilerABI_C.bin │ ├── CMakeSystem.cmake │ └── CompilerIdC │ │ ├── CMakeCCompilerId.c │ │ └── a.out ├── CMakeDirectoryInformation.cmake ├── CMakeOutput.log ├── Makefile.cmake ├── Makefile2 ├── TargetDirectories.txt ├── cmake.check_cache ├── feature_tests.bin ├── feature_tests.c ├── progress.marks └── twtxtc.dir │ ├── C.includecache │ ├── DependInfo.cmake │ ├── build.make │ ├── cJSON │ ├── cJSON.c.o │ └── cJSON_Utils.c.o │ ├── cmake_clean.cmake │ ├── depend.internal │ ├── depend.make │ ├── flags.make │ ├── link.txt │ ├── progress.make │ └── twtxt.c.o ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── README.md ├── cJSON ├── LICENSE ├── cJSON.c ├── cJSON.h ├── cJSON_Utils.c └── cJSON_Utils.h ├── cmake_install.cmake ├── twtxt.c ├── twtxt.h └── twtxtc /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeCache.txt 2 | -------------------------------------------------------------------------------- /CMakeFiles/3.10.2/CMakeCCompiler.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_COMPILER "/usr/bin/cc") 2 | set(CMAKE_C_COMPILER_ARG1 "") 3 | set(CMAKE_C_COMPILER_ID "GNU") 4 | set(CMAKE_C_COMPILER_VERSION "7.5.0") 5 | set(CMAKE_C_COMPILER_VERSION_INTERNAL "") 6 | set(CMAKE_C_COMPILER_WRAPPER "") 7 | set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "11") 8 | set(CMAKE_C_COMPILE_FEATURES "c_std_90;c_function_prototypes;c_std_99;c_restrict;c_variadic_macros;c_std_11;c_static_assert") 9 | set(CMAKE_C90_COMPILE_FEATURES "c_std_90;c_function_prototypes") 10 | set(CMAKE_C99_COMPILE_FEATURES "c_std_99;c_restrict;c_variadic_macros") 11 | set(CMAKE_C11_COMPILE_FEATURES "c_std_11;c_static_assert") 12 | 13 | set(CMAKE_C_PLATFORM_ID "Linux") 14 | set(CMAKE_C_SIMULATE_ID "") 15 | set(CMAKE_C_SIMULATE_VERSION "") 16 | 17 | 18 | 19 | set(CMAKE_AR "/usr/bin/ar") 20 | set(CMAKE_C_COMPILER_AR "/usr/bin/gcc-ar-7") 21 | set(CMAKE_RANLIB "/usr/bin/ranlib") 22 | set(CMAKE_C_COMPILER_RANLIB "/usr/bin/gcc-ranlib-7") 23 | set(CMAKE_LINKER "/usr/bin/ld") 24 | set(CMAKE_COMPILER_IS_GNUCC 1) 25 | set(CMAKE_C_COMPILER_LOADED 1) 26 | set(CMAKE_C_COMPILER_WORKS TRUE) 27 | set(CMAKE_C_ABI_COMPILED TRUE) 28 | set(CMAKE_COMPILER_IS_MINGW ) 29 | set(CMAKE_COMPILER_IS_CYGWIN ) 30 | if(CMAKE_COMPILER_IS_CYGWIN) 31 | set(CYGWIN 1) 32 | set(UNIX 1) 33 | endif() 34 | 35 | set(CMAKE_C_COMPILER_ENV_VAR "CC") 36 | 37 | if(CMAKE_COMPILER_IS_MINGW) 38 | set(MINGW 1) 39 | endif() 40 | set(CMAKE_C_COMPILER_ID_RUN 1) 41 | set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m) 42 | set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) 43 | set(CMAKE_C_LINKER_PREFERENCE 10) 44 | 45 | # Save compiler ABI information. 46 | set(CMAKE_C_SIZEOF_DATA_PTR "8") 47 | set(CMAKE_C_COMPILER_ABI "ELF") 48 | set(CMAKE_C_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") 49 | 50 | if(CMAKE_C_SIZEOF_DATA_PTR) 51 | set(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}") 52 | endif() 53 | 54 | if(CMAKE_C_COMPILER_ABI) 55 | set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}") 56 | endif() 57 | 58 | if(CMAKE_C_LIBRARY_ARCHITECTURE) 59 | set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") 60 | endif() 61 | 62 | set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "") 63 | if(CMAKE_C_CL_SHOWINCLUDES_PREFIX) 64 | set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}") 65 | endif() 66 | 67 | 68 | 69 | 70 | 71 | set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "gcc;gcc_s;c;gcc;gcc_s") 72 | set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/7;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") 73 | set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") 74 | -------------------------------------------------------------------------------- /CMakeFiles/3.10.2/CMakeDetermineCompilerABI_C.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neauoire/twtxtc/b1315b02c794b4429011f5f7565d574b452b529d/CMakeFiles/3.10.2/CMakeDetermineCompilerABI_C.bin -------------------------------------------------------------------------------- /CMakeFiles/3.10.2/CMakeSystem.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_HOST_SYSTEM "Linux-4.15.0-91-generic") 2 | set(CMAKE_HOST_SYSTEM_NAME "Linux") 3 | set(CMAKE_HOST_SYSTEM_VERSION "4.15.0-91-generic") 4 | set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64") 5 | 6 | 7 | 8 | set(CMAKE_SYSTEM "Linux-4.15.0-91-generic") 9 | set(CMAKE_SYSTEM_NAME "Linux") 10 | set(CMAKE_SYSTEM_VERSION "4.15.0-91-generic") 11 | set(CMAKE_SYSTEM_PROCESSOR "x86_64") 12 | 13 | set(CMAKE_CROSSCOMPILING "FALSE") 14 | 15 | set(CMAKE_SYSTEM_LOADED 1) 16 | -------------------------------------------------------------------------------- /CMakeFiles/3.10.2/CompilerIdC/CMakeCCompilerId.c: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | # error "A C++ compiler has been selected for C." 3 | #endif 4 | 5 | #if defined(__18CXX) 6 | # define ID_VOID_MAIN 7 | #endif 8 | #if defined(__CLASSIC_C__) 9 | /* cv-qualifiers did not exist in K&R C */ 10 | # define const 11 | # define volatile 12 | #endif 13 | 14 | 15 | /* Version number components: V=Version, R=Revision, P=Patch 16 | Version date components: YYYY=Year, MM=Month, DD=Day */ 17 | 18 | #if defined(__INTEL_COMPILER) || defined(__ICC) 19 | # define COMPILER_ID "Intel" 20 | # if defined(_MSC_VER) 21 | # define SIMULATE_ID "MSVC" 22 | # endif 23 | /* __INTEL_COMPILER = VRP */ 24 | # define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) 25 | # define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) 26 | # if defined(__INTEL_COMPILER_UPDATE) 27 | # define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE) 28 | # else 29 | # define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) 30 | # endif 31 | # if defined(__INTEL_COMPILER_BUILD_DATE) 32 | /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */ 33 | # define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) 34 | # endif 35 | # if defined(_MSC_VER) 36 | /* _MSC_VER = VVRR */ 37 | # define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) 38 | # define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) 39 | # endif 40 | 41 | #elif defined(__PATHCC__) 42 | # define COMPILER_ID "PathScale" 43 | # define COMPILER_VERSION_MAJOR DEC(__PATHCC__) 44 | # define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) 45 | # if defined(__PATHCC_PATCHLEVEL__) 46 | # define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) 47 | # endif 48 | 49 | #elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) 50 | # define COMPILER_ID "Embarcadero" 51 | # define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) 52 | # define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) 53 | # define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF) 54 | 55 | #elif defined(__BORLANDC__) 56 | # define COMPILER_ID "Borland" 57 | /* __BORLANDC__ = 0xVRR */ 58 | # define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) 59 | # define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) 60 | 61 | #elif defined(__WATCOMC__) && __WATCOMC__ < 1200 62 | # define COMPILER_ID "Watcom" 63 | /* __WATCOMC__ = VVRR */ 64 | # define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) 65 | # define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) 66 | # if (__WATCOMC__ % 10) > 0 67 | # define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) 68 | # endif 69 | 70 | #elif defined(__WATCOMC__) 71 | # define COMPILER_ID "OpenWatcom" 72 | /* __WATCOMC__ = VVRP + 1100 */ 73 | # define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100) 74 | # define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) 75 | # if (__WATCOMC__ % 10) > 0 76 | # define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) 77 | # endif 78 | 79 | #elif defined(__SUNPRO_C) 80 | # define COMPILER_ID "SunPro" 81 | # if __SUNPRO_C >= 0x5100 82 | /* __SUNPRO_C = 0xVRRP */ 83 | # define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12) 84 | # define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF) 85 | # define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) 86 | # else 87 | /* __SUNPRO_CC = 0xVRP */ 88 | # define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8) 89 | # define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF) 90 | # define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) 91 | # endif 92 | 93 | #elif defined(__HP_cc) 94 | # define COMPILER_ID "HP" 95 | /* __HP_cc = VVRRPP */ 96 | # define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000) 97 | # define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100) 98 | # define COMPILER_VERSION_PATCH DEC(__HP_cc % 100) 99 | 100 | #elif defined(__DECC) 101 | # define COMPILER_ID "Compaq" 102 | /* __DECC_VER = VVRRTPPPP */ 103 | # define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000) 104 | # define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100) 105 | # define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000) 106 | 107 | #elif defined(__IBMC__) && defined(__COMPILER_VER__) 108 | # define COMPILER_ID "zOS" 109 | /* __IBMC__ = VRP */ 110 | # define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) 111 | # define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) 112 | # define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) 113 | 114 | #elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800 115 | # define COMPILER_ID "XL" 116 | /* __IBMC__ = VRP */ 117 | # define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) 118 | # define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) 119 | # define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) 120 | 121 | #elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800 122 | # define COMPILER_ID "VisualAge" 123 | /* __IBMC__ = VRP */ 124 | # define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) 125 | # define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) 126 | # define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) 127 | 128 | #elif defined(__PGI) 129 | # define COMPILER_ID "PGI" 130 | # define COMPILER_VERSION_MAJOR DEC(__PGIC__) 131 | # define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) 132 | # if defined(__PGIC_PATCHLEVEL__) 133 | # define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) 134 | # endif 135 | 136 | #elif defined(_CRAYC) 137 | # define COMPILER_ID "Cray" 138 | # define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR) 139 | # define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) 140 | 141 | #elif defined(__TI_COMPILER_VERSION__) 142 | # define COMPILER_ID "TI" 143 | /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ 144 | # define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) 145 | # define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) 146 | # define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) 147 | 148 | #elif defined(__FUJITSU) || defined(__FCC_VERSION) || defined(__fcc_version) 149 | # define COMPILER_ID "Fujitsu" 150 | 151 | #elif defined(__TINYC__) 152 | # define COMPILER_ID "TinyCC" 153 | 154 | #elif defined(__BCC__) 155 | # define COMPILER_ID "Bruce" 156 | 157 | #elif defined(__SCO_VERSION__) 158 | # define COMPILER_ID "SCO" 159 | 160 | #elif defined(__clang__) && defined(__apple_build_version__) 161 | # define COMPILER_ID "AppleClang" 162 | # if defined(_MSC_VER) 163 | # define SIMULATE_ID "MSVC" 164 | # endif 165 | # define COMPILER_VERSION_MAJOR DEC(__clang_major__) 166 | # define COMPILER_VERSION_MINOR DEC(__clang_minor__) 167 | # define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) 168 | # if defined(_MSC_VER) 169 | /* _MSC_VER = VVRR */ 170 | # define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) 171 | # define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) 172 | # endif 173 | # define COMPILER_VERSION_TWEAK DEC(__apple_build_version__) 174 | 175 | #elif defined(__clang__) 176 | # define COMPILER_ID "Clang" 177 | # if defined(_MSC_VER) 178 | # define SIMULATE_ID "MSVC" 179 | # endif 180 | # define COMPILER_VERSION_MAJOR DEC(__clang_major__) 181 | # define COMPILER_VERSION_MINOR DEC(__clang_minor__) 182 | # define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) 183 | # if defined(_MSC_VER) 184 | /* _MSC_VER = VVRR */ 185 | # define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) 186 | # define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) 187 | # endif 188 | 189 | #elif defined(__GNUC__) 190 | # define COMPILER_ID "GNU" 191 | # define COMPILER_VERSION_MAJOR DEC(__GNUC__) 192 | # if defined(__GNUC_MINOR__) 193 | # define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) 194 | # endif 195 | # if defined(__GNUC_PATCHLEVEL__) 196 | # define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) 197 | # endif 198 | 199 | #elif defined(_MSC_VER) 200 | # define COMPILER_ID "MSVC" 201 | /* _MSC_VER = VVRR */ 202 | # define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) 203 | # define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) 204 | # if defined(_MSC_FULL_VER) 205 | # if _MSC_VER >= 1400 206 | /* _MSC_FULL_VER = VVRRPPPPP */ 207 | # define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) 208 | # else 209 | /* _MSC_FULL_VER = VVRRPPPP */ 210 | # define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) 211 | # endif 212 | # endif 213 | # if defined(_MSC_BUILD) 214 | # define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) 215 | # endif 216 | 217 | #elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) 218 | # define COMPILER_ID "ADSP" 219 | #if defined(__VISUALDSPVERSION__) 220 | /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ 221 | # define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24) 222 | # define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF) 223 | # define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF) 224 | #endif 225 | 226 | #elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) 227 | # define COMPILER_ID "IAR" 228 | # if defined(__VER__) 229 | # define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000) 230 | # define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000) 231 | # define COMPILER_VERSION_PATCH DEC((__VER__) % 1000) 232 | # define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) 233 | # endif 234 | 235 | #elif defined(__ARMCC_VERSION) 236 | # define COMPILER_ID "ARMCC" 237 | #if __ARMCC_VERSION >= 1000000 238 | /* __ARMCC_VERSION = VRRPPPP */ 239 | # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000) 240 | # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100) 241 | # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) 242 | #else 243 | /* __ARMCC_VERSION = VRPPPP */ 244 | # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000) 245 | # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10) 246 | # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) 247 | #endif 248 | 249 | 250 | #elif defined(__SDCC_VERSION_MAJOR) || defined(SDCC) 251 | # define COMPILER_ID "SDCC" 252 | # if defined(__SDCC_VERSION_MAJOR) 253 | # define COMPILER_VERSION_MAJOR DEC(__SDCC_VERSION_MAJOR) 254 | # define COMPILER_VERSION_MINOR DEC(__SDCC_VERSION_MINOR) 255 | # define COMPILER_VERSION_PATCH DEC(__SDCC_VERSION_PATCH) 256 | # else 257 | /* SDCC = VRP */ 258 | # define COMPILER_VERSION_MAJOR DEC(SDCC/100) 259 | # define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10) 260 | # define COMPILER_VERSION_PATCH DEC(SDCC % 10) 261 | # endif 262 | 263 | #elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) 264 | # define COMPILER_ID "MIPSpro" 265 | # if defined(_SGI_COMPILER_VERSION) 266 | /* _SGI_COMPILER_VERSION = VRP */ 267 | # define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100) 268 | # define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10) 269 | # define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10) 270 | # else 271 | /* _COMPILER_VERSION = VRP */ 272 | # define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100) 273 | # define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10) 274 | # define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10) 275 | # endif 276 | 277 | 278 | /* These compilers are either not known or too old to define an 279 | identification macro. Try to identify the platform and guess that 280 | it is the native compiler. */ 281 | #elif defined(__sgi) 282 | # define COMPILER_ID "MIPSpro" 283 | 284 | #elif defined(__hpux) || defined(__hpua) 285 | # define COMPILER_ID "HP" 286 | 287 | #else /* unknown compiler */ 288 | # define COMPILER_ID "" 289 | #endif 290 | 291 | /* Construct the string literal in pieces to prevent the source from 292 | getting matched. Store it in a pointer rather than an array 293 | because some compilers will just produce instructions to fill the 294 | array rather than assigning a pointer to a static array. */ 295 | char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; 296 | #ifdef SIMULATE_ID 297 | char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; 298 | #endif 299 | 300 | #ifdef __QNXNTO__ 301 | char const* qnxnto = "INFO" ":" "qnxnto[]"; 302 | #endif 303 | 304 | #if defined(__CRAYXE) || defined(__CRAYXC) 305 | char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]"; 306 | #endif 307 | 308 | #define STRINGIFY_HELPER(X) #X 309 | #define STRINGIFY(X) STRINGIFY_HELPER(X) 310 | 311 | /* Identify known platforms by name. */ 312 | #if defined(__linux) || defined(__linux__) || defined(linux) 313 | # define PLATFORM_ID "Linux" 314 | 315 | #elif defined(__CYGWIN__) 316 | # define PLATFORM_ID "Cygwin" 317 | 318 | #elif defined(__MINGW32__) 319 | # define PLATFORM_ID "MinGW" 320 | 321 | #elif defined(__APPLE__) 322 | # define PLATFORM_ID "Darwin" 323 | 324 | #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 325 | # define PLATFORM_ID "Windows" 326 | 327 | #elif defined(__FreeBSD__) || defined(__FreeBSD) 328 | # define PLATFORM_ID "FreeBSD" 329 | 330 | #elif defined(__NetBSD__) || defined(__NetBSD) 331 | # define PLATFORM_ID "NetBSD" 332 | 333 | #elif defined(__OpenBSD__) || defined(__OPENBSD) 334 | # define PLATFORM_ID "OpenBSD" 335 | 336 | #elif defined(__sun) || defined(sun) 337 | # define PLATFORM_ID "SunOS" 338 | 339 | #elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) 340 | # define PLATFORM_ID "AIX" 341 | 342 | #elif defined(__sgi) || defined(__sgi__) || defined(_SGI) 343 | # define PLATFORM_ID "IRIX" 344 | 345 | #elif defined(__hpux) || defined(__hpux__) 346 | # define PLATFORM_ID "HP-UX" 347 | 348 | #elif defined(__HAIKU__) 349 | # define PLATFORM_ID "Haiku" 350 | 351 | #elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) 352 | # define PLATFORM_ID "BeOS" 353 | 354 | #elif defined(__QNX__) || defined(__QNXNTO__) 355 | # define PLATFORM_ID "QNX" 356 | 357 | #elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) 358 | # define PLATFORM_ID "Tru64" 359 | 360 | #elif defined(__riscos) || defined(__riscos__) 361 | # define PLATFORM_ID "RISCos" 362 | 363 | #elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) 364 | # define PLATFORM_ID "SINIX" 365 | 366 | #elif defined(__UNIX_SV__) 367 | # define PLATFORM_ID "UNIX_SV" 368 | 369 | #elif defined(__bsdos__) 370 | # define PLATFORM_ID "BSDOS" 371 | 372 | #elif defined(_MPRAS) || defined(MPRAS) 373 | # define PLATFORM_ID "MP-RAS" 374 | 375 | #elif defined(__osf) || defined(__osf__) 376 | # define PLATFORM_ID "OSF1" 377 | 378 | #elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) 379 | # define PLATFORM_ID "SCO_SV" 380 | 381 | #elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) 382 | # define PLATFORM_ID "ULTRIX" 383 | 384 | #elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) 385 | # define PLATFORM_ID "Xenix" 386 | 387 | #elif defined(__WATCOMC__) 388 | # if defined(__LINUX__) 389 | # define PLATFORM_ID "Linux" 390 | 391 | # elif defined(__DOS__) 392 | # define PLATFORM_ID "DOS" 393 | 394 | # elif defined(__OS2__) 395 | # define PLATFORM_ID "OS2" 396 | 397 | # elif defined(__WINDOWS__) 398 | # define PLATFORM_ID "Windows3x" 399 | 400 | # else /* unknown platform */ 401 | # define PLATFORM_ID 402 | # endif 403 | 404 | #else /* unknown platform */ 405 | # define PLATFORM_ID 406 | 407 | #endif 408 | 409 | /* For windows compilers MSVC and Intel we can determine 410 | the architecture of the compiler being used. This is because 411 | the compilers do not have flags that can change the architecture, 412 | but rather depend on which compiler is being used 413 | */ 414 | #if defined(_WIN32) && defined(_MSC_VER) 415 | # if defined(_M_IA64) 416 | # define ARCHITECTURE_ID "IA64" 417 | 418 | # elif defined(_M_X64) || defined(_M_AMD64) 419 | # define ARCHITECTURE_ID "x64" 420 | 421 | # elif defined(_M_IX86) 422 | # define ARCHITECTURE_ID "X86" 423 | 424 | # elif defined(_M_ARM64) 425 | # define ARCHITECTURE_ID "ARM64" 426 | 427 | # elif defined(_M_ARM) 428 | # if _M_ARM == 4 429 | # define ARCHITECTURE_ID "ARMV4I" 430 | # elif _M_ARM == 5 431 | # define ARCHITECTURE_ID "ARMV5I" 432 | # else 433 | # define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM) 434 | # endif 435 | 436 | # elif defined(_M_MIPS) 437 | # define ARCHITECTURE_ID "MIPS" 438 | 439 | # elif defined(_M_SH) 440 | # define ARCHITECTURE_ID "SHx" 441 | 442 | # else /* unknown architecture */ 443 | # define ARCHITECTURE_ID "" 444 | # endif 445 | 446 | #elif defined(__WATCOMC__) 447 | # if defined(_M_I86) 448 | # define ARCHITECTURE_ID "I86" 449 | 450 | # elif defined(_M_IX86) 451 | # define ARCHITECTURE_ID "X86" 452 | 453 | # else /* unknown architecture */ 454 | # define ARCHITECTURE_ID "" 455 | # endif 456 | 457 | #elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) 458 | # if defined(__ICCARM__) 459 | # define ARCHITECTURE_ID "ARM" 460 | 461 | # elif defined(__ICCAVR__) 462 | # define ARCHITECTURE_ID "AVR" 463 | 464 | # else /* unknown architecture */ 465 | # define ARCHITECTURE_ID "" 466 | # endif 467 | #else 468 | # define ARCHITECTURE_ID 469 | #endif 470 | 471 | /* Convert integer to decimal digit literals. */ 472 | #define DEC(n) \ 473 | ('0' + (((n) / 10000000)%10)), \ 474 | ('0' + (((n) / 1000000)%10)), \ 475 | ('0' + (((n) / 100000)%10)), \ 476 | ('0' + (((n) / 10000)%10)), \ 477 | ('0' + (((n) / 1000)%10)), \ 478 | ('0' + (((n) / 100)%10)), \ 479 | ('0' + (((n) / 10)%10)), \ 480 | ('0' + ((n) % 10)) 481 | 482 | /* Convert integer to hex digit literals. */ 483 | #define HEX(n) \ 484 | ('0' + ((n)>>28 & 0xF)), \ 485 | ('0' + ((n)>>24 & 0xF)), \ 486 | ('0' + ((n)>>20 & 0xF)), \ 487 | ('0' + ((n)>>16 & 0xF)), \ 488 | ('0' + ((n)>>12 & 0xF)), \ 489 | ('0' + ((n)>>8 & 0xF)), \ 490 | ('0' + ((n)>>4 & 0xF)), \ 491 | ('0' + ((n) & 0xF)) 492 | 493 | /* Construct a string literal encoding the version number components. */ 494 | #ifdef COMPILER_VERSION_MAJOR 495 | char const info_version[] = { 496 | 'I', 'N', 'F', 'O', ':', 497 | 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', 498 | COMPILER_VERSION_MAJOR, 499 | # ifdef COMPILER_VERSION_MINOR 500 | '.', COMPILER_VERSION_MINOR, 501 | # ifdef COMPILER_VERSION_PATCH 502 | '.', COMPILER_VERSION_PATCH, 503 | # ifdef COMPILER_VERSION_TWEAK 504 | '.', COMPILER_VERSION_TWEAK, 505 | # endif 506 | # endif 507 | # endif 508 | ']','\0'}; 509 | #endif 510 | 511 | /* Construct a string literal encoding the internal version number. */ 512 | #ifdef COMPILER_VERSION_INTERNAL 513 | char const info_version_internal[] = { 514 | 'I', 'N', 'F', 'O', ':', 515 | 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_', 516 | 'i','n','t','e','r','n','a','l','[', 517 | COMPILER_VERSION_INTERNAL,']','\0'}; 518 | #endif 519 | 520 | /* Construct a string literal encoding the version number components. */ 521 | #ifdef SIMULATE_VERSION_MAJOR 522 | char const info_simulate_version[] = { 523 | 'I', 'N', 'F', 'O', ':', 524 | 's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[', 525 | SIMULATE_VERSION_MAJOR, 526 | # ifdef SIMULATE_VERSION_MINOR 527 | '.', SIMULATE_VERSION_MINOR, 528 | # ifdef SIMULATE_VERSION_PATCH 529 | '.', SIMULATE_VERSION_PATCH, 530 | # ifdef SIMULATE_VERSION_TWEAK 531 | '.', SIMULATE_VERSION_TWEAK, 532 | # endif 533 | # endif 534 | # endif 535 | ']','\0'}; 536 | #endif 537 | 538 | /* Construct the string literal in pieces to prevent the source from 539 | getting matched. Store it in a pointer rather than an array 540 | because some compilers will just produce instructions to fill the 541 | array rather than assigning a pointer to a static array. */ 542 | char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; 543 | char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; 544 | 545 | 546 | 547 | 548 | #if !defined(__STDC__) 549 | # if defined(_MSC_VER) && !defined(__clang__) 550 | # define C_DIALECT "90" 551 | # else 552 | # define C_DIALECT 553 | # endif 554 | #elif __STDC_VERSION__ >= 201000L 555 | # define C_DIALECT "11" 556 | #elif __STDC_VERSION__ >= 199901L 557 | # define C_DIALECT "99" 558 | #else 559 | # define C_DIALECT "90" 560 | #endif 561 | const char* info_language_dialect_default = 562 | "INFO" ":" "dialect_default[" C_DIALECT "]"; 563 | 564 | /*--------------------------------------------------------------------------*/ 565 | 566 | #ifdef ID_VOID_MAIN 567 | void main() {} 568 | #else 569 | # if defined(__CLASSIC_C__) 570 | int main(argc, argv) int argc; char *argv[]; 571 | # else 572 | int main(int argc, char* argv[]) 573 | # endif 574 | { 575 | int require = 0; 576 | require += info_compiler[argc]; 577 | require += info_platform[argc]; 578 | require += info_arch[argc]; 579 | #ifdef COMPILER_VERSION_MAJOR 580 | require += info_version[argc]; 581 | #endif 582 | #ifdef COMPILER_VERSION_INTERNAL 583 | require += info_version_internal[argc]; 584 | #endif 585 | #ifdef SIMULATE_ID 586 | require += info_simulate[argc]; 587 | #endif 588 | #ifdef SIMULATE_VERSION_MAJOR 589 | require += info_simulate_version[argc]; 590 | #endif 591 | #if defined(__CRAYXE) || defined(__CRAYXC) 592 | require += info_cray[argc]; 593 | #endif 594 | require += info_language_dialect_default[argc]; 595 | (void)argv; 596 | return require; 597 | } 598 | #endif 599 | -------------------------------------------------------------------------------- /CMakeFiles/3.10.2/CompilerIdC/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neauoire/twtxtc/b1315b02c794b4429011f5f7565d574b452b529d/CMakeFiles/3.10.2/CompilerIdC/a.out -------------------------------------------------------------------------------- /CMakeFiles/CMakeDirectoryInformation.cmake: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.10 3 | 4 | # Relative path conversion top directories. 5 | set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/derulin/Downloads/twtxtc/twtxtc") 6 | set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/derulin/Downloads/twtxtc/twtxtc") 7 | 8 | # Force unix paths in dependencies. 9 | set(CMAKE_FORCE_UNIX_PATHS 1) 10 | 11 | 12 | # The C and CXX include file regular expressions for this directory. 13 | set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") 14 | set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") 15 | set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) 16 | set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) 17 | -------------------------------------------------------------------------------- /CMakeFiles/CMakeOutput.log: -------------------------------------------------------------------------------- 1 | The system is: Linux - 4.15.0-91-generic - x86_64 2 | Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded. 3 | Compiler: /usr/bin/cc 4 | Build flags: 5 | Id flags: 6 | 7 | The output was: 8 | 0 9 | 10 | 11 | Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "a.out" 12 | 13 | The C compiler identification is GNU, found in "/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/3.10.2/CompilerIdC/a.out" 14 | 15 | Determining if the C compiler works passed with the following output: 16 | Change Dir: /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp 17 | 18 | Run Build Command:"/usr/bin/make" "cmTC_a8be4/fast" 19 | /usr/bin/make -f CMakeFiles/cmTC_a8be4.dir/build.make CMakeFiles/cmTC_a8be4.dir/build 20 | make[1]: Entering directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp' 21 | Building C object CMakeFiles/cmTC_a8be4.dir/testCCompiler.c.o 22 | /usr/bin/cc -o CMakeFiles/cmTC_a8be4.dir/testCCompiler.c.o -c /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp/testCCompiler.c 23 | Linking C executable cmTC_a8be4 24 | /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_a8be4.dir/link.txt --verbose=1 25 | /usr/bin/cc CMakeFiles/cmTC_a8be4.dir/testCCompiler.c.o -o cmTC_a8be4 26 | make[1]: Leaving directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp' 27 | 28 | 29 | Detecting C compiler ABI info compiled with the following output: 30 | Change Dir: /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp 31 | 32 | Run Build Command:"/usr/bin/make" "cmTC_8a6e4/fast" 33 | /usr/bin/make -f CMakeFiles/cmTC_8a6e4.dir/build.make CMakeFiles/cmTC_8a6e4.dir/build 34 | make[1]: Entering directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp' 35 | Building C object CMakeFiles/cmTC_8a6e4.dir/CMakeCCompilerABI.c.o 36 | /usr/bin/cc -o CMakeFiles/cmTC_8a6e4.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake-3.10/Modules/CMakeCCompilerABI.c 37 | Linking C executable cmTC_8a6e4 38 | /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_8a6e4.dir/link.txt --verbose=1 39 | /usr/bin/cc -v CMakeFiles/cmTC_8a6e4.dir/CMakeCCompilerABI.c.o -o cmTC_8a6e4 40 | Using built-in specs. 41 | COLLECT_GCC=/usr/bin/cc 42 | COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper 43 | OFFLOAD_TARGET_NAMES=nvptx-none 44 | OFFLOAD_TARGET_DEFAULT=1 45 | Target: x86_64-linux-gnu 46 | Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu 47 | Thread model: posix 48 | gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) 49 | COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/ 50 | LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/ 51 | COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_8a6e4' '-mtune=generic' '-march=x86-64' 52 | /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/ccQJaotd.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_8a6e4 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. CMakeFiles/cmTC_8a6e4.dir/CMakeCCompilerABI.c.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o 53 | COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_8a6e4' '-mtune=generic' '-march=x86-64' 54 | make[1]: Leaving directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp' 55 | 56 | 57 | Parsed C implicit link information from above output: 58 | link line regex: [^( *|.*[/\])(ld|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)] 59 | ignore line: [Change Dir: /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp] 60 | ignore line: [] 61 | ignore line: [Run Build Command:"/usr/bin/make" "cmTC_8a6e4/fast"] 62 | ignore line: [/usr/bin/make -f CMakeFiles/cmTC_8a6e4.dir/build.make CMakeFiles/cmTC_8a6e4.dir/build] 63 | ignore line: [make[1]: Entering directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp'] 64 | ignore line: [Building C object CMakeFiles/cmTC_8a6e4.dir/CMakeCCompilerABI.c.o] 65 | ignore line: [/usr/bin/cc -o CMakeFiles/cmTC_8a6e4.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake-3.10/Modules/CMakeCCompilerABI.c] 66 | ignore line: [Linking C executable cmTC_8a6e4] 67 | ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_8a6e4.dir/link.txt --verbose=1] 68 | ignore line: [/usr/bin/cc -v CMakeFiles/cmTC_8a6e4.dir/CMakeCCompilerABI.c.o -o cmTC_8a6e4 ] 69 | ignore line: [Using built-in specs.] 70 | ignore line: [COLLECT_GCC=/usr/bin/cc] 71 | ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper] 72 | ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none] 73 | ignore line: [OFFLOAD_TARGET_DEFAULT=1] 74 | ignore line: [Target: x86_64-linux-gnu] 75 | ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] 76 | ignore line: [Thread model: posix] 77 | ignore line: [gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) ] 78 | ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/] 79 | ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/] 80 | ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_8a6e4' '-mtune=generic' '-march=x86-64'] 81 | link line: [ /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/ccQJaotd.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_8a6e4 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. CMakeFiles/cmTC_8a6e4.dir/CMakeCCompilerABI.c.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o] 82 | arg [/usr/lib/gcc/x86_64-linux-gnu/7/collect2] ==> ignore 83 | arg [-plugin] ==> ignore 84 | arg [/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so] ==> ignore 85 | arg [-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper] ==> ignore 86 | arg [-plugin-opt=-fresolution=/tmp/ccQJaotd.res] ==> ignore 87 | arg [-plugin-opt=-pass-through=-lgcc] ==> ignore 88 | arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore 89 | arg [-plugin-opt=-pass-through=-lc] ==> ignore 90 | arg [-plugin-opt=-pass-through=-lgcc] ==> ignore 91 | arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore 92 | arg [--build-id] ==> ignore 93 | arg [--eh-frame-hdr] ==> ignore 94 | arg [-m] ==> ignore 95 | arg [elf_x86_64] ==> ignore 96 | arg [--hash-style=gnu] ==> ignore 97 | arg [--as-needed] ==> ignore 98 | arg [-dynamic-linker] ==> ignore 99 | arg [/lib64/ld-linux-x86-64.so.2] ==> ignore 100 | arg [-pie] ==> ignore 101 | arg [-znow] ==> ignore 102 | arg [-zrelro] ==> ignore 103 | arg [-o] ==> ignore 104 | arg [cmTC_8a6e4] ==> ignore 105 | arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o] ==> ignore 106 | arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o] ==> ignore 107 | arg [/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o] ==> ignore 108 | arg [-L/usr/lib/gcc/x86_64-linux-gnu/7] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7] 109 | arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] 110 | arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] 111 | arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu] 112 | arg [-L/lib/../lib] ==> dir [/lib/../lib] 113 | arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu] 114 | arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] 115 | arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../..] 116 | arg [CMakeFiles/cmTC_8a6e4.dir/CMakeCCompilerABI.c.o] ==> ignore 117 | arg [-lgcc] ==> lib [gcc] 118 | arg [--push-state] ==> ignore 119 | arg [--as-needed] ==> ignore 120 | arg [-lgcc_s] ==> lib [gcc_s] 121 | arg [--pop-state] ==> ignore 122 | arg [-lc] ==> lib [c] 123 | arg [-lgcc] ==> lib [gcc] 124 | arg [--push-state] ==> ignore 125 | arg [--as-needed] ==> ignore 126 | arg [-lgcc_s] ==> lib [gcc_s] 127 | arg [--pop-state] ==> ignore 128 | arg [/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o] ==> ignore 129 | arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o] ==> ignore 130 | collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7] ==> [/usr/lib/gcc/x86_64-linux-gnu/7] 131 | collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] 132 | collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] ==> [/usr/lib] 133 | collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu] 134 | collapse library dir [/lib/../lib] ==> [/lib] 135 | collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] 136 | collapse library dir [/usr/lib/../lib] ==> [/usr/lib] 137 | collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../..] ==> [/usr/lib] 138 | implicit libs: [gcc;gcc_s;c;gcc;gcc_s] 139 | implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/7;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib] 140 | implicit fwks: [] 141 | 142 | 143 | 144 | 145 | Detecting C [-std=c11] compiler features compiled with the following output: 146 | Change Dir: /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp 147 | 148 | Run Build Command:"/usr/bin/make" "cmTC_c4d4a/fast" 149 | /usr/bin/make -f CMakeFiles/cmTC_c4d4a.dir/build.make CMakeFiles/cmTC_c4d4a.dir/build 150 | make[1]: Entering directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp' 151 | Building C object CMakeFiles/cmTC_c4d4a.dir/feature_tests.c.o 152 | /usr/bin/cc -std=c11 -o CMakeFiles/cmTC_c4d4a.dir/feature_tests.c.o -c /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/feature_tests.c 153 | Linking C executable cmTC_c4d4a 154 | /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_c4d4a.dir/link.txt --verbose=1 155 | /usr/bin/cc CMakeFiles/cmTC_c4d4a.dir/feature_tests.c.o -o cmTC_c4d4a 156 | make[1]: Leaving directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp' 157 | 158 | 159 | Feature record: C_FEATURE:1c_function_prototypes 160 | Feature record: C_FEATURE:1c_restrict 161 | Feature record: C_FEATURE:1c_static_assert 162 | Feature record: C_FEATURE:1c_variadic_macros 163 | 164 | 165 | Detecting C [-std=c99] compiler features compiled with the following output: 166 | Change Dir: /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp 167 | 168 | Run Build Command:"/usr/bin/make" "cmTC_70d9c/fast" 169 | /usr/bin/make -f CMakeFiles/cmTC_70d9c.dir/build.make CMakeFiles/cmTC_70d9c.dir/build 170 | make[1]: Entering directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp' 171 | Building C object CMakeFiles/cmTC_70d9c.dir/feature_tests.c.o 172 | /usr/bin/cc -std=c99 -o CMakeFiles/cmTC_70d9c.dir/feature_tests.c.o -c /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/feature_tests.c 173 | Linking C executable cmTC_70d9c 174 | /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_70d9c.dir/link.txt --verbose=1 175 | /usr/bin/cc CMakeFiles/cmTC_70d9c.dir/feature_tests.c.o -o cmTC_70d9c 176 | make[1]: Leaving directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp' 177 | 178 | 179 | Feature record: C_FEATURE:1c_function_prototypes 180 | Feature record: C_FEATURE:1c_restrict 181 | Feature record: C_FEATURE:0c_static_assert 182 | Feature record: C_FEATURE:1c_variadic_macros 183 | 184 | 185 | Detecting C [-std=c90] compiler features compiled with the following output: 186 | Change Dir: /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp 187 | 188 | Run Build Command:"/usr/bin/make" "cmTC_94296/fast" 189 | /usr/bin/make -f CMakeFiles/cmTC_94296.dir/build.make CMakeFiles/cmTC_94296.dir/build 190 | make[1]: Entering directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp' 191 | Building C object CMakeFiles/cmTC_94296.dir/feature_tests.c.o 192 | /usr/bin/cc -std=c90 -o CMakeFiles/cmTC_94296.dir/feature_tests.c.o -c /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/feature_tests.c 193 | Linking C executable cmTC_94296 194 | /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_94296.dir/link.txt --verbose=1 195 | /usr/bin/cc CMakeFiles/cmTC_94296.dir/feature_tests.c.o -o cmTC_94296 196 | make[1]: Leaving directory '/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/CMakeTmp' 197 | 198 | 199 | Feature record: C_FEATURE:1c_function_prototypes 200 | Feature record: C_FEATURE:0c_restrict 201 | Feature record: C_FEATURE:0c_static_assert 202 | Feature record: C_FEATURE:0c_variadic_macros 203 | -------------------------------------------------------------------------------- /CMakeFiles/Makefile.cmake: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.10 3 | 4 | # The generator used is: 5 | set(CMAKE_DEPENDS_GENERATOR "Unix Makefiles") 6 | 7 | # The top level Makefile was generated from the following files: 8 | set(CMAKE_MAKEFILE_DEPENDS 9 | "CMakeCache.txt" 10 | "CMakeFiles/3.10.2/CMakeCCompiler.cmake" 11 | "CMakeFiles/3.10.2/CMakeSystem.cmake" 12 | "CMakeFiles/feature_tests.c" 13 | "CMakeLists.txt" 14 | "/usr/share/cmake-3.10/Modules/CMakeCCompiler.cmake.in" 15 | "/usr/share/cmake-3.10/Modules/CMakeCCompilerABI.c" 16 | "/usr/share/cmake-3.10/Modules/CMakeCInformation.cmake" 17 | "/usr/share/cmake-3.10/Modules/CMakeCommonLanguageInclude.cmake" 18 | "/usr/share/cmake-3.10/Modules/CMakeCompilerIdDetection.cmake" 19 | "/usr/share/cmake-3.10/Modules/CMakeDetermineCCompiler.cmake" 20 | "/usr/share/cmake-3.10/Modules/CMakeDetermineCompileFeatures.cmake" 21 | "/usr/share/cmake-3.10/Modules/CMakeDetermineCompiler.cmake" 22 | "/usr/share/cmake-3.10/Modules/CMakeDetermineCompilerABI.cmake" 23 | "/usr/share/cmake-3.10/Modules/CMakeDetermineCompilerId.cmake" 24 | "/usr/share/cmake-3.10/Modules/CMakeDetermineSystem.cmake" 25 | "/usr/share/cmake-3.10/Modules/CMakeFindBinUtils.cmake" 26 | "/usr/share/cmake-3.10/Modules/CMakeGenericSystem.cmake" 27 | "/usr/share/cmake-3.10/Modules/CMakeLanguageInformation.cmake" 28 | "/usr/share/cmake-3.10/Modules/CMakeParseImplicitLinkInfo.cmake" 29 | "/usr/share/cmake-3.10/Modules/CMakeSystem.cmake.in" 30 | "/usr/share/cmake-3.10/Modules/CMakeSystemSpecificInformation.cmake" 31 | "/usr/share/cmake-3.10/Modules/CMakeSystemSpecificInitialize.cmake" 32 | "/usr/share/cmake-3.10/Modules/CMakeTestCCompiler.cmake" 33 | "/usr/share/cmake-3.10/Modules/CMakeTestCompilerCommon.cmake" 34 | "/usr/share/cmake-3.10/Modules/CMakeUnixFindMake.cmake" 35 | "/usr/share/cmake-3.10/Modules/Compiler/ADSP-DetermineCompiler.cmake" 36 | "/usr/share/cmake-3.10/Modules/Compiler/ARMCC-DetermineCompiler.cmake" 37 | "/usr/share/cmake-3.10/Modules/Compiler/AppleClang-DetermineCompiler.cmake" 38 | "/usr/share/cmake-3.10/Modules/Compiler/Borland-DetermineCompiler.cmake" 39 | "/usr/share/cmake-3.10/Modules/Compiler/Bruce-C-DetermineCompiler.cmake" 40 | "/usr/share/cmake-3.10/Modules/Compiler/CMakeCommonCompilerMacros.cmake" 41 | "/usr/share/cmake-3.10/Modules/Compiler/Clang-DetermineCompiler.cmake" 42 | "/usr/share/cmake-3.10/Modules/Compiler/Clang-DetermineCompilerInternal.cmake" 43 | "/usr/share/cmake-3.10/Modules/Compiler/Compaq-C-DetermineCompiler.cmake" 44 | "/usr/share/cmake-3.10/Modules/Compiler/Cray-DetermineCompiler.cmake" 45 | "/usr/share/cmake-3.10/Modules/Compiler/Embarcadero-DetermineCompiler.cmake" 46 | "/usr/share/cmake-3.10/Modules/Compiler/Fujitsu-DetermineCompiler.cmake" 47 | "/usr/share/cmake-3.10/Modules/Compiler/GHS-DetermineCompiler.cmake" 48 | "/usr/share/cmake-3.10/Modules/Compiler/GNU-C-DetermineCompiler.cmake" 49 | "/usr/share/cmake-3.10/Modules/Compiler/GNU-C-FeatureTests.cmake" 50 | "/usr/share/cmake-3.10/Modules/Compiler/GNU-C.cmake" 51 | "/usr/share/cmake-3.10/Modules/Compiler/GNU-FindBinUtils.cmake" 52 | "/usr/share/cmake-3.10/Modules/Compiler/GNU.cmake" 53 | "/usr/share/cmake-3.10/Modules/Compiler/HP-C-DetermineCompiler.cmake" 54 | "/usr/share/cmake-3.10/Modules/Compiler/IAR-DetermineCompiler.cmake" 55 | "/usr/share/cmake-3.10/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake" 56 | "/usr/share/cmake-3.10/Modules/Compiler/Intel-DetermineCompiler.cmake" 57 | "/usr/share/cmake-3.10/Modules/Compiler/MIPSpro-DetermineCompiler.cmake" 58 | "/usr/share/cmake-3.10/Modules/Compiler/MSVC-DetermineCompiler.cmake" 59 | "/usr/share/cmake-3.10/Modules/Compiler/NVIDIA-DetermineCompiler.cmake" 60 | "/usr/share/cmake-3.10/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake" 61 | "/usr/share/cmake-3.10/Modules/Compiler/PGI-DetermineCompiler.cmake" 62 | "/usr/share/cmake-3.10/Modules/Compiler/PathScale-DetermineCompiler.cmake" 63 | "/usr/share/cmake-3.10/Modules/Compiler/SCO-DetermineCompiler.cmake" 64 | "/usr/share/cmake-3.10/Modules/Compiler/SDCC-C-DetermineCompiler.cmake" 65 | "/usr/share/cmake-3.10/Modules/Compiler/SunPro-C-DetermineCompiler.cmake" 66 | "/usr/share/cmake-3.10/Modules/Compiler/TI-DetermineCompiler.cmake" 67 | "/usr/share/cmake-3.10/Modules/Compiler/TinyCC-C-DetermineCompiler.cmake" 68 | "/usr/share/cmake-3.10/Modules/Compiler/VisualAge-C-DetermineCompiler.cmake" 69 | "/usr/share/cmake-3.10/Modules/Compiler/Watcom-DetermineCompiler.cmake" 70 | "/usr/share/cmake-3.10/Modules/Compiler/XL-C-DetermineCompiler.cmake" 71 | "/usr/share/cmake-3.10/Modules/Compiler/zOS-C-DetermineCompiler.cmake" 72 | "/usr/share/cmake-3.10/Modules/Internal/FeatureTesting.cmake" 73 | "/usr/share/cmake-3.10/Modules/Platform/Linux-GNU-C.cmake" 74 | "/usr/share/cmake-3.10/Modules/Platform/Linux-GNU.cmake" 75 | "/usr/share/cmake-3.10/Modules/Platform/Linux.cmake" 76 | "/usr/share/cmake-3.10/Modules/Platform/UnixPaths.cmake" 77 | ) 78 | 79 | # The corresponding makefile is: 80 | set(CMAKE_MAKEFILE_OUTPUTS 81 | "Makefile" 82 | "CMakeFiles/cmake.check_cache" 83 | ) 84 | 85 | # Byproducts of CMake generate step: 86 | set(CMAKE_MAKEFILE_PRODUCTS 87 | "CMakeFiles/3.10.2/CMakeSystem.cmake" 88 | "CMakeFiles/3.10.2/CMakeCCompiler.cmake" 89 | "CMakeFiles/3.10.2/CMakeCCompiler.cmake" 90 | "CMakeFiles/CMakeDirectoryInformation.cmake" 91 | ) 92 | 93 | # Dependency information for all targets: 94 | set(CMAKE_DEPEND_INFO_FILES 95 | "CMakeFiles/twtxtc.dir/DependInfo.cmake" 96 | ) 97 | -------------------------------------------------------------------------------- /CMakeFiles/Makefile2: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.10 3 | 4 | # Default target executed when no arguments are given to make. 5 | default_target: all 6 | 7 | .PHONY : default_target 8 | 9 | # The main recursive all target 10 | all: 11 | 12 | .PHONY : all 13 | 14 | # The main recursive preinstall target 15 | preinstall: 16 | 17 | .PHONY : preinstall 18 | 19 | #============================================================================= 20 | # Special targets provided by cmake. 21 | 22 | # Disable implicit rules so canonical targets will work. 23 | .SUFFIXES: 24 | 25 | 26 | # Remove some rules from gmake that .SUFFIXES does not remove. 27 | SUFFIXES = 28 | 29 | .SUFFIXES: .hpux_make_needs_suffix_list 30 | 31 | 32 | # Suppress display of executed commands. 33 | $(VERBOSE).SILENT: 34 | 35 | 36 | # A target that is always out of date. 37 | cmake_force: 38 | 39 | .PHONY : cmake_force 40 | 41 | #============================================================================= 42 | # Set environment variables for the build. 43 | 44 | # The shell in which to execute make rules. 45 | SHELL = /bin/sh 46 | 47 | # The CMake executable. 48 | CMAKE_COMMAND = /usr/bin/cmake 49 | 50 | # The command to remove a file. 51 | RM = /usr/bin/cmake -E remove -f 52 | 53 | # Escaping for special characters. 54 | EQUALS = = 55 | 56 | # The top-level source directory on which CMake was run. 57 | CMAKE_SOURCE_DIR = /home/derulin/Downloads/twtxtc/twtxtc 58 | 59 | # The top-level build directory on which CMake was run. 60 | CMAKE_BINARY_DIR = /home/derulin/Downloads/twtxtc/twtxtc 61 | 62 | #============================================================================= 63 | # Target rules for target CMakeFiles/twtxtc.dir 64 | 65 | # All Build rule for target. 66 | CMakeFiles/twtxtc.dir/all: 67 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/depend 68 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/build 69 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --progress-dir=/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles --progress-num=1,2,3,4 "Built target twtxtc" 70 | .PHONY : CMakeFiles/twtxtc.dir/all 71 | 72 | # Include target in all. 73 | all: CMakeFiles/twtxtc.dir/all 74 | 75 | .PHONY : all 76 | 77 | # Build rule for subdir invocation for target. 78 | CMakeFiles/twtxtc.dir/rule: cmake_check_build_system 79 | $(CMAKE_COMMAND) -E cmake_progress_start /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles 4 80 | $(MAKE) -f CMakeFiles/Makefile2 CMakeFiles/twtxtc.dir/all 81 | $(CMAKE_COMMAND) -E cmake_progress_start /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles 0 82 | .PHONY : CMakeFiles/twtxtc.dir/rule 83 | 84 | # Convenience name for target. 85 | twtxtc: CMakeFiles/twtxtc.dir/rule 86 | 87 | .PHONY : twtxtc 88 | 89 | # clean rule for target. 90 | CMakeFiles/twtxtc.dir/clean: 91 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/clean 92 | .PHONY : CMakeFiles/twtxtc.dir/clean 93 | 94 | # clean rule for target. 95 | clean: CMakeFiles/twtxtc.dir/clean 96 | 97 | .PHONY : clean 98 | 99 | #============================================================================= 100 | # Special targets to cleanup operation of make. 101 | 102 | # Special rule to run CMake to check the build system integrity. 103 | # No rule that depends on this can have commands that come from listfiles 104 | # because they might be regenerated. 105 | cmake_check_build_system: 106 | $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 107 | .PHONY : cmake_check_build_system 108 | 109 | -------------------------------------------------------------------------------- /CMakeFiles/TargetDirectories.txt: -------------------------------------------------------------------------------- 1 | /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/rebuild_cache.dir 2 | /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/twtxtc.dir 3 | /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/edit_cache.dir 4 | -------------------------------------------------------------------------------- /CMakeFiles/cmake.check_cache: -------------------------------------------------------------------------------- 1 | # This file is generated by cmake for dependency checking of the CMakeCache.txt file 2 | -------------------------------------------------------------------------------- /CMakeFiles/feature_tests.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neauoire/twtxtc/b1315b02c794b4429011f5f7565d574b452b529d/CMakeFiles/feature_tests.bin -------------------------------------------------------------------------------- /CMakeFiles/feature_tests.c: -------------------------------------------------------------------------------- 1 | 2 | const char features[] = {"\n" 3 | "C_FEATURE:" 4 | #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 304 5 | "1" 6 | #else 7 | "0" 8 | #endif 9 | "c_function_prototypes\n" 10 | "C_FEATURE:" 11 | #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 304 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 12 | "1" 13 | #else 14 | "0" 15 | #endif 16 | "c_restrict\n" 17 | "C_FEATURE:" 18 | #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201000L 19 | "1" 20 | #else 21 | "0" 22 | #endif 23 | "c_static_assert\n" 24 | "C_FEATURE:" 25 | #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 304 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 26 | "1" 27 | #else 28 | "0" 29 | #endif 30 | "c_variadic_macros\n" 31 | 32 | }; 33 | 34 | int main(int argc, char** argv) { (void)argv; return features[argc]; } 35 | -------------------------------------------------------------------------------- /CMakeFiles/progress.marks: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/C.includecache: -------------------------------------------------------------------------------- 1 | #IncludeRegexLine: ^[ ]*[#%][ ]*(include|import)[ ]*[<"]([^">]+)([">]) 2 | 3 | #IncludeRegexScan: ^.*$ 4 | 5 | #IncludeRegexComplain: ^$ 6 | 7 | #IncludeRegexTransform: 8 | 9 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.c 10 | string.h 11 | - 12 | stdio.h 13 | - 14 | math.h 15 | - 16 | stdlib.h 17 | - 18 | float.h 19 | - 20 | limits.h 21 | - 22 | ctype.h 23 | - 24 | locale.h 25 | - 26 | cJSON.h 27 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.h 28 | 29 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.h 30 | stddef.h 31 | - 32 | 33 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.c 34 | ctype.h 35 | - 36 | string.h 37 | - 38 | stdlib.h 39 | - 40 | stdio.h 41 | - 42 | limits.h 43 | - 44 | cJSON_Utils.h 45 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.h 46 | 47 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.h 48 | cJSON.h 49 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.h 50 | 51 | /home/derulin/Downloads/twtxtc/twtxtc/twtxt.c 52 | stdlib.h 53 | - 54 | stdio.h 55 | - 56 | string.h 57 | - 58 | time.h 59 | - 60 | sys/param.h 61 | - 62 | errno.h 63 | - 64 | windows.h 65 | - 66 | cJSON/cJSON.h 67 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.h 68 | cJSON/cJSON_Utils.h 69 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.h 70 | twtxt.h 71 | /home/derulin/Downloads/twtxtc/twtxtc/twtxt.h 72 | 73 | /home/derulin/Downloads/twtxtc/twtxtc/twtxt.h 74 | time.h 75 | - 76 | cJSON/cJSON.h 77 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.h 78 | stdlib.h 79 | - 80 | 81 | -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/DependInfo.cmake: -------------------------------------------------------------------------------- 1 | # The set of languages for which implicit dependencies are needed: 2 | set(CMAKE_DEPENDS_LANGUAGES 3 | "C" 4 | ) 5 | # The set of files for implicit dependencies of each language: 6 | set(CMAKE_DEPENDS_CHECK_C 7 | "/home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.c" "/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o" 8 | "/home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.c" "/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o" 9 | "/home/derulin/Downloads/twtxtc/twtxtc/twtxt.c" "/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/twtxtc.dir/twtxt.c.o" 10 | ) 11 | set(CMAKE_C_COMPILER_ID "GNU") 12 | 13 | # The include file search paths: 14 | set(CMAKE_C_TARGET_INCLUDE_PATH 15 | ) 16 | 17 | # Targets to which this target links. 18 | set(CMAKE_TARGET_LINKED_INFO_FILES 19 | ) 20 | 21 | # Fortran module output directory. 22 | set(CMAKE_Fortran_TARGET_MODULE_DIR "") 23 | -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/build.make: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.10 3 | 4 | # Delete rule output on recipe failure. 5 | .DELETE_ON_ERROR: 6 | 7 | 8 | #============================================================================= 9 | # Special targets provided by cmake. 10 | 11 | # Disable implicit rules so canonical targets will work. 12 | .SUFFIXES: 13 | 14 | 15 | # Remove some rules from gmake that .SUFFIXES does not remove. 16 | SUFFIXES = 17 | 18 | .SUFFIXES: .hpux_make_needs_suffix_list 19 | 20 | 21 | # Suppress display of executed commands. 22 | $(VERBOSE).SILENT: 23 | 24 | 25 | # A target that is always out of date. 26 | cmake_force: 27 | 28 | .PHONY : cmake_force 29 | 30 | #============================================================================= 31 | # Set environment variables for the build. 32 | 33 | # The shell in which to execute make rules. 34 | SHELL = /bin/sh 35 | 36 | # The CMake executable. 37 | CMAKE_COMMAND = /usr/bin/cmake 38 | 39 | # The command to remove a file. 40 | RM = /usr/bin/cmake -E remove -f 41 | 42 | # Escaping for special characters. 43 | EQUALS = = 44 | 45 | # The top-level source directory on which CMake was run. 46 | CMAKE_SOURCE_DIR = /home/derulin/Downloads/twtxtc/twtxtc 47 | 48 | # The top-level build directory on which CMake was run. 49 | CMAKE_BINARY_DIR = /home/derulin/Downloads/twtxtc/twtxtc 50 | 51 | # Include any dependencies generated for this target. 52 | include CMakeFiles/twtxtc.dir/depend.make 53 | 54 | # Include the progress variables for this target. 55 | include CMakeFiles/twtxtc.dir/progress.make 56 | 57 | # Include the compile flags for this target's objects. 58 | include CMakeFiles/twtxtc.dir/flags.make 59 | 60 | CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o: CMakeFiles/twtxtc.dir/flags.make 61 | CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o: cJSON/cJSON.c 62 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building C object CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o" 63 | /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -o CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o -c /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.c 64 | 65 | CMakeFiles/twtxtc.dir/cJSON/cJSON.c.i: cmake_force 66 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/twtxtc.dir/cJSON/cJSON.c.i" 67 | /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.c > CMakeFiles/twtxtc.dir/cJSON/cJSON.c.i 68 | 69 | CMakeFiles/twtxtc.dir/cJSON/cJSON.c.s: cmake_force 70 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/twtxtc.dir/cJSON/cJSON.c.s" 71 | /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.c -o CMakeFiles/twtxtc.dir/cJSON/cJSON.c.s 72 | 73 | CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o.requires: 74 | 75 | .PHONY : CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o.requires 76 | 77 | CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o.provides: CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o.requires 78 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o.provides.build 79 | .PHONY : CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o.provides 80 | 81 | CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o.provides.build: CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o 82 | 83 | 84 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o: CMakeFiles/twtxtc.dir/flags.make 85 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o: cJSON/cJSON_Utils.c 86 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building C object CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o" 87 | /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -o CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o -c /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.c 88 | 89 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.i: cmake_force 90 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.i" 91 | /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.c > CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.i 92 | 93 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.s: cmake_force 94 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.s" 95 | /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.c -o CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.s 96 | 97 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o.requires: 98 | 99 | .PHONY : CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o.requires 100 | 101 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o.provides: CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o.requires 102 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o.provides.build 103 | .PHONY : CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o.provides 104 | 105 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o.provides.build: CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o 106 | 107 | 108 | CMakeFiles/twtxtc.dir/twtxt.c.o: CMakeFiles/twtxtc.dir/flags.make 109 | CMakeFiles/twtxtc.dir/twtxt.c.o: twtxt.c 110 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Building C object CMakeFiles/twtxtc.dir/twtxt.c.o" 111 | /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -o CMakeFiles/twtxtc.dir/twtxt.c.o -c /home/derulin/Downloads/twtxtc/twtxtc/twtxt.c 112 | 113 | CMakeFiles/twtxtc.dir/twtxt.c.i: cmake_force 114 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/twtxtc.dir/twtxt.c.i" 115 | /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/derulin/Downloads/twtxtc/twtxtc/twtxt.c > CMakeFiles/twtxtc.dir/twtxt.c.i 116 | 117 | CMakeFiles/twtxtc.dir/twtxt.c.s: cmake_force 118 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/twtxtc.dir/twtxt.c.s" 119 | /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/derulin/Downloads/twtxtc/twtxtc/twtxt.c -o CMakeFiles/twtxtc.dir/twtxt.c.s 120 | 121 | CMakeFiles/twtxtc.dir/twtxt.c.o.requires: 122 | 123 | .PHONY : CMakeFiles/twtxtc.dir/twtxt.c.o.requires 124 | 125 | CMakeFiles/twtxtc.dir/twtxt.c.o.provides: CMakeFiles/twtxtc.dir/twtxt.c.o.requires 126 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/twtxt.c.o.provides.build 127 | .PHONY : CMakeFiles/twtxtc.dir/twtxt.c.o.provides 128 | 129 | CMakeFiles/twtxtc.dir/twtxt.c.o.provides.build: CMakeFiles/twtxtc.dir/twtxt.c.o 130 | 131 | 132 | # Object files for target twtxtc 133 | twtxtc_OBJECTS = \ 134 | "CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o" \ 135 | "CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o" \ 136 | "CMakeFiles/twtxtc.dir/twtxt.c.o" 137 | 138 | # External object files for target twtxtc 139 | twtxtc_EXTERNAL_OBJECTS = 140 | 141 | twtxtc: CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o 142 | twtxtc: CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o 143 | twtxtc: CMakeFiles/twtxtc.dir/twtxt.c.o 144 | twtxtc: CMakeFiles/twtxtc.dir/build.make 145 | twtxtc: CMakeFiles/twtxtc.dir/link.txt 146 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles --progress-num=$(CMAKE_PROGRESS_4) "Linking C executable twtxtc" 147 | $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/twtxtc.dir/link.txt --verbose=$(VERBOSE) 148 | 149 | # Rule to build all files generated by this target. 150 | CMakeFiles/twtxtc.dir/build: twtxtc 151 | 152 | .PHONY : CMakeFiles/twtxtc.dir/build 153 | 154 | CMakeFiles/twtxtc.dir/requires: CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o.requires 155 | CMakeFiles/twtxtc.dir/requires: CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o.requires 156 | CMakeFiles/twtxtc.dir/requires: CMakeFiles/twtxtc.dir/twtxt.c.o.requires 157 | 158 | .PHONY : CMakeFiles/twtxtc.dir/requires 159 | 160 | CMakeFiles/twtxtc.dir/clean: 161 | $(CMAKE_COMMAND) -P CMakeFiles/twtxtc.dir/cmake_clean.cmake 162 | .PHONY : CMakeFiles/twtxtc.dir/clean 163 | 164 | CMakeFiles/twtxtc.dir/depend: 165 | cd /home/derulin/Downloads/twtxtc/twtxtc && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/derulin/Downloads/twtxtc/twtxtc /home/derulin/Downloads/twtxtc/twtxtc /home/derulin/Downloads/twtxtc/twtxtc /home/derulin/Downloads/twtxtc/twtxtc /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/twtxtc.dir/DependInfo.cmake --color=$(COLOR) 166 | .PHONY : CMakeFiles/twtxtc.dir/depend 167 | 168 | -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neauoire/twtxtc/b1315b02c794b4429011f5f7565d574b452b529d/CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neauoire/twtxtc/b1315b02c794b4429011f5f7565d574b452b529d/CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/cmake_clean.cmake: -------------------------------------------------------------------------------- 1 | file(REMOVE_RECURSE 2 | "CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o" 3 | "CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o" 4 | "CMakeFiles/twtxtc.dir/twtxt.c.o" 5 | "twtxtc.pdb" 6 | "twtxtc" 7 | ) 8 | 9 | # Per-language clean rules from dependency scanning. 10 | foreach(lang C) 11 | include(CMakeFiles/twtxtc.dir/cmake_clean_${lang}.cmake OPTIONAL) 12 | endforeach() 13 | -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/depend.internal: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.10 3 | 4 | CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o 5 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.c 6 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.h 7 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o 8 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.h 9 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.c 10 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.h 11 | CMakeFiles/twtxtc.dir/twtxt.c.o 12 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON.h 13 | /home/derulin/Downloads/twtxtc/twtxtc/cJSON/cJSON_Utils.h 14 | /home/derulin/Downloads/twtxtc/twtxtc/twtxt.c 15 | /home/derulin/Downloads/twtxtc/twtxtc/twtxt.h 16 | -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/depend.make: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.10 3 | 4 | CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o: cJSON/cJSON.c 5 | CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o: cJSON/cJSON.h 6 | 7 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o: cJSON/cJSON.h 8 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o: cJSON/cJSON_Utils.c 9 | CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o: cJSON/cJSON_Utils.h 10 | 11 | CMakeFiles/twtxtc.dir/twtxt.c.o: cJSON/cJSON.h 12 | CMakeFiles/twtxtc.dir/twtxt.c.o: cJSON/cJSON_Utils.h 13 | CMakeFiles/twtxtc.dir/twtxt.c.o: twtxt.c 14 | CMakeFiles/twtxtc.dir/twtxt.c.o: twtxt.h 15 | 16 | -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/flags.make: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.10 3 | 4 | # compile C with /usr/bin/cc 5 | C_FLAGS = -O3 -DNDEBUG -std=gnu11 6 | 7 | C_DEFINES = 8 | 9 | C_INCLUDES = 10 | 11 | -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/link.txt: -------------------------------------------------------------------------------- 1 | /usr/bin/cc -O3 -DNDEBUG CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o CMakeFiles/twtxtc.dir/twtxt.c.o -o twtxtc 2 | -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/progress.make: -------------------------------------------------------------------------------- 1 | CMAKE_PROGRESS_1 = 1 2 | CMAKE_PROGRESS_2 = 2 3 | CMAKE_PROGRESS_3 = 3 4 | CMAKE_PROGRESS_4 = 4 5 | 6 | -------------------------------------------------------------------------------- /CMakeFiles/twtxtc.dir/twtxt.c.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neauoire/twtxtc/b1315b02c794b4429011f5f7565d574b452b529d/CMakeFiles/twtxtc.dir/twtxt.c.o -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(twtxtc C) 3 | 4 | set(CMAKE_BUILD_TYPE Release) 5 | set(CMAKE_C_STANDARD 11) 6 | 7 | if (MSVC) 8 | # meh 9 | add_definitions(-D_CRT_SECURE_NO_WARNINGS) 10 | endif (MSVC) 11 | 12 | add_executable(twtxtc cJSON/cJSON.c cJSON/cJSON_Utils.c twtxt.c) 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2017 Cthulhux 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.10 3 | 4 | # Default target executed when no arguments are given to make. 5 | default_target: all 6 | 7 | .PHONY : default_target 8 | 9 | # Allow only one "make -f Makefile2" at a time, but pass parallelism. 10 | .NOTPARALLEL: 11 | 12 | 13 | #============================================================================= 14 | # Special targets provided by cmake. 15 | 16 | # Disable implicit rules so canonical targets will work. 17 | .SUFFIXES: 18 | 19 | 20 | # Remove some rules from gmake that .SUFFIXES does not remove. 21 | SUFFIXES = 22 | 23 | .SUFFIXES: .hpux_make_needs_suffix_list 24 | 25 | 26 | # Suppress display of executed commands. 27 | $(VERBOSE).SILENT: 28 | 29 | 30 | # A target that is always out of date. 31 | cmake_force: 32 | 33 | .PHONY : cmake_force 34 | 35 | #============================================================================= 36 | # Set environment variables for the build. 37 | 38 | # The shell in which to execute make rules. 39 | SHELL = /bin/sh 40 | 41 | # The CMake executable. 42 | CMAKE_COMMAND = /usr/bin/cmake 43 | 44 | # The command to remove a file. 45 | RM = /usr/bin/cmake -E remove -f 46 | 47 | # Escaping for special characters. 48 | EQUALS = = 49 | 50 | # The top-level source directory on which CMake was run. 51 | CMAKE_SOURCE_DIR = /home/derulin/Downloads/twtxtc/twtxtc 52 | 53 | # The top-level build directory on which CMake was run. 54 | CMAKE_BINARY_DIR = /home/derulin/Downloads/twtxtc/twtxtc 55 | 56 | #============================================================================= 57 | # Targets provided globally by CMake. 58 | 59 | # Special rule for the target rebuild_cache 60 | rebuild_cache: 61 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." 62 | /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) 63 | .PHONY : rebuild_cache 64 | 65 | # Special rule for the target rebuild_cache 66 | rebuild_cache/fast: rebuild_cache 67 | 68 | .PHONY : rebuild_cache/fast 69 | 70 | # Special rule for the target edit_cache 71 | edit_cache: 72 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..." 73 | /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available. 74 | .PHONY : edit_cache 75 | 76 | # Special rule for the target edit_cache 77 | edit_cache/fast: edit_cache 78 | 79 | .PHONY : edit_cache/fast 80 | 81 | # The main all target 82 | all: cmake_check_build_system 83 | $(CMAKE_COMMAND) -E cmake_progress_start /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles/progress.marks 84 | $(MAKE) -f CMakeFiles/Makefile2 all 85 | $(CMAKE_COMMAND) -E cmake_progress_start /home/derulin/Downloads/twtxtc/twtxtc/CMakeFiles 0 86 | .PHONY : all 87 | 88 | # The main clean target 89 | clean: 90 | $(MAKE) -f CMakeFiles/Makefile2 clean 91 | .PHONY : clean 92 | 93 | # The main clean target 94 | clean/fast: clean 95 | 96 | .PHONY : clean/fast 97 | 98 | # Prepare targets for installation. 99 | preinstall: all 100 | $(MAKE) -f CMakeFiles/Makefile2 preinstall 101 | .PHONY : preinstall 102 | 103 | # Prepare targets for installation. 104 | preinstall/fast: 105 | $(MAKE) -f CMakeFiles/Makefile2 preinstall 106 | .PHONY : preinstall/fast 107 | 108 | # clear depends 109 | depend: 110 | $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 111 | .PHONY : depend 112 | 113 | #============================================================================= 114 | # Target rules for targets named twtxtc 115 | 116 | # Build rule for target. 117 | twtxtc: cmake_check_build_system 118 | $(MAKE) -f CMakeFiles/Makefile2 twtxtc 119 | .PHONY : twtxtc 120 | 121 | # fast build rule for target. 122 | twtxtc/fast: 123 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/build 124 | .PHONY : twtxtc/fast 125 | 126 | cJSON/cJSON.o: cJSON/cJSON.c.o 127 | 128 | .PHONY : cJSON/cJSON.o 129 | 130 | # target to build an object file 131 | cJSON/cJSON.c.o: 132 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/cJSON/cJSON.c.o 133 | .PHONY : cJSON/cJSON.c.o 134 | 135 | cJSON/cJSON.i: cJSON/cJSON.c.i 136 | 137 | .PHONY : cJSON/cJSON.i 138 | 139 | # target to preprocess a source file 140 | cJSON/cJSON.c.i: 141 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/cJSON/cJSON.c.i 142 | .PHONY : cJSON/cJSON.c.i 143 | 144 | cJSON/cJSON.s: cJSON/cJSON.c.s 145 | 146 | .PHONY : cJSON/cJSON.s 147 | 148 | # target to generate assembly for a file 149 | cJSON/cJSON.c.s: 150 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/cJSON/cJSON.c.s 151 | .PHONY : cJSON/cJSON.c.s 152 | 153 | cJSON/cJSON_Utils.o: cJSON/cJSON_Utils.c.o 154 | 155 | .PHONY : cJSON/cJSON_Utils.o 156 | 157 | # target to build an object file 158 | cJSON/cJSON_Utils.c.o: 159 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.o 160 | .PHONY : cJSON/cJSON_Utils.c.o 161 | 162 | cJSON/cJSON_Utils.i: cJSON/cJSON_Utils.c.i 163 | 164 | .PHONY : cJSON/cJSON_Utils.i 165 | 166 | # target to preprocess a source file 167 | cJSON/cJSON_Utils.c.i: 168 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.i 169 | .PHONY : cJSON/cJSON_Utils.c.i 170 | 171 | cJSON/cJSON_Utils.s: cJSON/cJSON_Utils.c.s 172 | 173 | .PHONY : cJSON/cJSON_Utils.s 174 | 175 | # target to generate assembly for a file 176 | cJSON/cJSON_Utils.c.s: 177 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/cJSON/cJSON_Utils.c.s 178 | .PHONY : cJSON/cJSON_Utils.c.s 179 | 180 | twtxt.o: twtxt.c.o 181 | 182 | .PHONY : twtxt.o 183 | 184 | # target to build an object file 185 | twtxt.c.o: 186 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/twtxt.c.o 187 | .PHONY : twtxt.c.o 188 | 189 | twtxt.i: twtxt.c.i 190 | 191 | .PHONY : twtxt.i 192 | 193 | # target to preprocess a source file 194 | twtxt.c.i: 195 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/twtxt.c.i 196 | .PHONY : twtxt.c.i 197 | 198 | twtxt.s: twtxt.c.s 199 | 200 | .PHONY : twtxt.s 201 | 202 | # target to generate assembly for a file 203 | twtxt.c.s: 204 | $(MAKE) -f CMakeFiles/twtxtc.dir/build.make CMakeFiles/twtxtc.dir/twtxt.c.s 205 | .PHONY : twtxt.c.s 206 | 207 | # Help Target 208 | help: 209 | @echo "The following are some of the valid targets for this Makefile:" 210 | @echo "... all (the default if no target is provided)" 211 | @echo "... clean" 212 | @echo "... depend" 213 | @echo "... rebuild_cache" 214 | @echo "... twtxtc" 215 | @echo "... edit_cache" 216 | @echo "... cJSON/cJSON.o" 217 | @echo "... cJSON/cJSON.i" 218 | @echo "... cJSON/cJSON.s" 219 | @echo "... cJSON/cJSON_Utils.o" 220 | @echo "... cJSON/cJSON_Utils.i" 221 | @echo "... cJSON/cJSON_Utils.s" 222 | @echo "... twtxt.o" 223 | @echo "... twtxt.i" 224 | @echo "... twtxt.s" 225 | .PHONY : help 226 | 227 | 228 | 229 | #============================================================================= 230 | # Special targets to cleanup operation of make. 231 | 232 | # Special rule to run CMake to check the build system integrity. 233 | # No rule that depends on this can have commands that come from listfiles 234 | # because they might be regenerated. 235 | cmake_check_build_system: 236 | $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 237 | .PHONY : cmake_check_build_system 238 | 239 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # twtxtc: A twtxt client in C. 2 | 3 | ## What is `twtxt`? 4 | 5 | `twtxt` is a decentralised, minimalist approach to micro-blogging, similar to Twitter but with self-hosted plaintext files. See the [original `twtxt` documentation](http://twtxt.readthedocs.io/en/latest/) for details. `twtxtc` is a `twtxt` client written in the C language. 6 | 7 | ## Requirements 8 | 9 | Build or download an appropriate [`curl` binary](https://curl.haxx.se/download.html) for your system and place it into your `$PATH` or the `twtxtc` folder. If you don't, you won't be able to retrieve your timeline. Sorry. 10 | 11 | ## Usage 12 | 13 | ./twtxtc [COMMAND] 14 | 15 | ### Commands 16 | 17 | tweet Adds to your twtxt timeline. 18 | timeline Displays your twtxt timeline. 19 | following Gives you a list of all people you follow. 20 | follow Adds the twtxt file from to your timeline. 21 | defines the user name to display. 22 | unfollow Removes the user with the display name from your timeline. 23 | help Displays a help screen. 24 | 25 | ## Building 26 | 27 | Use `cmake` to build `twtxtc`: 28 | 29 | cd path/to/source 30 | cmake . 31 | cmake --build . 32 | 33 | This should be all. 34 | 35 | ### Compiler flags 36 | 37 | For lazyness reasons, `twtxtc` only uses colors in the most prominent place, namely in the timeline: By default you will get an adequate combination of yellow and white in the list. If you don't want to have such nice colors because you prefer boring plain text (and/or you want to process the output automatically), you can use the `NO_COLORS` compiler flag to disable them. 38 | 39 | ## Configuration 40 | 41 | If found, `twtxtc` will use the `.twtxtconfig` file inside your `HOME` directory. (See `twtxtc help` for information on where it should be found.) The `.twtxtconfig` file is meant to be a valid JSON file like this: 42 | 43 | { 44 | "nickname": "your nickname", 45 | "twtxtfile": "twtxt.txt", 46 | "maxlog": 100, 47 | "spacing": " ", 48 | "following": { 49 | "user_1": "https://example.com/twtxt.txt", 50 | "user_2": "https://elsewhere.com/tweets.txt" 51 | } 52 | } 53 | 54 | Possible entries are: 55 | 56 | * `nickname`: Your preferred nickname. Only used to filter mentions to other people. 57 | * `twtxtfile`: The location of your `twtxt.txt` file. Defaults to `./twtxt.txt`. 58 | * `maxlog`: The maximum number of entries shown when you view your timeline. Defaults to 100. 59 | * `spacing`: A string value that contains the spacing between the user name and the text when viewing your timeline. Defaults to three spaces. 60 | * `following`: A list of users you follow. Can be managed with the `follow` and `unfollow` commands. 61 | 62 | The current limit of the list of users you are following is at 4 KiB. You probably won't reach that limit any time soon. 63 | 64 | ## TODO 65 | 66 | * I'd really like to have Unicode support in `twtxtc`. 67 | * Mentions *could* be made more obvious, e.g. bold formatting or so. 68 | 69 | ## Licenses 70 | 71 | `twtxtc` is licensed under the terms of the [WTFPL](http://wtfpl.net/txt/copying). It uses the lovely [`cJSON`](https://github.com/DaveGamble/cJSON/) library for certain functionalities, basically following the terms of the MIT license. Please read the particular `LICENSE` documents and/or the header files in case you are interested. 72 | -------------------------------------------------------------------------------- /cJSON/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2017 Dave Gamble and cJSON contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /cJSON/cJSON.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2017 Dave Gamble and cJSON contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifndef cJSON__h 24 | #define cJSON__h 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | /* project version */ 32 | #define CJSON_VERSION_MAJOR 1 33 | #define CJSON_VERSION_MINOR 5 34 | #define CJSON_VERSION_PATCH 9 35 | 36 | #include 37 | 38 | /* cJSON Types: */ 39 | #define cJSON_Invalid (0) 40 | #define cJSON_False (1 << 0) 41 | #define cJSON_True (1 << 1) 42 | #define cJSON_NULL (1 << 2) 43 | #define cJSON_Number (1 << 3) 44 | #define cJSON_String (1 << 4) 45 | #define cJSON_Array (1 << 5) 46 | #define cJSON_Object (1 << 6) 47 | #define cJSON_Raw (1 << 7) /* raw json */ 48 | 49 | #define cJSON_IsReference 256 50 | #define cJSON_StringIsConst 512 51 | 52 | /* The cJSON structure: */ 53 | typedef struct cJSON 54 | { 55 | /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ 56 | struct cJSON *next; 57 | struct cJSON *prev; 58 | /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ 59 | struct cJSON *child; 60 | 61 | /* The type of the item, as above. */ 62 | int type; 63 | 64 | /* The item's string, if type==cJSON_String and type == cJSON_Raw */ 65 | char *valuestring; 66 | /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ 67 | int valueint; 68 | /* The item's number, if type==cJSON_Number */ 69 | double valuedouble; 70 | 71 | /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ 72 | char *string; 73 | } cJSON; 74 | 75 | typedef struct cJSON_Hooks 76 | { 77 | void *(*malloc_fn)(size_t sz); 78 | void (*free_fn)(void *ptr); 79 | } cJSON_Hooks; 80 | 81 | typedef int cJSON_bool; 82 | 83 | #if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) 84 | #define __WINDOWS__ 85 | #endif 86 | #ifdef __WINDOWS__ 87 | 88 | /* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options: 89 | 90 | CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols 91 | CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) 92 | CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol 93 | 94 | For *nix builds that support visibility attribute, you can define similar behavior by 95 | 96 | setting default visibility to hidden by adding 97 | -fvisibility=hidden (for gcc) 98 | or 99 | -xldscope=hidden (for sun cc) 100 | to CFLAGS 101 | 102 | then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does 103 | 104 | */ 105 | 106 | /* export symbols by default, this is necessary for copy pasting the C and header file */ 107 | #if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) 108 | #define CJSON_EXPORT_SYMBOLS 109 | #endif 110 | 111 | #if defined(CJSON_HIDE_SYMBOLS) 112 | #define CJSON_PUBLIC(type) type __stdcall 113 | #elif defined(CJSON_EXPORT_SYMBOLS) 114 | #define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall 115 | #elif defined(CJSON_IMPORT_SYMBOLS) 116 | #define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall 117 | #endif 118 | #else /* !WIN32 */ 119 | #if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) 120 | #define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type 121 | #else 122 | #define CJSON_PUBLIC(type) type 123 | #endif 124 | #endif 125 | 126 | /* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. 127 | * This is to prevent stack overflows. */ 128 | #ifndef CJSON_NESTING_LIMIT 129 | #define CJSON_NESTING_LIMIT 1000 130 | #endif 131 | 132 | /* returns the version of cJSON as a string */ 133 | CJSON_PUBLIC(const char*) cJSON_Version(void); 134 | 135 | /* Supply malloc, realloc and free functions to cJSON */ 136 | CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); 137 | 138 | /* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ 139 | /* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ 140 | CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); 141 | /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ 142 | /* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ 143 | CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); 144 | 145 | /* Render a cJSON entity to text for transfer/storage. */ 146 | CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); 147 | /* Render a cJSON entity to text for transfer/storage without any formatting. */ 148 | CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); 149 | /* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ 150 | CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); 151 | /* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ 152 | /* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ 153 | CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); 154 | /* Delete a cJSON entity and all subentities. */ 155 | CJSON_PUBLIC(void) cJSON_Delete(cJSON *c); 156 | 157 | /* Returns the number of items in an array (or object). */ 158 | CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); 159 | /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ 160 | CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); 161 | /* Get item "string" from object. Case insensitive. */ 162 | CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); 163 | CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); 164 | CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); 165 | /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ 166 | CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); 167 | 168 | /* These functions check the type of an item */ 169 | CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); 170 | CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); 171 | CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); 172 | CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); 173 | CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); 174 | CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); 175 | CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); 176 | CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); 177 | CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); 178 | CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); 179 | 180 | /* These calls create a cJSON item of the appropriate type. */ 181 | CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); 182 | CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); 183 | CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); 184 | CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); 185 | CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); 186 | CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); 187 | /* raw json */ 188 | CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); 189 | CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); 190 | CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); 191 | 192 | /* These utilities create an Array of count items. */ 193 | CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); 194 | CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); 195 | CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); 196 | CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count); 197 | 198 | /* Append item to the specified array/object. */ 199 | CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item); 200 | CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); 201 | /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. 202 | * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before 203 | * writing to `item->string` */ 204 | CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); 205 | /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ 206 | CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); 207 | CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); 208 | 209 | /* Remove/Detatch items from Arrays/Objects. */ 210 | CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); 211 | CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); 212 | CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); 213 | CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); 214 | CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); 215 | CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); 216 | CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); 217 | 218 | /* Update array items. */ 219 | CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ 220 | CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); 221 | CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); 222 | CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); 223 | CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); 224 | 225 | /* Duplicate a cJSON item */ 226 | CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); 227 | /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will 228 | need to be released. With recurse!=0, it will duplicate any children connected to the item. 229 | The item->next and ->prev pointers are always zero on return from Duplicate. */ 230 | /* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. 231 | * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ 232 | CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); 233 | 234 | 235 | CJSON_PUBLIC(void) cJSON_Minify(char *json); 236 | 237 | /* Macros for creating things quickly. */ 238 | #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) 239 | #define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) 240 | #define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) 241 | #define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) 242 | #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) 243 | #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) 244 | #define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s)) 245 | 246 | /* When assigning an integer value, it needs to be propagated to valuedouble too. */ 247 | #define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) 248 | /* helper for the cJSON_SetNumberValue macro */ 249 | CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); 250 | #define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) 251 | 252 | /* Macro for iterating over an array or object */ 253 | #define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) 254 | 255 | /* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ 256 | CJSON_PUBLIC(void *) cJSON_malloc(size_t size); 257 | CJSON_PUBLIC(void) cJSON_free(void *object); 258 | 259 | #ifdef __cplusplus 260 | } 261 | #endif 262 | 263 | #endif 264 | -------------------------------------------------------------------------------- /cJSON/cJSON_Utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2017 Dave Gamble and cJSON contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifdef _MSC_VER 24 | #pragma warning(disable: 4068) /* twtxtfix: booo... :-) */ 25 | #endif 26 | #pragma GCC visibility push(default) 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #pragma GCC visibility pop 33 | 34 | #include "cJSON_Utils.h" 35 | 36 | /* define our own boolean type */ 37 | #define true ((cJSON_bool)1) 38 | #define false ((cJSON_bool)0) 39 | 40 | static unsigned char* cJSONUtils_strdup(const unsigned char* const string) 41 | { 42 | size_t length = 0; 43 | unsigned char *copy = NULL; 44 | 45 | length = strlen((const char*)string) + sizeof(""); 46 | copy = (unsigned char*) cJSON_malloc(length); 47 | if (copy == NULL) 48 | { 49 | return NULL; 50 | } 51 | memcpy(copy, string, length); 52 | 53 | return copy; 54 | } 55 | 56 | /* string comparison which doesn't consider NULL pointers equal */ 57 | static int compare_strings(const unsigned char *string1, const unsigned char *string2, const cJSON_bool case_sensitive) 58 | { 59 | if ((string1 == NULL) || (string2 == NULL)) 60 | { 61 | return 1; 62 | } 63 | 64 | if (string1 == string2) 65 | { 66 | return 0; 67 | } 68 | 69 | if (case_sensitive) 70 | { 71 | return strcmp((const char*)string1, (const char*)string2); 72 | } 73 | 74 | for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) 75 | { 76 | if (*string1 == '\0') 77 | { 78 | return 0; 79 | } 80 | } 81 | 82 | return tolower(*string1) - tolower(*string2); 83 | } 84 | 85 | /* Compare the next path element of two JSON pointers, two NULL pointers are considered unequal: */ 86 | static cJSON_bool compare_pointers(const unsigned char *name, const unsigned char *pointer, const cJSON_bool case_sensitive) 87 | { 88 | if ((name == NULL) || (pointer == NULL)) 89 | { 90 | return false; 91 | } 92 | 93 | for (; (*name != '\0') && (*pointer != '\0') && (*pointer != '/'); (void)name++, pointer++) /* compare until next '/' */ 94 | { 95 | if (*pointer == '~') 96 | { 97 | /* check for escaped '~' (~0) and '/' (~1) */ 98 | if (((pointer[1] != '0') || (*name != '~')) && ((pointer[1] != '1') || (*name != '/'))) 99 | { 100 | /* invalid escape sequence or wrong character in *name */ 101 | return false; 102 | } 103 | else 104 | { 105 | pointer++; 106 | } 107 | } 108 | else if ((!case_sensitive && (tolower(*name) != tolower(*pointer))) || (case_sensitive && (*name != *pointer))) 109 | { 110 | return false; 111 | } 112 | } 113 | if (((*pointer != 0) && (*pointer != '/')) != (*name != 0)) 114 | { 115 | /* one string has ended, the other not */ 116 | return false;; 117 | } 118 | 119 | return true; 120 | } 121 | 122 | /* calculate the length of a string if encoded as JSON pointer with ~0 and ~1 escape sequences */ 123 | static size_t pointer_encoded_length(const unsigned char *string) 124 | { 125 | size_t length; 126 | for (length = 0; *string != '\0'; (void)string++, length++) 127 | { 128 | /* character needs to be escaped? */ 129 | if ((*string == '~') || (*string == '/')) 130 | { 131 | length++; 132 | } 133 | } 134 | 135 | return length; 136 | } 137 | 138 | /* copy a string while escaping '~' and '/' with ~0 and ~1 JSON pointer escape codes */ 139 | static void encode_string_as_pointer(unsigned char *destination, const unsigned char *source) 140 | { 141 | for (; source[0] != '\0'; (void)source++, destination++) 142 | { 143 | if (source[0] == '/') 144 | { 145 | destination[1] = '1'; 146 | destination++; 147 | } 148 | else if (source[0] == '~') 149 | { 150 | destination[0] = '~'; 151 | destination[1] = '1'; 152 | destination++; 153 | } 154 | else 155 | { 156 | destination[0] = source[0]; 157 | } 158 | } 159 | 160 | destination[0] = '\0'; 161 | } 162 | 163 | CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const object, const cJSON * const target) 164 | { 165 | size_t child_index = 0; 166 | cJSON *current_child = 0; 167 | 168 | if ((object == NULL) || (target == NULL)) 169 | { 170 | return NULL; 171 | } 172 | 173 | if (object == target) 174 | { 175 | /* found */ 176 | return (char*)cJSONUtils_strdup((const unsigned char*)""); 177 | } 178 | 179 | /* recursively search all children of the object or array */ 180 | for (current_child = object->child; current_child != NULL; (void)(current_child = current_child->next), child_index++) 181 | { 182 | unsigned char *target_pointer = (unsigned char*)cJSONUtils_FindPointerFromObjectTo(current_child, target); 183 | /* found the target? */ 184 | if (target_pointer != NULL) 185 | { 186 | if (cJSON_IsArray(object)) 187 | { 188 | /* reserve enough memory for a 64 bit integer + '/' and '\0' */ 189 | unsigned char *full_pointer = (unsigned char*)cJSON_malloc(strlen((char*)target_pointer) + 20 + sizeof("/")); 190 | /* check if conversion to unsigned long is valid 191 | * This should be eliminated at compile time by dead code elimination 192 | * if size_t is an alias of unsigned long, or if it is bigger */ 193 | if (child_index > ULONG_MAX) 194 | { 195 | cJSON_free(target_pointer); 196 | return NULL; 197 | } 198 | sprintf((char*)full_pointer, "/%lu%s", (unsigned long)child_index, target_pointer); /* / */ 199 | cJSON_free(target_pointer); 200 | 201 | return (char*)full_pointer; 202 | } 203 | 204 | if (cJSON_IsObject(object)) 205 | { 206 | unsigned char *full_pointer = (unsigned char*)cJSON_malloc(strlen((char*)target_pointer) + pointer_encoded_length((unsigned char*)current_child->string) + 2); 207 | full_pointer[0] = '/'; 208 | encode_string_as_pointer(full_pointer + 1, (unsigned char*)current_child->string); 209 | strcat((char*)full_pointer, (char*)target_pointer); 210 | cJSON_free(target_pointer); 211 | 212 | return (char*)full_pointer; 213 | } 214 | 215 | /* reached leaf of the tree, found nothing */ 216 | cJSON_free(target_pointer); 217 | return NULL; 218 | } 219 | } 220 | 221 | /* not found */ 222 | return NULL; 223 | } 224 | 225 | /* non broken version of cJSON_GetArrayItem */ 226 | static cJSON *get_array_item(const cJSON *array, size_t item) 227 | { 228 | cJSON *child = array ? array->child : NULL; 229 | while ((child != NULL) && (item > 0)) 230 | { 231 | item--; 232 | child = child->next; 233 | } 234 | 235 | return child; 236 | } 237 | 238 | static cJSON_bool decode_array_index_from_pointer(const unsigned char * const pointer, size_t * const index) 239 | { 240 | size_t parsed_index = 0; 241 | size_t position = 0; 242 | 243 | if ((pointer[0] == '0') && ((pointer[1] != '\0') && (pointer[1] != '/'))) 244 | { 245 | /* leading zeroes are not permitted */ 246 | return 0; 247 | } 248 | 249 | for (position = 0; (pointer[position] >= '0') && (pointer[0] <= '9'); position++) 250 | { 251 | parsed_index = (10 * parsed_index) + (size_t)(pointer[position] - '0'); 252 | 253 | } 254 | 255 | if ((pointer[position] != '\0') && (pointer[position] != '/')) 256 | { 257 | return 0; 258 | } 259 | 260 | *index = parsed_index; 261 | 262 | return 1; 263 | } 264 | 265 | static cJSON *get_item_from_pointer(cJSON * const object, const char * pointer, const cJSON_bool case_sensitive) 266 | { 267 | cJSON *current_element = object; 268 | 269 | if (pointer == NULL) 270 | { 271 | return NULL; 272 | } 273 | 274 | /* follow path of the pointer */ 275 | while ((pointer[0] == '/') && (current_element != NULL)) 276 | { 277 | pointer++; 278 | if (cJSON_IsArray(current_element)) 279 | { 280 | size_t index = 0; 281 | if (!decode_array_index_from_pointer((const unsigned char*)pointer, &index)) 282 | { 283 | return NULL; 284 | } 285 | 286 | current_element = get_array_item(current_element, index); 287 | } 288 | else if (cJSON_IsObject(current_element)) 289 | { 290 | current_element = current_element->child; 291 | /* GetObjectItem. */ 292 | while ((current_element != NULL) && !compare_pointers((unsigned char*)current_element->string, (const unsigned char*)pointer, case_sensitive)) 293 | { 294 | current_element = current_element->next; 295 | } 296 | } 297 | else 298 | { 299 | return NULL; 300 | } 301 | 302 | /* skip to the next path token or end of string */ 303 | while ((pointer[0] != '\0') && (pointer[0] != '/')) 304 | { 305 | pointer++; 306 | } 307 | } 308 | 309 | return current_element; 310 | } 311 | 312 | CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointer(cJSON * const object, const char *pointer) 313 | { 314 | return get_item_from_pointer(object, pointer, false); 315 | } 316 | 317 | CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointerCaseSensitive(cJSON * const object, const char *pointer) 318 | { 319 | return get_item_from_pointer(object, pointer, true); 320 | } 321 | 322 | /* JSON Patch implementation. */ 323 | static void decode_pointer_inplace(unsigned char *string) 324 | { 325 | unsigned char *decoded_string = string; 326 | 327 | if (string == NULL) { 328 | return; 329 | } 330 | 331 | for (; *string; (void)decoded_string++, string++) 332 | { 333 | if (string[0] == '~') 334 | { 335 | if (string[1] == '0') 336 | { 337 | decoded_string[0] = '~'; 338 | } 339 | else if (string[1] == '1') 340 | { 341 | decoded_string[1] = '/'; 342 | } 343 | else 344 | { 345 | /* invalid escape sequence */ 346 | return; 347 | } 348 | 349 | string++; 350 | } 351 | } 352 | 353 | decoded_string[0] = '\0'; 354 | } 355 | 356 | /* non-broken cJSON_DetachItemFromArray */ 357 | static cJSON *detach_item_from_array(cJSON *array, size_t which) 358 | { 359 | cJSON *c = array->child; 360 | while (c && (which > 0)) 361 | { 362 | c = c->next; 363 | which--; 364 | } 365 | if (!c) 366 | { 367 | /* item doesn't exist */ 368 | return NULL; 369 | } 370 | if (c->prev) 371 | { 372 | /* not the first element */ 373 | c->prev->next = c->next; 374 | } 375 | if (c->next) 376 | { 377 | c->next->prev = c->prev; 378 | } 379 | if (c==array->child) 380 | { 381 | array->child = c->next; 382 | } 383 | /* make sure the detached item doesn't point anywhere anymore */ 384 | c->prev = c->next = NULL; 385 | 386 | return c; 387 | } 388 | 389 | /* detach an item at the given path */ 390 | static cJSON *detach_path(cJSON *object, const unsigned char *path, const cJSON_bool case_sensitive) 391 | { 392 | unsigned char *parent_pointer = NULL; 393 | unsigned char *child_pointer = NULL; 394 | cJSON *parent = NULL; 395 | cJSON *detached_item = NULL; 396 | 397 | /* copy path and split it in parent and child */ 398 | parent_pointer = cJSONUtils_strdup(path); 399 | if (parent_pointer == NULL) { 400 | goto cleanup; 401 | } 402 | 403 | child_pointer = (unsigned char*)strrchr((char*)parent_pointer, '/'); /* last '/' */ 404 | if (child_pointer == NULL) 405 | { 406 | goto cleanup; 407 | } 408 | /* split strings */ 409 | child_pointer[0] = '\0'; 410 | child_pointer++; 411 | 412 | parent = get_item_from_pointer(object, (char*)parent_pointer, case_sensitive); 413 | decode_pointer_inplace(child_pointer); 414 | 415 | if (cJSON_IsArray(parent)) 416 | { 417 | size_t index = 0; 418 | if (!decode_array_index_from_pointer(child_pointer, &index)) 419 | { 420 | goto cleanup; 421 | } 422 | detached_item = detach_item_from_array(parent, index); 423 | } 424 | else if (cJSON_IsObject(parent)) 425 | { 426 | detached_item = cJSON_DetachItemFromObject(parent, (char*)child_pointer); 427 | } 428 | else 429 | { 430 | /* Couldn't find object to remove child from. */ 431 | goto cleanup; 432 | } 433 | 434 | cleanup: 435 | if (parent_pointer != NULL) 436 | { 437 | cJSON_free(parent_pointer); 438 | } 439 | 440 | return detached_item; 441 | } 442 | 443 | /* sort lists using mergesort */ 444 | static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive) 445 | { 446 | cJSON *first = list; 447 | cJSON *second = list; 448 | cJSON *current_item = list; 449 | cJSON *result = list; 450 | cJSON *result_tail = NULL; 451 | 452 | if ((list == NULL) || (list->next == NULL)) 453 | { 454 | /* One entry is sorted already. */ 455 | return result; 456 | } 457 | 458 | while ((current_item != NULL) && (current_item->next != NULL) && (compare_strings((unsigned char*)current_item->string, (unsigned char*)current_item->next->string, case_sensitive) < 0)) 459 | { 460 | /* Test for list sorted. */ 461 | current_item = current_item->next; 462 | } 463 | if ((current_item == NULL) || (current_item->next == NULL)) 464 | { 465 | /* Leave sorted lists unmodified. */ 466 | return result; 467 | } 468 | 469 | /* reset pointer to the beginning */ 470 | current_item = list; 471 | while (current_item != NULL) 472 | { 473 | /* Walk two pointers to find the middle. */ 474 | second = second->next; 475 | current_item = current_item->next; 476 | /* advances current_item two steps at a time */ 477 | if (current_item != NULL) 478 | { 479 | current_item = current_item->next; 480 | } 481 | } 482 | if ((second != NULL) && (second->prev != NULL)) 483 | { 484 | /* Split the lists */ 485 | second->prev->next = NULL; 486 | } 487 | 488 | /* Recursively sort the sub-lists. */ 489 | first = sort_list(first, case_sensitive); 490 | second = sort_list(second, case_sensitive); 491 | result = NULL; 492 | 493 | /* Merge the sub-lists */ 494 | while ((first != NULL) && (second != NULL)) 495 | { 496 | cJSON *smaller = NULL; 497 | if (compare_strings((unsigned char*)first->string, (unsigned char*)second->string, false) < 0) 498 | { 499 | smaller = first; 500 | } 501 | else 502 | { 503 | smaller = second; 504 | } 505 | 506 | if (result == NULL) 507 | { 508 | /* start merged list with the smaller element */ 509 | result_tail = smaller; 510 | result = smaller; 511 | } 512 | else 513 | { 514 | /* add smaller element to the list */ 515 | result_tail->next = smaller; 516 | smaller->prev = result_tail; 517 | result_tail = smaller; 518 | } 519 | 520 | if (first == smaller) 521 | { 522 | first = first->next; 523 | } 524 | else 525 | { 526 | second = second->next; 527 | } 528 | } 529 | 530 | if (first != NULL) 531 | { 532 | /* Append rest of first list. */ 533 | if (result == NULL) 534 | { 535 | return first; 536 | } 537 | result_tail->next = first; 538 | first->prev = result_tail; 539 | } 540 | if (second != NULL) 541 | { 542 | /* Append rest of second list */ 543 | if (result == NULL) 544 | { 545 | return second; 546 | } 547 | result_tail->next = second; 548 | second->prev = result_tail; 549 | } 550 | 551 | return result; 552 | } 553 | 554 | static void sort_object(cJSON * const object, const cJSON_bool case_sensitive) 555 | { 556 | if (object == NULL) 557 | { 558 | return; 559 | } 560 | object->child = sort_list(object->child, case_sensitive); 561 | } 562 | 563 | static cJSON_bool compare_json(cJSON *a, cJSON *b, const cJSON_bool case_sensitive) 564 | { 565 | if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))) 566 | { 567 | /* mismatched type. */ 568 | return false; 569 | } 570 | switch (a->type & 0xFF) 571 | { 572 | case cJSON_Number: 573 | /* numeric mismatch. */ 574 | if ((a->valueint != b->valueint) || (a->valuedouble != b->valuedouble)) 575 | { 576 | return false; 577 | } 578 | else 579 | { 580 | return true; 581 | } 582 | 583 | case cJSON_String: 584 | /* string mismatch. */ 585 | if (strcmp(a->valuestring, b->valuestring) != 0) 586 | { 587 | return false; 588 | } 589 | else 590 | { 591 | return true; 592 | } 593 | 594 | case cJSON_Array: 595 | for ((void)(a = a->child), b = b->child; (a != NULL) && (b != NULL); (void)(a = a->next), b = b->next) 596 | { 597 | cJSON_bool identical = compare_json(a, b, case_sensitive); 598 | if (!identical) 599 | { 600 | return false; 601 | } 602 | } 603 | 604 | /* array size mismatch? (one of both children is not NULL) */ 605 | if ((a != NULL) || (b != NULL)) 606 | { 607 | return false; 608 | } 609 | else 610 | { 611 | return true; 612 | } 613 | 614 | case cJSON_Object: 615 | sort_object(a, case_sensitive); 616 | sort_object(b, case_sensitive); 617 | for ((void)(a = a->child), b = b->child; (a != NULL) && (b != NULL); (void)(a = a->next), b = b->next) 618 | { 619 | cJSON_bool identical = false; 620 | /* compare object keys */ 621 | if (compare_strings((unsigned char*)a->string, (unsigned char*)b->string, case_sensitive)) 622 | { 623 | /* missing member */ 624 | return false; 625 | } 626 | identical = compare_json(a, b, case_sensitive); 627 | if (!identical) 628 | { 629 | return false; 630 | } 631 | } 632 | 633 | /* object length mismatch (one of both children is not null) */ 634 | if ((a != NULL) || (b != NULL)) 635 | { 636 | return false; 637 | } 638 | else 639 | { 640 | return true; 641 | } 642 | 643 | default: 644 | break; 645 | } 646 | 647 | /* null, true or false */ 648 | return true; 649 | } 650 | 651 | /* non broken version of cJSON_InsertItemInArray */ 652 | static cJSON_bool insert_item_in_array(cJSON *array, size_t which, cJSON *newitem) 653 | { 654 | cJSON *child = array->child; 655 | while (child && (which > 0)) 656 | { 657 | child = child->next; 658 | which--; 659 | } 660 | if (which > 0) 661 | { 662 | /* item is after the end of the array */ 663 | return 0; 664 | } 665 | if (child == NULL) 666 | { 667 | cJSON_AddItemToArray(array, newitem); 668 | return 1; 669 | } 670 | 671 | /* insert into the linked list */ 672 | newitem->next = child; 673 | newitem->prev = child->prev; 674 | child->prev = newitem; 675 | 676 | /* was it at the beginning */ 677 | if (child == array->child) 678 | { 679 | array->child = newitem; 680 | } 681 | else 682 | { 683 | newitem->prev->next = newitem; 684 | } 685 | 686 | return 1; 687 | } 688 | 689 | static cJSON *get_object_item(const cJSON * const object, const char* name, const cJSON_bool case_sensitive) 690 | { 691 | if (case_sensitive) 692 | { 693 | return cJSON_GetObjectItemCaseSensitive(object, name); 694 | } 695 | 696 | return cJSON_GetObjectItem(object, name); 697 | } 698 | 699 | enum patch_operation { INVALID, ADD, REMOVE, REPLACE, MOVE, COPY, TEST }; 700 | 701 | static enum patch_operation decode_patch_operation(const cJSON * const patch, const cJSON_bool case_sensitive) 702 | { 703 | cJSON *operation = get_object_item(patch, "op", case_sensitive); 704 | if (!cJSON_IsString(operation)) 705 | { 706 | return INVALID; 707 | } 708 | 709 | if (strcmp(operation->valuestring, "add") == 0) 710 | { 711 | return ADD; 712 | } 713 | 714 | if (strcmp(operation->valuestring, "remove") == 0) 715 | { 716 | return REMOVE; 717 | } 718 | 719 | if (strcmp(operation->valuestring, "replace") == 0) 720 | { 721 | return REPLACE; 722 | } 723 | 724 | if (strcmp(operation->valuestring, "move") == 0) 725 | { 726 | return MOVE; 727 | } 728 | 729 | if (strcmp(operation->valuestring, "copy") == 0) 730 | { 731 | return COPY; 732 | } 733 | 734 | if (strcmp(operation->valuestring, "test") == 0) 735 | { 736 | return TEST; 737 | } 738 | 739 | return INVALID; 740 | } 741 | 742 | /* overwrite and existing item with another one and free resources on the way */ 743 | static void overwrite_item(cJSON * const root, const cJSON replacement) 744 | { 745 | if (root == NULL) 746 | { 747 | return; 748 | } 749 | 750 | if (root->string != NULL) 751 | { 752 | cJSON_free(root->string); 753 | } 754 | if (root->valuestring != NULL) 755 | { 756 | cJSON_free(root->valuestring); 757 | } 758 | if (root->child != NULL) 759 | { 760 | cJSON_Delete(root->child); 761 | } 762 | 763 | memcpy(root, &replacement, sizeof(cJSON)); 764 | } 765 | 766 | static int apply_patch(cJSON *object, const cJSON *patch, const cJSON_bool case_sensitive) 767 | { 768 | cJSON *path = NULL; 769 | cJSON *value = NULL; 770 | cJSON *parent = NULL; 771 | enum patch_operation opcode = INVALID; 772 | unsigned char *parent_pointer = NULL; 773 | unsigned char *child_pointer = NULL; 774 | int status = 0; 775 | 776 | path = get_object_item(patch, "path", case_sensitive); 777 | if (!cJSON_IsString(path)) 778 | { 779 | /* malformed patch. */ 780 | status = 2; 781 | goto cleanup; 782 | } 783 | 784 | opcode = decode_patch_operation(patch, case_sensitive); 785 | if (opcode == INVALID) 786 | { 787 | status = 3; 788 | goto cleanup; 789 | } 790 | else if (opcode == TEST) 791 | { 792 | /* compare value: {...} with the given path */ 793 | status = !compare_json(get_item_from_pointer(object, path->valuestring, case_sensitive), get_object_item(patch, "value", case_sensitive), case_sensitive); 794 | goto cleanup; 795 | } 796 | 797 | /* special case for replacing the root */ 798 | if (path->valuestring[0] == '\0') 799 | { 800 | if (opcode == REMOVE) 801 | { 802 | static const cJSON invalid = { NULL, NULL, NULL, cJSON_Invalid, NULL, 0, 0, NULL}; 803 | 804 | overwrite_item(object, invalid); 805 | 806 | status = 0; 807 | goto cleanup; 808 | } 809 | 810 | if ((opcode == REPLACE) || (opcode == ADD)) 811 | { 812 | value = get_object_item(patch, "value", case_sensitive); 813 | if (value == NULL) 814 | { 815 | /* missing "value" for add/replace. */ 816 | status = 7; 817 | goto cleanup; 818 | } 819 | 820 | value = cJSON_Duplicate(value, 1); 821 | if (value == NULL) 822 | { 823 | /* out of memory for add/replace. */ 824 | status = 8; 825 | goto cleanup; 826 | } 827 | 828 | overwrite_item(object, *value); 829 | 830 | /* delete the duplicated value */ 831 | cJSON_free(value); 832 | value = NULL; 833 | 834 | /* the string "value" isn't needed */ 835 | if (object->string != NULL) 836 | { 837 | cJSON_free(object->string); 838 | object->string = NULL; 839 | } 840 | 841 | status = 0; 842 | goto cleanup; 843 | } 844 | } 845 | 846 | if ((opcode == REMOVE) || (opcode == REPLACE)) 847 | { 848 | /* Get rid of old. */ 849 | cJSON *old_item = detach_path(object, (unsigned char*)path->valuestring, case_sensitive); 850 | if (old_item == NULL) 851 | { 852 | status = 13; 853 | goto cleanup; 854 | } 855 | cJSON_Delete(old_item); 856 | if (opcode == REMOVE) 857 | { 858 | /* For Remove, this job is done. */ 859 | status = 0; 860 | goto cleanup; 861 | } 862 | } 863 | 864 | /* Copy/Move uses "from". */ 865 | if ((opcode == MOVE) || (opcode == COPY)) 866 | { 867 | cJSON *from = get_object_item(patch, "from", case_sensitive); 868 | if (from == NULL) 869 | { 870 | /* missing "from" for copy/move. */ 871 | status = 4; 872 | goto cleanup; 873 | } 874 | 875 | if (opcode == MOVE) 876 | { 877 | value = detach_path(object, (unsigned char*)from->valuestring, case_sensitive); 878 | } 879 | if (opcode == COPY) 880 | { 881 | value = get_item_from_pointer(object, from->valuestring, case_sensitive); 882 | } 883 | if (value == NULL) 884 | { 885 | /* missing "from" for copy/move. */ 886 | status = 5; 887 | goto cleanup; 888 | } 889 | if (opcode == COPY) 890 | { 891 | value = cJSON_Duplicate(value, 1); 892 | } 893 | if (value == NULL) 894 | { 895 | /* out of memory for copy/move. */ 896 | status = 6; 897 | goto cleanup; 898 | } 899 | } 900 | else /* Add/Replace uses "value". */ 901 | { 902 | value = get_object_item(patch, "value", case_sensitive); 903 | if (value == NULL) 904 | { 905 | /* missing "value" for add/replace. */ 906 | status = 7; 907 | goto cleanup; 908 | } 909 | value = cJSON_Duplicate(value, 1); 910 | if (value == NULL) 911 | { 912 | /* out of memory for add/replace. */ 913 | status = 8; 914 | goto cleanup; 915 | } 916 | } 917 | 918 | /* Now, just add "value" to "path". */ 919 | 920 | /* split pointer in parent and child */ 921 | parent_pointer = cJSONUtils_strdup((unsigned char*)path->valuestring); 922 | child_pointer = (unsigned char*)strrchr((char*)parent_pointer, '/'); 923 | if (child_pointer != NULL) 924 | { 925 | child_pointer[0] = '\0'; 926 | child_pointer++; 927 | } 928 | parent = get_item_from_pointer(object, (char*)parent_pointer, case_sensitive); 929 | decode_pointer_inplace(child_pointer); 930 | 931 | /* add, remove, replace, move, copy, test. */ 932 | if ((parent == NULL) || (child_pointer == NULL)) 933 | { 934 | /* Couldn't find object to add to. */ 935 | status = 9; 936 | goto cleanup; 937 | } 938 | else if (cJSON_IsArray(parent)) 939 | { 940 | if (strcmp((char*)child_pointer, "-") == 0) 941 | { 942 | cJSON_AddItemToArray(parent, value); 943 | value = NULL; 944 | } 945 | else 946 | { 947 | size_t index = 0; 948 | if (!decode_array_index_from_pointer(child_pointer, &index)) 949 | { 950 | status = 11; 951 | goto cleanup; 952 | } 953 | 954 | if (!insert_item_in_array(parent, index, value)) 955 | { 956 | status = 10; 957 | goto cleanup; 958 | } 959 | value = NULL; 960 | } 961 | } 962 | else if (cJSON_IsObject(parent)) 963 | { 964 | if (case_sensitive) 965 | { 966 | cJSON_DeleteItemFromObjectCaseSensitive(parent, (char*)child_pointer); 967 | } 968 | else 969 | { 970 | cJSON_DeleteItemFromObject(parent, (char*)child_pointer); 971 | } 972 | cJSON_AddItemToObject(parent, (char*)child_pointer, value); 973 | value = NULL; 974 | } 975 | 976 | cleanup: 977 | if (value != NULL) 978 | { 979 | cJSON_Delete(value); 980 | } 981 | if (parent_pointer != NULL) 982 | { 983 | cJSON_free(parent_pointer); 984 | } 985 | 986 | return status; 987 | } 988 | 989 | CJSON_PUBLIC(int) cJSONUtils_ApplyPatches(cJSON * const object, const cJSON * const patches) 990 | { 991 | const cJSON *current_patch = NULL; 992 | int status = 0; 993 | 994 | if (!cJSON_IsArray(patches)) 995 | { 996 | /* malformed patches. */ 997 | return 1; 998 | } 999 | 1000 | if (patches != NULL) 1001 | { 1002 | current_patch = patches->child; 1003 | } 1004 | 1005 | while (current_patch != NULL) 1006 | { 1007 | status = apply_patch(object, current_patch, false); 1008 | if (status != 0) 1009 | { 1010 | return status; 1011 | } 1012 | current_patch = current_patch->next; 1013 | } 1014 | 1015 | return 0; 1016 | } 1017 | 1018 | CJSON_PUBLIC(int) cJSONUtils_ApplyPatchesCaseSensitive(cJSON * const object, const cJSON * const patches) 1019 | { 1020 | const cJSON *current_patch = NULL; 1021 | int status = 0; 1022 | 1023 | if (!cJSON_IsArray(patches)) 1024 | { 1025 | /* malformed patches. */ 1026 | return 1; 1027 | } 1028 | 1029 | if (patches != NULL) 1030 | { 1031 | current_patch = patches->child; 1032 | } 1033 | 1034 | while (current_patch != NULL) 1035 | { 1036 | status = apply_patch(object, current_patch, true); 1037 | if (status != 0) 1038 | { 1039 | return status; 1040 | } 1041 | current_patch = current_patch->next; 1042 | } 1043 | 1044 | return 0; 1045 | } 1046 | 1047 | static void compose_patch(cJSON * const patches, const unsigned char * const operation, const unsigned char * const path, const unsigned char *suffix, const cJSON * const value) 1048 | { 1049 | cJSON *patch = NULL; 1050 | 1051 | if ((patches == NULL) || (operation == NULL) || (path == NULL)) 1052 | { 1053 | return; 1054 | } 1055 | 1056 | patch = cJSON_CreateObject(); 1057 | if (patch == NULL) 1058 | { 1059 | return; 1060 | } 1061 | cJSON_AddItemToObject(patch, "op", cJSON_CreateString((const char*)operation)); 1062 | 1063 | if (suffix == NULL) 1064 | { 1065 | cJSON_AddItemToObject(patch, "path", cJSON_CreateString((const char*)path)); 1066 | } 1067 | else 1068 | { 1069 | size_t suffix_length = pointer_encoded_length(suffix); 1070 | size_t path_length = strlen((const char*)path); 1071 | unsigned char *full_path = (unsigned char*)cJSON_malloc(path_length + suffix_length + sizeof("/")); 1072 | 1073 | sprintf((char*)full_path, "%s/", (const char*)path); 1074 | encode_string_as_pointer(full_path + path_length + 1, suffix); 1075 | 1076 | cJSON_AddItemToObject(patch, "path", cJSON_CreateString((const char*)full_path)); 1077 | cJSON_free(full_path); 1078 | } 1079 | 1080 | if (value != NULL) 1081 | { 1082 | cJSON_AddItemToObject(patch, "value", cJSON_Duplicate(value, 1)); 1083 | } 1084 | cJSON_AddItemToArray(patches, patch); 1085 | } 1086 | 1087 | CJSON_PUBLIC(void) cJSONUtils_AddPatchToArray(cJSON * const array, const char * const operation, const char * const path, const cJSON * const value) 1088 | { 1089 | compose_patch(array, (const unsigned char*)operation, (const unsigned char*)path, NULL, value); 1090 | } 1091 | 1092 | static void create_patches(cJSON * const patches, const unsigned char * const path, cJSON * const from, cJSON * const to, const cJSON_bool case_sensitive) 1093 | { 1094 | if ((from == NULL) || (to == NULL)) 1095 | { 1096 | return; 1097 | } 1098 | 1099 | if ((from->type & 0xFF) != (to->type & 0xFF)) 1100 | { 1101 | compose_patch(patches, (const unsigned char*)"replace", path, 0, to); 1102 | return; 1103 | } 1104 | 1105 | switch (from->type & 0xFF) 1106 | { 1107 | case cJSON_Number: 1108 | if ((from->valueint != to->valueint) || (from->valuedouble != to->valuedouble)) 1109 | { 1110 | compose_patch(patches, (const unsigned char*)"replace", path, NULL, to); 1111 | } 1112 | return; 1113 | 1114 | case cJSON_String: 1115 | if (strcmp(from->valuestring, to->valuestring) != 0) 1116 | { 1117 | compose_patch(patches, (const unsigned char*)"replace", path, NULL, to); 1118 | } 1119 | return; 1120 | 1121 | case cJSON_Array: 1122 | { 1123 | size_t index = 0; 1124 | cJSON *from_child = from->child; 1125 | cJSON *to_child = to->child; 1126 | unsigned char *new_path = (unsigned char*)cJSON_malloc(strlen((const char*)path) + 20 + sizeof("/")); /* Allow space for 64bit int. log10(2^64) = 20 */ 1127 | 1128 | /* generate patches for all array elements that exist in both "from" and "to" */ 1129 | for (index = 0; (from_child != NULL) && (to_child != NULL); (void)(from_child = from_child->next), (void)(to_child = to_child->next), index++) 1130 | { 1131 | /* check if conversion to unsigned long is valid 1132 | * This should be eliminated at compile time by dead code elimination 1133 | * if size_t is an alias of unsigned long, or if it is bigger */ 1134 | if (index > ULONG_MAX) 1135 | { 1136 | cJSON_free(new_path); 1137 | return; 1138 | } 1139 | sprintf((char*)new_path, "%s/%lu", path, (unsigned long)index); /* path of the current array element */ 1140 | create_patches(patches, new_path, from_child, to_child, case_sensitive); 1141 | } 1142 | 1143 | /* remove leftover elements from 'from' that are not in 'to' */ 1144 | for (; (from_child != NULL); (void)(from_child = from_child->next)) 1145 | { 1146 | /* check if conversion to unsigned long is valid 1147 | * This should be eliminated at compile time by dead code elimination 1148 | * if size_t is an alias of unsigned long, or if it is bigger */ 1149 | if (index > ULONG_MAX) 1150 | { 1151 | cJSON_free(new_path); 1152 | return; 1153 | } 1154 | sprintf((char*)new_path, "%lu", (unsigned long)index); 1155 | compose_patch(patches, (const unsigned char*)"remove", path, new_path, NULL); 1156 | } 1157 | /* add new elements in 'to' that were not in 'from' */ 1158 | for (; (to_child != NULL); (void)(to_child = to_child->next), index++) 1159 | { 1160 | compose_patch(patches, (const unsigned char*)"add", path, (const unsigned char*)"-", to_child); 1161 | } 1162 | cJSON_free(new_path); 1163 | return; 1164 | } 1165 | 1166 | case cJSON_Object: 1167 | { 1168 | cJSON *from_child = NULL; 1169 | cJSON *to_child = NULL; 1170 | sort_object(from, case_sensitive); 1171 | sort_object(to, case_sensitive); 1172 | 1173 | from_child = from->child; 1174 | to_child = to->child; 1175 | /* for all object values in the object with more of them */ 1176 | while ((from_child != NULL) || (to_child != NULL)) 1177 | { 1178 | int diff; 1179 | if (from_child == NULL) 1180 | { 1181 | diff = 1; 1182 | } 1183 | else if (to_child == NULL) 1184 | { 1185 | diff = -1; 1186 | } 1187 | else 1188 | { 1189 | diff = compare_strings((unsigned char*)from_child->string, (unsigned char*)to_child->string, case_sensitive); 1190 | } 1191 | 1192 | if (diff == 0) 1193 | { 1194 | /* both object keys are the same */ 1195 | size_t path_length = strlen((const char*)path); 1196 | size_t from_child_name_length = pointer_encoded_length((unsigned char*)from_child->string); 1197 | unsigned char *new_path = (unsigned char*)cJSON_malloc(path_length + from_child_name_length + sizeof("/")); 1198 | 1199 | sprintf((char*)new_path, "%s/", path); 1200 | encode_string_as_pointer(new_path + path_length + 1, (unsigned char*)from_child->string); 1201 | 1202 | /* create a patch for the element */ 1203 | create_patches(patches, new_path, from_child, to_child, case_sensitive); 1204 | cJSON_free(new_path); 1205 | 1206 | from_child = from_child->next; 1207 | to_child = to_child->next; 1208 | } 1209 | else if (diff < 0) 1210 | { 1211 | /* object element doesn't exist in 'to' --> remove it */ 1212 | compose_patch(patches, (const unsigned char*)"remove", path, (unsigned char*)from_child->string, NULL); 1213 | 1214 | from_child = from_child->next; 1215 | } 1216 | else 1217 | { 1218 | /* object element doesn't exist in 'from' --> add it */ 1219 | compose_patch(patches, (const unsigned char*)"add", path, (unsigned char*)to_child->string, to_child); 1220 | 1221 | to_child = to_child->next; 1222 | } 1223 | } 1224 | return; 1225 | } 1226 | 1227 | default: 1228 | break; 1229 | } 1230 | } 1231 | 1232 | CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * const to) 1233 | { 1234 | cJSON *patches = NULL; 1235 | 1236 | if ((from == NULL) || (to == NULL)) 1237 | { 1238 | return NULL; 1239 | } 1240 | 1241 | patches = cJSON_CreateArray(); 1242 | create_patches(patches, (const unsigned char*)"", from, to, false); 1243 | 1244 | return patches; 1245 | } 1246 | 1247 | CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from, cJSON * const to) 1248 | { 1249 | cJSON *patches = NULL; 1250 | 1251 | if ((from == NULL) || (to == NULL)) 1252 | { 1253 | return NULL; 1254 | } 1255 | 1256 | patches = cJSON_CreateArray(); 1257 | create_patches(patches, (const unsigned char*)"", from, to, true); 1258 | 1259 | return patches; 1260 | } 1261 | 1262 | CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object) 1263 | { 1264 | sort_object(object, false); 1265 | } 1266 | 1267 | CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object) 1268 | { 1269 | sort_object(object, true); 1270 | } 1271 | 1272 | static cJSON *merge_patch(cJSON *target, const cJSON * const patch, const cJSON_bool case_sensitive) 1273 | { 1274 | cJSON *patch_child = NULL; 1275 | 1276 | if (!cJSON_IsObject(patch)) 1277 | { 1278 | /* scalar value, array or NULL, just duplicate */ 1279 | cJSON_Delete(target); 1280 | return cJSON_Duplicate(patch, 1); 1281 | } 1282 | 1283 | if (!cJSON_IsObject(target)) 1284 | { 1285 | cJSON_Delete(target); 1286 | target = cJSON_CreateObject(); 1287 | } 1288 | 1289 | patch_child = patch->child; 1290 | while (patch_child != NULL) 1291 | { 1292 | if (cJSON_IsNull(patch_child)) 1293 | { 1294 | /* NULL is the indicator to remove a value, see RFC7396 */ 1295 | if (case_sensitive) 1296 | { 1297 | cJSON_DeleteItemFromObjectCaseSensitive(target, patch_child->string); 1298 | } 1299 | else 1300 | { 1301 | cJSON_DeleteItemFromObject(target, patch_child->string); 1302 | } 1303 | } 1304 | else 1305 | { 1306 | cJSON *replace_me = NULL; 1307 | cJSON *replacement = NULL; 1308 | 1309 | if (case_sensitive) 1310 | { 1311 | replace_me = cJSON_DetachItemFromObjectCaseSensitive(target, patch_child->string); 1312 | } 1313 | else 1314 | { 1315 | replace_me = cJSON_DetachItemFromObject(target, patch_child->string); 1316 | } 1317 | 1318 | replacement = merge_patch(replace_me, patch_child, case_sensitive); 1319 | if (replacement == NULL) 1320 | { 1321 | return NULL; 1322 | } 1323 | 1324 | cJSON_AddItemToObject(target, patch_child->string, replacement); 1325 | } 1326 | patch_child = patch_child->next; 1327 | } 1328 | return target; 1329 | } 1330 | 1331 | CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatch(cJSON *target, const cJSON * const patch) 1332 | { 1333 | return merge_patch(target, patch, false); 1334 | } 1335 | 1336 | CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatchCaseSensitive(cJSON *target, const cJSON * const patch) 1337 | { 1338 | return merge_patch(target, patch, true); 1339 | } 1340 | 1341 | static cJSON *generate_merge_patch(cJSON * const from, cJSON * const to, const cJSON_bool case_sensitive) 1342 | { 1343 | cJSON *from_child = NULL; 1344 | cJSON *to_child = NULL; 1345 | cJSON *patch = NULL; 1346 | if (to == NULL) 1347 | { 1348 | /* patch to delete everything */ 1349 | return cJSON_CreateNull(); 1350 | } 1351 | if (!cJSON_IsObject(to) || !cJSON_IsObject(from)) 1352 | { 1353 | return cJSON_Duplicate(to, 1); 1354 | } 1355 | 1356 | sort_object(from, case_sensitive); 1357 | sort_object(to, case_sensitive); 1358 | 1359 | from_child = from->child; 1360 | to_child = to->child; 1361 | patch = cJSON_CreateObject(); 1362 | while (from_child || to_child) 1363 | { 1364 | int diff; 1365 | if (from_child != NULL) 1366 | { 1367 | if (to_child != NULL) 1368 | { 1369 | diff = strcmp(from_child->string, to_child->string); 1370 | } 1371 | else 1372 | { 1373 | diff = -1; 1374 | } 1375 | } 1376 | else 1377 | { 1378 | diff = 1; 1379 | } 1380 | 1381 | if (diff < 0) 1382 | { 1383 | /* from has a value that to doesn't have -> remove */ 1384 | cJSON_AddItemToObject(patch, from_child->string, cJSON_CreateNull()); 1385 | 1386 | from_child = from_child->next; 1387 | } 1388 | else if (diff > 0) 1389 | { 1390 | /* to has a value that from doesn't have -> add to patch */ 1391 | cJSON_AddItemToObject(patch, to_child->string, cJSON_Duplicate(to_child, 1)); 1392 | 1393 | to_child = to_child->next; 1394 | } 1395 | else 1396 | { 1397 | /* object key exists in both objects */ 1398 | if (!compare_json(from_child, to_child, case_sensitive)) 1399 | { 1400 | /* not identical --> generate a patch */ 1401 | cJSON_AddItemToObject(patch, to_child->string, cJSONUtils_GenerateMergePatch(from_child, to_child)); 1402 | } 1403 | 1404 | /* next key in the object */ 1405 | from_child = from_child->next; 1406 | to_child = to_child->next; 1407 | } 1408 | } 1409 | if (patch->child == NULL) 1410 | { 1411 | /* no patch generated */ 1412 | cJSON_Delete(patch); 1413 | return NULL; 1414 | } 1415 | 1416 | return patch; 1417 | } 1418 | 1419 | CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON * const from, cJSON * const to) 1420 | { 1421 | return generate_merge_patch(from, to, false); 1422 | } 1423 | 1424 | CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatchCaseSensitive(cJSON * const from, cJSON * const to) 1425 | { 1426 | return generate_merge_patch(from, to, true); 1427 | } 1428 | -------------------------------------------------------------------------------- /cJSON/cJSON_Utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2017 Dave Gamble and cJSON contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #include "cJSON.h" 24 | 25 | /* Implement RFC6901 (https://tools.ietf.org/html/rfc6901) JSON Pointer spec. */ 26 | CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointer(cJSON * const object, const char *pointer); 27 | CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointerCaseSensitive(cJSON * const object, const char *pointer); 28 | 29 | /* Implement RFC6902 (https://tools.ietf.org/html/rfc6902) JSON Patch spec. */ 30 | /* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */ 31 | CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * const to); 32 | CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from, cJSON * const to); 33 | /* Utility for generating patch array entries. */ 34 | CJSON_PUBLIC(void) cJSONUtils_AddPatchToArray(cJSON * const array, const char * const operation, const char * const path, const cJSON * const value); 35 | /* Returns 0 for success. */ 36 | CJSON_PUBLIC(int) cJSONUtils_ApplyPatches(cJSON * const object, const cJSON * const patches); 37 | CJSON_PUBLIC(int) cJSONUtils_ApplyPatchesCaseSensitive(cJSON * const object, const cJSON * const patches); 38 | 39 | /* 40 | // Note that ApplyPatches is NOT atomic on failure. To implement an atomic ApplyPatches, use: 41 | //int cJSONUtils_AtomicApplyPatches(cJSON **object, cJSON *patches) 42 | //{ 43 | // cJSON *modme = cJSON_Duplicate(*object, 1); 44 | // int error = cJSONUtils_ApplyPatches(modme, patches); 45 | // if (!error) 46 | // { 47 | // cJSON_Delete(*object); 48 | // *object = modme; 49 | // } 50 | // else 51 | // { 52 | // cJSON_Delete(modme); 53 | // } 54 | // 55 | // return error; 56 | //} 57 | // Code not added to library since this strategy is a LOT slower. 58 | */ 59 | 60 | /* Implement RFC7386 (https://tools.ietf.org/html/rfc7396) JSON Merge Patch spec. */ 61 | /* target will be modified by patch. return value is new ptr for target. */ 62 | CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatch(cJSON *target, const cJSON * const patch); 63 | CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatchCaseSensitive(cJSON *target, const cJSON * const patch); 64 | /* generates a patch to move from -> to */ 65 | /* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */ 66 | CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON * const from, cJSON * const to); 67 | CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatchCaseSensitive(cJSON * const from, cJSON * const to); 68 | 69 | /* Given a root object and a target object, construct a pointer from one to the other. */ 70 | CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const object, const cJSON * const target); 71 | 72 | /* Sorts the members of the object into alphabetical order. */ 73 | CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object); 74 | CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object); 75 | -------------------------------------------------------------------------------- /cmake_install.cmake: -------------------------------------------------------------------------------- 1 | # Install script for directory: /home/derulin/Downloads/twtxtc/twtxtc 2 | 3 | # Set the install prefix 4 | if(NOT DEFINED CMAKE_INSTALL_PREFIX) 5 | set(CMAKE_INSTALL_PREFIX "/usr/local") 6 | endif() 7 | string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") 8 | 9 | # Set the install configuration name. 10 | if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) 11 | if(BUILD_TYPE) 12 | string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" 13 | CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") 14 | else() 15 | set(CMAKE_INSTALL_CONFIG_NAME "Release") 16 | endif() 17 | message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") 18 | endif() 19 | 20 | # Set the component getting installed. 21 | if(NOT CMAKE_INSTALL_COMPONENT) 22 | if(COMPONENT) 23 | message(STATUS "Install component: \"${COMPONENT}\"") 24 | set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") 25 | else() 26 | set(CMAKE_INSTALL_COMPONENT) 27 | endif() 28 | endif() 29 | 30 | # Install shared libraries without execute permission? 31 | if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) 32 | set(CMAKE_INSTALL_SO_NO_EXE "1") 33 | endif() 34 | 35 | # Is this installation the result of a crosscompile? 36 | if(NOT DEFINED CMAKE_CROSSCOMPILING) 37 | set(CMAKE_CROSSCOMPILING "FALSE") 38 | endif() 39 | 40 | if(CMAKE_INSTALL_COMPONENT) 41 | set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") 42 | else() 43 | set(CMAKE_INSTALL_MANIFEST "install_manifest.txt") 44 | endif() 45 | 46 | string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT 47 | "${CMAKE_INSTALL_MANIFEST_FILES}") 48 | file(WRITE "/home/derulin/Downloads/twtxtc/twtxtc/${CMAKE_INSTALL_MANIFEST}" 49 | "${CMAKE_INSTALL_MANIFEST_CONTENT}") 50 | -------------------------------------------------------------------------------- /twtxt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * twtxtc: A twtxt client in C. 3 | * http://hub.darcs.net/dertuxmalwieder/twtxtc 4 | * 5 | * Licensed under the terms of the WTFPL. 6 | * You just DO WHAT THE FUCK YOU WANT TO. 7 | * 8 | * Uses the cJSON parser, licensed under the 9 | * terms of the MIT License. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 19 | 20 | #ifndef _WIN32 21 | # include /* MAXPATHLEN */ 22 | #else 23 | # ifdef _MSC_VER 24 | # include /* errno */ 25 | # endif 26 | # ifndef NO_COLORS 27 | # define WIN32_LEAN_AND_MEAN 28 | # include /* colored output */ 29 | # endif 30 | #endif 31 | 32 | #include "cJSON/cJSON.h" 33 | #include "cJSON/cJSON_Utils.h" /* for sorting */ 34 | #include "twtxt.h" 35 | 36 | 37 | int main(int argc, char *argv[]) { 38 | /* Find the home directory: */ 39 | #ifdef _MSC_VER 40 | char* buf = NULL; 41 | size_t sz = 0; 42 | if (_dupenv_s(&buf, &sz, "USERPROFILE") == 0 && buf != NULL) { 43 | strcpy_s(homedir, MAXPATHLEN, buf); 44 | free(buf); 45 | } 46 | #elif defined(_WIN32) 47 | strncpy(homedir, getenv("USERPROFILE"), MAXPATHLEN); 48 | #else 49 | strncpy(homedir, getenv("HOME"), MAXPATHLEN); 50 | #endif 51 | 52 | /* Parse arguments: */ 53 | if (argc < 2) { 54 | /* Not even a command was specified. Show usage and exit. */ 55 | showUsage(argv); 56 | return 1; 57 | } 58 | 59 | /* Find the default config file. */ 60 | #ifdef _WIN32 61 | strcpy_s(configfilespec, MAXPATHLEN, homedir); 62 | strcat_s(configfilespec, MAXPATHLEN, "\\.twtxtconfig"); 63 | #else 64 | strncpy(configfilespec, homedir, MAXPATHLEN); 65 | strncat(configfilespec, "/.twtxtconfig", MAXPATHLEN); 66 | #endif 67 | 68 | /* Find the default twtxt file. Requires the config file. */ 69 | #ifdef _WIN32 70 | strcpy_s(twtxtfilespec, MAXPATHLEN, getConfigValue("twtxtfile", "twtxt.txt")); 71 | #else 72 | strncpy(twtxtfilespec, getConfigValue("twtxtfile", "twtxt.txt"), MAXPATHLEN); 73 | #endif 74 | 75 | /* Find the default cURL executable file. */ 76 | #ifdef _WIN32 77 | /* We might or might not be on the PowerShell here. Define curl.exe as the 78 | curlfilespec because the built-in "curl" alias is too unpredictable. 79 | 80 | Note: Does _popen() actually respect shell aliases? I might or might not 81 | want to revisit this in the future. 82 | */ 83 | strcpy_s(curlfilespec, MAXPATHLEN, "curl.exe"); 84 | #else 85 | /* Meh. */ 86 | strncpy(curlfilespec, "curl", MAXPATHLEN); 87 | #endif 88 | 89 | /* argv[1] should be the command now. */ 90 | const char* command = argv[1]; 91 | 92 | if (strcmp(command, "tweet") == 0) { 93 | if (argc != 3) { 94 | /* No valid tweet specified. Show usage and exit. */ 95 | puts("Invalid number of parameters."); 96 | showUsage(argv); 97 | return 1; 98 | } 99 | 100 | /* Add to the twtxt file: */ 101 | FILE* twtxtfile; 102 | const char* text = argv[2]; 103 | 104 | #ifdef _MSC_VER 105 | errno_t err; 106 | if ((err = fopen_s(&twtxtfile, twtxtfilespec, "a")) != 0) { 107 | #else 108 | twtxtfile = fopen(twtxtfilespec, "a"); 109 | if (twtxtfile == NULL) { 110 | #endif 111 | /* Whoops... */ 112 | printf("Could not open '%s' for writing.\n", twtxtfilespec); 113 | puts("Please check the access rights to the specified directory and try again."); 114 | if (wrkbuf != NULL) { 115 | /* Clean up first. */ 116 | free(wrkbuf); 117 | } 118 | return 1; 119 | } 120 | 121 | /* Get the current time string: */ 122 | char timebuf[26]; 123 | time_t now; 124 | now = time(NULL); 125 | strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S%z", localtime(&now)); 126 | 127 | /* Add a colon in the timezone to match the official twtxt client format. 128 | Currently the string has 24 of the 25 available characters, the : needs 129 | to be inserted at pos. 23 (= timebuf[22]). 130 | */ 131 | timebuf[22] = ':'; 132 | timebuf[24] = '0'; 133 | timebuf[sizeof(timebuf)-1] = '\0'; /* Terminate! */ 134 | 135 | /* Write timestamp to file: */ 136 | fputs(timebuf, twtxtfile); 137 | putc('\t', twtxtfile); 138 | 139 | /* Write text with mentions to file: */ 140 | const char *prev_mention = text; 141 | for (;;) { 142 | /* Get mention opener. */ 143 | const char *mention = strchr(prev_mention, '@'); 144 | if (mention == NULL) 145 | break; 146 | /* Skip '@' */ 147 | mention += 1; 148 | 149 | /* Find mention length. */ 150 | size_t mention_len = 0; 151 | while (mention[mention_len] != '\0' && isalnum(mention[mention_len])) 152 | mention_len += 1; 153 | /* Empty mention, display everything up to '@' and continue. */ 154 | if (mention_len == 0) { 155 | fwrite(prev_mention, mention - prev_mention, 1, twtxtfile); 156 | prev_mention = mention; 157 | continue; 158 | } 159 | 160 | /* Write everything preceding mention. */ 161 | fwrite(prev_mention, mention - prev_mention - 1, 1, twtxtfile); 162 | 163 | /* Try to match nick to URL using the .following array. */ 164 | int found_url = 0; 165 | cJSON *following= cJSON_Parse(getConfigValue("following", NULL)); 166 | if (following != NULL) { 167 | for (cJSON *pair = following->child; pair != NULL; pair = pair->next) { 168 | const char *name = pair->string; 169 | const char *url = pair->valuestring; 170 | if (strlen(name) == mention_len && 171 | strncmp(pair->string, mention, mention_len) == 0) 172 | { 173 | /* Found URL, write formatted mention. */ 174 | found_url = 1; 175 | fprintf(twtxtfile, "@<%s %s>", name, url); 176 | break; 177 | } 178 | } 179 | cJSON_Delete(following); 180 | } 181 | 182 | /* Didn't find matching URL, write '@' and continue. */ 183 | if (!found_url) { 184 | putc('@', twtxtfile); 185 | prev_mention = mention; 186 | continue; 187 | } 188 | 189 | /* Skip processed mention. */ 190 | prev_mention = mention + mention_len; 191 | } 192 | fputs(prev_mention, twtxtfile); 193 | putc('\n', twtxtfile); 194 | 195 | /* Done. */ 196 | fclose(twtxtfile); 197 | } 198 | else if (strcmp(command, "timeline") == 0) { 199 | /* Fetch and display the timeline. */ 200 | FILE* curl_exec; 201 | 202 | /* Check for curl availability: */ 203 | char sCurlTestCommand[256]; 204 | sprintf(sCurlTestCommand, "%s 2>&1", curlfilespec); 205 | #ifdef _WIN32 206 | if ((curl_exec = _popen(sCurlTestCommand, "rt")) == NULL) { 207 | #else 208 | if ((curl_exec = popen(sCurlTestCommand, "r")) == NULL) { 209 | #endif 210 | puts("You don't seem to have a cURL executable in your $PATH. Mind to fix that?"); 211 | if (wrkbuf != NULL) { 212 | /* Clean up before returning. */ 213 | free(wrkbuf); 214 | } 215 | return 1; 216 | } 217 | 218 | /* Fetch all timeline txt files: */ 219 | cJSON* followingList = cJSON_Parse(getConfigValue("following", NULL)); 220 | if (followingList != NULL && cJSON_GetArraySize(followingList) > 0) { 221 | tweet_t *ptr = malloc(sizeof(tweet_t)); 222 | cJSON *followingIter = followingList->child; 223 | 224 | size_t iAllTweets = 0; 225 | size_t iLongestNickname = 0; 226 | 227 | while (followingIter) { 228 | /* followingIter->string = the user name 229 | followingIter->valuestring = the URL 230 | 231 | Try to retrieve all "timelines" and add them to 232 | the tweet list: 233 | */ 234 | 235 | char sCurlCommand[256]; 236 | sprintf(sCurlCommand, "%s -s %s", curlfilespec, followingIter->valuestring); 237 | #ifdef _WIN32 238 | curl_exec = _popen(sCurlCommand, "rt"); 239 | #else 240 | curl_exec = popen(sCurlCommand, "r"); 241 | #endif 242 | char output[512]; 243 | while (!feof(curl_exec)) { 244 | if (fgets(output, sizeof(output), curl_exec) != NULL) { 245 | /* Analyze which should contain a valid twtxt tweet now: */ 246 | int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0, tzh = 0, tzm = 0; 247 | int dummy = 0; 248 | char tweet[500]; /* or whatevs */ 249 | 250 | /* There are numerous ways for formatting timestamps in twtxt (because lol standards). */ 251 | char* style1 = "%4d-%2d-%2dT%2d:%2d:%2d+%2d:%2d\t%[^\n]"; /* yyyy-mm-ddThh:mm:ss+hh:mm\tTEXT */ 252 | char* style2 = "%4d-%2d-%2dT%2d:%2d:%2d.%6d+%2d:%2d\t%[^\n]"; /* yyyy-mm-ddThh:mm:ss.millisecs+hh:mm\tTEXT */ 253 | char* style3 = "%4d-%2d-%2dT%2d:%2d:%2dZ\t%[^\n]"; /* yyyy-mm-ddThh:mm:ssZ\tTEXT */ 254 | char* style4 = "%4d-%2d-%2dT%2d:%2d:%2d.%dZ\t%[^\n]"; /* yyyy-mm-ddThh:mm:ss.msZ\tTEXT */ 255 | char* style5 = "%4d-%2d-%2dT%2d:%2d:%2d.%6dZ\t%[^\n]"; /* yyyy-mm-ddThh:mm:ss.msZ\tTEXT */ 256 | 257 | /* Regex would probably be easier to handle here, but adds additional dependencies on some platforms. */ 258 | if (sscanf(output, style1, &year, &month, &day, &hour, &min, &sec, &tzh, &tzm, tweet) != 9) { 259 | if (sscanf(output, style2, &year, &month, &day, &hour, &min, &sec, &dummy, &tzh, &tzm, tweet) != 10) { 260 | if (sscanf(output, style3, &year, &month, &day, &hour, &min, &sec, tweet) != 7) { 261 | if (sscanf(output, style4, &year, &month, &day, &hour, &min, &sec, &dummy, tweet) != 8) { 262 | if (sscanf(output, style5, &year, &month, &day, &hour, &min, &sec, &dummy, tweet) != 8) { 263 | /* Not a valid twtxt tweet. */ 264 | continue; 265 | } 266 | } 267 | } 268 | } 269 | } 270 | 271 | /* Filter out time trolls: */ 272 | time_t now = time(0); 273 | struct tm * timeinfo = localtime(&now); 274 | if (timeinfo->tm_year + 1902 < year) { 275 | /* No chance. */ 276 | continue; 277 | } 278 | 279 | if (strlen(followingIter->string) > iLongestNickname) { 280 | /* We should only check the length of users who actually tweeted recently. 281 | The others are invisible to the user here. 282 | */ 283 | iLongestNickname = strlen(followingIter->string); 284 | } 285 | 286 | /* Mentions to someone else than me are against the, uhm, law or so. */ 287 | char mention[100]; 288 | char url[256]; 289 | char mentiontext[500]; 290 | char initialtext[500]; 291 | 292 | if (sscanf(tweet, "@<%s %[^>]> %s", mention, url, mentiontext) == 3) { 293 | if (strncmp(mention, getConfigValue("nickname", ""), strlen(mention)) != 0) { 294 | /* Nope, not me. */ 295 | continue; 296 | } 297 | else { 298 | /* Reformat. */ 299 | char newtweet[500]; 300 | sprintf(newtweet, "@%s %s", mention, mentiontext); 301 | #ifdef _MSC_VER 302 | strcpy_s(tweet, sizeof(tweet), newtweet); 303 | #else 304 | strncpy(tweet, newtweet, sizeof(tweet)); 305 | #endif 306 | } 307 | } 308 | 309 | /* Reformat inline mentions as well: */ 310 | if (sscanf(tweet, "%[^@] @<%s %[^>]> %s", initialtext, mention, url, mentiontext) == 4) { 311 | /* Reformat. */ 312 | char newtweet[500]; 313 | sprintf(newtweet, "%s @%s %s", initialtext, mention, mentiontext); 314 | #ifdef _MSC_VER 315 | strcpy_s(tweet, sizeof(tweet), newtweet); 316 | #else 317 | strncpy(tweet, newtweet, sizeof(tweet)); 318 | #endif 319 | } 320 | 321 | struct tm tweettime = { 322 | .tm_year = year - 1900, 323 | .tm_mon = month - 1, 324 | .tm_mday = day, 325 | .tm_hour = hour + tzh, 326 | .tm_min = min, 327 | .tm_sec = sec 328 | }; 329 | ptr[iAllTweets].datetime = tweettime; 330 | 331 | #ifdef _MSC_VER 332 | strcpy_s(ptr[iAllTweets].username, 50, followingIter->string); 333 | strcpy_s(ptr[iAllTweets].text, 512, tweet); 334 | #else 335 | strncpy(ptr[iAllTweets].username, followingIter->string, 50); 336 | strncpy(ptr[iAllTweets].text, tweet, 512); 337 | #endif 338 | iAllTweets++; 339 | 340 | /* Add space for more tweets: */ 341 | tweet_t *tmp_ptr; 342 | tmp_ptr = realloc(ptr, (iAllTweets + 1) * sizeof(tweet_t)); 343 | if (tmp_ptr == NULL) { 344 | /* :-( */ 345 | puts("realloc() failed. Panic!"); 346 | if (wrkbuf != NULL) { 347 | /* Don't panic without a cleanup though. */ 348 | free(wrkbuf); 349 | } 350 | return 1; 351 | } else { 352 | // everything went ok, update the original pointer (temp_struct) 353 | ptr = tmp_ptr; 354 | } 355 | } 356 | } 357 | 358 | followingIter = followingIter->next; 359 | } 360 | 361 | /* We need to rearrange the array by sorting by mktime(datetime), 362 | then print the top entries with their user name: */ 363 | tweetsort(ptr, iAllTweets); 364 | 365 | /* We probably have a sorted ptr now. Get its bottom . */ 366 | puts(""); 367 | double maxVal = MIN(atof(getConfigValue("maxlog", "100")), iAllTweets); 368 | printf("These are your newest %d tweets:\n\n", (int) maxVal); 369 | const char* spacing = getConfigValue("spacing", " "); 370 | 371 | int i = 0; /* loop variable */ 372 | int j = 0; /* limiter to maxVal */ 373 | for (i = iAllTweets; i >= 0, j <= maxVal; --i, ++j) { 374 | /* Print the newest tweets (usertweet). */ 375 | if (strlen(ptr[i].username) > iLongestNickname) { 376 | /* Faulty line. */ 377 | continue; 378 | } 379 | 380 | #ifdef NO_COLORS 381 | /* In no-color mode, the user name is prefixed with "@". */ 382 | printf("@%*s%s%s\n", (int) iLongestNickname, ptr[i].username, spacing, ptr[i].text); 383 | #else 384 | # ifdef _WIN32 385 | /* The user prefers colorful text. Hooray. Let's fire up the Windows API! */ 386 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 387 | CONSOLE_SCREEN_BUFFER_INFO consoleInfo; 388 | WORD saved_attributes; 389 | 390 | /* Make the user name yellow and the text white: */ 391 | GetConsoleScreenBufferInfo(hConsole, &consoleInfo); 392 | saved_attributes = consoleInfo.wAttributes; 393 | 394 | SetConsoleTextAttribute(hConsole, 14); /* 14 = yellow because wtf */ 395 | printf("@%*s", (int) iLongestNickname, ptr[i].username); 396 | 397 | /* Restore the original values. */ 398 | SetConsoleTextAttribute(hConsole, saved_attributes); 399 | printf("%s", spacing); 400 | 401 | SetConsoleTextAttribute(hConsole, 15); /* 15 = white because srsly */ 402 | printf("%s\n", ptr[i].text); 403 | 404 | /* Restore the original values again. */ 405 | SetConsoleTextAttribute(hConsole, saved_attributes); 406 | # else 407 | /* POSIX colors are not really more convenient. */ 408 | #define YELLOW "\x1B[33m" /* lol */ 409 | #define WHITE "\x1B[37m" /* actually ... */ 410 | #define RESET "\x1B[0m" /* WHY?! */ 411 | printf(YELLOW "@%*s" RESET "%s" WHITE "%s\n" RESET, (int) iLongestNickname, ptr[i].username, spacing, ptr[i].text); 412 | # endif 413 | #endif 414 | } 415 | 416 | free(ptr); 417 | cJSON_Delete(followingList); 418 | } 419 | 420 | #ifdef _WIN32 421 | _pclose(curl_exec); 422 | #else 423 | pclose(curl_exec); 424 | #endif 425 | } 426 | else if (strcmp(command, "following") == 0) { 427 | /* Fetch and display the subscribed users. */ 428 | listFollowing(getConfigValue("following", NULL)); 429 | if (wrkbuf != NULL) { 430 | puts(wrkbuf); 431 | } 432 | } 433 | else if (strcmp(command, "follow") == 0) { 434 | if (argc != 4) { 435 | /* No valid user+URL specified. Show usage and exit. */ 436 | puts("Invalid number of parameters."); 437 | showUsage(argv); 438 | return 1; 439 | } 440 | 441 | follow(getConfigValue("following", NULL), argv[2], argv[3]); 442 | } 443 | else if (strcmp(command, "unfollow") == 0) { 444 | if (argc != 3) { 445 | /* No valid user name specified. Show usage and exit. */ 446 | puts("Invalid number of parameters."); 447 | showUsage(argv); 448 | return 1; 449 | } 450 | 451 | unfollow(getConfigValue("following", NULL), argv[2]); 452 | } 453 | else if (strcmp(command, "help") == 0) { 454 | /* Display the help and exit. */ 455 | showUsage(argv); 456 | return 0; 457 | } 458 | else { 459 | /* Invalid command specified. Show usage and exit. */ 460 | printf("Invalid command: %s\n", command); 461 | showUsage(argv); 462 | return 1; 463 | } 464 | 465 | if (wrkbuf != NULL) { 466 | free(wrkbuf); 467 | } 468 | return 0; 469 | } 470 | 471 | 472 | void showUsage(char* argv[]) { 473 | /* Displays the available command-line flags. */ 474 | puts(""); 475 | puts("Usage:"); 476 | printf("\t%s [COMMAND]\n", argv[0]); 477 | puts(""); 478 | puts("Commands:"); 479 | puts("\ttweet \t\tAdds to your twtxt timeline."); 480 | puts("\ttimeline\t\tDisplays your twtxt timeline."); 481 | puts("\tfollowing\t\tGives you a list of all people you follow."); 482 | puts("\tfollow \tAdds the twtxt file from to your timeline."); 483 | puts("\t\t\t\t defines the user name to display."); 484 | puts("\tunfollow \t\tRemoves the user with the display name from your timeline."); 485 | puts("\thelp\t\t\tDisplays this help screen.\n"); 486 | puts("Configuration:"); 487 | puts("\ttwtxtc uses the following configuration file:"); 488 | #ifdef _WIN32 489 | printf("\t%s\\.twtxtconfig", homedir); 490 | #else 491 | printf("\t%s/.twtxtconfig", homedir); 492 | #endif 493 | puts("\n"); 494 | } 495 | 496 | 497 | void tweetsort(tweet_t* tweets, int size) { 498 | /* Quicksort over according to mktime(datetime). */ 499 | if (size < 2) { return; } 500 | 501 | int pivot = (int) mktime(&tweets[size / 2].datetime); 502 | 503 | int i, j; 504 | for (i = 0, j = size - 1; ; i++, j--) { 505 | while (mktime(&tweets[i].datetime) < pivot) { i++; } 506 | while (mktime(&tweets[j].datetime) > pivot) { j--; } 507 | 508 | if (i >= j) { break; } 509 | 510 | tweet_t temp = tweets[i]; 511 | tweets[i] = tweets[j]; 512 | tweets[j] = temp; 513 | } 514 | 515 | tweetsort(tweets, i); 516 | tweetsort(tweets + i, size - i); 517 | } 518 | 519 | 520 | cJSON* getConfigFile(void) { 521 | /* Returns the config. file as JSON object or NULL on errors. */ 522 | FILE *configfile; 523 | char* configstring; 524 | long lSize; 525 | 526 | /* Read the config file: */ 527 | configfile = fopen(configfilespec, "ab+"); 528 | if (!configfile) { 529 | /* Failed to read the file, suddenly...? */ 530 | printf("Could not open '%s'.\n", configfilespec); 531 | return NULL; 532 | } 533 | 534 | fseek(configfile, 0L, SEEK_END); 535 | lSize = ftell(configfile); 536 | rewind(configfile); 537 | 538 | configstring = calloc(1, lSize + 1); 539 | if (!configstring) { 540 | /* Allocation failed. */ 541 | puts("Memory allocation failed."); 542 | fclose(configfile); 543 | return NULL; 544 | } 545 | 546 | if (lSize > 0 && fread(configstring, lSize, 1, configfile) != 1) { 547 | /* File reading failed. */ 548 | fclose(configfile); 549 | free(configstring); 550 | puts("Could not read from the configuration file. You should check that."); 551 | return NULL; 552 | } 553 | 554 | fclose(configfile); 555 | 556 | /* Now parse the JSON. */ 557 | cJSON* ret = cJSON_Parse(lSize > 0 ? configstring : "{}"); 558 | free(configstring); 559 | 560 | return ret; 561 | } 562 | 563 | 564 | const char* getConfigValue(const char* key, const char* defaultvalue) { 565 | /* Reads the configuration value from . 566 | * Returns if the configuration file does not 567 | * exist or the key could not be found. */ 568 | cJSON* root = getConfigFile(); 569 | 570 | if (root == NULL) { 571 | /* Invalid configuration file, probably. */ 572 | puts("Please validate your .twtxtconfig format - we could not parse it. :-("); 573 | return defaultvalue; 574 | } 575 | 576 | if (strcmp(key, "following") == 0) { 577 | /* The list of users you follow is an object. Return it as such. */ 578 | return cJSON_Print(cJSON_GetObjectItem(root, "following")); 579 | } 580 | 581 | /* Parse the configuration file. */ 582 | char strvalue[512]; 583 | 584 | cJSON *jsonValue = cJSON_GetObjectItem(root, key); 585 | if (jsonValue == NULL) { 586 | /* We don't have this value. Return what was said to be normal. */ 587 | return defaultvalue; 588 | } 589 | 590 | /* Allocate some space: */ 591 | wrkbuf = (char *)malloc(sizeof(strvalue)); 592 | 593 | #ifdef _MSC_VER 594 | if (cJSON_IsNumber(jsonValue)) { 595 | sprintf_s(strvalue, sizeof(strvalue), "%f", jsonValue->valuedouble); 596 | } 597 | else { 598 | sprintf_s(strvalue, sizeof(strvalue), "%s", jsonValue->valuestring); 599 | } 600 | strcpy_s(wrkbuf, sizeof(strvalue), strvalue); 601 | #else 602 | if (cJSON_IsNumber(jsonValue)) { 603 | sprintf(strvalue, "%f", jsonValue->valuedouble); 604 | } 605 | else { 606 | sprintf(strvalue, "%s", jsonValue->valuestring); 607 | } 608 | strncpy(wrkbuf, strvalue, sizeof(strvalue)); 609 | #endif 610 | 611 | /* Cleanup */ 612 | cJSON_Delete(root); 613 | 614 | return wrkbuf == NULL ? defaultvalue : wrkbuf; 615 | } 616 | 617 | 618 | void listFollowing(const char* followingJSON) { 619 | /* Puts the list of users you follow into . */ 620 | cJSON *following = cJSON_Parse(followingJSON); 621 | 622 | if (following == NULL || cJSON_GetArraySize(following) == 0) { 623 | puts("You are not following any users yet.\n"); 624 | return; 625 | } 626 | 627 | /* There actually are people you follow. */ 628 | wrkbuf = (char *)malloc(4096); /* 4 KiB should be enough for now */ 629 | #ifdef _MSC_VER 630 | strcpy_s(wrkbuf, 4096, ""); 631 | #else 632 | strncpy(wrkbuf, "", 4096); 633 | #endif 634 | 635 | puts(""); 636 | puts("You are following these users:"); 637 | 638 | /* Sort the list first: */ 639 | cJSONUtils_SortObject(following); 640 | 641 | cJSON *followinglist = following->child; 642 | while (followinglist) { 643 | /* Traverse through the list. */ 644 | char strvalue[400]; 645 | 646 | #ifdef _MSC_VER 647 | sprintf_s(strvalue, sizeof(strvalue), " @%-20s [ %s ]\n", followinglist->string, followinglist->valuestring); 648 | strcat_s(wrkbuf, sizeof(strvalue), strvalue); 649 | #else 650 | sprintf(strvalue, " @%-20s [ %s ]", followinglist->string, followinglist->valuestring); 651 | strncat(wrkbuf, strvalue, sizeof(wrkbuf)); 652 | #endif 653 | followinglist = followinglist->next; 654 | } 655 | 656 | cJSON_Delete(followinglist); 657 | cJSON_Delete(following); 658 | } 659 | 660 | 661 | void follow(const char* followingJSON, const char* username, const char* URL) { 662 | /* Tries to follow . */ 663 | cJSON *following = cJSON_Parse(followingJSON); 664 | 665 | int hasFollowingList = 1; 666 | if (following == NULL) { 667 | /* This would be the first user to follow ... */ 668 | following = cJSON_CreateObject(); 669 | hasFollowingList = 0; 670 | } 671 | 672 | /* Avoid duplicates. */ 673 | cJSON *followinglist = following->child; 674 | 675 | while (followinglist) { 676 | /* followinglist->string = the user name */ 677 | if (strncmp(followinglist->string, username, strlen(followinglist->string)) == 0) { 678 | /* This is the user. */ 679 | puts("You already follow this user."); 680 | 681 | /* Clean up. */ 682 | cJSON_Delete(following); 683 | return; 684 | } 685 | 686 | followinglist = followinglist->next; 687 | } 688 | 689 | /* Add the data. */ 690 | cJSON_AddStringToObject(following, username, URL); 691 | 692 | /* Write the list back. */ 693 | cJSON* cjconfig = getConfigFile(); 694 | if (cjconfig != NULL) { 695 | if (hasFollowingList == 0) { 696 | /* The user had no following list up to this point. Add one. */ 697 | cJSON_AddItemToObject(cjconfig, "following", following); 698 | } 699 | else { 700 | cJSON_ReplaceItemInObject(cjconfig, "following", following); 701 | } 702 | FILE* configfile; 703 | #ifdef _MSC_VER 704 | errno_t err; 705 | if ((err = fopen_s(&configfile, configfilespec, "w")) != 0) { 706 | #else 707 | configfile = fopen(configfilespec, "w"); 708 | if (configfile == NULL) { 709 | #endif 710 | /* Whoops... */ 711 | printf("Could not open '%s' for writing.\n", configfilespec); 712 | puts("Please check the access rights and try again."); 713 | } 714 | else { 715 | fprintf(configfile, "%s", cJSON_Print(cjconfig)); 716 | fclose(configfile); 717 | 718 | printf("You follow @%s now.\n", username); 719 | } 720 | 721 | free(cjconfig); 722 | } 723 | 724 | cJSON_Delete(following); 725 | } 726 | 727 | void unfollow(const char* followingJSON, const char* username) { 728 | /* Tries to unfollow . */ 729 | cJSON *following = cJSON_Parse(followingJSON); 730 | 731 | if (following == NULL) { 732 | puts("You are not following any users yet."); 733 | return; 734 | } 735 | 736 | cJSON *followinglist = following->child; 737 | cJSON *newList = cJSON_CreateObject(); 738 | int foundUser = 0; 739 | 740 | while (followinglist) { 741 | /* followinglist->string = the user name */ 742 | if (strncmp(followinglist->string, username, strlen(followinglist->string)) == 0) { 743 | /* This is the user. Skip it. */ 744 | foundUser = 1; 745 | followinglist = followinglist->next; 746 | continue; 747 | } 748 | 749 | /* Build a new list by copying the old one minus the user to unfollow. */ 750 | cJSON_AddStringToObject(newList, followinglist->string, followinglist->valuestring); 751 | followinglist = followinglist->next; 752 | } 753 | 754 | if (!foundUser) { 755 | /* We can't unfollow a user we don't follow. */ 756 | puts("You do not follow this user."); 757 | } 758 | else { 759 | /* Write newList back into the configuration file. */ 760 | cJSON* cjconfig = getConfigFile(); 761 | if (cjconfig != NULL) { 762 | cJSON_ReplaceItemInObject(cjconfig, "following", newList); 763 | FILE* configfile; 764 | #ifdef _MSC_VER 765 | errno_t err; 766 | if ((err = fopen_s(&configfile, configfilespec, "w")) != 0) { 767 | #else 768 | configfile = fopen(configfilespec, "w"); 769 | if (configfile == NULL) { 770 | #endif 771 | /* Whoops... */ 772 | printf("Could not open '%s' for writing.\n", configfilespec); 773 | puts("Please check the access rights and try again."); 774 | } 775 | else { 776 | fprintf(configfile, "%s", cJSON_Print(cjconfig)); 777 | fclose(configfile); 778 | } 779 | } 780 | 781 | free(cjconfig); 782 | } 783 | cJSON_Delete(following); 784 | cJSON_Delete(newList); 785 | } 786 | -------------------------------------------------------------------------------- /twtxt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * twtxtc: A twtxt client in C. 3 | * http://hub.darcs.net/dertuxmalwieder/twtxtc 4 | * 5 | * Licensed under the terms of the WTFPL. 6 | * You just DO WHAT THE FUCK YOU WANT TO. 7 | * 8 | * Uses the cJSON parser, licensed under the 9 | * terms of the MIT License. 10 | */ 11 | 12 | #include 13 | #include "cJSON/cJSON.h" 14 | 15 | #ifdef _WIN32 16 | /* We need the path length first. */ 17 | #include 18 | #define MAXPATHLEN _MAX_PATH 19 | #endif 20 | 21 | char* wrkbuf; 22 | 23 | typedef struct _tweet_t { 24 | struct tm datetime; 25 | char username[50]; 26 | char text[512]; 27 | } tweet_t; 28 | 29 | 30 | /* PATHS */ 31 | 32 | char homedir[MAXPATHLEN]; 33 | char configfilespec[MAXPATHLEN]; 34 | char twtxtfilespec[MAXPATHLEN]; 35 | char curlfilespec[MAXPATHLEN]; 36 | 37 | 38 | /* FUNCTIONS */ 39 | 40 | void showUsage(char* argv[]); 41 | cJSON* getConfigFile(void); 42 | const char* getConfigValue(const char* key, const char* defaultvalue); 43 | 44 | void listFollowing(const char* followingJSON); 45 | void follow(const char* followingJSON, const char* username, const char* URL); 46 | void unfollow(const char* followingJSON, const char* username); 47 | void tweetsort(tweet_t* tweets, int size); 48 | -------------------------------------------------------------------------------- /twtxtc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neauoire/twtxtc/b1315b02c794b4429011f5f7565d574b452b529d/twtxtc --------------------------------------------------------------------------------