diff --git a/td/generate/tl-parser/CMakeLists.txt b/td/generate/tl-parser/CMakeLists.txt index fd178b3ef..251eb2b39 100644 --- a/td/generate/tl-parser/CMakeLists.txt +++ b/td/generate/tl-parser/CMakeLists.txt @@ -1,20 +1,19 @@ -cmake_minimum_required(VERSION 3.0) -project(tl-parser) +cmake_minimum_required(VERSION 3.0 FATAL_ERROR) + +project(tl-parser LANGUAGES C) set(SOURCES crc32.h crc32.c tlc.c tl-parser.c tl-parser.h tl-parser-tree.h tl-tl.h portable_endian.h) if (WIN32) - list(APPEND SOURCES wingetopt.c wingetopt.h) + add_definitions("-D_CRT_SECURE_NO_WARNINGS") + list(APPEND SOURCES wgetopt.c wgetopt.h) + if (MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8 /wd4101 /wd4244 /wd4267") + endif() endif() -if (MSVC) - set(CMAKE_EXE_LINKER_FLAGS "/SUBSYSTEM:CONSOLE") -endif() - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG .) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE .) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO .) add_executable(${PROJECT_NAME} ${SOURCES}) + if (NOT WIN32) - target_link_libraries(${PROJECT_NAME} m) + target_link_libraries(${PROJECT_NAME} m) endif() diff --git a/td/generate/tl-parser/crc32.c b/td/generate/tl-parser/crc32.c index c73f64341..b7e02181b 100644 --- a/td/generate/tl-parser/crc32.c +++ b/td/generate/tl-parser/crc32.c @@ -26,13 +26,6 @@ #include "crc32.h" -static inline unsigned _bswap32(unsigned x) { - return ((x << 24) & 0xff000000 ) | - ((x << 8) & 0x00ff0000 ) | - ((x >> 8) & 0x0000ff00 ) | - ((x >> 24) & 0x000000ff ); -} - unsigned int crc32_table[256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, @@ -304,36 +297,7 @@ unsigned int crc32_table0[256] = { 0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1, }; -unsigned crc32_partial_old (const void *data, int len, unsigned crc) { - const char *p = data; - for (; len > 0; len--) { - crc = crc32_table[(crc ^ *p++) & 0xff] ^ (crc >> 8); - } - return crc; -} - -/* -unsigned crc32_partial_fast (const void *data, int len, unsigned crc) { - const int *p = (const int *) data; - int x; - for (x = (len >> 2); x > 0; x--) { - crc ^= *p++; - crc = crc32_table0[crc & 0xff] ^ crc32_table1[(crc & 0xff00) >> 8] ^ crc32_table2[(crc & 0xff0000) >> 16] ^ crc32_table[crc >> 24]; - } - const char *q = (const char *) p; - switch (len & 3) { - case 3: - crc = crc32_table[(crc ^ *q++) & 0xff] ^ (crc >> 8); - case 2: - crc = crc32_table[(crc ^ *q++) & 0xff] ^ (crc >> 8); - case 1: - crc = crc32_table[(crc ^ *q++) & 0xff] ^ (crc >> 8); - } - return crc; -} -*/ - -unsigned crc32_partial (const void *data, int len, unsigned crc) { +static unsigned int crc32_partial (const void *data, int len, unsigned crc) { const int *p = (const int *) data; int x; #define DO_ONE(v) crc ^= v; crc = crc32_table0[crc & 0xff] ^ crc32_table1[(crc & 0xff00) >> 8] ^ crc32_table2[(crc & 0xff0000) >> 16] ^ crc32_table[crc >> 24]; @@ -375,289 +339,7 @@ unsigned crc32_partial (const void *data, int len, unsigned crc) { return crc; } -unsigned compute_crc32 (const void *data, int len) { +unsigned int compute_crc32 (const void *data, int len) { return crc32_partial (data, len, -1) ^ -1; } -unsigned long long crc64_table[256] = { - 0x0000000000000000LL, 0xb32e4cbe03a75f6fLL, 0xf4843657a840a05bLL, 0x47aa7ae9abe7ff34LL, - 0x7bd0c384ff8f5e33LL, 0xc8fe8f3afc28015cLL, 0x8f54f5d357cffe68LL, 0x3c7ab96d5468a107LL, - 0xf7a18709ff1ebc66LL, 0x448fcbb7fcb9e309LL, 0x0325b15e575e1c3dLL, 0xb00bfde054f94352LL, - 0x8c71448d0091e255LL, 0x3f5f08330336bd3aLL, 0x78f572daa8d1420eLL, 0xcbdb3e64ab761d61LL, - 0x7d9ba13851336649LL, 0xceb5ed8652943926LL, 0x891f976ff973c612LL, 0x3a31dbd1fad4997dLL, - 0x064b62bcaebc387aLL, 0xb5652e02ad1b6715LL, 0xf2cf54eb06fc9821LL, 0x41e11855055bc74eLL, - 0x8a3a2631ae2dda2fLL, 0x39146a8fad8a8540LL, 0x7ebe1066066d7a74LL, 0xcd905cd805ca251bLL, - 0xf1eae5b551a2841cLL, 0x42c4a90b5205db73LL, 0x056ed3e2f9e22447LL, 0xb6409f5cfa457b28LL, - 0xfb374270a266cc92LL, 0x48190ecea1c193fdLL, 0x0fb374270a266cc9LL, 0xbc9d3899098133a6LL, - 0x80e781f45de992a1LL, 0x33c9cd4a5e4ecdceLL, 0x7463b7a3f5a932faLL, 0xc74dfb1df60e6d95LL, - 0x0c96c5795d7870f4LL, 0xbfb889c75edf2f9bLL, 0xf812f32ef538d0afLL, 0x4b3cbf90f69f8fc0LL, - 0x774606fda2f72ec7LL, 0xc4684a43a15071a8LL, 0x83c230aa0ab78e9cLL, 0x30ec7c140910d1f3LL, - 0x86ace348f355aadbLL, 0x3582aff6f0f2f5b4LL, 0x7228d51f5b150a80LL, 0xc10699a158b255efLL, - 0xfd7c20cc0cdaf4e8LL, 0x4e526c720f7dab87LL, 0x09f8169ba49a54b3LL, 0xbad65a25a73d0bdcLL, - 0x710d64410c4b16bdLL, 0xc22328ff0fec49d2LL, 0x85895216a40bb6e6LL, 0x36a71ea8a7ace989LL, - 0x0adda7c5f3c4488eLL, 0xb9f3eb7bf06317e1LL, 0xfe5991925b84e8d5LL, 0x4d77dd2c5823b7baLL, - 0x64b62bcaebc387a1LL, 0xd7986774e864d8ceLL, 0x90321d9d438327faLL, 0x231c512340247895LL, - 0x1f66e84e144cd992LL, 0xac48a4f017eb86fdLL, 0xebe2de19bc0c79c9LL, 0x58cc92a7bfab26a6LL, - 0x9317acc314dd3bc7LL, 0x2039e07d177a64a8LL, 0x67939a94bc9d9b9cLL, 0xd4bdd62abf3ac4f3LL, - 0xe8c76f47eb5265f4LL, 0x5be923f9e8f53a9bLL, 0x1c4359104312c5afLL, 0xaf6d15ae40b59ac0LL, - 0x192d8af2baf0e1e8LL, 0xaa03c64cb957be87LL, 0xeda9bca512b041b3LL, 0x5e87f01b11171edcLL, - 0x62fd4976457fbfdbLL, 0xd1d305c846d8e0b4LL, 0x96797f21ed3f1f80LL, 0x2557339fee9840efLL, - 0xee8c0dfb45ee5d8eLL, 0x5da24145464902e1LL, 0x1a083bacedaefdd5LL, 0xa9267712ee09a2baLL, - 0x955cce7fba6103bdLL, 0x267282c1b9c65cd2LL, 0x61d8f8281221a3e6LL, 0xd2f6b4961186fc89LL, - 0x9f8169ba49a54b33LL, 0x2caf25044a02145cLL, 0x6b055fede1e5eb68LL, 0xd82b1353e242b407LL, - 0xe451aa3eb62a1500LL, 0x577fe680b58d4a6fLL, 0x10d59c691e6ab55bLL, 0xa3fbd0d71dcdea34LL, - 0x6820eeb3b6bbf755LL, 0xdb0ea20db51ca83aLL, 0x9ca4d8e41efb570eLL, 0x2f8a945a1d5c0861LL, - 0x13f02d374934a966LL, 0xa0de61894a93f609LL, 0xe7741b60e174093dLL, 0x545a57dee2d35652LL, - 0xe21ac88218962d7aLL, 0x5134843c1b317215LL, 0x169efed5b0d68d21LL, 0xa5b0b26bb371d24eLL, - 0x99ca0b06e7197349LL, 0x2ae447b8e4be2c26LL, 0x6d4e3d514f59d312LL, 0xde6071ef4cfe8c7dLL, - 0x15bb4f8be788911cLL, 0xa6950335e42fce73LL, 0xe13f79dc4fc83147LL, 0x521135624c6f6e28LL, - 0x6e6b8c0f1807cf2fLL, 0xdd45c0b11ba09040LL, 0x9aefba58b0476f74LL, 0x29c1f6e6b3e0301bLL, - 0xc96c5795d7870f42LL, 0x7a421b2bd420502dLL, 0x3de861c27fc7af19LL, 0x8ec62d7c7c60f076LL, - 0xb2bc941128085171LL, 0x0192d8af2baf0e1eLL, 0x4638a2468048f12aLL, 0xf516eef883efae45LL, - 0x3ecdd09c2899b324LL, 0x8de39c222b3eec4bLL, 0xca49e6cb80d9137fLL, 0x7967aa75837e4c10LL, - 0x451d1318d716ed17LL, 0xf6335fa6d4b1b278LL, 0xb199254f7f564d4cLL, 0x02b769f17cf11223LL, - 0xb4f7f6ad86b4690bLL, 0x07d9ba1385133664LL, 0x4073c0fa2ef4c950LL, 0xf35d8c442d53963fLL, - 0xcf273529793b3738LL, 0x7c0979977a9c6857LL, 0x3ba3037ed17b9763LL, 0x888d4fc0d2dcc80cLL, - 0x435671a479aad56dLL, 0xf0783d1a7a0d8a02LL, 0xb7d247f3d1ea7536LL, 0x04fc0b4dd24d2a59LL, - 0x3886b22086258b5eLL, 0x8ba8fe9e8582d431LL, 0xcc0284772e652b05LL, 0x7f2cc8c92dc2746aLL, - 0x325b15e575e1c3d0LL, 0x8175595b76469cbfLL, 0xc6df23b2dda1638bLL, 0x75f16f0cde063ce4LL, - 0x498bd6618a6e9de3LL, 0xfaa59adf89c9c28cLL, 0xbd0fe036222e3db8LL, 0x0e21ac88218962d7LL, - 0xc5fa92ec8aff7fb6LL, 0x76d4de52895820d9LL, 0x317ea4bb22bfdfedLL, 0x8250e80521188082LL, - 0xbe2a516875702185LL, 0x0d041dd676d77eeaLL, 0x4aae673fdd3081deLL, 0xf9802b81de97deb1LL, - 0x4fc0b4dd24d2a599LL, 0xfceef8632775faf6LL, 0xbb44828a8c9205c2LL, 0x086ace348f355aadLL, - 0x34107759db5dfbaaLL, 0x873e3be7d8faa4c5LL, 0xc094410e731d5bf1LL, 0x73ba0db070ba049eLL, - 0xb86133d4dbcc19ffLL, 0x0b4f7f6ad86b4690LL, 0x4ce50583738cb9a4LL, 0xffcb493d702be6cbLL, - 0xc3b1f050244347ccLL, 0x709fbcee27e418a3LL, 0x3735c6078c03e797LL, 0x841b8ab98fa4b8f8LL, - 0xadda7c5f3c4488e3LL, 0x1ef430e13fe3d78cLL, 0x595e4a08940428b8LL, 0xea7006b697a377d7LL, - 0xd60abfdbc3cbd6d0LL, 0x6524f365c06c89bfLL, 0x228e898c6b8b768bLL, 0x91a0c532682c29e4LL, - 0x5a7bfb56c35a3485LL, 0xe955b7e8c0fd6beaLL, 0xaeffcd016b1a94deLL, 0x1dd181bf68bdcbb1LL, - 0x21ab38d23cd56ab6LL, 0x9285746c3f7235d9LL, 0xd52f0e859495caedLL, 0x6601423b97329582LL, - 0xd041dd676d77eeaaLL, 0x636f91d96ed0b1c5LL, 0x24c5eb30c5374ef1LL, 0x97eba78ec690119eLL, - 0xab911ee392f8b099LL, 0x18bf525d915feff6LL, 0x5f1528b43ab810c2LL, 0xec3b640a391f4fadLL, - 0x27e05a6e926952ccLL, 0x94ce16d091ce0da3LL, 0xd3646c393a29f297LL, 0x604a2087398eadf8LL, - 0x5c3099ea6de60cffLL, 0xef1ed5546e415390LL, 0xa8b4afbdc5a6aca4LL, 0x1b9ae303c601f3cbLL, - 0x56ed3e2f9e224471LL, 0xe5c372919d851b1eLL, 0xa26908783662e42aLL, 0x114744c635c5bb45LL, - 0x2d3dfdab61ad1a42LL, 0x9e13b115620a452dLL, 0xd9b9cbfcc9edba19LL, 0x6a978742ca4ae576LL, - 0xa14cb926613cf817LL, 0x1262f598629ba778LL, 0x55c88f71c97c584cLL, 0xe6e6c3cfcadb0723LL, - 0xda9c7aa29eb3a624LL, 0x69b2361c9d14f94bLL, 0x2e184cf536f3067fLL, 0x9d36004b35545910LL, - 0x2b769f17cf112238LL, 0x9858d3a9ccb67d57LL, 0xdff2a94067518263LL, 0x6cdce5fe64f6dd0cLL, - 0x50a65c93309e7c0bLL, 0xe388102d33392364LL, 0xa4226ac498dedc50LL, 0x170c267a9b79833fLL, - 0xdcd7181e300f9e5eLL, 0x6ff954a033a8c131LL, 0x28532e49984f3e05LL, 0x9b7d62f79be8616aLL, - 0xa707db9acf80c06dLL, 0x14299724cc279f02LL, 0x5383edcd67c06036LL, 0xe0ada17364673f59LL -}; - -unsigned long long crc64_partial (const void *data, int len, unsigned long long crc) { - const char *p = data; - for (; len > 0; len--) { - crc = crc64_table[(crc ^ *p++) & 0xff] ^ (crc >> 8); - } - return crc; -} - -unsigned long long crc64 (const void *data, int len) { - return crc64_partial (data, len, -1LL) ^ -1LL; -} - -static unsigned gf32_matrix_times (unsigned *matrix, unsigned vector) { - unsigned sum = 0; - while (vector) { - if (vector & 1) { - sum ^= *matrix; - } - vector >>= 1; - matrix++; - } - return sum; -} - -static void gf32_matrix_square (unsigned *square, unsigned *matrix) { - int n = 0; - do { - square[n] = gf32_matrix_times (matrix, matrix[n]); - } while (++n < 32); -} - -unsigned compute_crc32_combine (unsigned crc1, unsigned crc2, int len2) { - assert (len2 < (1 << 29)); - static int power_buf_initialized = 0; - static unsigned power_buf[1024]; - int n; - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) { - return crc1; - } - if (!power_buf_initialized) { - power_buf[0] = 0xedb88320UL; - for (n = 0; n < 31; n++) { - power_buf[n+1] = 1U << n; - } - for (n = 1; n < 32; n++) { - gf32_matrix_square (power_buf + (n << 5), power_buf + ((n - 1) << 5)); - } - power_buf_initialized = 1; - } - - unsigned int *p = power_buf + 64; - do { - p += 32; - if (len2 & 1) { - crc1 = gf32_matrix_times (p, crc1); - } - len2 >>= 1; - } while (len2); - return crc1 ^ crc2; -} - - -/********************************* crc32 repair ************************/ -struct fcb_table_entry { - unsigned p; //zeta ^ k - int i; -}; - -static inline unsigned gf32_mod (unsigned long long r, int high_bit) { - int j = high_bit; - for (j = high_bit; j >= 32; j--) { - if ((1ULL << j) & r) { - r ^= 0x04C11DB7ULL << (j - 32); - } - } - return (unsigned) r; -} - -static unsigned gf32_mult (unsigned a, unsigned b) { - int i; - const unsigned long long m = b; - unsigned long long r = 0; - for (i = 0; i < 32; i++) { - if (a & (1U << i)) { - r ^= m << i; - } - } - return gf32_mod (r, 62); -} - -static unsigned gf32_shl (unsigned int a, int shift) { - unsigned long long r = a; - r <<= shift; - return gf32_mod (r, 31 + shift); -} - -static unsigned gf32_pow (unsigned a, int k) { - if (!k) { return 1; } - unsigned x = gf32_pow (gf32_mult (a, a), k >> 1); - if (k & 1) { - x = gf32_mult (x, a); - } - return x; -} - -static int cmp_fcb_table_entry (const void *a, const void *b) { - const struct fcb_table_entry *x = a; - const struct fcb_table_entry *y = b; - if (x->p < y->p) { return -1; } - if (x->p > y->p) { return 1; } - if (x->i < y->i) { return -1; } - if (x->i > y->i) { return 1; } - return 0; -} - -#define GROUP_SWAP(x,m,s) ((x & m) << s) | ((x & (~m)) >> s) -static unsigned revbin (unsigned x) { - x = GROUP_SWAP(x,0x55555555U,1); - x = GROUP_SWAP(x,0x33333333U,2); - x = GROUP_SWAP(x,0x0f0f0f0fU,4); - x = _bswap32 (x); - return x; -} -#undef GROUP_SWAP - -static inline unsigned xmult (unsigned a) { - unsigned r = a << 1; - if (a & (1U<<31)) { - r ^= 0x04C11DB7U; - } - return r; -} - -static int find_corrupted_bit (int size, unsigned d) { - int i, j; - size += 4; - d = revbin (d); - int n = size << 3; - int r = (int) (sqrt (n) + 0.5); - struct fcb_table_entry *T = calloc (r, sizeof (struct fcb_table_entry)); - assert (T != NULL); - T[0].i = 0; - T[0].p = 1; - for (i = 1; i < r; i++) { - T[i].i = i; - T[i].p = xmult (T[i-1].p); - } - assert (xmult (0x82608EDB) == 1); - qsort (T, r, sizeof (T[0]), cmp_fcb_table_entry); - unsigned q = gf32_pow (0x82608EDB, r); - - unsigned A[32]; - for (i = 0; i < 32; i++) { - A[i] = gf32_shl (q, i); - } - - unsigned x = d; - int max_j = n / r, res = -1; - for (j = 0; j <= max_j; j++) { - int a = -1, b = r; - while (b - a > 1) { - int c = ((a + b) >> 1); - if (T[c].p <= x) { a = c; } else { b = c; } - } - if (a >= 0 && T[a].p == x) { - res = T[a].i + r * j; - break; - } - x = gf32_matrix_times (A, x); - } - free (T); - return res; -} - -static int repair_bit (unsigned char *input, int l, int k) { - if (k < 0) { - return -1; - } - int idx = k >> 5, bit = k & 31, i = (l - 1) - (idx - 1) * 4; - while (bit >= 8) { - i--; - bit -= 8; - } - if (i < 0) { - return -2; - } - if (i >= l) { - return -3; - } - int j = 7 - bit; - input[i] ^= 1 << j; - return 0; -} - -int crc32_check_and_repair (void *input, int l, unsigned *input_crc32, int force_exit) { - unsigned computed_crc32 = compute_crc32 (input, l); - const unsigned crc32_diff = computed_crc32 ^ (*input_crc32); - if (!crc32_diff) { - return 0; - } - int k = find_corrupted_bit (l, crc32_diff); - int r = repair_bit (input, l, k); - if (!r) { - assert (compute_crc32 (input, l) == *input_crc32); - return 1; - } - if (!(crc32_diff & (crc32_diff - 1))) { /* crc32_diff is power of 2 */ - *input_crc32 = computed_crc32; - return 2; - } - assert (!force_exit); - *input_crc32 = computed_crc32; - return -1; -} diff --git a/td/generate/tl-parser/crc32.h b/td/generate/tl-parser/crc32.h index fdf8da89c..b461784b3 100644 --- a/td/generate/tl-parser/crc32.h +++ b/td/generate/tl-parser/crc32.h @@ -28,29 +28,7 @@ extern "C" { #endif -extern unsigned int crc32_table[256]; -unsigned crc32_partial (const void *data, int len, unsigned crc); - //unsigned crc32_partial_fast (const void *data, int len, unsigned crc); - //unsigned crc32_partial_fastest (const void *data, int len, unsigned crc); -unsigned compute_crc32 (const void *data, int len); -unsigned compute_crc32_combine (unsigned crc1, unsigned crc2, int len2); - -extern unsigned long long crc64_table[256]; -unsigned long long crc64_partial (const void *data, int len, unsigned long long crc); -unsigned long long crc64 (const void *data, int len); - -//unsigned gf32_matrix_times (unsigned *matrix, unsigned vector); - -/* crc32_check_and_repair returns - 0 : Cyclic redundancy check is ok - 1 : Cyclic redundancy check fails, but we fix one bit in input - 2 : Cyclic redundancy check fails, but we fix one bit in input_crc32 - -1 : Cyclic redundancy check fails, no repair possible. - In this case *input_crc32 will be equal crc32 (input, l) - - Case force_exit == 1 (case 1, 2: kprintf call, case -1: assert fail). -*/ -int crc32_check_and_repair (void *input, int l, unsigned *input_crc32, int force_exit); +unsigned int compute_crc32 (const void *data, int len); #ifdef __cplusplus } diff --git a/td/generate/tl-parser/portable_endian.h b/td/generate/tl-parser/portable_endian.h index b39a51ea6..9f6d2f41c 100644 --- a/td/generate/tl-parser/portable_endian.h +++ b/td/generate/tl-parser/portable_endian.h @@ -65,9 +65,9 @@ #elif defined(__WINDOWS__) # include -# ifdef __MINGW32__ +#ifdef __MINGW32__ # include -# endif +#endif # if BYTE_ORDER == LITTLE_ENDIAN diff --git a/td/generate/tl-parser/tl-parser.c b/td/generate/tl-parser/tl-parser.c index 7f03766cc..04c9ab4af 100644 --- a/td/generate/tl-parser/tl-parser.c +++ b/td/generate/tl-parser/tl-parser.c @@ -24,24 +24,19 @@ #define _FILE_OFFSET_BITS 64 -#if defined(_MSC_VER) -#include -#include -#include -#else -#include -#endif #include #include #include +#include #include #include +#include #include #include -#include "crc32.h" #include "portable_endian.h" #include "tl-parser-tree.h" #include "tl-parser.h" +#include "crc32.h" #include "tl-tl.h" extern int verbosity; @@ -66,12 +61,6 @@ int total_functions_num; #define talloc0(a) calloc(a,1) #define tstrdup(a) strdup(a) -#define TL_FAIL return 0; -#define TL_INIT(x) struct tl_combinator_tree *x = 0; -#define TL_TRY(f,x) { struct tl_combinator_tree *_t = f; if (!_t) { TL_FAIL;} x = tl_union (x, _t); if (!x) { TL_FAIL; }} -#define TL_ERROR(...) fprintf (stderr, __VA_ARGS__); -#define TL_WARNING(...) fprintf (stderr, __VA_ARGS__); - typedef char error_int_must_be_4_byte[(sizeof (int) == 4) ? 1 : -1]; typedef char error_long_long_must_be_8_byte[(sizeof (long long) == 8) ? 1 : -1]; @@ -82,10 +71,7 @@ struct tree *tree; struct tree *tree_alloc (void) { struct tree *T = talloc (sizeof (*T)); - if (!T) { - TL_ERROR("Out of memory: cannot allocate tree\n"); - abort(); - } + assert (T); memset (T, 0, sizeof (*T)); return T; } @@ -93,34 +79,31 @@ struct tree *tree_alloc (void) { void tree_add_child (struct tree *P, struct tree *C) { if (P->nc == P->size) { void **t = talloc (sizeof (void *) * (++P->size)); - if (!t) { - TL_ERROR("Out of memory: cannot allocate tree child\n"); - abort(); - } memcpy (t, P->c, sizeof (void *) * (P->size - 1)); if (P->c) { tfree (P->c, sizeof (void *) * (P->size - 1)); } P->c = (void *)t; + assert (P->c); } P->c[P->nc ++] = C; } void tree_delete (struct tree *T) { - if (T) { - int i; - for (i = 0; i < T->nc; i++) { - if(T->c[i]) tree_delete(T->c[i]); - } - if (T->c) { - tfree(T->c, sizeof(void*) * T->nc); - } - tfree(T, sizeof(*T)); - } + assert (T); + int i; + for (i = 0; i < T->nc; i++) { + assert (T->c[i]); + tree_delete (T->c[i]); + } + if (T->c) { + tfree (T->c, sizeof (void *) * T->nc); + } + tfree (T, sizeof (*T)); } void tree_del_child (struct tree *P) { - if (!P->nc) abort(); + assert (P->nc); tree_delete (P->c[--P->nc]); } @@ -198,11 +181,11 @@ void parse_error (const char *e) { } void tl_print_parse_error (void) { - TL_ERROR("Error near line %d pos %d: `%s`\n", last_error_line + 1, last_error_line_pos + 1, last_error); + fprintf (stderr, "Error near line %d pos %d: `%s`\n", last_error_line + 1, last_error_line_pos + 1, last_error); } char *parse_lex (void) { - while (1) { + while (1) { while (curch && is_whitespace (curch)) { nextch (); } if (curch == '/' && nextch () == '/') { while (nextch () != 10); @@ -252,7 +235,7 @@ char *parse_lex (void) { case '.': nextch (); parse.lex.len = 1; - parse.lex.type = lex_char; + parse.lex.type = lex_char; return (parse.lex.ptr = p); case 'a': case 'b': @@ -351,10 +334,10 @@ char *parse_lex (void) { int ok = 1; for (i = 0; i < 8; i++) { if (!is_hexdigit (nextch())) { - if (curch == ' ' && i >= 5) { + if (curch == ' ' && i >= 5) { ok = 2; break; - } else { + } else { parse_error ("Hex digit expected"); parse.lex.type = lex_error; return (parse.lex.ptr = (void *)-1); @@ -387,17 +370,13 @@ char *parse_lex (void) { parse.lex.type = lex_error; return (parse.lex.ptr = (void *)-1); } - + } int expect (char *s) { if (!parse.lex.ptr || parse.lex.ptr == (void *)-1 || parse.lex.type == lex_error || parse.lex.type == lex_none || parse.lex.len != (int)strlen (s) || memcmp (s, parse.lex.ptr, parse.lex.len)) { static char buf[1000]; -#if defined(_MSC_VER) && _MSC_VER >= 1400 - sprintf_s(buf, 1000, "Expected %s", s); -#else - sprintf(buf, "Expected %s", s); -#endif + sprintf (buf, "Expected %s", s); parse_error (buf); return -1; } else { @@ -407,37 +386,27 @@ int expect (char *s) { } struct parse *tl_init_parse_file (const char *fname) { -#if defined(_MSC_VER) && _MSC_VER >= 1400 - int fd = 0; - if (_sopen_s(&fd, fname, _O_RDONLY | _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE) != 0) { - char errorStr[256] = { 0 }; - strerror_s(errorStr, 256, errno); - TL_ERROR("Error %s\n", errorStr); -#elif defined(WIN32) || defined(_WIN32) - int fd = open(fname, O_RDONLY | O_BINARY); - if (fd < 0) { - TL_ERROR("Error %s\n", strerror(errno)); -#else - int fd = open(fname, O_RDONLY); - if (fd < 0) { - TL_ERROR("Error %m\n"); -#endif - abort(); - return 0; + FILE *f = fopen (fname, "rb"); + if (f == NULL) { + fprintf (stderr, "Failed to open the input file.\n"); + return NULL; } - long long size = lseek (fd, 0, SEEK_END); - if (size <= 0) { - TL_ERROR("size is %"_PRINTF_INT64_"d. Too small.\n", size); - return 0; + if (fseek (f, 0, SEEK_END) != 0) { + fprintf (stderr, "Can't seek to the end of the input file.\n"); + return NULL; } + long size = ftell (f); + if (size <= 0 || size > INT_MAX) { + fprintf (stderr, "Size is %ld. Too small or too big.\n", size); + return NULL; + } + fseek (f, 0, SEEK_SET); + static struct parse save; - save.text = talloc (size); - lseek (fd, 0, SEEK_SET); - save.len = read (fd, save.text, size); - if (save.len != size) { - TL_ERROR("cannot read all bytes %" _PRINTF_INT64_"d from file.\n", size); - return 0; - } + save.text = talloc ((size_t)size); + save.len = fread (save.text, 1, (size_t)size, f); + assert (save.len == size); + fclose (f); save.pos = 0; save.line = 0; save.line_pos = 0; @@ -484,7 +453,7 @@ struct tree *parse_full_combinator_id (void) { } else { parse_error ("Can not parse full combinator id"); PARSE_FAIL; - } + } } struct tree *parse_combinator_id (void) { @@ -498,7 +467,7 @@ struct tree *parse_combinator_id (void) { } else { parse_error ("Can not parse combinator id"); PARSE_FAIL; - } + } } struct tree *parse_var_ident (void) { @@ -626,7 +595,7 @@ struct tree *parse_subexpr (void) { was_term = 1; PARSE_TRY (parse_term); if (S) { - tree_add_child (T, S); + tree_add_child (T, S); } else { break; } @@ -745,7 +714,7 @@ struct tree *parse_args4 (void) { if (S) { tree_add_child (T, S); } else { - load_parse (so); + load_parse (so); } if (LEX_CHAR ('!')) { PARSE_ADD (type_exclam); @@ -764,7 +733,7 @@ struct tree *parse_args3 (void) { if (S) { tree_add_child (T, S); } else { - load_parse (so); + load_parse (so); } if (LEX_CHAR ('!')) { PARSE_ADD (type_exclam); @@ -788,7 +757,7 @@ struct tree *parse_args2 (void) { if (S) { tree_add_child (T, S); } else { - load_parse (so); + load_parse (so); } struct parse save2 = save_parse (); PARSE_TRY (parse_multiplicity); @@ -820,7 +789,7 @@ struct tree *parse_args1 (void) { if (S) { tree_add_child (T, S); } else { - load_parse (so); + load_parse (so); } if (LEX_CHAR ('!')) { PARSE_ADD (type_exclam); @@ -961,10 +930,7 @@ struct tree *parse_program (void) { } struct tree *tl_parse_lex (struct parse *_parse) { - if (!_parse) { - TL_ERROR("Invalid parse in tl_parse_lex (bug?)"); - abort(); - } + assert (_parse); load_parse (*_parse); if (parse.lex.type == lex_none) { parse_lex (); @@ -1013,6 +979,11 @@ DEFINE_TREE (var_value, struct tl_var_value, tl_var_value_cmp, empty) DEFINE_TREE (tl_field,char *,strcmp, 0) //tree_tl_field_t *tl_field_tree; +#define TL_FAIL return 0; +#define TL_INIT(x) struct tl_combinator_tree *x = 0; +#define TL_TRY(f,x) { struct tl_combinator_tree *_t = f; if (!_t) { TL_FAIL;} x = tl_union (x, _t); if (!x) { TL_FAIL; }} +#define TL_ERROR(...) fprintf (stderr, __VA_ARGS__); +#define TL_WARNING(...) fprintf (stderr, __VA_ARGS__); void tl_set_var_value (struct tree_var_value **T, struct tl_combinator_tree *var, struct tl_combinator_tree *value) { struct tl_var_value t = {.ptr = var, .val = value, .num_val = 0}; @@ -1059,10 +1030,8 @@ int tl_is_type_name (const char *id, int len) { } int tl_add_field (char *id) { - if (namespace_level < 0 || namespace_level >= 10) { - TL_ERROR("Invalid namespace level %d\n", namespace_level); - abort(); - } + assert (namespace_level < 10); + assert (namespace_level >= 0); if (tree_lookup_tl_field (fields[namespace_level], id)) { return 0; } @@ -1072,7 +1041,7 @@ int tl_add_field (char *id) { void tl_clear_fields (void) { // tree_act_tl_field (fields[namespace_level], (void *)free); - fields[namespace_level] = tree_clear_tl_field (fields[namespace_level]); + fields[namespace_level] = tree_clear_tl_field (fields[namespace_level]); } struct tl_var *tl_add_var (char *id, struct tl_combinator_tree *ptr, int type) { @@ -1123,21 +1092,14 @@ struct tl_var *tl_get_var (char *_id, int len) { void namespace_push (void) { namespace_level ++; - if (namespace_level > 9) { - TL_ERROR("namespace level push exceeded\n"); - abort(); - } + assert (namespace_level < 10); tl_clear_vars (); tl_clear_fields (); } void namespace_pop (void) { namespace_level --; - if (namespace_level < 0) - { - TL_ERROR("namespace level pop exceeded\n"); - abort(); - } + assert (namespace_level >= 0); } struct tl_type *tl_get_type (const char *_id, int len) { @@ -1175,7 +1137,7 @@ struct tl_type *tl_add_type (const char *_id, int len, int params_num, long long t->flags = 0; t->real_id = 0; if (params_num >= 0) { - if (params_num > 64) abort(); + assert (params_num <= 64); t->params_num = params_num; t->params_types = params_types; } else { @@ -1188,9 +1150,10 @@ struct tl_type *tl_add_type (const char *_id, int len, int params_num, long long } void tl_add_type_param (struct tl_type *t, int x) { - if (!(t->flags & 4) || t->params_num > 64) abort(); + assert (t->flags & 4); + assert (t->params_num <= 64); if (x) { - t->params_types |= (1ull << (t->params_num ++)); + t->params_types |= (1ull << (t->params_num ++)); } else { t->params_num ++; } @@ -1203,7 +1166,7 @@ int tl_type_set_params (struct tl_type *t, int x, long long y) { t->flags &= ~4; } else { if (t->params_num != x || t->params_types != y) { - TL_ERROR("Wrong num of params (type %s)\n", t->id); + fprintf (stderr, "Wrong num of params (type %s)\n", t->id); return 0; } } @@ -1223,10 +1186,7 @@ struct tl_constructor *tl_get_constructor (const char *_id, int len) { } struct tl_constructor *tl_add_constructor (struct tl_type *a, const char *_id, int len, int force_magic) { - if (!a) { - TL_ERROR("Invalid type in add constructor\n"); - abort(); - } + assert (a); if (a->flags & 1) { TL_ERROR ("New constructor for type `%s` after final statement\n", a->id); return 0; @@ -1239,12 +1199,12 @@ struct tl_constructor *tl_add_constructor (struct tl_type *a, const char *_id, i unsigned magic = 0; if (x < len) { - if (len - x < 6 || len - x > 9) abort(); + assert (len - x >= 6 && len - x <= 9); int i; for (i = 1; i < len - x; i++) { magic = (magic << 4) + (_id[x + i] <= '9' ? _id[x + i] - '0' : _id[x + i] - 'a' + 10); } - if (!magic || magic == (unsigned)-1) abort(); + assert (magic && magic != (unsigned)-1); } len = x; @@ -1256,13 +1216,13 @@ struct tl_constructor *tl_add_constructor (struct tl_type *a, const char *_id, i return 0; } } else { - if (len != 1) abort(); + assert (len == 1); } struct tl_constructor *t = talloc (sizeof (*t)); t->type = a; t->name = magic; - t->id = id; + t->id = id; t->print_id = tstrdup (id); t->real_id = 0; @@ -1273,7 +1233,7 @@ struct tl_constructor *tl_add_constructor (struct tl_type *a, const char *_id, i t->left = t->right = 0; a->constructors = realloc (a->constructors, sizeof (void *) * (a->constructors_num + 1)); - if(!a->constructors) abort(); + assert (a->constructors); a->constructors[a->constructors_num ++] = t; if (*id != '_') { tl_constructor_tree = tree_insert_tl_constructor (tl_constructor_tree, t, lrand48 ()); @@ -1293,6 +1253,7 @@ struct tl_constructor *tl_get_function (const char *_id, int len) { } struct tl_constructor *tl_add_function (struct tl_type *a, const char *_id, int len, int force_magic) { +// assert (a); int x = 0; while (x < len && ((_id[x] != '#') || force_magic)) { x++; } char *id = talloc (x + 1); @@ -1301,12 +1262,12 @@ struct tl_constructor *tl_add_function (struct tl_type *a, const char *_id, int unsigned magic = 0; if (x < len) { - if (len - x < 6 || len - x > 9) abort(); + assert (len - x >= 6 && len - x <= 9); int i; for (i = 1; i < len - x; i++) { magic = (magic << 4) + (_id[x + i] <= '9' ? _id[x + i] - '0' : _id[x + i] - 'a' + 10); } - if (!magic || magic == (unsigned)-1) abort(); + assert (magic && magic != (unsigned)-1); } len = x; @@ -1321,7 +1282,7 @@ struct tl_constructor *tl_add_function (struct tl_type *a, const char *_id, int struct tl_constructor *t = talloc (sizeof (*t)); t->type = a; t->name = magic; - t->id = id; + t->id = id; t->print_id = tstrdup (id); t->real_id = 0; @@ -1341,7 +1302,7 @@ int buf_pos; struct tl_combinator_tree *alloc_ctree_node (void) { struct tl_combinator_tree *T = talloc (sizeof (*T)); - if (!T) { TL_ERROR("Out of memory: cannot allocate ctree node\n"); abort(); } + assert (T); memset (T, 0, sizeof (*T)); return T; } @@ -1349,7 +1310,6 @@ struct tl_combinator_tree *alloc_ctree_node (void) { struct tl_combinator_tree *tl_tree_dup (struct tl_combinator_tree *T) { if (!T) { return 0; } struct tl_combinator_tree *S = talloc (sizeof (*S)); - if (!S) { TL_ERROR("Out of memory: cannot duplicate tree\n"); abort(); } memcpy (S, T, sizeof (*S)); S->left = tl_tree_dup (T->left); S->right = tl_tree_dup (T->right); @@ -1357,14 +1317,14 @@ struct tl_combinator_tree *tl_tree_dup (struct tl_combinator_tree *T) { } struct tl_type *tl_tree_get_type (struct tl_combinator_tree *T) { - if (T->type != type_type) abort(); + assert (T->type == type_type); if (T->act == act_array) { return 0;} while (T->left) { T = T->left; if (T->act == act_array) { return 0;} - if (T->type != type_type) abort(); + assert (T->type == type_type); } - if (T->act != act_type && T->act != act_var && T->act != act_array) abort(); + assert (T->act == act_type || T->act == act_var || T->act == act_array); return T->act == act_type ? T->data : 0; } @@ -1375,9 +1335,10 @@ void tl_tree_set_len (struct tl_combinator_tree *T) { H->left->type_len = H->type_len + 1; H = H->left; } - if (H->type != type_type) abort(); + assert (H->type == type_type); struct tl_type *t = H->data; - if (!t || H->type_len != t->params_num) abort(); + assert (t); + assert (H->type_len == t->params_num); } void tl_buf_reset (void) { @@ -1409,7 +1370,7 @@ void tl_buf_add_string_q (char *s, int len, int x) { void tl_buf_add_tree (struct tl_combinator_tree *T, int x) { if (!T) { return; } - if (T == (void*)-1l || T == (void*)-2l) abort(); + assert (T != (void *)-1l && T != (void *)-2l); switch (T->act) { case act_question_mark: tl_buf_add_string_q ("?", -1, x); @@ -1424,7 +1385,7 @@ void tl_buf_add_tree (struct tl_combinator_tree *T, int x) { } else { struct tl_type *t = T->data; if (T->flags & 4) { - if (t->constructors_num != 1) abort(); + assert (t->constructors_num == 1); tl_buf_add_string_q (t->constructors[0]->real_id ? t->constructors[0]->real_id : t->constructors[0]->id, -1, x); } else { tl_buf_add_string_q (t->real_id ? t->real_id : t->id, -1, x); @@ -1451,11 +1412,7 @@ void tl_buf_add_tree (struct tl_combinator_tree *T, int x) { tl_buf_add_string_q ((char *)v->data, -1, x); if (T->type == type_num && T->type_flags) { static char _buf[30]; -#if defined(_MSC_VER) && _MSC_VER >= 1400 - sprintf_s(_buf, 30, "+%"_PRINTF_INT64_"d", T->type_flags); -#else - sprintf(_buf, "+%"_PRINTF_INT64_"d", T->type_flags); -#endif + sprintf (_buf, "+%lld", T->type_flags); tl_buf_add_string_q (_buf, -1, 0); } } @@ -1482,7 +1439,7 @@ void tl_buf_add_tree (struct tl_combinator_tree *T, int x) { case act_nat_const: { static char _buf[30]; - snprintf (_buf, 29, "%"_PRINTF_INT64_"d", T->type_flags); + snprintf (_buf, 29, "%lld", T->type_flags); tl_buf_add_string_q (_buf, -1, x); return; } @@ -1492,26 +1449,22 @@ void tl_buf_add_tree (struct tl_combinator_tree *T, int x) { tl_buf_add_string_q ((char *)v->data, -1, x); tl_buf_add_string_q (".", -1, 0); static char _buf[30]; -#if defined(_MSC_VER) && _MSC_VER >= 1400 - sprintf_s(_buf, 30, "%"_PRINTF_INT64_"d", T->left->type_flags); -#else - sprintf(_buf, "%"_PRINTF_INT64_"d", T->left->type_flags); -#endif + sprintf (_buf, "%lld", T->left->type_flags); tl_buf_add_string_q (_buf, -1, 0); tl_buf_add_string_q ("?", -1, 0); tl_buf_add_tree (T->right, 0); return; } - + default: - TL_ERROR( "%s %s\n", TL_ACT (T->act), TL_TYPE (T->type)); - abort(); + fprintf (stderr, "%s %s\n", TL_ACT (T->act), TL_TYPE (T->type)); + assert (0); return; } } int tl_count_combinator_name (struct tl_constructor *c) { - if (!c) { abort(); } + assert (c); tl_buf_reset (); tl_buf_add_string_nospace (c->real_id ? c->real_id : c->id, -1); tl_buf_add_tree (c->left, 1); @@ -1519,7 +1472,7 @@ int tl_count_combinator_name (struct tl_constructor *c) { tl_buf_add_tree (c->right, 1); //fprintf (stderr, "%.*s\n", buf_pos, buf); if (!c->name) { - c->name = compute_crc32(buf, buf_pos); + c->name = compute_crc32 (buf, buf_pos); } return c->name; } @@ -1528,17 +1481,13 @@ int tl_print_combinator (struct tl_constructor *c) { tl_buf_reset (); tl_buf_add_string_nospace (c->real_id ? c->real_id : c->id, -1); static char _buf[10]; -#if defined(_MSC_VER) && _MSC_VER >= 1400 - sprintf_s(_buf, 10, "#%08x", c->name); -#else - sprintf(_buf, "#%08x", c->name); -#endif + sprintf (_buf, "#%08x", c->name); tl_buf_add_string_nospace (_buf, -1); tl_buf_add_tree (c->left, 1); tl_buf_add_string ("=", -1); tl_buf_add_tree (c->right, 1); if (output_expressions >= 1) { - TL_ERROR("%.*s\n", buf_pos, buf); + fprintf (stderr, "%.*s\n", buf_pos, buf); } /* if (!c->name) { c->name = compute_crc32 (buf, buf_pos); @@ -1547,22 +1496,22 @@ int tl_print_combinator (struct tl_constructor *c) { } int _tl_finish_subtree (struct tl_combinator_tree *R, int x, long long y) { - if (R->type != type_type || R->type_len >= 0 || (R->act != act_arg && R->act != act_type)) { - abort(); - } + assert (R->type == type_type); + assert (R->type_len < 0); + assert (R->act == act_arg || R->act == act_type); R->type_len = x; R->type_flags = y; if (R->act == act_type) { struct tl_type *t = R->data; - if (!t) { abort(); } + assert (t); return tl_type_set_params (t, x, y); } - if ((R->right->type != type_type || R->right->type_len != 0) && R->right->type != type_num && R->right->type != type_num_value) abort(); + assert ((R->right->type == type_type && R->right->type_len == 0) || R->right->type == type_num || R->right->type == type_num_value); return _tl_finish_subtree (R->left, x + 1, y * 2 + (R->right->type == type_num || R->right->type == type_num_value)); } int tl_finish_subtree (struct tl_combinator_tree *R) { - if (!R) { abort(); } + assert (R); if (R->type != type_type) { return 1; } @@ -1600,7 +1549,7 @@ struct tl_combinator_tree *tl_union (struct tl_combinator_tree *L, struct tl_com tfree (v, sizeof (*v)); R->type_flags += L->type_flags; return R; - case type_list_item: + case type_list_item: case type_list: if (R->type != type_list_item) { TL_ERROR ("Union: type mistmatch\n"); @@ -1612,7 +1561,7 @@ struct tl_combinator_tree *tl_union (struct tl_combinator_tree *L, struct tl_com case type_type: if (L->type_len == 0) { TL_ERROR ("Arguments number exceeds type arity\n"); - return 0; + return 0; } if (R->type != type_num && R->type != type_type && R->type != type_num_value) { TL_ERROR ("Union: type mistmatch\n"); @@ -1625,10 +1574,10 @@ struct tl_combinator_tree *tl_union (struct tl_combinator_tree *L, struct tl_com } if (R->type_len > 0) { TL_ERROR ("Argument type must have full number of arguments\n"); - return 0; + return 0; } if (L->type_len > 0 && ((L->type_flags & 1) != (R->type == type_num || R->type == type_num_value))) { - TL_ERROR ("Argument types mistmatch: L->type_flags = %"_PRINTF_INT64_"d, R->type = %s\n", L->flags, TL_TYPE (R->type)); + TL_ERROR ("Argument types mistmatch: L->type_flags = %lld, R->type = %s\n", L->flags, TL_TYPE (R->type)); return 0; } v->type = type_type; @@ -1637,17 +1586,17 @@ struct tl_combinator_tree *tl_union (struct tl_combinator_tree *L, struct tl_com v->type_flags = L->type_flags >> 1; return v; default: - abort(); + assert (0); return 0; } } struct tl_combinator_tree *tl_parse_any_term (struct tree *T, int s); struct tl_combinator_tree *tl_parse_term (struct tree *T, int s) { - if (T->type != type_term) return NULL; + assert (T->type == type_term); int i = 0; while (i < T->nc && T->c[i]->type == type_percent) { i ++; s ++; } - if (i >= T->nc) abort(); + assert (i < T->nc); TL_INIT (L); while (i < T->nc) { TL_TRY (tl_parse_any_term (T->c[i], s), L); @@ -1659,21 +1608,24 @@ struct tl_combinator_tree *tl_parse_term (struct tree *T, int s) { struct tl_combinator_tree *tl_parse_type_term (struct tree *T, int s) { - if (T->nc != 1 || T->type != type_type_term) abort(); - struct tl_combinator_tree *Z = tl_parse_term (T->c[0], s); + assert (T->type == type_type_term); + assert (T->nc == 1); + struct tl_combinator_tree *Z = tl_parse_term (T->c[0], s); if (!Z || Z->type != type_type) { if (Z) { TL_ERROR ("type_term: found type %s\n", TL_TYPE (Z->type)); } TL_FAIL; } return Z; } struct tl_combinator_tree *tl_parse_nat_term (struct tree *T, int s) { - if (T->nc != 1 || T->type != type_nat_term) abort(); + assert (T->type == type_nat_term); + assert (T->nc == 1); struct tl_combinator_tree *Z = tl_parse_term (T->c[0], s); if (!Z || (Z->type != type_num && Z->type != type_num_value)) { if (Z) { TL_ERROR ("nat_term: found type %s\n", TL_TYPE (Z->type)); }TL_FAIL; } return Z; } struct tl_combinator_tree *tl_parse_subexpr (struct tree *T, int s) { - if (T->nc < 1 || T->type != type_subexpr) abort(); + assert (T->type == type_subexpr); + assert (T->nc >= 1); int i; TL_INIT (L); for (i = 0; i < T->nc; i++) { @@ -1684,7 +1636,8 @@ struct tl_combinator_tree *tl_parse_subexpr (struct tree *T, int s) { } struct tl_combinator_tree *tl_parse_expr (struct tree *T, int s) { - if (T->nc < 1 || T->type != type_expr) abort(); + assert (T->type == type_expr); + assert (T->nc >= 1); int i; TL_INIT (L); for (i = 0; i < T->nc; i++) { @@ -1695,11 +1648,14 @@ struct tl_combinator_tree *tl_parse_expr (struct tree *T, int s) { } struct tl_combinator_tree *tl_parse_nat_const (struct tree *T, int s) { - if (T->type != type_nat_const || T->nc) abort(); + assert (T->type == type_nat_const); + assert (!T->nc); if (s > 0) { - TL_ERROR ("Nat const can not precede with %%\n"); + TL_ERROR ("Nat const can not preceed with %%\n"); TL_FAIL; } + assert (T->type == type_nat_const); + assert (!T->nc); TL_INIT (L); L = alloc_ctree_node (); L->act = act_nat_const; @@ -1714,16 +1670,16 @@ struct tl_combinator_tree *tl_parse_nat_const (struct tree *T, int s) { } struct tl_combinator_tree *tl_parse_ident (struct tree *T, int s) { - if (T->type != type_type_ident && T->type != type_var_ident && T->type != type_boxed_type_ident) abort(); - if (T->nc) abort(); + assert (T->type == type_type_ident || T->type == type_var_ident || T->type == type_boxed_type_ident); + assert (!T->nc); struct tl_var *v = tl_get_var (T->text, T->len); TL_INIT (L); - if (v) { + if (v) { L = alloc_ctree_node (); L->act = act_var; L->type = v->type ? type_num : type_type; if (L->type == type_num && s) { - TL_ERROR ("Nat var can not precede with %%\n"); + TL_ERROR ("Nat var can not preceed with %%\n"); TL_FAIL; } else { if (s) { @@ -1750,7 +1706,7 @@ struct tl_combinator_tree *tl_parse_ident (struct tree *T, int s) { struct tl_constructor *c = tl_get_constructor (T->text, T->len); if (c) { - if (!c->type) abort(); + assert (c->type); if (c->type->constructors_num != 1) { TL_ERROR ("Constructor can be used only if it is the only constructor of the type\n"); return 0; @@ -1777,7 +1733,7 @@ struct tl_combinator_tree *tl_parse_ident (struct tree *T, int s) { L->data = t; L->type = type_type; L->type_len = t->params_num; - L->type_flags = t->params_types; + L->type_flags = t->params_types; return L; } else { TL_ERROR ("Not a type/var ident `%.*s`\n", T->len, T->text); @@ -1803,24 +1759,28 @@ struct tl_combinator_tree *tl_parse_any_term (struct tree *T, int s) { case type_var_ident: return tl_parse_ident (T, s); default: - TL_ERROR("type = %d\n", T->type); - abort(); - return 0; + fprintf (stderr, "type = %d\n", T->type); + assert (0); + return 0; } } struct tl_combinator_tree *tl_parse_multiplicity (struct tree *T) { - if (T->type != type_multiplicity || T->nc != 1) abort(); + assert (T->type == type_multiplicity); + assert (T->nc == 1); return tl_parse_nat_term (T->c[0], 0); } struct tl_combinator_tree *tl_parse_opt_args (struct tree *T) { - if (!T || T->type != type_opt_args || T->nc < 2) abort(); + assert (T); + assert (T->type == type_opt_args); + assert (T->nc >= 2); TL_INIT (R); TL_TRY (tl_parse_type_term (T->c[T->nc - 1], 0), R); - if (R->type != type_type || R->type_len) abort(); - if (!tl_finish_subtree(R)) abort(); + assert (R->type == type_type && !R->type_len); + assert (tl_finish_subtree (R)); struct tl_type *t = tl_tree_get_type (R); + //assert (t); int tt = -1; if (t && !strcmp (t->id, "#")) { tt = 1; @@ -1853,7 +1813,7 @@ struct tl_combinator_tree *tl_parse_opt_args (struct tree *T) { S->act = act_field; S->data = i >= 0 ? mystrdup (T->c[i]->text, T->c[i]->len) : 0; if (tt >= 0) { - if (!S->data) abort(); + assert (S->data); tl_add_var (S->data, S, tt); } S->flags = 33; @@ -1864,7 +1824,9 @@ struct tl_combinator_tree *tl_parse_opt_args (struct tree *T) { struct tl_combinator_tree *tl_parse_args (struct tree *T); struct tl_combinator_tree *tl_parse_args2 (struct tree *T) { - if (!T || T->type != type_args2 || T->nc < 1) abort(); + assert (T); + assert (T->type == type_args2); + assert (T->nc >= 1); TL_INIT (R); TL_INIT (L); int x = 0; @@ -1872,11 +1834,11 @@ struct tl_combinator_tree *tl_parse_args2 (struct tree *T) { if (T->c[x]->type == type_var_ident_opt || T->c[x]->type == type_var_ident) { field_name = mystrdup (T->c[x]->text, T->c[x]->len); if (!tl_add_field (field_name)) { - TL_ERROR ("Duplicate field name %s\n", field_name); + TL_ERROR ("Duplicate field name %s\n", field_name); TL_FAIL; } x ++; - } + } //fprintf (stderr, "%d %d\n", x, T->nc); if (T->c[x]->type == type_multiplicity) { L = tl_parse_multiplicity (T->c[x]); @@ -1884,7 +1846,7 @@ struct tl_combinator_tree *tl_parse_args2 (struct tree *T) { x ++; } else { struct tl_var *v = tl_get_last_num_var (); - if (!v) { + if (!v) { TL_ERROR ("Expected multiplicity or nat var\n"); TL_FAIL; } @@ -1918,18 +1880,21 @@ struct tl_combinator_tree *tl_parse_args2 (struct tree *T) { H->right = 0; H->data = field_name; H->type_len = 0; - + return H; } void tl_mark_vars (struct tl_combinator_tree *T); struct tl_combinator_tree *tl_parse_args134 (struct tree *T) { - if (!T || T->nc < 1 || (T->type != type_args1 && T->type != type_args3 && T->type != type_args4)) abort(); + assert (T); + assert (T->type == type_args1 || T->type == type_args3 || T->type == type_args4); + assert (T->nc >= 1); TL_INIT (R); TL_TRY (tl_parse_type_term (T->c[T->nc - 1], 0), R); - if (!tl_finish_subtree(R)) abort(); - if (R->type != type_type || R->type_len) abort(); + assert (tl_finish_subtree (R)); + assert (R->type == type_type && !R->type_len); struct tl_type *t = tl_tree_get_type (R); + //assert (t); int tt = -1; if (t && !strcmp (t->id, "#")) { tt = 1; @@ -1948,7 +1913,7 @@ struct tl_combinator_tree *tl_parse_args134 (struct tree *T) { last --; } if (last >= 0 && T->c[last]->type == type_optional_arg_def) { - if (T->c[last]->nc != 2) abort(); + assert (T->c[last]->nc == 2); TL_INIT (E); E = alloc_ctree_node (); E->type = type_type; E->act = act_opt_field; @@ -1995,21 +1960,18 @@ struct tl_combinator_tree *tl_parse_args134 (struct tree *T) { } } if (tt >= 0) { + //assert (S->data); char *name = S->data; if (!name) { static char s[20]; -#if defined(_MSC_VER) && _MSC_VER >= 1400 - sprintf_s(s, 20, "%"_PRINTF_INT64_"d", lrand48() * (1ll << 32) + lrand48()); -#else - sprintf(s, "%"_PRINTF_INT64_"d", lrand48() * (1ll << 32) + lrand48()); -#endif + sprintf (s, "%lld", lrand48 () * (1ll << 32) + lrand48 ()); name = s; } struct tl_var *v = tl_add_var (name, S, tt); if (!v) {TL_FAIL;} v->flags |= 2; } - + H = tl_union (H, S); } return H; @@ -2017,7 +1979,8 @@ struct tl_combinator_tree *tl_parse_args134 (struct tree *T) { struct tl_combinator_tree *tl_parse_args (struct tree *T) { - if (T->type != type_args || T->nc != 1) abort(); + assert (T->type == type_args); + assert (T->nc == 1); switch (T->c[0]->type) { case type_args1: return tl_parse_args134 (T->c[0]); @@ -2028,9 +1991,9 @@ struct tl_combinator_tree *tl_parse_args (struct tree *T) { case type_args4: return tl_parse_args134 (T->c[0]); default: - abort(); + assert (0); return 0; - } + } } void tl_mark_vars (struct tl_combinator_tree *T) { @@ -2038,7 +2001,7 @@ void tl_mark_vars (struct tl_combinator_tree *T) { if (T->act == act_var) { char *id = ((struct tl_combinator_tree *)(T->data))->data; struct tl_var *v = tl_get_var (id, strlen (id)); - if (!v) abort(); + assert (v); v->flags |= 1; } tl_mark_vars (T->left); @@ -2046,8 +2009,10 @@ void tl_mark_vars (struct tl_combinator_tree *T) { } struct tl_combinator_tree *tl_parse_result_type (struct tree *T) { - if (T->type != type_result_type || T->nc > 64 || T->nc < 1) abort(); - + assert (T->type == type_result_type); + assert (T->nc >= 1); + assert (T->nc <= 64); + TL_INIT (L); if (tl_get_var (T->c[0]->text, T->c[0]->len)) { @@ -2064,12 +2029,13 @@ struct tl_combinator_tree *tl_parse_result_type (struct tree *T) { TL_FAIL; } L->data = v->ptr; +// assert (v->ptr); } else { L = alloc_ctree_node (); L->act = act_type; L->type = type_type; struct tl_type *t = tl_add_type (T->c[0]->text, T->c[0]->len, -1, 0); - if (!t) abort(); + assert (t); L->type_len = t->params_num; L->type_flags = t->params_types; L->data = t; @@ -2077,8 +2043,8 @@ struct tl_combinator_tree *tl_parse_result_type (struct tree *T) { int i; for (i = 1; i < T->nc; i++) { TL_TRY (tl_parse_any_term (T->c[i], 0), L); - if (!L->right) abort(); - if (L->right->type != type_num && L->right->type != type_num_value && (L->right->type != type_type || L->right->type_len != 0)) abort(); + assert (L->right); + assert (L->right->type == type_num || L->right->type == type_num_value || (L->right->type == type_type && L->right->type_len == 0)); } } @@ -2096,7 +2062,8 @@ void tl_var_check_used (struct tl_var *v) { } int tl_parse_combinator_decl (struct tree *T, int fun) { - if (T->type != type_combinator_decl || T->nc < 3) abort(); + assert (T->type == type_combinator_decl); + assert (T->nc >= 3); namespace_level = 0; tl_clear_vars (); tl_clear_fields (); @@ -2112,7 +2079,7 @@ int tl_parse_combinator_decl (struct tree *T, int fun) { TL_TRY (tl_parse_args (T->c[i]), L); i++; } - if (i != T->nc - 2 || T->c[i]->type != type_equals) abort(); + assert (i == T->nc - 2 && T->c[i]->type == type_equals); i ++; R = tl_parse_result_type (T->c[i]); @@ -2122,16 +2089,16 @@ int tl_parse_combinator_decl (struct tree *T, int fun) { if (!fun && !t) { TL_ERROR ("Only functions can return variables\n"); } - if (!t && !fun) abort(); - - if (namespace_level != 0) abort(); + assert (t || fun); + + assert (namespace_level == 0); __ok = 1; tree_act_tl_var (vars[0], tl_var_check_used); if (!__ok) { TL_ERROR ("Not all variables are used in right side\n"); TL_FAIL; } - + if (tl_get_constructor (T->c[0]->text, T->c[0]->len) || tl_get_function (T->c[0]->text, T->c[0]->len)) { TL_ERROR ("Duplicate combinator id %.*s\n", T->c[0]->len, T->c[0]->text); return 0; @@ -2140,7 +2107,7 @@ int tl_parse_combinator_decl (struct tree *T, int fun) { if (!c) { TL_FAIL; } c->left = L; c->right = R; - + if (!c->name) { tl_count_combinator_name (c); } @@ -2150,25 +2117,23 @@ int tl_parse_combinator_decl (struct tree *T, int fun) { } void change_var_ptrs (struct tl_combinator_tree *O, struct tl_combinator_tree *D, struct tree_var_value **V) { - if (O && D) { - if (O->act == act_field) { - struct tl_type* t = tl_tree_get_type(O->left); - if (t && (!strcmp(t->id, "#") || !strcmp(t->id, "Type"))) { - tl_set_var_value(V, O, D); - } - } - if (O->act == act_var) { - if (D->data != O->data) abort(); - D->data = tl_get_var_value(V, O->data); - if (!D->data) abort(); - } - change_var_ptrs(O->left, D->left, V); - change_var_ptrs(O->right, D->right, V); + if (!O || !D) { + assert (!O && !D); + return; } - else if (!O && !D) { - abort(); + if (O->act == act_field) { + struct tl_type *t = tl_tree_get_type (O->left); + if (t && (!strcmp (t->id, "#") || !strcmp (t->id, "Type"))) { + tl_set_var_value (V, O, D); + } } - + if (O->act == act_var) { + assert (D->data == O->data); + D->data = tl_get_var_value (V, O->data); + assert (D->data); + } + change_var_ptrs (O->left, D->left, V); + change_var_ptrs (O->right, D->right, V); } struct tl_combinator_tree *change_first_var (struct tl_combinator_tree *O, struct tl_combinator_tree **X, struct tl_combinator_tree *Y) { @@ -2198,7 +2163,7 @@ struct tl_combinator_tree *change_first_var (struct tl_combinator_tree *O, struc if (O->data == *X) { struct tl_combinator_tree *R = tl_tree_dup (Y); if (O->type == type_num || O->type == type_num_value) { R->type_flags += O->type_flags; } - return R; + return R; } } struct tl_combinator_tree *t; @@ -2209,7 +2174,7 @@ struct tl_combinator_tree *change_first_var (struct tl_combinator_tree *O, struc if (!t) { return 0;} if (t == (void *)-1l) { return (void *)-1l; } if (t != (void *)-2l) { return t;} - return (void *)-1l; + return (void *)-1l; } if (t != (void *)-2l) { O->left = t; @@ -2217,7 +2182,7 @@ struct tl_combinator_tree *change_first_var (struct tl_combinator_tree *O, struc t = change_first_var (O->right, X, Y); if (!t) { return 0;} if (t == (void *)-1l) { - return O->left; + return O->left; } if (t != (void *)-2l) { O->right = t; @@ -2243,7 +2208,7 @@ void check_nat_val (struct tl_var_value v) { return; } } - if (L->type != type_num) abort(); + assert (L->type == type_num); x += L->type_flags; x += tl_get_var_value_num (_T, L->data); L = tl_get_var_value (_T, L->data); @@ -2260,9 +2225,9 @@ int check_constructors_equal (struct tl_combinator_tree *L, struct tl_combinator } struct tl_combinator_tree *reduce_type (struct tl_combinator_tree *A, struct tl_type *t) { - if (!A) abort(); + assert (A); if (A->type_len == t->params_num) { - if (A->type_flags != t->params_types) abort(); + assert (A->type_flags == t->params_types); A->act = act_type; A->type = type_type; A->left = A->right = 0; @@ -2276,7 +2241,7 @@ struct tl_combinator_tree *reduce_type (struct tl_combinator_tree *A, struct tl_ struct tl_combinator_tree *change_value_var (struct tl_combinator_tree *O, struct tree_var_value **X) { if (!O) { return (void *)-2l; }; while (O->act == act_var) { - if (!O->data) abort(); + assert (O->data); if (!tl_get_var_value (X, O->data)) { break; } @@ -2302,7 +2267,7 @@ struct tl_combinator_tree *change_value_var (struct tl_combinator_tree *O, struc if (!t) { return 0;} if (t == (void *)-1l) { return (void *)-1l; } if (t != (void *)-2l) { return t;} - return (void *)-1l; + return (void *)-1l; } if (t != (void *)-2l) { O->left = t; @@ -2310,7 +2275,7 @@ struct tl_combinator_tree *change_value_var (struct tl_combinator_tree *O, struc t = change_value_var (O->right, X); if (!t) { return 0;} if (t == (void *)-1l) { - return O->left; + return O->left; } if (t != (void *)-2l) { O->right = t; @@ -2319,8 +2284,10 @@ struct tl_combinator_tree *change_value_var (struct tl_combinator_tree *O, struc } int tl_parse_partial_type_app_decl (struct tree *T) { - if (!T || T->type != type_partial_type_app_decl || T->nc < 1 || T->c[0]->type != type_boxed_type_ident) abort(); + assert (T->type == type_partial_type_app_decl); + assert (T->nc >= 1); + assert (T->c[0]->type == type_boxed_type_ident); struct tl_type *t = tl_get_type (T->c[0]->text, T->c[0]->len); if (!t) { TL_ERROR ("Can not make partial app for unknown type\n"); @@ -2330,7 +2297,7 @@ int tl_parse_partial_type_app_decl (struct tree *T) { tl_type_finalize (t); struct tl_combinator_tree *L = tl_parse_ident (T->c[0], 0); - if (!L) abort(); + assert (L); int i; tl_buf_reset (); int cc = T->nc - 1; @@ -2354,10 +2321,10 @@ int tl_parse_partial_type_app_decl (struct tree *T) { static char _buf[100000]; snprintf (_buf, 100000, "%s%.*s", t->id, buf_pos, buf); struct tl_type *nt = tl_add_type (_buf, strlen (_buf), t->params_num - cc, t->params_types >> cc); - if (!nt) abort(); + assert (nt); //snprintf (_buf, 100000, "%s #", t->id); //nt->real_id = strdup (_buf); - + for (i = 0; i < t->constructors_num; i++) { struct tl_constructor *c = t->constructors[i]; struct tree_var_value *V = 0; @@ -2365,7 +2332,7 @@ int tl_parse_partial_type_app_decl (struct tree *T) { TL_INIT (B); A = tl_tree_dup (c->left); B = tl_tree_dup (c->right); - + struct tree_var_value *W = 0; change_var_ptrs (c->left, A, &W); change_var_ptrs (c->right, B, &W); @@ -2376,13 +2343,13 @@ int tl_parse_partial_type_app_decl (struct tree *T) { A = change_value_var (A, &V); if (A == (void *)-1l) { A = 0;} B = change_value_var (B, &V); - if (B == (void*)-1l) abort(); + assert (B != (void *)-1l); snprintf (_buf, 100000, "%s%.*s", c->id, buf_pos, buf); struct tl_constructor *r = tl_add_constructor (nt, _buf, strlen (_buf), 1); snprintf (_buf, 100000, "%s", c->id); r->real_id = tstrdup (_buf); - + r->left = A; r->right = B; if (!r->name) { @@ -2395,7 +2362,7 @@ int tl_parse_partial_type_app_decl (struct tree *T) { } int tl_parse_partial_comb_app_decl (struct tree *T, int fun) { - if (T->type != type_partial_comb_app_decl) abort(); + assert (T->type == type_partial_comb_app_decl); struct tl_constructor *c = !fun ? tl_get_constructor (T->c[0]->text, T->c[0]->len) : tl_get_function (T->c[0]->text, T->c[0]->len); if (!c) { @@ -2410,8 +2377,8 @@ int tl_parse_partial_comb_app_decl (struct tree *T, int fun) { TL_INIT (R); L = tl_tree_dup (c->left); R = tl_tree_dup (c->right); - - + + struct tree_var_value *V = 0; change_var_ptrs (c->left, L, &V); change_var_ptrs (c->right, R, &V); @@ -2424,7 +2391,7 @@ int tl_parse_partial_comb_app_decl (struct tree *T, int fun) { TL_INIT (Z); X = tl_parse_any_term (T->c[i], 0); struct tl_combinator_tree *K = 0; - if (!(Z = change_first_var (L, &K, X))) { + if (!(Z = change_first_var (L, &K, X))) { TL_FAIL; } L = Z; @@ -2435,7 +2402,7 @@ int tl_parse_partial_comb_app_decl (struct tree *T, int fun) { if (!(Z = change_first_var (R, &K, X))) { TL_FAIL; } - if (Z != R) abort(); + assert (Z == R); tl_buf_add_tree (X, 1); } @@ -2457,7 +2424,8 @@ int tl_parse_partial_comb_app_decl (struct tree *T, int fun) { int tl_parse_partial_app_decl (struct tree *T, int fun) { - if (T->nc != 1 || T->type != type_partial_app_decl) abort(); + assert (T->type == type_partial_app_decl); + assert (T->nc == 1); if (T->c[0]->type == type_partial_comb_app_decl) { return tl_parse_partial_comb_app_decl (T->c[0], fun); } else { @@ -2470,7 +2438,8 @@ int tl_parse_partial_app_decl (struct tree *T, int fun) { } int tl_parse_final_final (struct tree *T) { - if (T->nc != 1 || T->type != type_final_final) abort(); + assert (T->type == type_final_final); + assert (T->nc == 1); struct tl_type *R; if ((R = tl_get_type (T->c[0]->text, T->c[0]->len))) { R->flags |= 1; @@ -2482,7 +2451,8 @@ int tl_parse_final_final (struct tree *T) { } int tl_parse_final_new (struct tree *T) { - if (T->nc != 1 || T->type != type_final_new) abort(); + assert (T->type == type_final_new); + assert (T->nc == 1); if (tl_get_type (T->c[0]->text, T->c[0]->len)) { TL_ERROR ("New statement: type `%.*s` already declared\n", T->c[0]->len, T->c[0]->text); TL_FAIL; @@ -2492,19 +2462,22 @@ int tl_parse_final_new (struct tree *T) { } int tl_parse_final_empty (struct tree *T) { - if (T->type != type_final_empty || T->nc != 1) abort(); + assert (T->type == type_final_empty); + assert (T->nc == 1); if (tl_get_type (T->c[0]->text, T->c[0]->len)) { TL_ERROR ("New statement: type `%.*s` already declared\n", T->c[0]->len, T->c[0]->text); TL_FAIL; } struct tl_type *t = tl_add_type (T->c[0]->text, T->c[0]->len, 0, 0); - if (!t) abort(); + assert (t); t->flags |= 1 | FLAG_EMPTY; return 1; } int tl_parse_final_decl (struct tree *T, int fun) { - if (T->type != type_final_decl || fun || T->nc != 1) abort(); + assert (T->type == type_final_decl); + assert (!fun); + assert (T->nc == 1); switch (T->c[0]->type) { case type_final_new: return tl_parse_final_new (T->c[0]); @@ -2513,7 +2486,7 @@ int tl_parse_final_decl (struct tree *T, int fun) { case type_final_empty: return tl_parse_final_empty (T->c[0]); default: - abort(); + assert (0); return 0; } } @@ -2523,9 +2496,11 @@ int tl_parse_builtin_combinator_decl (struct tree *T, int fun) { TL_ERROR ("Builtin type can not be described in function block\n"); return -1; } - if (T->nc != 2 || T->type != type_builtin_combinator_decl || T->c[0]->type != - type_full_combinator_id || T->c[1]->type != type_boxed_type_ident) - abort(); + assert (T->type == type_builtin_combinator_decl); + assert (T->nc == 2); + assert (T->c[0]->type == type_full_combinator_id); + assert (T->c[1]->type == type_boxed_type_ident); + if ((!mystrcmp2 (T->c[0]->text, T->c[0]->len, "int") && !mystrcmp2 (T->c[1]->text, T->c[1]->len, "Int")) || (!mystrcmp2 (T->c[0]->text, T->c[0]->len, "long") && !mystrcmp2 (T->c[1]->text, T->c[1]->len, "Long")) || @@ -2541,7 +2516,7 @@ int tl_parse_builtin_combinator_decl (struct tree *T, int fun) { if (!c) { return 0; } - + c->left = alloc_ctree_node (); c->left->act = act_question_mark; c->left->type = type_list_item; @@ -2564,7 +2539,8 @@ int tl_parse_builtin_combinator_decl (struct tree *T, int fun) { } int tl_parse_declaration (struct tree *T, int fun) { - if (T->nc != 1 || T->type != type_declaration) abort(); + assert (T->type == type_declaration); + assert (T->nc == 1); switch (T->c[0]->type) { case type_combinator_decl: return tl_parse_combinator_decl (T->c[0], fun); @@ -2575,13 +2551,13 @@ int tl_parse_declaration (struct tree *T, int fun) { case type_builtin_combinator_decl: return tl_parse_builtin_combinator_decl (T->c[0], fun); default: - abort(); + assert (0); return 0; } } int tl_parse_constr_declarations (struct tree *T) { - if (T->type != type_constr_declarations) abort(); + assert (T->type == type_constr_declarations); int i; for (i = 0; i < T->nc; i++) { TL_TRY_PES (tl_parse_declaration (T->c[i], 0)); @@ -2590,7 +2566,7 @@ int tl_parse_constr_declarations (struct tree *T) { } int tl_parse_fun_declarations (struct tree *T) { - if (T->type != type_fun_declarations) abort(); + assert (T->type == type_fun_declarations); int i; for (i = 0; i < T->nc; i++) { TL_TRY_PES (tl_parse_declaration (T->c[i], 1)); @@ -2616,9 +2592,10 @@ int tl_tree_lookup_value (struct tl_combinator_tree *L, void *var, struct tree_v } int tl_tree_lookup_value_nat (struct tl_combinator_tree *L, void *var, long long x, struct tree_var_value **T) { - if (!L) abort(); + assert (L); if (L->type == type_num_value) { return -1; } - if (L->type != type_num || L->act != act_var) abort(); + assert (L->type == type_num); + assert (L->act == act_var); if (L->data == var) { return x == L->type_flags ? 0 : 1; } else { @@ -2631,119 +2608,111 @@ int tl_tree_lookup_value_nat (struct tl_combinator_tree *L, void *var, long long } int uniformize (struct tl_combinator_tree *L, struct tl_combinator_tree *R, struct tree_var_value **T) { - if (L && R) { - if (R->act == act_var) { - struct tl_combinator_tree* _ = R; R = L; L = _; - } - - if (L->type == type_type) { - if (R->type != type_type || L->type_len != R->type_len || L->type_flags != R->type_flags) { - return 0; - } - if (R->data == (void*)-1l || L->data == (void*)-1l) { return 1; } - if (L->act == act_var) { - int x = tl_tree_lookup_value(R, L->data, T); - if (x > 0) { - // if (tl_tree_lookup_value (R, L->data, T) > 0) { - return 0; - } - if (x == 0) { - return 1; - } - struct tl_combinator_tree* E = tl_get_var_value(T, L->data); - if (!E) { - tl_set_var_value(T, L->data, R); - return 1; - } - else { - return uniformize(E, R, T); - } - } - else { - if (L->act != R->act || L->data != R->data) { - return 0; - } - return uniformize(L->left, R->left, T) && uniformize(L->right, R->right, T); - } - } - else { - if (L->type != type_num && L->type != type_num_value) abort(); - if (R->type != type_num && R->type != type_num_value) { - return 0; - } - if (R->type != type_num && R->type != type_num_value) abort(); - if (R->data == (void*)-1l || L->data == (void*)-1l) { return 1; } - long long x = 0; - struct tl_combinator_tree* K = L; - while (1) { - x += K->type_flags; - if (K->type == type_num_value) { - break; - } - if (!tl_get_var_value(T, K->data)) { - int s = tl_tree_lookup_value_nat(R, K->data, K->type_flags, T); - if (s > 0) { - return 0; - } - if (s == 0) { - return 1; - } - /*tl_set_var_value_num (T, K->data, R, -x); - return 1;*/ - break; - } - x += tl_get_var_value_num(T, K->data); - K = tl_get_var_value(T, K->data); - } - long long y = 0; - struct tl_combinator_tree* M = R; - while (1) { - y += M->type_flags; - if (M->type == type_num_value) { - break; - } - if (!tl_get_var_value(T, M->data)) { - int s = tl_tree_lookup_value_nat(L, M->data, M->type_flags, T); - if (s > 0) { - return 0; - } - if (s == 0) { - return 1; - } - /*tl_set_var_value_num (T, M->data, L, -y); - return 1;*/ - break; - } - y += tl_get_var_value_num(T, M->data); - M = tl_get_var_value(T, M->data); - } - if (K->type == type_num_value && M->type == type_num_value) { - return x == y; - } - if (M->type == type_num_value) { - tl_set_var_value_num(T, K->data, M, -(x - y + M->type_flags)); - return 1; - } - else if (K->type == type_num_value) { - tl_set_var_value_num(T, M->data, K, -(y - x + K->type_flags)); - return 1; - } - else { - if (x >= y) { - tl_set_var_value_num(T, K->data, M, -(x - y + M->type_flags)); - } - else { - tl_set_var_value_num(T, M->data, K, -(y - x + K->type_flags)); - } - return 1; - } - } - return 0; - } else if (!L && !R) { - return 1; - } else { - abort(); + if (!L || !R) { + assert (!L && !R); + return 1; } + if (R->act == act_var) { + struct tl_combinator_tree *_ = R; R = L; L = _; + } + + if (L->type == type_type) { + if (R->type != type_type || L->type_len != R->type_len || L->type_flags != R->type_flags) { + return 0; + } + if (R->data == (void *)-1l || L->data == (void *)-1l) { return 1;} + if (L->act == act_var) { + int x = tl_tree_lookup_value (R, L->data, T); + if (x > 0) { +// if (tl_tree_lookup_value (R, L->data, T) > 0) { + return 0; + } + if (x == 0) { + return 1; + } + struct tl_combinator_tree *E = tl_get_var_value (T, L->data); + if (!E) { + tl_set_var_value (T, L->data, R); + return 1; + } else { + return uniformize (E, R, T); + } + } else { + if (L->act != R->act || L->data != R->data) { + return 0; + } + return uniformize (L->left, R->left, T) && uniformize (L->right, R->right, T); + } + } else { + assert (L->type == type_num || L->type == type_num_value); + if (R->type != type_num && R->type != type_num_value) { + return 0; + } + assert (R->type == type_num || R->type == type_num_value); + if (R->data == (void *)-1l || L->data == (void *)-1l) { return 1;} + long long x = 0; + struct tl_combinator_tree *K = L; + while (1) { + x += K->type_flags; + if (K->type == type_num_value) { + break; + } + if (!tl_get_var_value (T, K->data)) { + int s = tl_tree_lookup_value_nat (R, K->data, K->type_flags, T); + if (s > 0) { + return 0; + } + if (s == 0) { + return 1; + } + /*tl_set_var_value_num (T, K->data, R, -x); + return 1;*/ + break; + } + x += tl_get_var_value_num (T, K->data); + K = tl_get_var_value (T, K->data); + } + long long y = 0; + struct tl_combinator_tree *M = R; + while (1) { + y += M->type_flags; + if (M->type == type_num_value) { + break; + } + if (!tl_get_var_value (T, M->data)) { + int s = tl_tree_lookup_value_nat (L, M->data, M->type_flags, T); + if (s > 0) { + return 0; + } + if (s == 0) { + return 1; + } + /*tl_set_var_value_num (T, M->data, L, -y); + return 1;*/ + break; + } + y += tl_get_var_value_num (T, M->data); + M = tl_get_var_value (T, M->data); + } + if (K->type == type_num_value && M->type == type_num_value) { + return x == y; + } + if (M->type == type_num_value) { + tl_set_var_value_num (T, K->data, M, -(x - y + M->type_flags)); + return 1; + } else if (K->type == type_num_value) { + tl_set_var_value_num (T, M->data, K, -(y - x + K->type_flags)); + return 1; + } else { + if (x >= y) { + tl_set_var_value_num (T, K->data, M, -(x - y + M->type_flags)); + } else { + tl_set_var_value_num (T, M->data, K, -(y - x + K->type_flags)); + } + return 1; + } + } + return 0; } @@ -2751,7 +2720,7 @@ void tl_type_check (struct tl_type *t) { if (!__ok) return; if (!strcmp (t->id, "#")) { t->name = 0x70659eff; return; } if (!strcmp (t->id, "Type")) { t->name = 0x2cecf817; return; } - if (t->constructors_num <= 0 && !(t->flags & FLAG_EMPTY)) { + if (t->constructors_num <= 0 && !(t->flags & FLAG_EMPTY)) { TL_ERROR ("Type %s has no constructors\n", t->id); __ok = 0; return; @@ -2770,7 +2739,7 @@ void tl_type_check (struct tl_type *t) { } } if ((t->flags & 24) == 24) { - TL_WARNING ("Warning: Type %s has overlapping costructors, but it is used with `%%`\n", t->id); + TL_WARNING ("Warning: Type %s has overlapping costructors, but it is used with `%%`\n", t->id); } int z = 0; int sid = 0; @@ -2797,7 +2766,8 @@ void tl_type_check (struct tl_type *t) { } struct tl_program *tl_parse (struct tree *T) { - if (!T || T->type != type_tl_program) return 0; + assert (T); + assert (T->type == type_tl_program); int i; tl_program_cur = talloc (sizeof (*tl_program_cur)); tl_add_type ("#", 1, 0, 0); @@ -2814,27 +2784,17 @@ struct tl_program *tl_parse (struct tree *T) { return tl_program_cur; } -int __f; +FILE *__f; int num = 0; void wint (int a) { // printf ("%d ", a); a = htole32 (a); - int r = write(__f, &a, 4); - if (r != 4) - { - TL_ERROR("Cannot write int %d, file might be corrupted", a); - abort(); - } + assert (fwrite (&a, 1, 4, __f) == 4); } void wdata (const void *x, int len) { - int r = write(__f, x, len); - if (r != len) - { - TL_ERROR("Cannot write data len %d, file might be corrupted", len); - abort(); - } + assert (fwrite (x, 1, len, __f) == len); } void wstr (const char *s) { @@ -2843,15 +2803,10 @@ void wstr (const char *s) { int x = strlen (s); if (x <= 254) { unsigned char x_c = (unsigned char)x; - int r = write(__f, &x_c, 1); - if (r != 1) - { - TL_ERROR("Cannot write string %s, file might be corrupted", s); - abort(); - } + assert (fwrite (&x_c, 1, 1, __f) == 1); } else { - TL_ERROR("String is too big...\n"); - abort(); + fprintf (stderr, "String is too big...\n"); + assert (0); } wdata (s, x); x ++; // The header, containing the length, which is 1 byte @@ -2869,21 +2824,15 @@ void wstr (const char *s) { void wll (long long a) { // printf ("%lld ", a); a = htole64 (a); - int r = write(__f, &a, 8); - if (r != 8) - { - TL_ERROR("Cannot write long long %lld, file might be corrupted", a); - abort(); - } + assert (fwrite (&a, 1, 8, __f) == 8); } int count_list_size (struct tl_combinator_tree *T) { + assert (T->type == type_list || T->type == type_list_item); if (T->type == type_list_item) { return 1; - } else if (T->type == type_list) { - return count_list_size(T->left) + count_list_size(T->right); } else { - abort(); + return count_list_size (T->left) + count_list_size (T->right); } } @@ -2927,22 +2876,25 @@ void write_var_type_flags (long long flags) { } if (new_flags & FLAG_BARE) { TL_ERROR ("Sorry, bare vars are not (yet ?) supported.\n"); - abort(); + assert (!(new_flags & FLAG_BARE)); } wint (new_flags); } void write_tree (struct tl_combinator_tree *T, int extra, struct tree_var_value **v, int *last_var); void write_args (struct tl_combinator_tree *T, struct tree_var_value **v, int *last_var) { + assert (T->type == type_list || T->type == type_list_item); if (T->type == type_list) { - if (!T->left || !T->right || T->act != act_union) abort(); + assert (T->act == act_union); + assert (T->left); + assert (T->right); write_args (T->left, v, last_var); write_args (T->right, v, last_var); return; } - if (T->type != type_list_item) abort(); wint (TLS_ARG_V2); - if (T->act != act_field || !T->left) abort(); + assert (T->act == act_field); + assert (T->left); wstr (T->data && strcmp (T->data, "_") ? T->data : 0); long long f = T->flags; if (T->left->act == act_opt_field) { @@ -2955,7 +2907,7 @@ void write_args (struct tl_combinator_tree *T, struct tree_var_value **v, int *l tl_set_var_value_num (v, T, 0, (*last_var) - 1); } else { write_field_flags (f); - } + } write_tree (T->left, 0, v, last_var); } @@ -2975,13 +2927,14 @@ void write_type_rec (struct tl_combinator_tree *T, int cc, struct tree_var_value } write_tree (T->right, 0, v, last_var); } else { + assert (T->act == act_var || T->act == act_type); if (T->act == act_var) { - if (cc) abort(); + assert (!cc); wint (TLS_TYPE_VAR); wint (tl_get_var_value_num (v, T->data)); write_var_type_flags (T->flags); //wint (T->flags); - } else if (T->act == act_type) { + } else { wint (TLS_TYPE_EXPR); struct tl_type *t = T->data; wint (t->name); @@ -2989,17 +2942,15 @@ void write_type_rec (struct tl_combinator_tree *T, int cc, struct tree_var_value // wint (T->flags); wint (cc); // fprintf (stderr, "cc = %d\n", cc); - } else { - abort(); } } } void write_opt_type (struct tl_combinator_tree *T, struct tree_var_value **v, int *last_var) { - if (!T) abort(); wint (tl_get_var_value_num (v, T->left->data)); wint (T->left->type_flags); // write_tree (T->right, 0, v, last_var); + assert (T); T = T->right; switch (T->type) { case type_type: @@ -3008,16 +2959,16 @@ void write_opt_type (struct tl_combinator_tree *T, struct tree_var_value **v, in } else if (T->act == act_type || T->act == act_var || T->act == act_arg) { write_type_rec (T, 0, v, last_var); } else { - abort(); + assert (0); } break; default: - abort(); + assert (0); } } void write_tree (struct tl_combinator_tree *T, int extra, struct tree_var_value **v, int *last_var) { - if (!T) abort(); + assert (T); switch (T->type) { case type_list_item: case type_list: @@ -3042,12 +2993,12 @@ void write_tree (struct tl_combinator_tree *T, int extra, struct tree_var_value } else if (T->act == act_type || T->act == act_var || T->act == act_arg) { write_type_rec (T, 0, v, last_var); } else { - if (T->act != act_opt_field) abort(); + assert (T->act == act_opt_field); write_opt_type (T, v, last_var); } break; default: - abort(); + assert (0); } } @@ -3067,12 +3018,12 @@ int is_builtin_type (const char *id) { } void write_combinator (struct tl_constructor *c) { - struct tree_var_value* T = 0; - int x = 0; - if (!c->right) abort(); wint (c->name); wstr (c->id); wint (c->type ? c->type->name : 0); + struct tree_var_value *T = 0; + int x = 0; + assert (c->right); if (c->left) { if (is_builtin_type (c->id)) { wint (TLS_COMBINATOR_LEFT_BUILTIN); @@ -3107,7 +3058,7 @@ void write_type_constructors (struct tl_type *t) { } } -void write_types (int f) { +void write_types (FILE *f) { __f = f; wint (TLS_SCHEMA_V2); wint (0); diff --git a/td/generate/tl-parser/tl-parser.h b/td/generate/tl-parser/tl-parser.h index 7eb752478..59209d4a5 100644 --- a/td/generate/tl-parser/tl-parser.h +++ b/td/generate/tl-parser/tl-parser.h @@ -24,20 +24,8 @@ #ifndef __TL_PARSER_NEW_H__ #define __TL_PARSER_NEW_H__ -#if defined(WIN32) || defined(_WIN32) -#define lrand48() rand() -#define _PRINTF_INT64_ "I64" -#if defined(_MSC_VER) && _MSC_VER >= 1400 -#define read _read -#define write _write -#define close _close -#define lseek _lseek -#define strdup _strdup -#define __attribute__(x) -#endif -#else -#define _PRINTF_INT64_ "ll" -#endif + +#include enum lex_type { lex_error, @@ -208,7 +196,7 @@ struct tree *tl_parse_lex (struct parse *P); void tl_print_parse_error (void); struct tl_program *tl_parse (struct tree *T); -void write_types (int f); +void write_types (FILE *f); #define FLAG_BARE 1 #define FLAG_OPT_VAR (1 << 17) @@ -218,4 +206,18 @@ void write_types (int f); #define FLAG_DEFAULT_CONSTRUCTOR (1 << 25) #define FLAG_EMPTY (1 << 10) +#ifdef NDEBUG +#undef assert +#define assert(x) if (!(x)) { fprintf(stderr, "Assertion error!\n"); abort(); } +#endif + +#ifdef _WIN32 +#include "wgetopt.h" + +#define __attribute__(x) + +#define lrand48() rand() +#define strdup _strdup +#endif + #endif diff --git a/td/generate/tl-parser/tlc.c b/td/generate/tl-parser/tlc.c index 153eacd64..52fb7266e 100644 --- a/td/generate/tl-parser/tlc.c +++ b/td/generate/tl-parser/tlc.c @@ -24,16 +24,14 @@ #include #include +#include -#if defined(_MSC_VER) -#include -#include -#include -#include "wingetopt.h" -#else +#include "tl-parser.h" + +#ifndef _WIN32 #include #endif -#include "tl-parser.h" + #include #include #include @@ -58,26 +56,10 @@ void usage (void) { } int vkext_write (const char *filename) { -#if defined(_MSC_VER) && _MSC_VER >= 1400 - int f = 0; - int r = _sopen_s(&f, filename, _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE); - if (r != 0) - { - fprintf(stderr, "Cannot write file %s\n", filename); - abort(); - } -#elif defined(WIN32) || defined(_WIN32) - int f = open(filename, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0640); -#else - int f = open (filename, O_CREAT | O_WRONLY | O_TRUNC, 0640); -#endif - if (!f) - { - fprintf(stderr, "Cannot write file %s\n", filename); - abort(); - } + FILE *f = fopen(filename, "wb"); + assert (f != NULL); write_types (f); - close (f); + fclose (f); return 0; } @@ -103,14 +85,14 @@ void print_backtrace (void) { } #else void print_backtrace (void) { - if (write (1, "No libexec. Backtrace disabled\n", 32) < 0) { + if (fwrite ("No libexec. Backtrace disabled\n", 32, 1, stderr) < 0) { // Sad thing } } #endif void sig_segv_handler (int signum __attribute__ ((unused))) { - if (write (1, "SIGSEGV received\n", 18) < 0) { + if (fwrite ("SIGSEGV received\n", 18, 1, stderr) < 0) { // Sad thing } print_backtrace (); @@ -118,7 +100,7 @@ void sig_segv_handler (int signum __attribute__ ((unused))) { } void sig_abrt_handler (int signum __attribute__ ((unused))) { - if (write (1, "SIGABRT received\n", 18) < 0) { + if (fwrite ("SIGABRT received\n", 18, 1, stderr) < 0) { // Sad thing } print_backtrace (); @@ -150,17 +132,17 @@ int main (int argc, char **argv) { if (argc != optind + 1) { usage (); } - + struct parse *P = tl_init_parse_file (argv[optind]); if (!P) { - return 0; + return 1; } struct tree *T; if (!(T = tl_parse_lex (P))) { fprintf (stderr, "Error in parse:\n"); tl_print_parse_error (); - return 0; + return 1; } else { if (verbosity) { fprintf (stderr, "Parse ok\n"); diff --git a/td/generate/tl-parser/wgetopt.c b/td/generate/tl-parser/wgetopt.c new file mode 100644 index 000000000..4557b9211 --- /dev/null +++ b/td/generate/tl-parser/wgetopt.c @@ -0,0 +1,1274 @@ +/* Getopt for GNU. +NOTE: getopt is now part of the C library, so if you don't know what +"Keep this file name-space clean" means, talk to drepper@gnu.org +before changing it! +Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001 +Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with the GNU C Library; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . +Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems +reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not +actually compiling the library itself. This code is part of the GNU C +Library, but also included in many other GNU distributions. Compiling +and linking in this code is a waste when using the GNU C library +(especially if it is a shared library). Rather than having every GNU +program understand `configure --with-gnu-libc' and omit the object files, +it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include +to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them +contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. */ +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# ifndef _ +# define _(msgid) gettext (msgid) +# endif +# else +# define _(msgid) (msgid) +# endif +# if defined _LIBC && defined USE_IN_LIBIO +# include +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' +but it behaves differently for the user, since it allows the user +to intersperse the options with the other arguments. + +As `getopt' works, it permutes the elements of ARGV so that, +when it is done, all the options precede everything else. Thus +all application programs are extended to handle flexible argument order. + +Setting the environment variable POSIXLY_CORRECT disables permutation. +Then the behavior is completely standard. + +GNU application programs can use a third alternative mode in which +they can distinguish the relative order of options and other arguments. */ + +#include "wgetopt.h" + +/* For communication from `getopt' to the caller. +When `getopt' finds an option that takes an argument, +the argument value is returned here. +Also, when `ordering' is RETURN_IN_ORDER, +each non-option ARGV-element is returned here. */ + +char *optarg; + +/* Index in ARGV of the next element to be scanned. +This is used for communication to and from the caller +and for communication between successive calls to `getopt'. + +On entry to `getopt', zero means this is the first call; initialize. + +When `getopt' returns -1, this is the index of the first of the +non-option elements that the caller should itself scan. + +Otherwise, `optind' communicates from one call to the next +how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which +causes problems with re-calling getopt as programs generally don't +know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element +in which the last option character we returned was found. +This allows us to pick up the scan where we left off. + +If this is zero, or a null string, it means resume the scan +by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message +for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. +This must be initialized on some systems to avoid linking in the +system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + +If the caller did not specify anything, +the default is REQUIRE_ORDER if the environment variable +POSIXLY_CORRECT is defined, PERMUTE otherwise. + +REQUIRE_ORDER means don't recognize them as options; +stop option processing when the first non-option is seen. +This is what Unix does. +This mode of operation is selected by either setting the environment +variable POSIXLY_CORRECT, or using `+' as the first character +of the list of option characters. + +PERMUTE is the default. We permute the contents of ARGV as we scan, +so that eventually all the non-options are at the end. This allows options +to be given in any order, even with programs that were not written to +expect this. + +RETURN_IN_ORDER is an option available to programs that were written +to expect options and other ARGV-elements in any order and that care about +the ordering of the two. We describe each non-option ARGV-element +as if it were the argument of an option with character code 1. +Using `-' as the first character of the list of option characters +selects this mode of operation. + +The special argument `--' forces an end of option-scanning regardless +of the value of `ordering'. In the case of RETURN_IN_ORDER, only +`--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries +because there are many ways it can cause trouble. +On some systems, it contains special magic macros that don't work +in GCC. */ +# include +# define my_index strchr +#else + +#define HAVE_STRING_H 1 +# if HAVE_STRING_H +# include +# else +# include +# endif + +/* Avoid depending on library functions or files +whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv(); +#endif + +static char * +my_index(str, chr) +const char *str; +int chr; +{ + while (*str) + { + if (*str == chr) + return (char *)str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. +If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. +That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, +and has done so at least since version 2.4.5. -- rms. */ +extern int strlen(const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have +been skipped. `first_nonopt' is the index in ARGV of the first of them; +`last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Stored original parameters. +XXX This is no good solution. We should rather copy the args so +that we can compare them later. But we must not use malloc(3). */ +extern int __libc_argc; +extern char **__libc_argv; + +/* Bash 2.0 gives us an environment variable containing flags +indicating ARGV elements that should not be considered arguments. */ + +# ifdef USE_NONOPTION_FLAGS +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; +# endif + +# ifdef USE_NONOPTION_FLAGS +# define SWAP_FLAGS(ch1, ch2) \ +if (nonoption_flags_len > 0) \ +{ \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ +} +# else +# define SWAP_FLAGS(ch1, ch2) +# endif +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. +One subsequence is elements [first_nonopt,last_nonopt) +which contains all the non-options that have been skipped so far. +The other is elements [last_nonopt,optind), which contains all +the options processed since those non-options were skipped. + +`first_nonopt' and `last_nonopt' are relocated so that they describe +the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange(char **); +#endif + +static void +exchange(argv) +char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc(top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset(__mempcpy(new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS(bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS(bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize(int, char *const *, const char *); +#endif +static const char * +_getopt_initialize(argc, argv, optstring) +int argc; +char *const *argv; +const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (posixly_correct == NULL + && argc == __libc_argc && argv == __libc_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen(orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *)malloc(nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset(__mempcpy(__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters +given in OPTSTRING. + +If an element of ARGV starts with '-', and is not exactly "-" or "--", +then it is an option element. The characters of this element +(aside from the initial '-') are option characters. If `getopt' +is called repeatedly, it returns successively each of the option characters +from each of the option elements. + +If `getopt' finds another option character, it returns that character, +updating `optind' and `nextchar' so that the next call to `getopt' can +resume the scan with the following option character or ARGV-element. + +If there are no more option characters, `getopt' returns -1. +Then `optind' is the index in ARGV of the first ARGV-element +that is not an option. (The ARGV-elements have been permuted +so that those that are not options now come last.) + +OPTSTRING is a string containing the legitimate option characters. +If an option character is seen that is not listed in OPTSTRING, +return '?' after printing an error message. If you set `opterr' to +zero, the error message is suppressed but we still return '?'. + +If a char in OPTSTRING is followed by a colon, that means it wants an arg, +so the following text in the same ARGV-element, or the text of the following +ARGV-element, is returned in `optarg'. Two colons mean an option that +wants an optional arg; if there is text in the current ARGV-element, +it is returned in `optarg', otherwise `optarg' is set to zero. + +If OPTSTRING starts with `-' or `+', it requests different methods of +handling the non-option ARGV-elements. +See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + +Long-named options begin with `--' instead of `-'. +Their names may be abbreviated as long as the abbreviation is unique +or is an exact match for some defined option. If they have an +argument, it follows the option name in the same ARGV-element, separated +from the option name by a `=', or else the in next ARGV-element. +When `getopt' finds a long-named option, it returns 0 if that option's +`flag' field is nonzero, the value of the option's `val' field +if the `flag' field is zero. + +The elements of ARGV aren't really const, because we permute them. +But we pretend they're const in the prototype to be compatible +with other systems. + +LONGOPTS is a vector of `struct option' terminated by an +element containing a name which is zero. + +LONGIND returns the index in LONGOPT of the long-named option found. +It is only valid when a long-named option has been found by the most +recent call. + +If LONG_ONLY is nonzero, '-' as well as '--' can introduce +long-named options. */ + +int +_getopt_internal(argc, argv, optstring, longopts, longind, long_only) +int argc; +char *const *argv; +const char *optstring; +const struct option *longopts; +int *longind; +int long_only; +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + if (argc < 1) + return -1; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize(argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange((char **)argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp(argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange((char **)argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index(optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int)(nameend - nextchar) + == (unsigned int)strlen(p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf(&buf, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + + if (_IO_fwide(stderr, 0) > 0) + __fwprintf(stderr, L"%s", buf); + else + fputs(buf, stderr); + + free(buf); +#else + fprintf(stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); +#endif + } + nextchar += strlen(nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; +#endif + + if (argv[optind - 1][1] == '-') + { + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf(&buf, _("\ + %s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#else + fprintf(stderr, _("\ + %s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf(&buf, _("\ + %s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], + pfound->name); +#else + fprintf(stderr, _("\ + %s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (_IO_fwide(stderr, 0) > 0) + __fwprintf(stderr, L"%s", buf); + else + fputs(buf, stderr); + + free(buf); +#endif + } + + nextchar += strlen(nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf(&buf, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + + if (_IO_fwide(stderr, 0) > 0) + __fwprintf(stderr, L"%s", buf); + else + fputs(buf, stderr); + + free(buf); +#else + fprintf(stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); +#endif + } + nextchar += strlen(nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen(nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index(optstring, *nextchar) == NULL) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; +#endif + + if (argv[optind][1] == '-') + { + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf(&buf, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); +#else + fprintf(stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf(&buf, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); +#else + fprintf(stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (_IO_fwide(stderr, 0) > 0) + __fwprintf(stderr, L"%s", buf); + else + fputs(buf, stderr); + + free(buf); +#endif + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index(optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; +#endif + + if (posixly_correct) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf(&buf, _("%s: illegal option -- %c\n"), + argv[0], c); +#else + fprintf(stderr, _("%s: illegal option -- %c\n"), argv[0], c); +#endif + } + else + { +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf(&buf, _("%s: invalid option -- %c\n"), + argv[0], c); +#else + fprintf(stderr, _("%s: invalid option -- %c\n"), argv[0], c); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (_IO_fwide(stderr, 0) > 0) + __fwprintf(stderr, L"%s", buf); + else + fputs(buf, stderr); + + free(buf); +#endif + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf(&buf, _("%s: option requires an argument -- %c\n"), + argv[0], c); + + if (_IO_fwide(stderr, 0) > 0) + __fwprintf(stderr, L"%s", buf); + else + fputs(buf, stderr); + + free(buf); +#else + fprintf(stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int)(nameend - nextchar) == strlen(p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf(&buf, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + + if (_IO_fwide(stderr, 0) > 0) + __fwprintf(stderr, L"%s", buf); + else + fputs(buf, stderr); + + free(buf); +#else + fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); +#endif + } + nextchar += strlen(nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf(&buf, _("\ + %s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + if (_IO_fwide(stderr, 0) > 0) + __fwprintf(stderr, L"%s", buf); + else + fputs(buf, stderr); + + free(buf); +#else + fprintf(stderr, _("\ + %s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + + nextchar += strlen(nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf(&buf, _("\ + %s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + + if (_IO_fwide(stderr, 0) > 0) + __fwprintf(stderr, L"%s", buf); + else + fputs(buf, stderr); + + free(buf); +#else + fprintf(stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); +#endif + } + nextchar += strlen(nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen(nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf(&buf, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + + if (_IO_fwide(stderr, 0) > 0) + __fwprintf(stderr, L"%s", buf); + else + fputs(buf, stderr); + + free(buf); +#else + fprintf(stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt(argc, argv, optstring) +int argc; +char *const *argv; +const char *optstring; +{ + return _getopt_internal(argc, argv, optstring, + (const struct option *) 0, + (int *)0, + 0); +} + + + + +int +getopt_long(int argc, char *const *argv, const char *options, +const struct option *long_options, int *opt_index) +{ + return _getopt_internal(argc, argv, options, long_options, opt_index, 0, 0); +} + +int +getopt_long_only(int argc, char *const *argv, const char *options, +const struct option *long_options, int *opt_index) +{ + return _getopt_internal(argc, argv, options, long_options, opt_index, 1, 0); +} + + + + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing +the above definition of `getopt'. */ + +int +main(argc, argv) +int argc; +char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt(argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf("option %c\n", c); + break; + + case 'a': + printf("option a\n"); + break; + + case 'b': + printf("option b\n"); + break; + + case 'c': + printf("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + } + + exit(0); +} + +#endif /* TEST */ diff --git a/td/generate/tl-parser/wgetopt.h b/td/generate/tl-parser/wgetopt.h new file mode 100644 index 000000000..6e2fa2718 --- /dev/null +++ b/td/generate/tl-parser/wgetopt.h @@ -0,0 +1,193 @@ +/* Declarations for getopt. + Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2009,2010 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +/* If __GNU_LIBRARY__ is not already defined, either we are being used + standalone, or this is the first header included in the source file. + If we are being used with glibc, we need to include , but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include , which will pull in for us + if it's from glibc. (Why ctype.h? It's guaranteed to exist and it + doesn't flood the namespace with stuff the way some other headers do.) */ +#if !defined __GNU_LIBRARY__ +# include +#endif + +#ifndef __THROW +# ifndef __GNUC_PREREQ +# define __GNUC_PREREQ(maj, min) (0) +# endif +# if defined __cplusplus && __GNUC_PREREQ (2,8) +# define __THROW throw () +# else +# define __THROW +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ + const char *name; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) + __THROW; + +# if defined __need_getopt && defined __USE_POSIX2 \ + && !defined __USE_POSIX_IMPLICITLY && !defined __USE_GNU +/* The GNU getopt has more functionality than the standard version. The + additional functionality can be disable at runtime. This redirection + helps to also do this at runtime. */ +# ifdef __REDIRECT + extern int __REDIRECT_NTH (getopt, (int ___argc, char *const *___argv, + const char *__shortopts), + __posix_getopt); +# else +extern int __posix_getopt (int ___argc, char *const *___argv, + const char *__shortopts) __THROW; +# define getopt __posix_getopt +# endif +# endif +#else /* not __GNU_LIBRARY__ */ +extern int getopt (); +#endif /* __GNU_LIBRARY__ */ + +#ifndef __need_getopt +extern int getopt_long (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW; +extern int getopt_long_only (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW; + +#endif + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/td/generate/tl-parser/wingetopt.c b/td/generate/tl-parser/wingetopt.c deleted file mode 100644 index 09dac17a4..000000000 --- a/td/generate/tl-parser/wingetopt.c +++ /dev/null @@ -1,82 +0,0 @@ -/* -POSIX getopt for Windows - -AT&T Public License - -Code given out at the 1985 UNIFORUM conference in Dallas. -*/ - -#ifndef __GNUC__ - -#include "wingetopt.h" -#include -#include - -#ifndef NULL -#define NULL 0 -#endif -#define EOF (-1) -#define ERR(s, c) if(opterr){\ - char errbuf[2];\ - errbuf[0] = c; errbuf[1] = '\n';\ - fputs(argv[0], stderr);\ - fputs(s, stderr);\ - fputc(c, stderr);} -//(void) write(2, argv[0], (unsigned)strlen(argv[0]));\ - //(void) write(2, s, (unsigned)strlen(s));\ - //(void) write(2, errbuf, 2);} - -int opterr = 1; -int optind = 1; -int optopt; -char *optarg; - -int -getopt(argc, argv, opts) -int argc; -char **argv, *opts; -{ - static int sp = 1; - register int c; - register char *cp; - - if (sp == 1) - if (optind >= argc || - argv[optind][0] != '-' || argv[optind][1] == '\0') - return(EOF); - else if (strcmp(argv[optind], "--") == (int)NULL) { - optind++; - return(EOF); - } - optopt = c = argv[optind][sp]; - if (c == ':' || (cp = strchr(opts, c)) == NULL) { - ERR(": illegal option -- ", c); - if (argv[optind][++sp] == '\0') { - optind++; - sp = 1; - } - return('?'); - } - if (*++cp == ':') { - if (argv[optind][sp + 1] != '\0') - optarg = &argv[optind++][sp + 1]; - else if (++optind >= argc) { - ERR(": option requires an argument -- ", c); - sp = 1; - return('?'); - } - else - optarg = argv[optind++]; - sp = 1; - } - else { - if (argv[optind][++sp] == '\0') { - sp = 1; - optind++; - } - optarg = NULL; - } - return(c); -} - -#endif /* __GNUC__ */ \ No newline at end of file diff --git a/td/generate/tl-parser/wingetopt.h b/td/generate/tl-parser/wingetopt.h deleted file mode 100644 index 4372c6601..000000000 --- a/td/generate/tl-parser/wingetopt.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -POSIX getopt for Windows - -AT&T Public License - -Code given out at the 1985 UNIFORUM conference in Dallas. -*/ - -#ifdef __GNUC__ -#include -#endif -#ifndef __GNUC__ - -#ifndef _WINGETOPT_H_ -#define _WINGETOPT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - extern int opterr; - extern int optind; - extern int optopt; - extern char *optarg; - extern int getopt(int argc, char **argv, char *opts); - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H_ */ -#endif /* __GNUC__ */ \ No newline at end of file