diff --git a/auto-static-print.c b/auto-static-print.c deleted file mode 100644 index 0c42764..0000000 --- a/auto-static-print.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - This file is part of tgl-library - - This 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. - - This 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 this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - Copyright Vitaly Valtman 2014 -*/ - -#include -#include -#include - -static int cur_token_len; -static char *cur_token; -static int cur_token_real_len; -static int cur_token_quoted; -static int multiline_output = 1; -static int multiline_offset; -static int multiline_offset_size = 2; - -static int *in_ptr, *in_end; - -static inline int fetch_int (void) { - return *(in_ptr ++); -} - -static inline int fetch_long (void) { - long long r = *(long long *)in_ptr; - in_ptr += 2; - return r; -} - -static inline int fetch_long (void) { - long long r = *(long long *)in_ptr; - in_ptr += 2; - return r; -} - -static inline void out_int (int a) {} -static inline void out_double (double a) {} -static inline void out_string (char *s, int l) {} -static inline void out_long (long long a) {} - -static int disable_field_names; - -#define expect_token(token,len) \ - if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return -1; } \ - local_next_token (); - -#define expect_token_ptr(token,len) \ - if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return 0; } \ - local_next_token (); - -#define expect_token_autocomplete(token,len) \ - if (cur_token_len == -3 && len >= cur_token_real_len && !memcmp (cur_token, token, cur_token_real_len)) { set_autocomplete_string (token); return -1; }\ - if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return -1; } \ - local_next_token (); - -#define expect_token_ptr_autocomplete(token,len) \ - if (cur_token_len == -3 && len >= cur_token_real_len && !memcmp (cur_token, token, cur_token_real_len)) { set_autocomplete_string (token); return 0; }\ - if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return 0; } \ - local_next_token (); - - -static int autocomplete_mode; -static char *autocomplete_string; -static int (*autocomplete_fun)(const char *, int, int, char **); - -static void set_autocomplete_string (const char *s) { - if (autocomplete_string) { free (autocomplete_string); } - autocomplete_string = strdup (s); - assert (autocomplete_string); - autocomplete_mode = 1; -} - -static void set_autocomplete_type (int (*f)(const char *, int, int, char **)) { - autocomplete_fun = f; - autocomplete_mode = 2; -} - -static int is_int (void) { - if (cur_token_len <= 0) { return 0; } - char c = cur_token[cur_token_len]; - cur_token[cur_token_len] = 0; - char *p = 0; - - if (strtoll (cur_token, &p, 10)) {} - cur_token[cur_token_len] = c; - - return p == cur_token + cur_token_len; -} - -static long long get_int (void) { - if (cur_token_len <= 0) { return 0; } - char c = cur_token[cur_token_len]; - cur_token[cur_token_len] = 0; - char *p = 0; - - long long val = strtoll (cur_token, &p, 0); - cur_token[cur_token_len] = c; - - return val; -} - -static int is_double (void) { - if (cur_token_len <= 0) { return 0; } - char c = cur_token[cur_token_len]; - cur_token[cur_token_len] = 0; - char *p = 0; - - if (strtod (cur_token, &p)) {} - cur_token[cur_token_len] = c; - - return p == cur_token + cur_token_len; -} - -static double get_double (void) { - if (cur_token_len <= 0) { return 0; } - char c = cur_token[cur_token_len]; - cur_token[cur_token_len] = 0; - char *p = 0; - - double val = strtod (cur_token, &p); - cur_token[cur_token_len] = c; - - return val; -} - -static struct paramed_type *paramed_type_dup (struct paramed_type *P) { - if (ODDP (P)) { return P; } - struct paramed_type *R = malloc (sizeof (*R)); - assert (R); - R->type = malloc (sizeof (*R->type)); - assert (R->type); - memcpy (R->type, P->type, sizeof (*P->type)); - R->type->id = strdup (P->type->id); - assert (R->type->id); - - if (P->type->params_num) { - R->params = malloc (sizeof (void *) * P->type->params_num); - assert (R->params); - int i; - for (i = 0; i < P->type->params_num; i++) { - R->params[i] = paramed_type_dup (P->params[i]); - } - } - return R; -} - -void tgl_paramed_type_free (struct paramed_type *P) { - if (ODDP (P)) { return; } - if (P->type->params_num) { - int i; - for (i = 0; i < P->type->params_num; i++) { - tgl_paramed_type_free (P->params[i]); - } - free (P->params); - } - free (P->type->id); - free (P->type); - free (P); -} - -static char *buffer_pos, *buffer_end; - -static int is_wspc (char c) { - return c <= 32 && c > 0; -} - -static void skip_wspc (void) { - while (buffer_pos < buffer_end && is_wspc (*buffer_pos)) { - buffer_pos ++; - } -} - -static int is_letter (char c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-'; -} - - -static char exp_buffer[1 << 25];; -static int exp_buffer_pos; - -static inline int is_hex (char c) { - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'); -} - -static inline int hex2dec (char c) { - if (c >= '0' && c <= '9') { return c - '0'; } - else { return c - 'a' + 10; } -} - -static void expand_backslashed (char *s, int len) { - int backslashed = 0; - exp_buffer_pos = 0; - int i = 0; - while (i < len) { - assert (i + 3 <= (1 << 25)); - if (backslashed) { - backslashed = 0; - switch (s[i ++]) { - case 'n': - exp_buffer[exp_buffer_pos ++] = '\n'; - break; - case 'r': - exp_buffer[exp_buffer_pos ++] = '\r'; - break; - case 't': - exp_buffer[exp_buffer_pos ++] = '\t'; - break; - case 'b': - exp_buffer[exp_buffer_pos ++] = '\b'; - break; - case 'a': - exp_buffer[exp_buffer_pos ++] = '\a'; - break; - case '\\': - exp_buffer[exp_buffer_pos ++] = '\\'; - break; - case 'x': - if (i + 2 > len || !is_hex (s[i]) || !is_hex (s[i + 1])) { - exp_buffer_pos = -1; - return; - } - exp_buffer[exp_buffer_pos ++] = hex2dec (s[i]) * 16 + hex2dec (s[i + 1]); - i += 2; - break; - default: - break; - } - } else { - if (s[i] == '\\') { - backslashed = 1; - i ++; - } else { - exp_buffer[exp_buffer_pos ++] = s[i ++]; - } - } - } -} - -static void local_next_token (void) { - skip_wspc (); - cur_token_quoted = 0; - if (buffer_pos >= buffer_end) { - cur_token_len = -3; - cur_token_real_len = 0; - return; - } - char c = *buffer_pos; - if (is_letter (c)) { - cur_token = buffer_pos; - while (buffer_pos < buffer_end && is_letter (*buffer_pos)) { - buffer_pos ++; - } - if (buffer_pos < buffer_end) { - cur_token_len = buffer_pos - cur_token; - } else { - cur_token_real_len = buffer_pos - cur_token; - cur_token_len = -3; - } - return; - } else if (c == '"') { - cur_token_quoted = 1; - cur_token = buffer_pos ++; - int backslashed = 0; - while (buffer_pos < buffer_end && (*buffer_pos != '"' || backslashed)) { - if (*buffer_pos == '\\') { - backslashed ^= 1; - } else { - backslashed = 0; - } - buffer_pos ++; - } - if (*buffer_pos == '"') { - buffer_pos ++; - expand_backslashed (cur_token + 1, buffer_pos - cur_token - 2); - if (exp_buffer_pos < 0) { - cur_token_len = -2; - } else { - cur_token_len = exp_buffer_pos; - cur_token = exp_buffer; - } - } else { - cur_token_len = -2; - } - return; - } else { - if (c) { - cur_token = buffer_pos ++; - cur_token_len = 1; - } else { - cur_token_len = -3; - cur_token_real_len = 0; - } - } -} - -#define MAX_FVARS 100 -static struct paramed_type *fvars[MAX_FVARS]; -static int fvars_pos; - -static void add_var_to_be_freed (struct paramed_type *P) { - assert (fvars_pos < MAX_FVARS); - fvars[fvars_pos ++] = P; -} - -static void free_vars_to_be_freed (void) { - int i; - for (i = 0; i < fvars_pos; i++) { - tgl_paramed_type_free (fvars[i]); - } - fvars_pos = 0; -} - -int tglf_extf_autocomplete (const char *text, int text_len, int index, char **R, char *data, int data_len) { - if (index == -1) { - buffer_pos = data; - buffer_end = data + data_len; - autocomplete_mode = 0; - local_next_token (); - struct paramed_type *P = autocomplete_function_any (); - free_vars_to_be_freed (); - if (P) { tgl_paramed_type_free (P); } - } - if (autocomplete_mode == 0) { return -1; } - int len = strlen (text); - if (autocomplete_mode == 1) { - if (index >= 0) { return -1; } - index = 0; - if (!strncmp (text, autocomplete_string, len)) { - *R = strdup (autocomplete_string); - assert (*R); - return index; - } else { - return -1; - } - } else { - return autocomplete_fun (text, len, index, R); - } -} - -struct paramed_type *tglf_extf_store (const char *data, int data_len) { - buffer_pos = (char *)data; - buffer_end = (char *)(data + data_len); - local_next_token (); - return store_function_any (); -} - -#define OUT_BUF_SIZE (1 << 25) -static char out_buf[OUT_BUF_SIZE]; -static int out_buf_pos; - -#define eprintf(...) \ - do { \ - out_buf_pos += snprintf (out_buf + out_buf_pos, OUT_BUF_SIZE - out_buf_pos, __VA_ARGS__);\ - assert (out_buf_pos < OUT_BUF_SIZE);\ - } while (0)\ - -static int valid_utf8_char (const char *str) { - unsigned char c = (unsigned char) *str; - int n = 0; - - if ((c & 0x80) == 0x00) { - n = 0; - } else if ((c & 0xe0) == 0xc0) { - n = 1; - } else if ((c & 0xf0) == 0xe0) { - n = 2; - } else if ((c & 0xf8) == 0xf0) { - n = 3; - } else if ((c & 0xfc) == 0xf8) { - n = 4; - } else if ((c & 0xfe) == 0xfc) { - n = 5; - } else { - return -1; - } - - int i; - for (i = 0; i < n; i ++) { - if ((((unsigned char)(str[i + 1])) & 0xc0) != 0x80) { - return -1; - } - } - return n + 1; -} - -static void print_escaped_string (const char *str, int len) { - eprintf ("\""); - const char *end = str + len; - while (str < end) { - int n = valid_utf8_char (str); - if (n < 0) { - eprintf ("\\x%02x", (int)(unsigned char)*str); - str ++; - } else if (n >= 2) { - int i; - for (i = 0; i < n; i++) { - eprintf ("%c", *(str ++)); - } - } else if (((unsigned char)*str) >= ' ' && *str != '"' && *str != '\\') { - eprintf ("%c", *str); - str ++; - } else { - switch (*str) { - case '\n': - eprintf("\\n"); - break; - case '\r': - eprintf("\\r"); - break; - case '\t': - eprintf("\\t"); - break; - case '\b': - eprintf("\\b"); - break; - case '\a': - eprintf("\\a"); - break; - case '\\': - eprintf ("\\\\"); - break; - case '"': - eprintf ("\\\""); - break; - default: - eprintf ("\\x%02x", (int)(unsigned char)*str); - break; - } - str ++; - } - } - eprintf ("\""); -} - -static void print_offset (void) { - int i; - for (i = 0; i < multiline_offset; i++) { - eprintf (" "); - } -} - -char *tglf_extf_fetch (struct paramed_type *T) { - out_buf_pos = 0; - fetch_type_any (T); - return out_buf; -} diff --git a/auto-static.c b/auto-static.c deleted file mode 100644 index ac92658..0000000 --- a/auto-static.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - This file is part of tgl-library - - This 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. - - This 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 this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - Copyright Vitaly Valtman 2014 -*/ - -#include "mtproto-common.h" -#include "config.h" -#include - -#ifndef DISABLE_EXTF -static int cur_token_len; -static char *cur_token; -static int cur_token_real_len; -static int cur_token_quoted; -static int multiline_output = 1; -static int multiline_offset; -static int multiline_offset_size = 2; - -static int disable_field_names; - -#define expect_token(token,len) \ - if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return -1; } \ - local_next_token (); - -#define expect_token_ptr(token,len) \ - if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return 0; } \ - local_next_token (); - -#define expect_token_autocomplete(token,len) \ - if (cur_token_len == -3 && len >= cur_token_real_len && !memcmp (cur_token, token, cur_token_real_len)) { set_autocomplete_string (token); return -1; }\ - if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return -1; } \ - local_next_token (); - -#define expect_token_ptr_autocomplete(token,len) \ - if (cur_token_len == -3 && len >= cur_token_real_len && !memcmp (cur_token, token, cur_token_real_len)) { set_autocomplete_string (token); return 0; }\ - if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return 0; } \ - local_next_token (); - - -static int autocomplete_mode; -static char *autocomplete_string; -static int (*autocomplete_fun)(const char *, int, int, char **); - -static void set_autocomplete_string (const char *s) { - if (autocomplete_string) { free (autocomplete_string); } - autocomplete_string = strdup (s); - assert (autocomplete_string); - autocomplete_mode = 1; -} - -static void set_autocomplete_type (int (*f)(const char *, int, int, char **)) { - autocomplete_fun = f; - autocomplete_mode = 2; -} - -static int is_int (void) { - if (cur_token_len <= 0) { return 0; } - char c = cur_token[cur_token_len]; - cur_token[cur_token_len] = 0; - char *p = 0; - - if (strtoll (cur_token, &p, 10)) {} - cur_token[cur_token_len] = c; - - return p == cur_token + cur_token_len; -} - -static long long get_int (void) { - if (cur_token_len <= 0) { return 0; } - char c = cur_token[cur_token_len]; - cur_token[cur_token_len] = 0; - char *p = 0; - - long long val = strtoll (cur_token, &p, 0); - cur_token[cur_token_len] = c; - - return val; -} - -static int is_double (void) { - if (cur_token_len <= 0) { return 0; } - char c = cur_token[cur_token_len]; - cur_token[cur_token_len] = 0; - char *p = 0; - - if (strtod (cur_token, &p)) {} - cur_token[cur_token_len] = c; - - return p == cur_token + cur_token_len; -} - -static double get_double (void) { - if (cur_token_len <= 0) { return 0; } - char c = cur_token[cur_token_len]; - cur_token[cur_token_len] = 0; - char *p = 0; - - double val = strtod (cur_token, &p); - cur_token[cur_token_len] = c; - - return val; -} - -static struct paramed_type *paramed_type_dup (struct paramed_type *P) { - if (ODDP (P)) { return P; } - struct paramed_type *R = malloc (sizeof (*R)); - assert (R); - R->type = malloc (sizeof (*R->type)); - assert (R->type); - memcpy (R->type, P->type, sizeof (*P->type)); - R->type->id = strdup (P->type->id); - assert (R->type->id); - - if (P->type->params_num) { - R->params = malloc (sizeof (void *) * P->type->params_num); - assert (R->params); - int i; - for (i = 0; i < P->type->params_num; i++) { - R->params[i] = paramed_type_dup (P->params[i]); - } - } - return R; -} - -void tgl_paramed_type_free (struct paramed_type *P) { - if (ODDP (P)) { return; } - if (P->type->params_num) { - int i; - for (i = 0; i < P->type->params_num; i++) { - tgl_paramed_type_free (P->params[i]); - } - free (P->params); - } - free (P->type->id); - free (P->type); - free (P); -} - -static char *buffer_pos, *buffer_end; - -static int is_wspc (char c) { - return c <= 32 && c > 0; -} - -static void skip_wspc (void) { - while (buffer_pos < buffer_end && is_wspc (*buffer_pos)) { - buffer_pos ++; - } -} - -static int is_letter (char c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-'; -} - - -static char exp_buffer[1 << 25];; -static int exp_buffer_pos; - -static inline int is_hex (char c) { - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'); -} - -static inline int hex2dec (char c) { - if (c >= '0' && c <= '9') { return c - '0'; } - else { return c - 'a' + 10; } -} - -static void expand_backslashed (char *s, int len) { - int backslashed = 0; - exp_buffer_pos = 0; - int i = 0; - while (i < len) { - assert (i + 3 <= (1 << 25)); - if (backslashed) { - backslashed = 0; - switch (s[i ++]) { - case 'n': - exp_buffer[exp_buffer_pos ++] = '\n'; - break; - case 'r': - exp_buffer[exp_buffer_pos ++] = '\r'; - break; - case 't': - exp_buffer[exp_buffer_pos ++] = '\t'; - break; - case 'b': - exp_buffer[exp_buffer_pos ++] = '\b'; - break; - case 'a': - exp_buffer[exp_buffer_pos ++] = '\a'; - break; - case '\\': - exp_buffer[exp_buffer_pos ++] = '\\'; - break; - case 'x': - if (i + 2 > len || !is_hex (s[i]) || !is_hex (s[i + 1])) { - exp_buffer_pos = -1; - return; - } - exp_buffer[exp_buffer_pos ++] = hex2dec (s[i]) * 16 + hex2dec (s[i + 1]); - i += 2; - break; - default: - break; - } - } else { - if (s[i] == '\\') { - backslashed = 1; - i ++; - } else { - exp_buffer[exp_buffer_pos ++] = s[i ++]; - } - } - } -} - -static void local_next_token (void) { - skip_wspc (); - cur_token_quoted = 0; - if (buffer_pos >= buffer_end) { - cur_token_len = -3; - cur_token_real_len = 0; - return; - } - char c = *buffer_pos; - if (is_letter (c)) { - cur_token = buffer_pos; - while (buffer_pos < buffer_end && is_letter (*buffer_pos)) { - buffer_pos ++; - } - if (buffer_pos < buffer_end) { - cur_token_len = buffer_pos - cur_token; - } else { - cur_token_real_len = buffer_pos - cur_token; - cur_token_len = -3; - } - return; - } else if (c == '"') { - cur_token_quoted = 1; - cur_token = buffer_pos ++; - int backslashed = 0; - while (buffer_pos < buffer_end && (*buffer_pos != '"' || backslashed)) { - if (*buffer_pos == '\\') { - backslashed ^= 1; - } else { - backslashed = 0; - } - buffer_pos ++; - } - if (*buffer_pos == '"') { - buffer_pos ++; - expand_backslashed (cur_token + 1, buffer_pos - cur_token - 2); - if (exp_buffer_pos < 0) { - cur_token_len = -2; - } else { - cur_token_len = exp_buffer_pos; - cur_token = exp_buffer; - } - } else { - cur_token_len = -2; - } - return; - } else { - if (c) { - cur_token = buffer_pos ++; - cur_token_len = 1; - } else { - cur_token_len = -3; - cur_token_real_len = 0; - } - } -} - -#define MAX_FVARS 100 -static struct paramed_type *fvars[MAX_FVARS]; -static int fvars_pos; - -static void add_var_to_be_freed (struct paramed_type *P) { - assert (fvars_pos < MAX_FVARS); - fvars[fvars_pos ++] = P; -} - -static void free_vars_to_be_freed (void) { - int i; - for (i = 0; i < fvars_pos; i++) { - tgl_paramed_type_free (fvars[i]); - } - fvars_pos = 0; -} - -int tglf_extf_autocomplete (struct tgl_state *TLS, const char *text, int text_len, int index, char **R, char *data, int data_len) { - if (index == -1) { - buffer_pos = data; - buffer_end = data + data_len; - autocomplete_mode = 0; - local_next_token (); - struct paramed_type *P = autocomplete_function_any (); - free_vars_to_be_freed (); - if (P) { tgl_paramed_type_free (P); } - } - if (autocomplete_mode == 0) { return -1; } - int len = strlen (text); - if (autocomplete_mode == 1) { - if (index >= 0) { return -1; } - index = 0; - if (!strncmp (text, autocomplete_string, len)) { - *R = strdup (autocomplete_string); - assert (*R); - return index; - } else { - return -1; - } - } else { - return autocomplete_fun (text, len, index, R); - } -} - -struct paramed_type *tglf_extf_store (struct tgl_state *TLS, const char *data, int data_len) { - buffer_pos = (char *)data; - buffer_end = (char *)(data + data_len); - local_next_token (); - return store_function_any (); -} - -#define OUT_BUF_SIZE (1 << 25) -static char out_buf[OUT_BUF_SIZE]; -static int out_buf_pos; - -#define eprintf(...) \ - do { \ - out_buf_pos += snprintf (out_buf + out_buf_pos, OUT_BUF_SIZE - out_buf_pos, __VA_ARGS__);\ - assert (out_buf_pos < OUT_BUF_SIZE);\ - } while (0)\ - -static int valid_utf8_char (const char *str) { - unsigned char c = (unsigned char) *str; - int n = 0; - - if ((c & 0x80) == 0x00) { - n = 0; - } else if ((c & 0xe0) == 0xc0) { - n = 1; - } else if ((c & 0xf0) == 0xe0) { - n = 2; - } else if ((c & 0xf8) == 0xf0) { - n = 3; - } else if ((c & 0xfc) == 0xf8) { - n = 4; - } else if ((c & 0xfe) == 0xfc) { - n = 5; - } else { - return -1; - } - - int i; - for (i = 0; i < n; i ++) { - if ((((unsigned char)(str[i + 1])) & 0xc0) != 0x80) { - return -1; - } - } - return n + 1; -} - -static void print_escaped_string (const char *str, int len) { - eprintf ("\""); - const char *end = str + len; - while (str < end) { - int n = valid_utf8_char (str); - if (n < 0) { - eprintf ("\\x%02x", (int)(unsigned char)*str); - str ++; - } else if (n >= 2) { - int i; - for (i = 0; i < n; i++) { - eprintf ("%c", *(str ++)); - } - } else if (((unsigned char)*str) >= ' ' && *str != '"' && *str != '\\') { - eprintf ("%c", *str); - str ++; - } else { - switch (*str) { - case '\n': - eprintf("\\n"); - break; - case '\r': - eprintf("\\r"); - break; - case '\t': - eprintf("\\t"); - break; - case '\b': - eprintf("\\b"); - break; - case '\a': - eprintf("\\a"); - break; - case '\\': - eprintf ("\\\\"); - break; - case '"': - eprintf ("\\\""); - break; - default: - eprintf ("\\x%02x", (int)(unsigned char)*str); - break; - } - str ++; - } - } - eprintf ("\""); -} - -static void print_offset (void) { - int i; - for (i = 0; i < multiline_offset; i++) { - eprintf (" "); - } -} - -char *tglf_extf_fetch (struct tgl_state *TLS, struct paramed_type *T) { - out_buf_pos = 0; - if (fetch_type_any (T) < 0) { return 0; } - return out_buf; -} -#endif diff --git a/auto.h b/auto.h deleted file mode 100644 index f41bed0..0000000 --- a/auto.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - This file is part of tgl-library - - This 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. - - This 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 this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - Copyright Vitaly Valtman 2014 -*/ -#ifndef __AUTO_H__ -#define __AUTO_H__ - -struct tl_type_descr { - unsigned name; - char *id; - int params_num; - long long params_types; -}; - -struct paramed_type { - struct tl_type_descr *type; - struct paramed_type **params; -}; - -#define NAME_ARRAY 0x89932ad9 - -#define TYPE_TO_PARAM(NAME) (&(struct paramed_type) {.type = &tl_type_## NAME, .params=0}) -#define TYPE_TO_PARAM_1(NAME,PARAM1) (&(struct paramed_type) {.type = &tl_type_## NAME, .params=(struct paramed_type *[1]){PARAM1}}) -#define ODDP(x) (((long)(x)) & 1) -#define EVENP(x) (!ODDP(x)) -#define INT2PTR(x) (void *)(long)(((long)x) * 2 + 1) -#define PTR2INT(x) ((((long)x) - 1) / 2) - -void tgl_paramed_type_free (struct paramed_type *P); - -#include "auto/auto-header.h" - -#endif diff --git a/binlog.c b/binlog.c deleted file mode 100644 index 93d4a9a..0000000 --- a/binlog.c +++ /dev/null @@ -1,2261 +0,0 @@ -/* - This file is part of tgl-library - - This 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. - - This 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 this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - Copyright Vitaly Valtman 2013-2014 -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "binlog.h" -#include "mtproto-common.h" -//#include "net.h" -#include "include.h" -#include "mtproto-client.h" - -#include "tgl.h" -#include "auto.h" - -#include "structures.h" - -#include - -#define BINLOG_BUFFER_SIZE (1 << 20) -static int binlog_buffer[BINLOG_BUFFER_SIZE]; -static int *rptr; -static int *wptr; -//static int TLS->binlog_fd; -static int in_replay_log; // should be used ONLY for DEBUG - - -#define MAX_LOG_EVENT_SIZE (1 << 17) - -char *get_binlog_file_name (void); - -static void *alloc_log_event (int l UU) { - return binlog_buffer; -} - -static long long binlog_pos; - -static int fetch_comb_binlog_start (struct tgl_state *TLS, void *extra) { - return 0; -} - -static int fetch_comb_binlog_dc_option (struct tgl_state *TLS, void *extra) { - int id = fetch_int (); - int l1 = prefetch_strlen (); - assert (l1 >= 0); - char *name = fetch_str (l1); - int l2 = prefetch_strlen (); - assert (l2 >= 0); - char *ip = fetch_str (l2); - int port = fetch_int (); - - vlogprintf (E_NOTICE, "DC%d '%.*s' update: %.*s:%d\n", id, l1, name, l2, ip, port); - - tglmp_alloc_dc (TLS, id, tstrndup (ip, l2), port); - return 0; -} - -static int fetch_comb_binlog_auth_key (struct tgl_state *TLS, void *extra) { - int num = fetch_int (); - assert (num >= 0 && num <= MAX_DC_ID); - assert (TLS->DC_list[num]); - TLS->DC_list[num]->auth_key_id = fetch_long (); - fetch_ints (TLS->DC_list[num]->auth_key, 64); - TLS->DC_list[num]->flags |= 1; - return 0; -} - -static int fetch_comb_binlog_default_dc (struct tgl_state *TLS, void *extra) { - int num = fetch_int (); - assert (num >= 0 && num <= MAX_DC_ID); - TLS->DC_working = TLS->DC_list[num]; - TLS->dc_working_num = num; - return 0; -} - -static int fetch_comb_binlog_our_id (struct tgl_state *TLS, void *extra) { - TLS->our_id = fetch_int (); - if (TLS->callback.our_id) { - TLS->callback.our_id (TLS, TLS->our_id); - } - return 0; -} - -static int fetch_comb_binlog_dc_signed (struct tgl_state *TLS, void *extra) { - int num = fetch_int (); - assert (num >= 0 && num <= MAX_DC_ID); - assert (TLS->DC_list[num]); - TLS->DC_list[num]->has_auth = 1; - return 0; -} - -static int fetch_comb_binlog_dc_salt (struct tgl_state *TLS, void *extra) { - int num = fetch_int (); - assert (num >= 0 && num <= MAX_DC_ID); - assert (TLS->DC_list[num]); - TLS->DC_list[num]->server_salt = fetch_long (); - return 0; -} - -static int fetch_comb_binlog_set_dh_params (struct tgl_state *TLS, void *extra) { - if (TLS->encr_prime) { tfree (TLS->encr_prime, 256); } - TLS->encr_root = fetch_int (); - TLS->encr_prime = talloc (256); - fetch_ints (TLS->encr_prime, 64); - TLS->encr_param_version = fetch_int (); - - return 0; -} - -static int fetch_comb_binlog_set_pts (struct tgl_state *TLS, void *extra) { - int new_pts = fetch_int (); - assert (new_pts >= TLS->pts); - vlogprintf (E_DEBUG - 1 + 2 * in_replay_log, "pts %d=>%d\n", TLS->pts, new_pts); - TLS->pts = new_pts; - return 0; -} - -static int fetch_comb_binlog_set_qts (struct tgl_state *TLS, void *extra) { - int new_qts = fetch_int (); - assert (new_qts >= TLS->qts); - vlogprintf (E_DEBUG - 1 + 2 * in_replay_log, "qts %d=>%d\n", TLS->qts, new_qts); - TLS->qts = new_qts; - return 0; -} - -static int fetch_comb_binlog_set_date (struct tgl_state *TLS, void *extra) { - int new_date = fetch_int (); - if (new_date < TLS->date) { return 0; } - assert (new_date >= TLS->date); - TLS->date = new_date; - return 0; -} - -static int fetch_comb_binlog_set_seq (struct tgl_state *TLS, void *extra) { - int new_seq = fetch_int (); - if (new_seq < TLS->seq) { - vlogprintf (E_ERROR, "Error: old_seq = %d, new_seq = %d\n", TLS->seq, new_seq); - } - assert (new_seq >= TLS->seq); - vlogprintf (E_DEBUG - 1 + 2 * in_replay_log, "seq %d=>%d\n", TLS->seq, new_seq); - TLS->seq = new_seq; - return 0; -} - -static int fetch_comb_binlog_user_add (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - if (!_U) { - _U = talloc0 (sizeof (*_U)); - _U->id = id; - tglp_insert_user (TLS, _U); - } else { - assert (!(_U->flags & FLAG_CREATED)); - } - struct tgl_user *U = (void *)_U; - U->flags |= FLAG_CREATED; - if (tgl_get_peer_id (id) == TLS->our_id) { - U->flags |= FLAG_USER_SELF; - } - U->first_name = fetch_str_dup (); - U->last_name = fetch_str_dup (); - assert (!U->print_name); - U->print_name = TLS->callback.create_print_name (TLS, U->id, U->first_name, U->last_name, 0, 0); - - tglp_peer_insert_name (TLS, (void *)U); - U->access_hash = fetch_long (); - U->phone = fetch_str_dup (); - if (fetch_int ()) { - U->flags |= FLAG_USER_CONTACT; - } - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, U, TGL_UPDATE_CREATED); - } - return 0; -} - -static int fetch_comb_binlog_user_delete (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - U->flags |= FLAG_DELETED; - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_DELETED); - } - return 0; -} - -static int fetch_comb_binlog_user_set_access_hash (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - U->user.access_hash = fetch_long (); - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_ACCESS_HASH); - } - return 0; -} - -static int fetch_comb_binlog_user_set_phone (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - if (U->user.phone) { - tfree_str (U->user.phone); - } - U->user.phone = fetch_str_dup (); - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_PHONE); - } - return 0; -} - -static int fetch_comb_binlog_user_set_friend (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - int friend = fetch_int (); - if (friend) { U->flags |= FLAG_USER_CONTACT; } - else { U->flags &= ~FLAG_USER_CONTACT; } - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_CONTACT); - } - return 0; -} - -static int fetch_comb_binlog_user_set_full_photo (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - if (U->flags & FLAG_HAS_PHOTO) { - tgls_free_photo (TLS, &U->user.photo); - } - tglf_fetch_photo (TLS, &U->user.photo); - U->flags |= FLAG_HAS_PHOTO; - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_PHOTO); - } - return 0; -} - -static int fetch_comb_binlog_user_set_blocked (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - - U->user.blocked = fetch_int (); - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_BLOCKED); - } - return 0; -} - -static int fetch_comb_binlog_user_set_real_name (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - assert (U->flags & FLAG_CREATED); - - if (U->user.real_first_name) { tfree_str (U->user.real_first_name); } - if (U->user.real_last_name) { tfree_str (U->user.real_last_name); } - U->user.real_first_name = fetch_str_dup (); - U->user.real_last_name = fetch_str_dup (); - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_REAL_NAME); - } - return 0; -} - -static int fetch_comb_binlog_user_set_name (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - - if (U->user.first_name) { tfree_str (U->user.first_name); } - if (U->user.last_name) { tfree_str (U->user.last_name); } - U->user.first_name = fetch_str_dup (); - U->user.last_name = fetch_str_dup (); - if (U->print_name) { - tglp_peer_delete_name (TLS, U); - tfree_str (U->print_name); - } - U->print_name = TLS->callback.create_print_name (TLS, U->id, U->user.first_name, U->user.last_name, 0, 0); - tglp_peer_insert_name (TLS, (void *)U); - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_NAME); - } - return 0; -} - -static int fetch_comb_binlog_user_set_username (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - - if (U->user.username) { tfree_str (U->user.username); } - U->user.username = fetch_str_dup (); - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_USERNAME); - } - return 0; -} - -static int fetch_comb_binlog_user_set_photo (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - - - unsigned y = fetch_int (); - if (y == CODE_user_profile_photo_empty) { - U->user.photo_id = 0; - U->user.photo_big.dc = -2; - U->user.photo_small.dc = -2; - } else { - assert (y == CODE_user_profile_photo); - U->user.photo_id = fetch_long (); - tglf_fetch_file_location (TLS, &U->user.photo_small); - tglf_fetch_file_location (TLS, &U->user.photo_big); - } - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_PHOTO); - } - return 0; -} - -static int fetch_comb_binlog_encr_chat_delete (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - assert (_U); - struct tgl_secret_chat *U = &_U->encr_chat; - memset (U->key, 0, sizeof (U->key)); - U->flags |= FLAG_DELETED; - U->state = sc_deleted; - if (U->nonce) { - tfree_secure (U->nonce, 256); - U->nonce = 0; - } - if (U->g_key) { - tfree_secure (U->g_key, 256); - U->g_key = 0; - } - - if (TLS->callback.secret_chat_update) { - TLS->callback.secret_chat_update (TLS, U, TGL_UPDATE_DELETED); - } - return 0; -} - -static int fetch_comb_binlog_encr_chat_requested (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - if (!_U) { - _U = talloc0 (sizeof (*_U)); - _U->id = id; - tglp_insert_encrypted_chat (TLS, _U); - } else { - assert (!(_U->flags & FLAG_CREATED)); - } - struct tgl_secret_chat *U = (void *)_U; - U->access_hash = fetch_long (); - U->date = fetch_int (); - U->admin_id = fetch_int (); - U->user_id = fetch_int (); - - tgl_peer_t *Us = tgl_peer_get (TLS, TGL_MK_USER (U->user_id)); - assert (!U->print_name); - if (Us) { - U->print_name = TLS->callback.create_print_name (TLS, id, "!", Us->user.first_name, Us->user.last_name, 0); - } else { - static char buf[100]; - tsnprintf (buf, 99, "user#%d", U->user_id); - U->print_name = TLS->callback.create_print_name (TLS, id, "!", buf, 0, 0); - } - tglp_peer_insert_name (TLS, (void *)U); - U->g_key = talloc (256); - U->nonce = talloc (256); - fetch_ints (U->g_key, 64); - fetch_ints (U->nonce, 64); - - U->flags |= FLAG_CREATED; - U->state = sc_request; - - if (TLS->callback.secret_chat_update) { - TLS->callback.secret_chat_update (TLS, U, TGL_UPDATE_REQUESTED); - } - return 0; -} - -static int fetch_comb_binlog_encr_chat_set_access_hash (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - U->encr_chat.access_hash = fetch_long (); - if (TLS->callback.secret_chat_update) { - TLS->callback.secret_chat_update (TLS, (void *)U, TGL_UPDATE_ACCESS_HASH); - } - return 0; -} - -static int fetch_comb_binlog_encr_chat_set_date (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - U->encr_chat.date = fetch_int (); - return 0; -} - -static int fetch_comb_binlog_encr_chat_set_ttl (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - U->encr_chat.ttl = fetch_int (); - return 0; -} - -static int fetch_comb_binlog_encr_chat_set_layer (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - U->encr_chat.layer = fetch_int (); - return 0; -} - -static int fetch_comb_binlog_encr_chat_set_state (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - U->encr_chat.state = fetch_int (); - return 0; -} - -static int fetch_comb_binlog_encr_chat_accepted (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - assert (_U); - struct tgl_secret_chat *U = &_U->encr_chat; - if (!U->g_key) { - U->g_key = talloc (256); - } - if (!U->nonce) { - U->nonce = talloc (256); - } - - fetch_ints (U->g_key, 64); - fetch_ints (U->nonce, 64); - U->key_fingerprint = fetch_long (); - - if (U->state == sc_waiting) { - tgl_do_create_keys_end (TLS, U); - } - U->state = sc_ok; - - if (TLS->callback.secret_chat_update) { - TLS->callback.secret_chat_update (TLS, U, TGL_UPDATE_WORKING); - } - return 0; -} - -static int fetch_comb_binlog_encr_chat_set_key (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - assert (_U); - struct tgl_secret_chat *U = &_U->encr_chat; - fetch_ints (U->key, 64); - U->key_fingerprint = fetch_long (); - return 0; -} - -static int fetch_comb_binlog_encr_chat_update_seq (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - assert (_U); - _U->encr_chat.in_seq_no = fetch_int (); - _U->encr_chat.last_in_seq_no = fetch_int (); - return 0; -} - -static int fetch_comb_binlog_encr_chat_set_seq (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - assert (_U); - _U->encr_chat.in_seq_no = fetch_int (); - _U->encr_chat.last_in_seq_no = fetch_int (); - _U->encr_chat.out_seq_no = fetch_int (); - return 0; -} - -static int fetch_comb_binlog_encr_chat_init (struct tgl_state *TLS, void *extra) { - tgl_peer_t *P = talloc0 (sizeof (*P)); - P->id = TGL_MK_ENCR_CHAT (fetch_int ()); - assert (!tgl_peer_get (TLS, P->id)); - P->encr_chat.user_id = fetch_int (); - P->encr_chat.admin_id = TLS->our_id; - tglp_insert_encrypted_chat (TLS, P); - tgl_peer_t *Us = tgl_peer_get (TLS, TGL_MK_USER (P->encr_chat.user_id)); - assert (Us); - P->print_name = TLS->callback.create_print_name (TLS, P->id, "!", Us->user.first_name, Us->user.last_name, 0); - tglp_peer_insert_name (TLS, P); - - P->encr_chat.g_key = talloc (256); - fetch_ints (P->encr_chat.key, 64); - fetch_ints (P->encr_chat.g_key, 64); - P->flags |= FLAG_CREATED; - - if (TLS->callback.secret_chat_update) { - TLS->callback.secret_chat_update (TLS, (void *)P, TGL_UPDATE_CREATED); - } - return 0; -} - -static int fetch_comb_binlog_encr_chat_create (struct tgl_state *TLS, void *extra) { - tgl_peer_t *P = talloc0 (sizeof (*P)); - P->id = TGL_MK_ENCR_CHAT (fetch_int ()); - assert (!tgl_peer_get (TLS, P->id)); - P->encr_chat.user_id = fetch_int (); - P->encr_chat.admin_id = fetch_int (); - tglp_insert_encrypted_chat (TLS, P); - P->print_name = fetch_str_dup (); - tglp_peer_insert_name (TLS, P); - - P->flags |= FLAG_CREATED; - - if (TLS->callback.secret_chat_update) { - TLS->callback.secret_chat_update (TLS, (void *)P, TGL_UPDATE_CREATED); - } - return 0; -} - -static int fetch_comb_binlog_chat_create (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_CHAT (fetch_int ()); - tgl_peer_t *_C = tgl_peer_get (TLS, id); - if (!_C) { - _C = talloc0 (sizeof (*_C)); - _C->id = id; - tglp_insert_chat (TLS, _C); - } else { - assert (!(_C->flags & FLAG_CREATED)); - } - struct tgl_chat *C = &_C->chat; - C->flags = FLAG_CREATED | fetch_int (); - C->title = fetch_str_dup (); - assert (!C->print_title); - C->print_title = TLS->callback.create_print_name (TLS, id, C->title, 0, 0, 0); - tglp_peer_insert_name (TLS, (void *)C); - C->users_num = fetch_int (); - C->date = fetch_int (); - C->version = fetch_int (); - - fetch_data (&C->photo_big, sizeof (struct tgl_file_location)); - fetch_data (&C->photo_small, sizeof (struct tgl_file_location)); - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, C, TGL_UPDATE_CREATED); - } - return 0; -} - -static int fetch_comb_binlog_chat_change_flags (struct tgl_state *TLS, void *extra) { - tgl_peer_t *C = tgl_peer_get (TLS, TGL_MK_CHAT (fetch_int ())); - assert (C && (C->flags & FLAG_CREATED)); - C->chat.flags |= fetch_int (); - C->chat.flags &= ~fetch_int (); - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, (void *)C, TGL_UPDATE_FLAGS); - } - return 0; -} - -static int fetch_comb_binlog_chat_set_title (struct tgl_state *TLS, void *extra) { - tgl_peer_t *C = tgl_peer_get (TLS, TGL_MK_CHAT (fetch_int ())); - assert (C && (C->flags & FLAG_CREATED)); - - if (C->chat.title) { tfree_str (C->chat.title); } - C->chat.title = fetch_str_dup (); - if (C->print_name) { - tglp_peer_delete_name (TLS, (void *)C); - tfree_str (C->print_name); - } - C->print_name = TLS->callback.create_print_name (TLS, C->id, C->chat.title, 0, 0, 0); - tglp_peer_insert_name (TLS, (void *)C); - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, (void *)C, TGL_UPDATE_TITLE); - } - return 0; -} - -static int fetch_comb_binlog_chat_set_photo (struct tgl_state *TLS, void *extra) { - tgl_peer_t *C = tgl_peer_get (TLS, TGL_MK_CHAT (fetch_int ())); - assert (C && (C->flags & FLAG_CREATED)); - fetch_data (&C->photo_big, sizeof (struct tgl_file_location)); - fetch_data (&C->photo_small, sizeof (struct tgl_file_location)); - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, (void *)C, TGL_UPDATE_PHOTO); - } - return 0; -} - -static int fetch_comb_binlog_chat_set_date (struct tgl_state *TLS, void *extra) { - tgl_peer_t *C = tgl_peer_get (TLS, TGL_MK_CHAT (fetch_int ())); - assert (C && (C->flags & FLAG_CREATED)); - C->chat.date = fetch_int (); - return 0; -} - -static int fetch_comb_binlog_chat_set_version (struct tgl_state *TLS, void *extra) { - tgl_peer_t *C = tgl_peer_get (TLS, TGL_MK_CHAT (fetch_int ())); - assert (C && (C->flags & FLAG_CREATED)); - C->chat.version = fetch_int (); - C->chat.users_num = fetch_int (); - return 0; -} - -static int fetch_comb_binlog_chat_set_admin (struct tgl_state *TLS, void *extra) { - tgl_peer_t *C = tgl_peer_get (TLS, TGL_MK_CHAT (fetch_int ())); - assert (C && (C->flags & FLAG_CREATED)); - C->chat.admin_id = fetch_int (); - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, (void *)C, TGL_UPDATE_ADMIN); - } - return 0; -} - -static int fetch_comb_binlog_chat_set_participants (struct tgl_state *TLS, void *extra) { - tgl_peer_t *C = tgl_peer_get (TLS, TGL_MK_CHAT (fetch_int ())); - assert (C && (C->flags & FLAG_CREATED)); - C->chat.user_list_version = fetch_int (); - if (C->chat.user_list) { tfree (C->chat.user_list, 12 * C->chat.user_list_size); } - C->chat.user_list_size = fetch_int (); - C->chat.user_list = talloc (12 * C->chat.user_list_size); - fetch_ints (C->chat.user_list, 3 * C->chat.user_list_size); - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, (void *)C, TGL_UPDATE_MEMBERS); - } - return 0; -} - -static int fetch_comb_binlog_chat_set_full_photo (struct tgl_state *TLS, void *extra) { - tgl_peer_t *C = tgl_peer_get (TLS, TGL_MK_CHAT (fetch_int ())); - assert (C && (C->flags & FLAG_CREATED)); - - assert (C && (C->flags & FLAG_CREATED)); - if (C->flags & FLAG_HAS_PHOTO) { - tgls_free_photo (TLS, &C->chat.photo); - } - tglf_fetch_photo (TLS, &C->chat.photo); - C->flags |= FLAG_HAS_PHOTO; - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, (void *)C, TGL_UPDATE_PHOTO); - } - return 0; -} - -static int fetch_comb_binlog_chat_add_participant (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_CHAT (fetch_int ()); - tgl_peer_t *_C = tgl_peer_get (TLS, id); - assert (_C && (_C->flags & FLAG_CREATED)); - struct tgl_chat *C = &_C->chat; - - int version = fetch_int (); - int user = fetch_int (); - int inviter = fetch_int (); - int date = fetch_int (); - assert (C->user_list_version < version); - - int i; - for (i = 0; i < C->user_list_size; i++) { - assert (C->user_list[i].user_id != user); - } - - C->user_list_size ++; - C->user_list = trealloc (C->user_list, 12 * C->user_list_size - 12, 12 * C->user_list_size); - C->user_list[C->user_list_size - 1].user_id = user; - C->user_list[C->user_list_size - 1].inviter_id = inviter; - C->user_list[C->user_list_size - 1].date = date; - C->user_list_version = version; - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, C, TGL_UPDATE_MEMBERS); - } - return 0; -} - -static int fetch_comb_binlog_chat_del_participant (struct tgl_state *TLS, void *extra) { - tgl_peer_id_t id = TGL_MK_CHAT (fetch_int ()); - tgl_peer_t *_C = tgl_peer_get (TLS, id); - assert (_C && (_C->flags & FLAG_CREATED)); - struct tgl_chat *C = &_C->chat; - - int version = fetch_int (); - int user = fetch_int (); - assert (C->user_list_version < version); - - int i; - for (i = 0; i < C->user_list_size; i++) { - if (C->user_list[i].user_id == user) { - struct tgl_chat_user t; - t = C->user_list[i]; - C->user_list[i] = C->user_list[C->user_list_size - 1]; - C->user_list[C->user_list_size - 1] = t; - } - } - assert (C->user_list[C->user_list_size - 1].user_id == user); - C->user_list_size --; - C->user_list = trealloc (C->user_list, 12 * C->user_list_size + 12, 12 * C->user_list_size); - C->user_list_version = version; - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, C, TGL_UPDATE_MEMBERS); - } - return 0; -} - -static int fetch_comb_binlog_create_message_text (struct tgl_state *TLS, void *extra) { - long long id = fetch_int (); - - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - - M->flags |= FLAG_CREATED; - M->from_id = TGL_MK_USER (fetch_int ()); - int t = fetch_int (); - if (t == TGL_PEER_ENCR_CHAT) { - M->flags |= FLAG_ENCRYPTED; - } - - M->to_id = tgl_set_peer_id (t, fetch_int ()); - M->date = fetch_int (); - M->unread = fetch_int (); - - int l = prefetch_strlen (); - M->message = talloc (l + 1); - memcpy (M->message, fetch_str (l), l); - M->message[l] = 0; - M->message_len = l; - - if (t == TGL_PEER_ENCR_CHAT) { - M->media.type = tgl_message_media_none; - } else { - M->media.type = tgl_message_media_none; - } - - //M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - - tglm_message_insert (TLS, M); - return 0; -} - -static int fetch_comb_binlog_send_message_text (struct tgl_state *TLS, void *extra) { - long long id = fetch_long (); - - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - - M->flags |= FLAG_CREATED; - M->from_id = TGL_MK_USER (fetch_int ()); - int t = fetch_int (); - if (t == TGL_PEER_ENCR_CHAT) { - M->flags |= FLAG_ENCRYPTED; - } - - M->to_id = tgl_set_peer_id (t, fetch_int ()); - if (t == TGL_PEER_ENCR_CHAT) { - tgl_peer_t *P = tgl_peer_get (TLS, M->to_id); - if (P && P->encr_chat.layer >= 17) { - P->encr_chat.out_seq_no ++; - } - } - M->date = fetch_int (); - - int l = prefetch_strlen (); - M->message = talloc (l + 1); - memcpy (M->message, fetch_str (l), l); - M->message[l] = 0; - M->message_len = l; - - if (t == TGL_PEER_ENCR_CHAT) { - M->media.type = tgl_message_media_none; - } else { - M->media.type = tgl_message_media_none; - } - - M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - - tglm_message_insert (TLS, M); - tglm_message_insert_unsent (TLS, M); - M->flags |= FLAG_PENDING; - return 0; -} - -static int fetch_comb_binlog_send_message_action_encr (struct tgl_state *TLS, void *extra) { - long long id = fetch_long (); - - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - - M->flags |= FLAG_CREATED | FLAG_ENCRYPTED; - M->from_id = TGL_MK_USER (fetch_int ()); - - int t = fetch_int (); - M->to_id = tgl_set_peer_id (t, fetch_int ()); - M->date = fetch_int (); - - M->media.type = tgl_message_media_none; - tglf_fetch_message_action_encrypted (TLS, &M->action); - - tgl_peer_t *P = tgl_peer_get (TLS, M->to_id); - if (P) { - if (P->encr_chat.layer >= 17) { - P->encr_chat.out_seq_no ++; - } - } - - M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - M->service = 1; - - tglm_message_insert (TLS, M); - tglm_message_insert_unsent (TLS, M); - M->flags |= FLAG_PENDING; - return 0; -} - -static int fetch_comb_binlog_create_message_text_fwd (struct tgl_state *TLS, void *extra) { - long long id = fetch_int (); - - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - - M->flags |= FLAG_CREATED; - M->from_id = TGL_MK_USER (fetch_int ()); - int t = fetch_int (); - if (t == TGL_PEER_ENCR_CHAT) { - M->flags |= FLAG_ENCRYPTED; - } - - M->to_id = tgl_set_peer_id (t, fetch_int ()); - M->date = fetch_int (); - - M->fwd_from_id = TGL_MK_USER (fetch_int ()); - M->fwd_date = fetch_int (); - - M->unread = fetch_int (); - - int l = prefetch_strlen (); - M->message = talloc (l + 1); - memcpy (M->message, fetch_str (l), l); - M->message[l] = 0; - M->message_len = l; - - if (t == TGL_PEER_ENCR_CHAT) { - M->media.type = tgl_message_media_none; - } else { - M->media.type = tgl_message_media_none; - } - - //M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - - tglm_message_insert (TLS, M); - - return 0; -} - -static int fetch_comb_binlog_create_message_media (struct tgl_state *TLS, void *extra) { - int id = fetch_int (); - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - M->flags |= FLAG_CREATED; - M->from_id = TGL_MK_USER (fetch_int ()); - int t = fetch_int (); - M->to_id = tgl_set_peer_id (t, fetch_int ()); - M->date = fetch_int (); - - M->unread = fetch_int (); - - int l = prefetch_strlen (); - M->message = talloc (l + 1); - memcpy (M->message, fetch_str (l), l); - M->message[l] = 0; - M->message_len = l; - - tglf_fetch_message_media (TLS, &M->media); - //M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - - tglm_message_insert (TLS, M); - return 0; -} - -static int fetch_comb_binlog_create_message_media_encr (struct tgl_state *TLS, void *extra) { - long long id = fetch_long (); - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - M->flags |= FLAG_CREATED | FLAG_ENCRYPTED; - M->from_id = TGL_MK_USER (fetch_int ()); - int t = fetch_int (); - M->to_id = tgl_set_peer_id (t, fetch_int ()); - M->date = fetch_int (); - - int l = prefetch_strlen (); - M->message = talloc (l + 1); - memcpy (M->message, fetch_str (l), l); - M->message[l] = 0; - M->message_len = l; - - tglf_fetch_message_media_encrypted (TLS, &M->media); - tglf_fetch_encrypted_message_file (TLS, &M->media); - M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - - tglm_message_insert (TLS, M); - return 0; -} - -static int fetch_comb_binlog_create_message_media_encr_pending (struct tgl_state *TLS, void *extra) { - long long id = fetch_long (); - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - M->flags |= FLAG_CREATED | FLAG_ENCRYPTED; - M->from_id = TGL_MK_USER (fetch_int ()); - int t = fetch_int (); - M->to_id = tgl_set_peer_id (t, fetch_int ()); - M->date = fetch_int (); - - tgl_peer_t *P = tgl_peer_get (TLS, M->to_id); - if (P) { - if (P->encr_chat.layer >= 17) { - P->encr_chat.out_seq_no ++; - } - } - - int l = prefetch_strlen (); - M->message = talloc (l + 1); - memcpy (M->message, fetch_str (l), l); - M->message[l] = 0; - M->message_len = l; - - tglf_fetch_message_media_encrypted (TLS, &M->media); - M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - - tglm_message_insert (TLS, M); - tglm_message_insert_unsent (TLS, M); - M->flags |= FLAG_PENDING; - return 0; -} - -static int fetch_comb_binlog_create_message_media_encr_sent (struct tgl_state *TLS, void *extra) { - long long id = fetch_long (); - struct tgl_message *M = tgl_message_get (TLS, id); - assert (M && (M->flags & FLAG_CREATED)); - tglf_fetch_encrypted_message_file (TLS, &M->media); - tglm_message_remove_unsent (TLS, M); - M->flags &= ~FLAG_PENDING; - return 0; -} - -static int fetch_comb_binlog_create_message_media_fwd (struct tgl_state *TLS, void *extra) { - int id = fetch_int (); - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - M->flags |= FLAG_CREATED; - M->from_id = TGL_MK_USER (fetch_int ()); - int t = fetch_int (); - M->to_id = tgl_set_peer_id (t, fetch_int ()); - M->date = fetch_int (); - - M->fwd_from_id = TGL_MK_USER (fetch_int ()); - M->fwd_date = fetch_int (); - - M->unread = fetch_int (); - - int l = prefetch_strlen (); - M->message = talloc (l + 1); - memcpy (M->message, fetch_str (l), l); - M->message[l] = 0; - M->message_len = l; - - tglf_fetch_message_media (TLS, &M->media); - //M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - - tglm_message_insert (TLS, M); - return 0; -} - -static int fetch_comb_binlog_create_message_service (struct tgl_state *TLS, void *extra) { - int id = fetch_int (); - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - M->flags |= FLAG_CREATED; - M->from_id = TGL_MK_USER (fetch_int ()); - int t = fetch_int (); - M->to_id = tgl_set_peer_id (t, fetch_int ()); - M->date = fetch_int (); - - M->unread = fetch_int (); - - tglf_fetch_message_action (TLS, &M->action); - //M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - M->service = 1; - - tglm_message_insert (TLS, M); - return 0; -} - -static int fetch_comb_binlog_create_message_service_encr (struct tgl_state *TLS, void *extra) { - long long id = fetch_long (); - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - M->flags |= FLAG_CREATED | FLAG_ENCRYPTED; - M->from_id = TGL_MK_USER (fetch_int ()); - int t = fetch_int (); - assert (t == TGL_PEER_ENCR_CHAT); - M->to_id = tgl_set_peer_id (t, fetch_int ()); - M->date = fetch_int (); - - struct tgl_secret_chat *E = (void *)tgl_peer_get (TLS, M->to_id); - assert (E); - - tglf_fetch_message_action_encrypted (TLS, &M->action); - M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - M->service = 1; - - if (!M->out && M->action.type == tgl_message_action_notify_layer) { - E->layer = M->action.layer; - } - - tglm_message_insert (TLS, M); - return 0; -} - -static int fetch_comb_binlog_create_message_service_fwd (struct tgl_state *TLS, void *extra) { - int id = fetch_int (); - struct tgl_message *M = tgl_message_get (TLS, id); - if (!M) { - M = tglm_message_alloc (TLS, id); - } else { - assert (!(M->flags & FLAG_CREATED)); - } - M->flags |= FLAG_CREATED; - M->from_id = TGL_MK_USER (fetch_int ()); - int t = fetch_int (); - M->to_id = tgl_set_peer_id (t, fetch_int ()); - M->date = fetch_int (); - - M->fwd_from_id = TGL_MK_USER (fetch_int ()); - M->fwd_date = fetch_int (); - - M->unread = fetch_int (); - - tglf_fetch_message_action (TLS, &M->action); - //M->unread = 1; - M->out = tgl_get_peer_id (M->from_id) == TLS->our_id; - M->service = 1; - - tglm_message_insert (TLS, M); - return 0; -} - -static int fetch_comb_binlog_message_set_unread_long (struct tgl_state *TLS, void *extra) { - struct tgl_message *M = tgl_message_get (TLS, fetch_long ()); - assert (M); - if (M->unread) { - M->unread = 0; - if (TLS->callback.marked_read) { - TLS->callback.marked_read (TLS, 1, &M); - } - } - return 0; -} - -static int fetch_comb_binlog_message_set_unread (struct tgl_state *TLS, void *extra) { - struct tgl_message *M = tgl_message_get (TLS, fetch_int ()); - assert (M); - if (M->unread) { - M->unread = 0; - if (TLS->callback.marked_read) { - TLS->callback.marked_read (TLS, 1, &M); - } - } - return 0; -} - -static int fetch_comb_binlog_set_message_sent (struct tgl_state *TLS, void *extra) { - struct tgl_message *M = tgl_message_get (TLS, fetch_long ()); - assert (M); - tglm_message_remove_unsent (TLS, M); - M->flags &= ~FLAG_PENDING; - return 0; -} - -static int fetch_comb_binlog_set_msg_id (struct tgl_state *TLS, void *extra) { - struct tgl_message *M = tgl_message_get (TLS, fetch_long ()); - assert (M); - if (M->flags & FLAG_PENDING) { - tglm_message_remove_unsent (TLS, M); - M->flags &= ~FLAG_PENDING; - } - tglm_message_remove_tree (TLS, M); - tglm_message_del_peer (TLS, M); - M->id = fetch_int (); - if (tgl_message_get (TLS, M->id)) { - tgls_free_message (TLS, M); - } else { - tglm_message_insert_tree (TLS, M); - tglm_message_add_peer (TLS, M); - } - return 0; -} - -static int fetch_comb_binlog_delete_msg (struct tgl_state *TLS, void *extra) { - struct tgl_message *M = tgl_message_get (TLS, fetch_long ()); - assert (M); - if (M->flags & FLAG_PENDING) { - tglm_message_remove_unsent (TLS, M); - M->flags &= ~FLAG_PENDING; - } - tglm_message_remove_tree (TLS, M); - tglm_message_del_peer (TLS, M); - tglm_message_del_use (TLS, M); - tgls_free_message (TLS, M); - return 0; -} - - -static int fetch_comb_binlog_msg_seq_update (struct tgl_state *TLS, void *extra) { - struct tgl_message *M = tgl_message_get (TLS, fetch_long ()); - assert (M); - TLS->seq ++; - vlogprintf (E_DEBUG - 1 + 2 * in_replay_log, "seq %d=>%d\n", TLS->seq - 1, TLS->seq); - - if (!(M->flags & FLAG_ENCRYPTED)) { - if (TLS->max_msg_id < M->id) { - TLS->max_msg_id = M->id; - } - } - - if (TLS->callback.msg_receive) { - TLS->callback.msg_receive (TLS, M); - } - return 0; -} - -static int fetch_comb_binlog_msg_update (struct tgl_state *TLS, void *extra) { - struct tgl_message *M = tgl_message_get (TLS, fetch_long ()); - if (!M) { return 0; } - assert (M); - - if (!(M->flags & FLAG_ENCRYPTED)) { - if (TLS->max_msg_id < M->id) { - TLS->max_msg_id = M->id; - } - } - - if (TLS->callback.msg_receive) { - TLS->callback.msg_receive (TLS, M); - } - return 0; -} - -static int fetch_comb_binlog_reset_authorization (struct tgl_state *TLS, void *extra) { - int i; - for (i = 0; i <= TLS->max_dc_num; i++) if (TLS->DC_list[i]) { - struct tgl_dc *D = TLS->DC_list[i]; - D->flags = 0; - D->state = st_init; - D->auth_key_id = D->temp_auth_key_id = 0; - D->has_auth = 0; - } - TLS->seq = 0; - TLS->qts = 0; - return 0; -} - -#define FETCH_COMBINATOR_FUNCTION(NAME) \ - case CODE_ ## NAME:\ - ok = fetch_comb_ ## NAME (TLS, 0); \ - break; \ - - -static void replay_log_event (struct tgl_state *TLS) { - assert (rptr < wptr); - int op = *rptr; - - vlogprintf (E_DEBUG, "replay_log_event: log_pos=%lld, op=0x%08x\n", binlog_pos, op); - - in_ptr = rptr; - in_end = wptr; - assert (skip_type_any (TYPE_TO_PARAM(binlog_update)) >= 0); - in_end = in_ptr; - in_ptr = rptr; - - int ok = -1; - in_ptr ++; - - switch (op) { - FETCH_COMBINATOR_FUNCTION (binlog_start) - FETCH_COMBINATOR_FUNCTION (binlog_dc_option) - FETCH_COMBINATOR_FUNCTION (binlog_auth_key) - FETCH_COMBINATOR_FUNCTION (binlog_default_dc) - FETCH_COMBINATOR_FUNCTION (binlog_our_id) - FETCH_COMBINATOR_FUNCTION (binlog_dc_signed) - FETCH_COMBINATOR_FUNCTION (binlog_dc_salt) - - FETCH_COMBINATOR_FUNCTION (binlog_set_dh_params) - FETCH_COMBINATOR_FUNCTION (binlog_set_pts) - FETCH_COMBINATOR_FUNCTION (binlog_set_qts) - FETCH_COMBINATOR_FUNCTION (binlog_set_date) - FETCH_COMBINATOR_FUNCTION (binlog_set_seq) - - FETCH_COMBINATOR_FUNCTION (binlog_user_add) - FETCH_COMBINATOR_FUNCTION (binlog_user_delete) - FETCH_COMBINATOR_FUNCTION (binlog_user_set_access_hash) - FETCH_COMBINATOR_FUNCTION (binlog_user_set_phone) - FETCH_COMBINATOR_FUNCTION (binlog_user_set_friend) - FETCH_COMBINATOR_FUNCTION (binlog_user_set_full_photo) - FETCH_COMBINATOR_FUNCTION (binlog_user_set_blocked) - FETCH_COMBINATOR_FUNCTION (binlog_user_set_name) - FETCH_COMBINATOR_FUNCTION (binlog_user_set_username) - FETCH_COMBINATOR_FUNCTION (binlog_user_set_photo) - - FETCH_COMBINATOR_FUNCTION (binlog_user_set_real_name) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_delete) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_requested) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_access_hash) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_date) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_ttl) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_layer) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_state) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_accepted) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_key) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_update_seq) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_seq) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_init) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_create) - - FETCH_COMBINATOR_FUNCTION (binlog_chat_create) - FETCH_COMBINATOR_FUNCTION (binlog_chat_change_flags) - FETCH_COMBINATOR_FUNCTION (binlog_chat_set_title) - FETCH_COMBINATOR_FUNCTION (binlog_chat_set_photo) - FETCH_COMBINATOR_FUNCTION (binlog_chat_set_date) - FETCH_COMBINATOR_FUNCTION (binlog_chat_set_version) - FETCH_COMBINATOR_FUNCTION (binlog_chat_set_admin) - FETCH_COMBINATOR_FUNCTION (binlog_chat_set_participants) - FETCH_COMBINATOR_FUNCTION (binlog_chat_set_full_photo) - FETCH_COMBINATOR_FUNCTION (binlog_chat_add_participant) - FETCH_COMBINATOR_FUNCTION (binlog_chat_del_participant) - - FETCH_COMBINATOR_FUNCTION (binlog_create_message_text) - FETCH_COMBINATOR_FUNCTION (binlog_send_message_text) - FETCH_COMBINATOR_FUNCTION (binlog_send_message_action_encr) - FETCH_COMBINATOR_FUNCTION (binlog_create_message_text_fwd) - FETCH_COMBINATOR_FUNCTION (binlog_create_message_media) - FETCH_COMBINATOR_FUNCTION (binlog_create_message_media_encr) - FETCH_COMBINATOR_FUNCTION (binlog_create_message_media_encr_pending) - FETCH_COMBINATOR_FUNCTION (binlog_create_message_media_encr_sent) - FETCH_COMBINATOR_FUNCTION (binlog_create_message_media_fwd) - FETCH_COMBINATOR_FUNCTION (binlog_create_message_service) - FETCH_COMBINATOR_FUNCTION (binlog_create_message_service_encr) - FETCH_COMBINATOR_FUNCTION (binlog_create_message_service_fwd) - FETCH_COMBINATOR_FUNCTION (binlog_message_set_unread) - FETCH_COMBINATOR_FUNCTION (binlog_message_set_unread_long) - FETCH_COMBINATOR_FUNCTION (binlog_set_message_sent) - FETCH_COMBINATOR_FUNCTION (binlog_set_msg_id) - FETCH_COMBINATOR_FUNCTION (binlog_delete_msg) - FETCH_COMBINATOR_FUNCTION (binlog_msg_seq_update) - FETCH_COMBINATOR_FUNCTION (binlog_msg_update) - FETCH_COMBINATOR_FUNCTION (binlog_reset_authorization) - default: - vlogprintf (E_ERROR, "Unknown op 0x%08x\n", op); - assert (0); - } - assert (ok >= 0); - - assert (in_ptr == in_end); - binlog_pos += (in_ptr - rptr) * 4; - rptr = in_ptr; -} - -static void create_new_binlog (struct tgl_state *TLS) { - clear_packet (); - //static int s[1000]; - - //packet_ptr = s; - out_int (CODE_binlog_start); - if (TLS->test_mode) { - out_int (CODE_binlog_dc_option); - out_int (1); - out_string (""); - out_string (TG_SERVER_TEST_1); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (2); - out_string (""); - out_string (TG_SERVER_TEST_2); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (3); - out_string (""); - out_string (TG_SERVER_TEST_3); - out_int (443); - out_int (CODE_binlog_default_dc); - out_int (2); - } else { - out_int (CODE_binlog_dc_option); - out_int (1); - out_string (""); - out_string (TG_SERVER_1); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (2); - out_string (""); - out_string (TG_SERVER_2); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (3); - out_string (""); - out_string (TG_SERVER_3); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (4); - out_string (""); - out_string (TG_SERVER_4); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (5); - out_string (""); - out_string (TG_SERVER_5); - out_int (443); - out_int (CODE_binlog_default_dc); - out_int (2); - } - - int fd = open (TLS->binlog_name, O_WRONLY | O_EXCL | O_CREAT, 0600); - if (fd < 0) { - perror ("Write new binlog"); - exit (2); - } - assert (write (fd, packet_buffer, (packet_ptr - packet_buffer) * 4) == (packet_ptr - packet_buffer) * 4); - close (fd); -} - - -void tgl_replay_log (struct tgl_state *TLS) { - if (!TLS->binlog_enabled) { return; } - if (access (TLS->binlog_name, F_OK) < 0) { - printf ("No binlog found. Creating new one\n"); - create_new_binlog (TLS); - } - int fd = open (TLS->binlog_name, O_RDONLY); - if (fd < 0) { - perror ("binlog open"); - exit (2); - } - int end = 0; - in_replay_log = 1; - while (1) { - if (!end && wptr - rptr < MAX_LOG_EVENT_SIZE / 4) { - if (wptr == rptr) { - wptr = rptr = binlog_buffer; - } else { - int x = wptr - rptr; - memcpy (binlog_buffer, rptr, 4 * x); - wptr -= (rptr - binlog_buffer); - rptr = binlog_buffer; - } - int l = (binlog_buffer + BINLOG_BUFFER_SIZE - wptr) * 4; - int k = read (fd, wptr, l); - if (k < 0) { - perror ("read binlog"); - exit (2); - } - assert (!(k & 3)); - if (k < l) { - end = 1; - } - wptr += (k / 4); - } - if (wptr == rptr) { break; } - replay_log_event (TLS); - } - in_replay_log = 0; - close (fd); -} - -static int b_packet_buffer[PACKET_BUFFER_SIZE]; - -void tgl_reopen_binlog_for_writing (struct tgl_state *TLS) { - TLS->binlog_fd = open (TLS->binlog_name, O_WRONLY); - if (TLS->binlog_fd < 0) { - perror ("binlog open"); - exit (2); - } - - assert (lseek (TLS->binlog_fd, binlog_pos, SEEK_SET) == binlog_pos); - if (flock (TLS->binlog_fd, LOCK_EX | LOCK_NB) < 0) { - perror ("get lock"); - exit (2); - } -} - -static void add_log_event (struct tgl_state *TLS, const int *data, int len) { - vlogprintf (E_DEBUG, "Add log event: magic = 0x%08x, len = %d\n", data[0], len); - assert (!(len & 3)); - rptr = (void *)data; - wptr = rptr + (len / 4); - int *in = in_ptr; - int *end = in_end; - replay_log_event (TLS); - if (rptr != wptr) { - vlogprintf (E_ERROR, "Unread %lld ints. Len = %d\n", (long long)(wptr - rptr), len); - assert (rptr == wptr); - } - if (TLS->binlog_enabled) { - assert (TLS->binlog_fd > 0); - assert (write (TLS->binlog_fd, data, len) == len); - } - in_ptr = in; - in_end = end; -} - -void bl_do_set_auth_key_id (struct tgl_state *TLS, int num, unsigned char *buf) { - static unsigned char sha1_buffer[20]; - SHA1 (buf, 256, sha1_buffer); - long long fingerprint = *(long long *)(sha1_buffer + 12); - int *ev = alloc_log_event (8 + 8 + 256); - ev[0] = CODE_binlog_auth_key; - ev[1] = num; - *(long long *)(ev + 2) = fingerprint; - memcpy (ev + 4, buf, 256); - add_log_event (TLS, ev, 8 + 8 + 256); -} - -void bl_do_set_our_id (struct tgl_state *TLS, int id) { - if (TLS->our_id) { - assert (TLS->our_id == id); - return; - } - int *ev = alloc_log_event (8); - ev[0] = CODE_binlog_our_id; - ev[1] = id; - add_log_event (TLS, ev, 8); - //write_auth_file (); -} - -void bl_do_user_add (struct tgl_state *TLS, int id, const char *f, int fl, const char *l, int ll, long long access_token, const char *p, int pl, int contact) { - clear_packet (); - out_int (CODE_binlog_user_add); - out_int (id); - out_cstring (f ? f : "", fl); - out_cstring (l ? l : "", ll); - out_long (access_token); - out_cstring (p ? p : "", pl); - out_int (contact); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_user_delete (struct tgl_state *TLS, struct tgl_user *U) { - if (U->flags & FLAG_DELETED) { return; } - int *ev = alloc_log_event (8); - ev[0] = CODE_binlog_user_delete; - ev[1] = tgl_get_peer_id (U->id); - add_log_event (TLS, ev, 8); -} - -void bl_do_set_user_profile_photo (struct tgl_state *TLS, struct tgl_user *U, long long photo_id, struct tgl_file_location *big, struct tgl_file_location *small) { - if (photo_id == U->photo_id) { return; } - if (!photo_id) { - int *ev = alloc_log_event (12); - ev[0] = CODE_binlog_user_set_photo; - ev[1] = tgl_get_peer_id (U->id); - ev[2] = CODE_user_profile_photo_empty; - add_log_event (TLS, ev, 12); - } else { - clear_packet (); - out_int (CODE_binlog_user_set_photo); - out_int (tgl_get_peer_id (U->id)); - out_int (CODE_user_profile_photo); - out_long (photo_id); - if (small->dc >= 0) { - out_int (CODE_file_location); - out_int (small->dc); - out_long (small->volume); - out_int (small->local_id); - out_long (small->secret); - } else { - out_int (CODE_file_location_unavailable); - out_long (small->volume); - out_int (small->local_id); - out_long (small->secret); - } - if (big->dc >= 0) { - out_int (CODE_file_location); - out_int (big->dc); - out_long (big->volume); - out_int (big->local_id); - out_long (big->secret); - } else { - out_int (CODE_file_location_unavailable); - out_long (big->volume); - out_int (big->local_id); - out_long (big->secret); - } - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); - } -} - -void bl_do_user_set_name (struct tgl_state *TLS, struct tgl_user *U, const char *f, int fl, const char *l, int ll) { - if ((U->first_name && (int)strlen (U->first_name) == fl && !strncmp (U->first_name, f, fl)) && - (U->last_name && (int)strlen (U->last_name) == ll && !strncmp (U->last_name, l, ll))) { - return; - } - clear_packet (); - out_int (CODE_binlog_user_set_name); - out_int (tgl_get_peer_id (U->id)); - out_cstring (f, fl); - out_cstring (l, ll); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_user_set_username (struct tgl_state *TLS, struct tgl_user *U, const char *f, int l) { - if ((U->username && (int)strlen (U->username) == l && !strncmp (U->username, f, l)) || - (!l && !U->username)) { - return; - } - clear_packet (); - out_int (CODE_binlog_user_set_username); - out_int (tgl_get_peer_id (U->id)); - out_cstring (f, l); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_user_set_access_hash (struct tgl_state *TLS, struct tgl_user *U, long long access_token) { - if (U->access_hash == access_token) { return; } - int *ev = alloc_log_event (16); - ev[0] = CODE_binlog_user_set_access_hash; - ev[1] = tgl_get_peer_id (U->id); - *(long long *)(ev + 2) = access_token; - add_log_event (TLS, ev, 16); -} - -void bl_do_user_set_phone (struct tgl_state *TLS, struct tgl_user *U, const char *p, int pl) { - if (U->phone && (int)strlen (U->phone) == pl && !strncmp (U->phone, p, pl)) { - return; - } - clear_packet (); - out_int (CODE_binlog_user_set_phone); - out_int (tgl_get_peer_id (U->id)); - out_cstring (p, pl); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_user_set_friend (struct tgl_state *TLS, struct tgl_user *U, int friend) { - if (friend == ((U->flags & FLAG_USER_CONTACT) != 0)) { return ; } - int *ev = alloc_log_event (12); - ev[0] = CODE_binlog_user_set_friend; - ev[1] = tgl_get_peer_id (U->id); - ev[2] = friend; - add_log_event (TLS, ev, 12); -} - -void bl_do_dc_option (struct tgl_state *TLS, int id, int l1, const char *name, int l2, const char *ip, int port) { - struct tgl_dc *DC = TLS->DC_list[id]; - if (DC && !strncmp (ip, DC->ip, l2)) { return; } - - clear_packet (); - out_int (CODE_binlog_dc_option); - out_int (id); - out_cstring (name, l1); - out_cstring (ip, l2); - out_int (port); - - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_dc_signed (struct tgl_state *TLS, int id) { - int *ev = alloc_log_event (8); - ev[0] = CODE_binlog_dc_signed; - ev[1] = id; - add_log_event (TLS, ev, 8); -} - -void bl_do_set_working_dc (struct tgl_state *TLS, int num) { - int *ev = alloc_log_event (8); - ev[0] = CODE_binlog_default_dc; - ev[1] = num; - add_log_event (TLS, ev, 8); -} - -void bl_do_user_set_full_photo (struct tgl_state *TLS, struct tgl_user *U, const int *start, int len) { - if (U->photo.id == *(long long *)(start + 1)) { return; } - int *ev = alloc_log_event (len + 8); - ev[0] = CODE_binlog_user_set_full_photo; - ev[1] = tgl_get_peer_id (U->id); - memcpy (ev + 2, start, len); - add_log_event (TLS, ev, len + 8); -} - -void bl_do_user_set_blocked (struct tgl_state *TLS, struct tgl_user *U, int blocked) { - if (U->blocked == blocked) { return; } - int *ev = alloc_log_event (12); - ev[0] = CODE_binlog_user_set_blocked; - ev[1] = tgl_get_peer_id (U->id); - ev[2] = blocked; - add_log_event (TLS, ev, 12); -} - -void bl_do_user_set_real_name (struct tgl_state *TLS, struct tgl_user *U, const char *f, int fl, const char *l, int ll) { - if ((U->real_first_name && (int)strlen (U->real_first_name) == fl && !strncmp (U->real_first_name, f, fl)) && - (U->real_last_name && (int)strlen (U->real_last_name) == ll && !strncmp (U->real_last_name, l, ll))) { - return; - } - clear_packet (); - out_int (CODE_binlog_user_set_real_name); - out_int (tgl_get_peer_id (U->id)); - out_cstring (f, fl); - out_cstring (l, ll); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_encr_chat_delete (struct tgl_state *TLS, struct tgl_secret_chat *U) { - if (!(U->flags & FLAG_CREATED) || U->state == sc_deleted || U->state == sc_none) { return; } - int *ev = alloc_log_event (8); - ev[0] = CODE_binlog_encr_chat_delete; - ev[1] = tgl_get_peer_id (U->id); - add_log_event (TLS, ev, 8); -} - -void bl_do_encr_chat_requested (struct tgl_state *TLS, struct tgl_secret_chat *U, long long access_hash, int date, int admin_id, int user_id, unsigned char g_key[], unsigned char nonce[]) { - if (U->state != sc_none) { return; } - int *ev = alloc_log_event (540); - ev[0] = CODE_binlog_encr_chat_requested; - ev[1] = tgl_get_peer_id (U->id); - *(long long *)(ev + 2) = access_hash; - ev[4] = date; - ev[5] = admin_id; - ev[6] = user_id; - memcpy (ev + 7, g_key, 256); - memcpy (ev + 7 + 64, nonce, 256); - add_log_event (TLS, ev, 540); -} - -void bl_do_encr_chat_set_access_hash (struct tgl_state *TLS, struct tgl_secret_chat *U, long long access_hash) { - if (U->access_hash == access_hash) { return; } - int *ev = alloc_log_event (16); - ev[0] = CODE_binlog_encr_chat_set_access_hash; - ev[1] = tgl_get_peer_id (U->id); - *(long long *)(ev + 2) = access_hash; - add_log_event (TLS, ev, 16); -} - -void bl_do_encr_chat_set_date (struct tgl_state *TLS, struct tgl_secret_chat *U, int date) { - if (U->date == date) { return; } - int *ev = alloc_log_event (12); - ev[0] = CODE_binlog_encr_chat_set_date; - ev[1] = tgl_get_peer_id (U->id); - ev[2] = date; - add_log_event (TLS, ev, 12); -} - -void bl_do_encr_chat_set_ttl (struct tgl_state *TLS, struct tgl_secret_chat *U, int ttl) { - if (U->ttl == ttl) { return; } - int *ev = alloc_log_event (12); - ev[0] = CODE_binlog_encr_chat_set_ttl; - ev[1] = tgl_get_peer_id (U->id); - ev[2] = ttl; - add_log_event (TLS, ev, 12); -} - -void bl_do_encr_chat_set_layer (struct tgl_state *TLS, struct tgl_secret_chat *U, int layer) { - if (U->layer >= layer) { return; } - int *ev = alloc_log_event (12); - ev[0] = CODE_binlog_encr_chat_set_layer; - ev[1] = tgl_get_peer_id (U->id); - ev[2] = layer; - add_log_event (TLS, ev, 12); -} - -void bl_do_encr_chat_set_state (struct tgl_state *TLS, struct tgl_secret_chat *U, enum tgl_secret_chat_state state) { - if (U->state == state) { return; } - int *ev = alloc_log_event (12); - ev[0] = CODE_binlog_encr_chat_set_state; - ev[1] = tgl_get_peer_id (U->id); - ev[2] = state; - add_log_event (TLS, ev, 12); -} - -void bl_do_encr_chat_accepted (struct tgl_state *TLS, struct tgl_secret_chat *U, const unsigned char g_key[], const unsigned char nonce[], long long key_fingerprint) { - if (U->state != sc_waiting && U->state != sc_request) { return; } - int *ev = alloc_log_event (528); - ev[0] = CODE_binlog_encr_chat_accepted; - ev[1] = tgl_get_peer_id (U->id); - memcpy (ev + 2, g_key, 256); - memcpy (ev + 66, nonce, 256); - *(long long *)(ev + 130) = key_fingerprint; - add_log_event (TLS, ev, 528); -} - -void bl_do_encr_chat_create (struct tgl_state *TLS, int id, int user_id, int admin_id, char *name, int name_len) { - clear_packet (); - out_int (CODE_binlog_encr_chat_create); - out_int (id); - out_int (user_id); - out_int (admin_id); - out_cstring (name, name_len); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_encr_chat_set_key (struct tgl_state *TLS, struct tgl_secret_chat *E, unsigned char key[], long long key_fingerprint) { - int *ev = alloc_log_event (272); - ev[0] = CODE_binlog_encr_chat_set_key; - ev[1] = tgl_get_peer_id (E->id); - memcpy (ev + 2, key, 256); - *(long long *)(ev + 66) = key_fingerprint; - add_log_event (TLS, ev, 272); -} - -void bl_do_encr_chat_update_seq (struct tgl_state *TLS, struct tgl_secret_chat *E, int in_seq_no, int out_seq_no) { - int *ev = alloc_log_event (16); - ev[0] = CODE_binlog_encr_chat_update_seq; - ev[1] = tgl_get_peer_id (E->id); - ev[2] = in_seq_no; - ev[3] = out_seq_no; - add_log_event (TLS, ev, 16); -} - -void bl_do_encr_chat_set_seq (struct tgl_state *TLS, struct tgl_secret_chat *E, int in_seq_no, int last_in_seq_no, int out_seq_no) { - int *ev = alloc_log_event (20); - ev[0] = CODE_binlog_encr_chat_set_seq; - ev[1] = tgl_get_peer_id (E->id); - ev[2] = in_seq_no; - ev[3] = last_in_seq_no; - ev[4] = out_seq_no; - add_log_event (TLS, ev, 20); -} - -void bl_do_set_dh_params (struct tgl_state *TLS, int root, unsigned char prime[], int version) { - int *ev = alloc_log_event (268); - ev[0] = CODE_binlog_set_dh_params; - ev[1] = root; - memcpy (ev + 2, prime, 256); - ev[66] = version; - add_log_event (TLS, ev, 268); -} - -void bl_do_encr_chat_init (struct tgl_state *TLS, int id, int user_id, unsigned char random[], unsigned char g_a[]) { - int *ev = alloc_log_event (524); - ev[0] = CODE_binlog_encr_chat_init; - ev[1] = id; - ev[2] = user_id; - memcpy (ev + 3, random, 256); - memcpy (ev + 67, g_a, 256); - add_log_event (TLS, ev, 524); -} - -void bl_do_set_pts (struct tgl_state *TLS, int pts) { - if (TLS->locks & TGL_LOCK_DIFF) { return; } - if (pts <= TLS->pts) { return; } - int *ev = alloc_log_event (8); - ev[0] = CODE_binlog_set_pts; - ev[1] = pts; - add_log_event (TLS, ev, 8); -} - -void bl_do_set_qts (struct tgl_state *TLS, int qts) { - if (TLS->locks & TGL_LOCK_DIFF) { return; } - if (qts <= TLS->qts) { return; } - int *ev = alloc_log_event (8); - ev[0] = CODE_binlog_set_qts; - ev[1] = qts; - add_log_event (TLS, ev, 8); -} - -void bl_do_set_date (struct tgl_state *TLS, int date) { - if (TLS->locks & TGL_LOCK_DIFF) { return; } - if (date <= TLS->date) { return; } - int *ev = alloc_log_event (8); - ev[0] = CODE_binlog_set_date; - ev[1] = date; - add_log_event (TLS, ev, 8); -} - -void bl_do_set_seq (struct tgl_state *TLS, int seq) { - if (TLS->locks & TGL_LOCK_DIFF) { return; } - if (seq == TLS->seq) { return; } - int *ev = alloc_log_event (8); - ev[0] = CODE_binlog_set_seq; - ev[1] = seq; - add_log_event (TLS, ev, 8); -} - -void bl_do_create_chat (struct tgl_state *TLS, struct tgl_chat *C, int y, const char *s, int l, int users_num, int date, int version, struct tgl_file_location *big, struct tgl_file_location *small) { - clear_packet (); - out_int (CODE_binlog_chat_create); - out_int (tgl_get_peer_id (C->id)); - out_int (y); - out_cstring (s, l); - out_int (users_num); - out_int (date); - out_int (version); - out_data (big, sizeof (struct tgl_file_location)); - out_data (small, sizeof (struct tgl_file_location)); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_chat_forbid (struct tgl_state *TLS, struct tgl_chat *C, int on) { - if (on) { - if (C->flags & FLAG_FORBIDDEN) { return; } - int *ev = alloc_log_event (16); - ev[0] = CODE_binlog_chat_change_flags; - ev[1] = tgl_get_peer_id (C->id); - ev[2] = FLAG_FORBIDDEN; - ev[3] = 0; - add_log_event (TLS, ev, 16); - } else { - if (!(C->flags & FLAG_FORBIDDEN)) { return; } - int *ev = alloc_log_event (16); - ev[0] = CODE_binlog_chat_change_flags; - ev[1] = tgl_get_peer_id (C->id); - ev[2] = 0; - ev[3] = FLAG_FORBIDDEN; - add_log_event (TLS, ev, 16); - } -} - -void bl_do_chat_set_title (struct tgl_state *TLS, struct tgl_chat *C, const char *s, int l) { - if (C->title && (int)strlen (C->title) == l && !strncmp (C->title, s, l)) { return; } - clear_packet (); - out_int (CODE_binlog_chat_set_title); - out_int (tgl_get_peer_id (C->id)); - out_cstring (s, l); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_chat_set_photo (struct tgl_state *TLS, struct tgl_chat *C, struct tgl_file_location *big, struct tgl_file_location *small) { - if (!memcmp (&C->photo_small, small, sizeof (struct tgl_file_location)) && - !memcmp (&C->photo_big, big, sizeof (struct tgl_file_location))) { return; } - clear_packet (); - out_int (CODE_binlog_chat_set_photo); - out_int (tgl_get_peer_id (C->id)); - out_data (big, sizeof (struct tgl_file_location)); - out_data (small, sizeof (struct tgl_file_location)); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_chat_set_date (struct tgl_state *TLS, struct tgl_chat *C, int date) { - if (C->date == date) { return; } - int *ev = alloc_log_event (12); - ev[0] = CODE_binlog_chat_set_date; - ev[1] = tgl_get_peer_id (C->id); - ev[2] = date; - add_log_event (TLS, ev, 12); -} - -void bl_do_chat_set_set_in_chat (struct tgl_state *TLS, struct tgl_chat *C, int on) { - if (on) { - if (C->flags & FLAG_CHAT_IN_CHAT) { return; } - int *ev = alloc_log_event (16); - ev[0] = CODE_binlog_chat_change_flags; - ev[1] = tgl_get_peer_id (C->id); - ev[2] = FLAG_CHAT_IN_CHAT; - ev[3] = 0; - add_log_event (TLS, ev, 16); - } else { - if (!(C->flags & FLAG_CHAT_IN_CHAT)) { return; } - int *ev = alloc_log_event (16); - ev[0] = CODE_binlog_chat_change_flags; - ev[1] = tgl_get_peer_id (C->id); - ev[2] = 0; - ev[3] = FLAG_CHAT_IN_CHAT; - add_log_event (TLS, ev, 16); - } -} - -void bl_do_chat_set_version (struct tgl_state *TLS, struct tgl_chat *C, int version, int user_num) { - if (C->version >= version) { return; } - int *ev = alloc_log_event (16); - ev[0] = CODE_binlog_chat_set_version; - ev[1] = tgl_get_peer_id (C->id); - ev[2] = version; - ev[3] = user_num; - add_log_event (TLS, ev, 16); -} - -void bl_do_chat_set_admin (struct tgl_state *TLS, struct tgl_chat *C, int admin) { - if (C->admin_id == admin) { return; } - int *ev = alloc_log_event (12); - ev[0] = CODE_binlog_chat_set_admin; - ev[1] = tgl_get_peer_id (C->id); - ev[2] = admin; - add_log_event (TLS, ev, 12); -} - -void bl_do_chat_set_participants (struct tgl_state *TLS, struct tgl_chat *C, int version, int user_num, struct tgl_chat_user *users) { - if (C->user_list_version >= version) { return; } - int *ev = alloc_log_event (12 * user_num + 16); - ev[0] = CODE_binlog_chat_set_participants; - ev[1] = tgl_get_peer_id (C->id); - ev[2] = version; - ev[3] = user_num; - memcpy (ev + 4, users, 12 * user_num); - add_log_event (TLS, ev, 12 * user_num + 16); -} - -void bl_do_chat_set_full_photo (struct tgl_state *TLS, struct tgl_chat *U, const int *start, int len) { - if (U->photo.id == *(long long *)(start + 1)) { return; } - int *ev = alloc_log_event (len + 8); - ev[0] = CODE_binlog_chat_set_full_photo; - ev[1] = tgl_get_peer_id (U->id); - memcpy (ev + 2, start, len); - add_log_event (TLS, ev, len + 8); -} - -void bl_do_chat_add_user (struct tgl_state *TLS, struct tgl_chat *C, int version, int user, int inviter, int date) { - if (C->user_list_version >= version || !C->user_list_version) { return; } - int *ev = alloc_log_event (24); - ev[0] = CODE_binlog_chat_add_participant; - ev[1] = tgl_get_peer_id (C->id); - ev[2] = version; - ev[3] = user; - ev[4] = inviter; - ev[5] = date; - add_log_event (TLS, ev, 24); -} - -void bl_do_chat_del_user (struct tgl_state *TLS, struct tgl_chat *C, int version, int user) { - if (C->user_list_version >= version || !C->user_list_version) { return; } - int *ev = alloc_log_event (16); - ev[0] = CODE_binlog_chat_del_participant; - ev[1] = tgl_get_peer_id (C->id); - ev[2] = version; - ev[3] = user; - add_log_event (TLS, ev, 16); -} - -void bl_do_create_message_text (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int unread, int l, const char *s) { - clear_packet (); - out_int (CODE_binlog_create_message_text); - out_int (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_int (unread); - out_cstring (s, l); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_send_message_text (struct tgl_state *TLS, long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s) { - clear_packet (); - out_int (CODE_binlog_send_message_text); - out_long (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_cstring (s, l); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_send_message_action_encr (struct tgl_state *TLS, long long msg_id, int from_id, int to_type, int to_id, int date, int l, const int *action) { - clear_packet (); - out_int (CODE_binlog_send_message_action_encr); - out_long (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_ints (action, l); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_create_message_text_fwd (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int unread, int l, const char *s) { - clear_packet (); - out_int (CODE_binlog_create_message_text_fwd); - out_int (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_int (fwd); - out_int (fwd_date); - out_int (unread); - out_cstring (s, l); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_create_message_media (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int unread, int l, const char *s, const int *data, int len) { - clear_packet (); - out_int (CODE_binlog_create_message_media); - out_int (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_int (unread); - out_cstring (s, l); - out_ints (data, len); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_create_message_media_encr (struct tgl_state *TLS, long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len, const int *data2, int len2) { - clear_packet (); - out_int (CODE_binlog_create_message_media_encr); - out_long (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_cstring (s, l); - out_ints (data, len); - out_ints (data2, len2); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_create_message_media_encr_pending (struct tgl_state *TLS, long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len) { - int *s_packet_buffer = packet_buffer; - int *s_packet_ptr = packet_ptr; - packet_buffer = b_packet_buffer; - clear_packet (); - out_int (CODE_binlog_create_message_media_encr_pending); - out_long (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_cstring (s, l); - out_ints (data, len); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); - packet_buffer = s_packet_buffer; - packet_ptr = s_packet_ptr; -} - -void bl_do_create_message_media_encr_sent (struct tgl_state *TLS, long long msg_id, const int *data, int len) { - clear_packet (); - out_int (CODE_binlog_create_message_media_encr_sent); - out_long (msg_id); - out_ints (data, len); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_create_message_media_fwd (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int unread, int l, const char *s, const int *data, int len) { - clear_packet (); - out_int (CODE_binlog_create_message_media_fwd); - out_int (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_int (fwd); - out_int (fwd_date); - out_int (unread); - out_cstring (s, l); - out_ints (data, len); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_create_message_service (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int unread, const int *data, int len) { - clear_packet (); - out_int (CODE_binlog_create_message_service); - out_int (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_int (unread); - out_ints (data, len); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_create_message_service_encr (struct tgl_state *TLS, long long msg_id, int from_id, int to_type, int to_id, int date, const int *data, int len) { - clear_packet (); - out_int (CODE_binlog_create_message_service_encr); - out_long (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_ints (data, len); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_create_message_service_fwd (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int unread, const int *data, int len) { - clear_packet (); - out_int (CODE_binlog_create_message_service_fwd); - out_int (msg_id); - out_int (from_id); - out_int (to_type); - out_int (to_id); - out_int (date); - out_int (fwd); - out_int (fwd_date); - out_int (unread); - out_ints (data, len); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_unread_long (struct tgl_state *TLS, struct tgl_message *M, int unread) { - if (unread || !M->unread) { return; } - clear_packet (); - out_int (CODE_binlog_message_set_unread_long); - out_long (M->id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_unread (struct tgl_state *TLS, struct tgl_message *M, int unread) { - if (M->id != (int)M->id) { bl_do_set_unread_long (TLS, M, unread); } - if (unread || !M->unread) { return; } - clear_packet (); - out_int (CODE_binlog_message_set_unread); - out_int (M->id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_message_sent (struct tgl_state *TLS, struct tgl_message *M) { - if (!(M->flags & FLAG_PENDING)) { return; } - clear_packet (); - out_int (CODE_binlog_set_message_sent); - out_long (M->id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_msg_id (struct tgl_state *TLS, struct tgl_message *M, int id) { - if (M->id == id) { return; } - clear_packet (); - out_int (CODE_binlog_set_msg_id); - out_long (M->id); - out_int (id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_delete_msg (struct tgl_state *TLS, struct tgl_message *M) { - clear_packet (); - out_int (CODE_binlog_delete_msg); - out_long (M->id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_msg_seq_update (struct tgl_state *TLS, long long id) { - if (TLS->locks & TGL_LOCK_DIFF) { - return; // We will receive this update in get_difference, that works now - } - clear_packet (); - out_int (CODE_binlog_msg_seq_update); - out_long (id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_msg_update (struct tgl_state *TLS, long long id) { - clear_packet (); - out_int (CODE_binlog_msg_update); - out_long (id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_reset_authorization (struct tgl_state *TLS) { - clear_packet (); - out_int (CODE_binlog_reset_authorization); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} -/*void bl_do_add_dc (int id, const char *ip, int l, int port, long long auth_key_id, const char *auth_key) { - clear_packet (); - out_int (CODE_binlog_add_dc); - out_long (id); - out_cstring (ip, l); - out_int (port); - out_long (auth_key_id); - out_ints ((void *)auth_key, 64); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -}*/ diff --git a/binlog.h b/binlog.h deleted file mode 100644 index e17c032..0000000 --- a/binlog.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - This file is part of tgl-library - - This 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. - - This 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 this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - Copyright Vitaly Valtman 2013-2014 -*/ -#ifndef __BINLOG_H__ -#define __BINLOG_H__ - -//#include "structures.h" -#include "tgl.h" - -void bl_do_set_auth_key_id (struct tgl_state *TLS, int num, unsigned char *buf); - -void bl_do_dc_option (struct tgl_state *TLS, int id, int l1, const char *name, int l2, const char *ip, int port); - -void bl_do_set_our_id (struct tgl_state *TLS, int id); -void bl_do_user_add (struct tgl_state *TLS, int id, const char *f, int fl, const char *l, int ll, long long access_token, const char *p, int pl, int contact); -void bl_do_user_delete (struct tgl_state *TLS, struct tgl_user *U); -void bl_do_set_user_profile_photo (struct tgl_state *TLS, struct tgl_user *U, long long photo_id, struct tgl_file_location *big, struct tgl_file_location *small); -void bl_do_user_set_name (struct tgl_state *TLS, struct tgl_user *U, const char *f, int fl, const char *l, int ll); -void bl_do_user_set_username (struct tgl_state *TLS, struct tgl_user *U, const char *f, int l); -void bl_do_user_set_access_hash (struct tgl_state *TLS, struct tgl_user *U, long long access_token); -void bl_do_user_set_phone (struct tgl_state *TLS, struct tgl_user *U, const char *p, int pl); -void bl_do_user_set_friend (struct tgl_state *TLS, struct tgl_user *U, int friend); -void bl_do_user_set_full_photo (struct tgl_state *TLS, struct tgl_user *U, const int *start, int len); -void bl_do_user_set_blocked (struct tgl_state *TLS, struct tgl_user *U, int blocked); -void bl_do_user_set_real_name (struct tgl_state *TLS, struct tgl_user *U, const char *f, int fl, const char *l, int ll); - -void bl_do_encr_chat_delete (struct tgl_state *TLS, struct tgl_secret_chat *U); -void bl_do_encr_chat_requested (struct tgl_state *TLS, struct tgl_secret_chat *U, long long access_hash, int date, int admin_id, int user_id, unsigned char g_key[], unsigned char nonce[]); -void bl_do_encr_chat_create (struct tgl_state *TLS, int id, int user_id, int admin_id, char *name, int name_len); -void bl_do_encr_chat_set_access_hash (struct tgl_state *TLS, struct tgl_secret_chat *U, long long access_hash); -void bl_do_encr_chat_set_date (struct tgl_state *TLS, struct tgl_secret_chat *U, int date); -void bl_do_encr_chat_set_state (struct tgl_state *TLS, struct tgl_secret_chat *U, enum tgl_secret_chat_state state); -void bl_do_encr_chat_set_ttl (struct tgl_state *TLS, struct tgl_secret_chat *U, int ttl); -void bl_do_encr_chat_set_layer (struct tgl_state *TLS, struct tgl_secret_chat *U, int layer); -void bl_do_encr_chat_accepted (struct tgl_state *TLS, struct tgl_secret_chat *U, const unsigned char g_key[], const unsigned char nonce[], long long key_fingerprint); -void bl_do_encr_chat_set_key (struct tgl_state *TLS, struct tgl_secret_chat *E, unsigned char key[], long long key_fingerprint); -void bl_do_encr_chat_init (struct tgl_state *TLS, int id, int user_id, unsigned char random[], unsigned char g_a[]); -void bl_do_encr_chat_update_seq (struct tgl_state *TLS, struct tgl_secret_chat *E, int in_seq_no, int out_seq_no); -void bl_do_encr_chat_set_seq (struct tgl_state *TLS, struct tgl_secret_chat *E, int in_seq_no, int last_in_seq_no, int out_seq_no); - -void bl_do_dc_signed (struct tgl_state *TLS, int id); -void bl_do_set_working_dc (struct tgl_state *TLS, int num); -void bl_do_set_dh_params (struct tgl_state *TLS, int root, unsigned char prime[], int version); - -void bl_do_set_pts (struct tgl_state *TLS, int pts); -void bl_do_set_qts (struct tgl_state *TLS, int qts); -void bl_do_set_seq (struct tgl_state *TLS, int seq); -void bl_do_set_date (struct tgl_state *TLS, int date); - -void bl_do_create_chat (struct tgl_state *TLS, struct tgl_chat *C, int y, const char *s, int l, int users_num, int date, int version, struct tgl_file_location *big, struct tgl_file_location *small); -void bl_do_chat_forbid (struct tgl_state *TLS, struct tgl_chat *C, int on); -void bl_do_chat_set_title (struct tgl_state *TLS, struct tgl_chat *C, const char *s, int l); -void bl_do_chat_set_photo (struct tgl_state *TLS, struct tgl_chat *C, struct tgl_file_location *big, struct tgl_file_location *small); -void bl_do_chat_set_date (struct tgl_state *TLS, struct tgl_chat *C, int date); -void bl_do_chat_set_set_in_chat (struct tgl_state *TLS, struct tgl_chat *C, int on); -void bl_do_chat_set_version (struct tgl_state *TLS, struct tgl_chat *C, int version, int user_num); -void bl_do_chat_set_admin (struct tgl_state *TLS, struct tgl_chat *C, int admin); -void bl_do_chat_set_participants (struct tgl_state *TLS, struct tgl_chat *C, int version, int user_num, struct tgl_chat_user *users); -void bl_do_chat_set_full_photo (struct tgl_state *TLS, struct tgl_chat *U, const int *start, int len); -void bl_do_chat_add_user (struct tgl_state *TLS, struct tgl_chat *C, int version, int user, int inviter, int date); -void bl_do_chat_del_user (struct tgl_state *TLS, struct tgl_chat *C, int version, int user); - -void bl_do_create_message_text (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int unread, int l, const char *s); -void bl_do_create_message_text_fwd (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int unread, int l, const char *s); -void bl_do_create_message_service (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int unread, const int *data, int len); -void bl_do_create_message_service_fwd (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int unread, const int *data, int len); -void bl_do_create_message_media (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int unread, int l, const char *s, const int *data, int len); -void bl_do_create_message_media_encr_pending (struct tgl_state *TLS, long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len); -void bl_do_create_message_media_encr_sent (struct tgl_state *TLS, long long msg_id, const int *data, int len); -void bl_do_create_message_media_fwd (struct tgl_state *TLS, int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int unread, int l, const char *s, const int *data, int len); -void bl_do_create_message_media_encr (struct tgl_state *TLS, long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len, const int *data2, int len2); -void bl_do_create_message_service_encr (struct tgl_state *TLS, long long msg_id, int from_id, int to_type, int to_id, int date, const int *data, int len); -void bl_do_send_message_text (struct tgl_state *TLS, long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s); -void bl_do_send_message_action_encr (struct tgl_state *TLS, long long msg_id, int from_id, int to_type, int to_id, int date, int l, const int *s); -void bl_do_set_unread (struct tgl_state *TLS, struct tgl_message *M, int unread); -void bl_do_set_message_sent (struct tgl_state *TLS, struct tgl_message *M); -void bl_do_set_msg_id (struct tgl_state *TLS, struct tgl_message *M, int id); -void bl_do_delete_msg (struct tgl_state *TLS, struct tgl_message *M); - -void bl_do_msg_seq_update (struct tgl_state *TLS, long long id); -void bl_do_msg_update (struct tgl_state *TLS, long long id); - -void bl_do_reset_authorization (struct tgl_state *TLS); - -//void bl_do_add_dc (int id, const char *ip, int l, int port, long long auth_key_id, const char *auth_key); -#endif diff --git a/dump-tl-file.c b/dump-tl-file.c deleted file mode 100644 index 541a688..0000000 --- a/dump-tl-file.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "auto.h" - -int *tgl_in_ptr, *tgl_in_end; - -int tgl_packet_buffer[0]; -int *tgl_packet_ptr; - -char *tgl_strdup (char *s) { - return strdup (s); -} - -void tgl_out_cstring (const char *str, long len) {} -char *tglf_extf_fetch (struct paramed_type *T); - -#define LEN (1 << 28) -static int x[LEN / 4]; -int main (int argc, char **argv) { - int i; - int dump_binlog = 0; - while ((i = getopt (argc, argv, "b")) != -1) { - switch (i) { - case 'b': - dump_binlog = 1; - break; - default: - printf ("unknown option '%c'\n", (char)i); - exit (1); - } - } - if (!dump_binlog) { - exit (1); - } - if (optind + 1 != argc) { - exit (1); - } - int fd = open (argv[optind], O_RDONLY); - if (fd < 0) { - perror ("open"); - exit (1); - } - int r = read (fd, x, LEN); - if (r <= 0) { - perror ("read"); - exit (1); - } - if (r == LEN) { - printf ("Too long file\n"); - exit (1); - } - assert (!(r & 3)); - tgl_in_ptr = x; - tgl_in_end = x + (r / 4); - while (tgl_in_ptr < tgl_in_end) { - if (dump_binlog) { - char *R = tglf_extf_fetch (TYPE_TO_PARAM(binlog_update)); - if (!R) { - printf ("Can not fetch\n"); - exit (1); - } - printf ("%s\n", R); - } - } - return 0; -} diff --git a/tl-parser.c b/tl-parser.c deleted file mode 100644 index 4c99121..0000000 --- a/tl-parser.c +++ /dev/null @@ -1,3077 +0,0 @@ -/* - This file is part of tgl-libary/tlc - - Tgl-library/tlc is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - Tgl-library/tlc 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this tgl-library/tlc. If not, see . - - Copyright Vitaly Valtman 2014 - - It is derivative work of VK/KittenPHP-DB-Engine (https://github.com/vk-com/kphp-kdb/) - Copyright 2012-2013 Vkontakte Ltd - 2012-2013 Vitaliy Valtman - -*/ - -#define _FILE_OFFSET_BITS 64 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tree.h" -#include "tl-parser.h" -#include "crc32.h" -#include "tl-tl.h" -#include "tools.h" -#include "config.h" - -extern int verbosity; -extern int schema_version; -extern int output_expressions; - - -int total_types_num; -int total_constructors_num; -int total_functions_num; - - -/*char *tstrdup (const char *s) { - assert (s); - char *r = talloc (strlen (s) + 1); - memcpy (r, s, strlen (s) + 1); - return r; -}*/ - -char curch; -struct parse parse; - -struct tree *tree; - -struct tree *tree_alloc (void) { - struct tree *T = talloc (sizeof (*T)); - assert (T); - memset (T, 0, sizeof (*T)); - return T; -} - -void tree_add_child (struct tree *P, struct tree *C) { - if (P->nc == P->size) { - void **t = talloc (sizeof (void *) * (++P->size)); - 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) { - 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) { - assert (P->nc); - tree_delete (P->c[--P->nc]); -} - - -char nextch (void) { - if (parse.pos < parse.len - 1) { - curch = parse.text[++parse.pos]; - } else { - curch = 0; - } - if (curch == 10) { - parse.line ++; - parse.line_pos = 0; - } else { - if (curch) { - parse.line_pos ++; - } - } - return curch; -} - - -struct parse save_parse (void) { - return parse; -} - -void load_parse (struct parse _parse) { - parse = _parse; - curch = parse.pos > parse.len ? 0: parse.text[parse.pos] ; -} - -int is_whitespace (char c) { - return (c <= 32); -} - -int is_uletter (char c) { - return (c >= 'A' && c <= 'Z'); -} - -int is_lletter (char c) { - return (c >= 'a' && c <= 'z'); -} - -int is_letter (char c) { - return is_uletter (c) || is_lletter (c); -} - -int is_digit (char c) { - return (c >= '0' && c <= '9'); -} - -int is_hexdigit (char c) { - return is_digit (c) || (c >= 'a' && c <= 'f'); -} - -int is_ident_char (char c) { - return is_digit (c) || is_letter (c) || c == '_'; -} - -int last_error_pos; -int last_error_line; -int last_error_line_pos; -char *last_error; - -void parse_error (const char *e) { - if (parse.pos > last_error_pos) { - last_error_pos = parse.pos; - last_error_line = parse.line; - last_error_line_pos = parse.line_pos; - if (last_error) { - tfree (last_error, strlen (last_error) + 1); - } - last_error = tstrdup (e); - } -} - -void tl_print_parse_error (void) { - 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 (curch && is_whitespace (curch)) { nextch (); } - if (curch == '/' && nextch () == '/') { - while (nextch () != 10); - nextch (); - } else { - break; - } - } - if (!curch) { - parse.lex.len = 0; - parse.lex.type = lex_eof; - return (parse.lex.ptr = 0); - } - char *p = parse.text + parse.pos; - parse.lex.flags = 0; - switch (curch) { - case '-': - if (nextch () != '-' || nextch () != '-') { - parse_error ("Can not parse triple minus"); - parse.lex.type = lex_error; - return (parse.lex.ptr = (void *)-1); - } else { - parse.lex.len = 3; - parse.lex.type = lex_triple_minus; - nextch (); - return (parse.lex.ptr = p); - } - case ':': - case ';': - case '(': - case ')': - case '[': - case ']': - case '{': - case '}': - case '=': - case '#': - case '?': - case '%': - case '<': - case '>': - case '+': - case ',': - case '*': - case '_': - case '!': - case '.': - nextch (); - parse.lex.len = 1; - parse.lex.type = lex_char; - return (parse.lex.ptr = p); - case 'a'...'z': - case 'A'...'Z': - parse.lex.flags = 0; - if (is_uletter (curch)) { - while (is_ident_char (nextch ())); - parse.lex.len = parse.text + parse.pos - p; - parse.lex.ptr = p; - if (parse.lex.len == 5 && !memcmp (parse.lex.ptr, "Final", 5)) { - parse.lex.type = lex_final; - } else if (parse.lex.len == 3 && !memcmp (parse.lex.ptr, "New", 3)) { - parse.lex.type = lex_new; - } else if (parse.lex.len == 5 && !memcmp (parse.lex.ptr, "Empty", 5)) { - parse.lex.type = lex_empty; - } else { - parse.lex.type = lex_uc_ident; - } - return (parse.lex.ptr = p); - } - while (is_ident_char (nextch ())); - if (curch == '.' && !is_letter (parse.text[parse.pos + 1])) { - parse.lex.len = parse.text + parse.pos - p; - parse.lex.type = lex_lc_ident; - return (parse.lex.ptr = p); - } - if (curch == '.') { - parse.lex.flags |= 1; - nextch (); - if (is_uletter (curch)) { - while (is_ident_char (nextch ())); - parse.lex.len = parse.text + parse.pos - p; - parse.lex.type = lex_uc_ident; - return (parse.lex.ptr = p); - } - if (is_lletter (curch)) { - while (is_ident_char (nextch ())); - } else { - parse_error ("Expected letter"); - parse.lex.type = lex_error; - return (parse.lex.ptr = (void *)-1); - } - } - if (curch == '#') { - parse.lex.flags |= 2; - int i; - int ok = 1; - for (i = 0; i < 8; i++) { - if (!is_hexdigit (nextch())) { - if (curch == ' ' && i >= 5) { - ok = 2; - break; - } else { - parse_error ("Hex digit expected"); - parse.lex.type = lex_error; - return (parse.lex.ptr = (void *)-1); - } - } - } - if (ok == 1) { - nextch (); - } - } - parse.lex.len = parse.text + parse.pos - p; - parse.lex.type = lex_lc_ident; - return (parse.lex.ptr = p); - case '0'...'9': - while (is_digit (nextch ())); - parse.lex.len = parse.text + parse.pos - p; - parse.lex.type = lex_num; - return (parse.lex.ptr = p); - default: - parse_error ("Unknown lexem"); - 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]; - sprintf (buf, "Expected %s", s); - parse_error (buf); - return -1; - } else { - parse_lex (); - } - return 1; -} - -struct parse *tl_init_parse_file (const char *fname) { - int fd = open (fname, O_RDONLY); - if (fd < 0) { - fprintf (stderr, "Error %m\n"); - assert (0); - return 0; - } - long long size = lseek (fd, 0, SEEK_END); - if (size <= 0) { - fprintf (stderr, "size is %lld. Too small.\n", size); - return 0; - } - static struct parse save; - save.text = talloc (size); - lseek (fd, 0, SEEK_SET); - save.len = read (fd, save.text, size); - assert (save.len == size); - save.pos = 0; - save.line = 0; - save.line_pos = 0; - save.lex.ptr = save.text; - save.lex.len = 0; - save.lex.type = lex_none; - return &save; -} - -#define PARSE_INIT(_type) struct parse save = save_parse (); struct tree *T = tree_alloc (); T->type = (_type); T->lex_line = parse.line; T->lex_line_pos = parse.line_pos; struct tree *S __attribute__ ((unused)); -#define PARSE_FAIL load_parse (save); tree_delete (T); return 0; -#define PARSE_OK return T; -#define PARSE_TRY_PES(x) if (!(S = x ())) { PARSE_FAIL; } { tree_add_child (T, S); } -#define PARSE_TRY_OPT(x) if ((S = x ())) { tree_add_child (T, S); PARSE_OK } -#define PARSE_TRY(x) S = x (); -#define PARSE_ADD(_type) S = tree_alloc (); S->type = _type; tree_add_child (T, S); -#define EXPECT(s) if (expect (s) < 0) { PARSE_FAIL; } -#define LEX_CHAR(c) (parse.lex.type == lex_char && *parse.lex.ptr == c) -struct tree *parse_args (void); -struct tree *parse_expr (void); - -struct tree *parse_boxed_type_ident (void) { - PARSE_INIT (type_boxed_type_ident); - if (parse.lex.type != lex_uc_ident) { - parse_error ("Can not parse boxed type"); - PARSE_FAIL; - } else { - T->text = parse.lex.ptr; - T->len = parse.lex.len; - T->flags = parse.lex.flags; - parse_lex (); - PARSE_OK; - } -} - -struct tree *parse_full_combinator_id (void) { - PARSE_INIT (type_full_combinator_id); - if (parse.lex.type == lex_lc_ident || LEX_CHAR('_')) { - T->text = parse.lex.ptr; - T->len = parse.lex.len; - T->flags = parse.lex.flags; - parse_lex (); - PARSE_OK; - } else { - parse_error ("Can not parse full combinator id"); - PARSE_FAIL; - } -} - -struct tree *parse_combinator_id (void) { - PARSE_INIT (type_combinator_id); - if (parse.lex.type == lex_lc_ident && !(parse.lex.flags & 2)) { - T->text = parse.lex.ptr; - T->len = parse.lex.len; - T->flags = parse.lex.flags; - parse_lex (); - PARSE_OK; - } else { - parse_error ("Can not parse combinator id"); - PARSE_FAIL; - } -} - -struct tree *parse_var_ident (void) { - PARSE_INIT (type_var_ident); - if ((parse.lex.type == lex_lc_ident || parse.lex.type == lex_uc_ident) && !(parse.lex.flags & 3)) { - T->text = parse.lex.ptr; - T->len = parse.lex.len; - T->flags = parse.lex.flags; - parse_lex (); - PARSE_OK; - } else { - parse_error ("Can not parse var ident"); - PARSE_FAIL; - } -} - -struct tree *parse_var_ident_opt (void) { - PARSE_INIT (type_var_ident_opt); - if ((parse.lex.type == lex_lc_ident || parse.lex.type == lex_uc_ident)&& !(parse.lex.flags & 3)) { - T->text = parse.lex.ptr; - T->len = parse.lex.len; - T->flags = parse.lex.flags; - parse_lex (); - PARSE_OK; - } else if (LEX_CHAR ('_')) { - T->text = parse.lex.ptr; - T->len = parse.lex.len; - T->flags = parse.lex.flags; - parse_lex (); - PARSE_OK; - } else { - parse_error ("Can not parse var ident opt"); - PARSE_FAIL; - } -} - -struct tree *parse_nat_const (void) { - PARSE_INIT (type_nat_const); - if (parse.lex.type == lex_num) { - T->text = parse.lex.ptr; - T->len = parse.lex.len; - T->flags = parse.lex.flags; - parse_lex (); - PARSE_OK; - } else { - parse_error ("Can not parse nat const"); - PARSE_FAIL; - } -} - -struct tree *parse_type_ident (void) { - PARSE_INIT (type_type_ident); - if (parse.lex.type == lex_uc_ident && !(parse.lex.flags & 2)) { - T->text = parse.lex.ptr; - T->len = parse.lex.len; - T->flags = parse.lex.flags; - parse_lex (); - PARSE_OK; - } else if (parse.lex.type == lex_lc_ident && !(parse.lex.flags & 2)) { - T->text = parse.lex.ptr; - T->len = parse.lex.len; - T->flags = parse.lex.flags; - parse_lex (); - PARSE_OK; - } else if (LEX_CHAR ('#')) { - T->text = parse.lex.ptr; - T->len = parse.lex.len; - T->flags = parse.lex.flags; - parse_lex (); - PARSE_OK; - } else { - parse_error ("Can not parse type ident"); - PARSE_FAIL; - } -} - -struct tree *parse_term (void) { - PARSE_INIT (type_term); - while (LEX_CHAR ('%')) { - EXPECT ("%") - PARSE_ADD (type_percent); - } - if (LEX_CHAR ('(')) { - EXPECT ("("); - PARSE_TRY_PES (parse_expr); - EXPECT (")"); - PARSE_OK; - } - PARSE_TRY (parse_type_ident); - if (S) { - tree_add_child (T, S); - if (LEX_CHAR ('<')) { - EXPECT ("<"); - while (1) { - PARSE_TRY_PES (parse_expr); - if (LEX_CHAR ('>')) { break; } - EXPECT (","); - } - EXPECT (">"); - } - PARSE_OK; - } - PARSE_TRY_OPT (parse_type_ident); - PARSE_TRY_OPT (parse_var_ident); - PARSE_TRY_OPT (parse_nat_const); - PARSE_FAIL; -} - -struct tree *parse_nat_term (void) { - PARSE_INIT (type_nat_term); - PARSE_TRY_PES (parse_term); - PARSE_OK; -} - -struct tree *parse_subexpr (void) { - PARSE_INIT (type_subexpr); - int was_term = 0; - int cc = 0; - - while (1) { - PARSE_TRY (parse_nat_const); - if (S) { - tree_add_child (T, S); - } else if (!was_term) { - was_term = 1; - PARSE_TRY (parse_term); - if (S) { - tree_add_child (T, S); - } else { - break; - } - } - cc ++; - if (!LEX_CHAR ('+')) { - break; - } - EXPECT ("+"); - } - if (!cc) { - PARSE_FAIL; - } else { - PARSE_OK; - } -} - -struct tree *parse_expr (void) { - PARSE_INIT (type_expr); - int cc = 0; - while (1) { - PARSE_TRY (parse_subexpr); - if (S) { - tree_add_child (T, S); - cc ++; - } else { - if (cc < 1) { PARSE_FAIL; } - else { PARSE_OK; } - } - } -} - - - -struct tree *parse_final_empty (void) { - PARSE_INIT (type_final_empty); - EXPECT ("Empty"); - PARSE_TRY_PES (parse_boxed_type_ident); - PARSE_OK; -} - -struct tree *parse_final_new (void) { - PARSE_INIT (type_final_new); - EXPECT ("New"); - PARSE_TRY_PES (parse_boxed_type_ident); - PARSE_OK; -} - -struct tree *parse_final_final (void) { - PARSE_INIT (type_final_final); - EXPECT ("Final"); - PARSE_TRY_PES (parse_boxed_type_ident); - PARSE_OK; -} - -struct tree *parse_partial_comb_app_decl (void) { - PARSE_INIT (type_partial_comb_app_decl); - PARSE_TRY_PES (parse_combinator_id); - while (1) { - PARSE_TRY_PES (parse_subexpr); - if (LEX_CHAR (';')) { break; } - } - PARSE_OK; -} - -struct tree *parse_partial_type_app_decl (void) { - PARSE_INIT (type_partial_type_app_decl); - PARSE_TRY_PES (parse_boxed_type_ident); - if (LEX_CHAR ('<')) { - EXPECT ("<"); - while (1) { - PARSE_TRY_PES (parse_expr); - if (LEX_CHAR ('>')) { break; } - EXPECT (","); - } - EXPECT (">"); - PARSE_OK; - } else { - while (1) { - PARSE_TRY_PES (parse_subexpr); - if (LEX_CHAR (';')) { break; } - } - PARSE_OK; - } -} - - - - -struct tree *parse_multiplicity (void) { - PARSE_INIT (type_multiplicity); - PARSE_TRY_PES (parse_nat_term); - PARSE_OK; -} - - -struct tree *parse_type_term (void) { - PARSE_INIT (type_type_term); - PARSE_TRY_PES (parse_term); - PARSE_OK; -} - -struct tree *parse_optional_arg_def (void) { - PARSE_INIT (type_optional_arg_def); - PARSE_TRY_PES (parse_var_ident); - EXPECT ("."); - PARSE_TRY_PES (parse_nat_const); - EXPECT ("?"); - PARSE_OK; -} - -struct tree *parse_args4 (void) { - PARSE_INIT (type_args4); - struct parse so = save_parse (); - PARSE_TRY (parse_optional_arg_def); - if (S) { - tree_add_child (T, S); - } else { - load_parse (so); - } - if (LEX_CHAR ('!')) { - PARSE_ADD (type_exclam); - EXPECT ("!"); - } - PARSE_TRY_PES (parse_type_term); - PARSE_OK; -} - -struct tree *parse_args3 (void) { - PARSE_INIT (type_args3); - PARSE_TRY_PES (parse_var_ident_opt); - EXPECT (":"); - struct parse so = save_parse (); - PARSE_TRY (parse_optional_arg_def); - if (S) { - tree_add_child (T, S); - } else { - load_parse (so); - } - if (LEX_CHAR ('!')) { - PARSE_ADD (type_exclam); - EXPECT ("!"); - } - PARSE_TRY_PES (parse_type_term); - PARSE_OK; -} - -struct tree *parse_args2 (void) { - PARSE_INIT (type_args2); - PARSE_TRY (parse_var_ident_opt); - if (S && LEX_CHAR (':')) { - tree_add_child (T, S); - EXPECT (":"); - } else { - load_parse (save); - } - struct parse so = save_parse (); - PARSE_TRY (parse_optional_arg_def); - if (S) { - tree_add_child (T, S); - } else { - load_parse (so); - } - struct parse save2 = save_parse (); - PARSE_TRY (parse_multiplicity); - if (S && LEX_CHAR ('*')) { - tree_add_child (T, S); - EXPECT ("*"); - } else { - load_parse (save2); - } - EXPECT ("["); - while (1) { - if (LEX_CHAR (']')) { break; } - PARSE_TRY_PES (parse_args); - } - EXPECT ("]"); - PARSE_OK; -} - -struct tree *parse_args1 (void) { - PARSE_INIT (type_args1); - EXPECT ("("); - while (1) { - PARSE_TRY_PES (parse_var_ident_opt); - if (LEX_CHAR(':')) { break; } - } - EXPECT (":"); - struct parse so = save_parse (); - PARSE_TRY (parse_optional_arg_def); - if (S) { - tree_add_child (T, S); - } else { - load_parse (so); - } - if (LEX_CHAR ('!')) { - PARSE_ADD (type_exclam); - EXPECT ("!"); - } - PARSE_TRY_PES (parse_type_term); - EXPECT (")"); - PARSE_OK; -} - -struct tree *parse_args (void) { - PARSE_INIT (type_args); - PARSE_TRY_OPT (parse_args1); - PARSE_TRY_OPT (parse_args2); - PARSE_TRY_OPT (parse_args3); - PARSE_TRY_OPT (parse_args4); - PARSE_FAIL; -} - -struct tree *parse_opt_args (void) { - PARSE_INIT (type_opt_args); - while (1) { - PARSE_TRY_PES (parse_var_ident); - if (parse.lex.type == lex_char && *parse.lex.ptr == ':') { break;} - } - EXPECT (":"); - PARSE_TRY_PES (parse_type_term); - PARSE_OK; -} - -struct tree *parse_final_decl (void) { - PARSE_INIT (type_final_decl); - PARSE_TRY_OPT (parse_final_new); - PARSE_TRY_OPT (parse_final_final); - PARSE_TRY_OPT (parse_final_empty); - PARSE_FAIL; -} - -struct tree *parse_partial_app_decl (void) { - PARSE_INIT (type_partial_app_decl); - PARSE_TRY_OPT (parse_partial_type_app_decl); - PARSE_TRY_OPT (parse_partial_comb_app_decl); - PARSE_FAIL; -} - -struct tree *parse_result_type (void) { - PARSE_INIT (type_result_type); - PARSE_TRY_PES (parse_boxed_type_ident); - if (LEX_CHAR ('<')) { - EXPECT ("<"); - while (1) { - PARSE_TRY_PES (parse_expr); - if (LEX_CHAR ('>')) { break; } - EXPECT (","); - } - EXPECT (">"); - PARSE_OK; - } else { - while (1) { - if (LEX_CHAR (';')) { PARSE_OK; } - PARSE_TRY_PES (parse_subexpr); - } - } -} - -struct tree *parse_combinator_decl (void) { - PARSE_INIT (type_combinator_decl); - PARSE_TRY_PES (parse_full_combinator_id) - while (1) { - if (LEX_CHAR ('{')) { - parse_lex (); - PARSE_TRY_PES (parse_opt_args); - EXPECT ("}"); - } else { - break; - } - } - while (1) { - if (LEX_CHAR ('=')) { break; } - PARSE_TRY_PES (parse_args); - } - EXPECT ("="); - PARSE_ADD (type_equals); - - PARSE_TRY_PES (parse_result_type); - PARSE_OK; -} - -struct tree *parse_builtin_combinator_decl (void) { - PARSE_INIT (type_builtin_combinator_decl); - PARSE_TRY_PES (parse_full_combinator_id) - EXPECT ("?"); - EXPECT ("="); - PARSE_TRY_PES (parse_boxed_type_ident); - PARSE_OK; -} - -struct tree *parse_declaration (void) { - PARSE_INIT (type_declaration); - PARSE_TRY_OPT (parse_combinator_decl); - PARSE_TRY_OPT (parse_partial_app_decl); - PARSE_TRY_OPT (parse_final_decl); - PARSE_TRY_OPT (parse_builtin_combinator_decl); - PARSE_FAIL; -} - -struct tree *parse_constr_declarations (void) { - PARSE_INIT (type_constr_declarations); - if (parse.lex.type == lex_triple_minus || parse.lex.type == lex_eof) { PARSE_OK; } - while (1) { - PARSE_TRY_PES (parse_declaration); - EXPECT (";"); - if (parse.lex.type == lex_eof || parse.lex.type == lex_triple_minus) { PARSE_OK; } - } -} - -struct tree *parse_fun_declarations (void) { - PARSE_INIT (type_fun_declarations); - if (parse.lex.type == lex_triple_minus || parse.lex.type == lex_eof) { PARSE_OK; } - while (1) { - PARSE_TRY_PES (parse_declaration); - EXPECT (";"); - if (parse.lex.type == lex_eof || parse.lex.type == lex_triple_minus) { PARSE_OK; } - } -} - -struct tree *parse_program (void) { - PARSE_INIT (type_tl_program); - while (1) { - PARSE_TRY_PES (parse_constr_declarations); - if (parse.lex.type == lex_eof) { PARSE_OK; } - if (parse.lex.type == lex_error || expect ("---") < 0 || expect ("functions") < 0 || expect ("---") < 0) { PARSE_FAIL; } - - PARSE_TRY_PES (parse_fun_declarations); - if (parse.lex.type == lex_eof) { PARSE_OK; } - if (parse.lex.type == lex_error || expect ("---") < 0 || expect ("types") < 0 || expect ("---") < 0) { PARSE_FAIL; } - } -} - -struct tree *tl_parse_lex (struct parse *_parse) { - assert (_parse); - load_parse (*_parse); - if (parse.lex.type == lex_none) { - parse_lex (); - } - if (parse.lex.type == lex_error) { - return 0; - } - return parse_program (); -} - -int mystrcmp2 (const char *b, int len, const char *a) { - int c = strncmp (b, a, len); - return c ? a[len] ? -1 : 0 : c; -} - -char *mystrdup (const char *a, int len) { - char *z = talloc (len + 1); - memcpy (z, a, len); - z[len] = 0; - return z; -} - -struct tl_program *tl_program_cur; -#define TL_TRY_PES(x) if (!(x)) { return 0; } - -#define tl_type_cmp(a,b) (strcmp (a->id, b->id)) -DEFINE_TREE (tl_type,struct tl_type *,tl_type_cmp,0) -struct tree_tl_type *tl_type_tree; - -DEFINE_TREE (tl_constructor,struct tl_constructor *,tl_type_cmp,0) -struct tree_tl_constructor *tl_constructor_tree; -struct tree_tl_constructor *tl_function_tree; - -DEFINE_TREE (tl_var,struct tl_var *,tl_type_cmp,0) - -struct tl_var_value { - struct tl_combinator_tree *ptr; - struct tl_combinator_tree *val; - int num_val; -}; - -#define tl_var_value_cmp(a,b) (((char *)a.ptr) - ((char *)b.ptr)) -struct tl_var_value empty; -DEFINE_TREE (var_value, struct tl_var_value, tl_var_value_cmp, empty) -//tree_tl_var_t *tl_var_tree; - -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}; - if (tree_lookup_var_value (*T, t).ptr) { - *T = tree_delete_var_value (*T, t); - } - *T = tree_insert_var_value (*T, t, lrand48 ()); -} - -void tl_set_var_value_num (struct tree_var_value **T, struct tl_combinator_tree *var, struct tl_combinator_tree *value, long long num_value) { - struct tl_var_value t = {.ptr = var, .val = value, .num_val = num_value}; - if (tree_lookup_var_value (*T, t).ptr) { - *T = tree_delete_var_value (*T, t); - } - *T = tree_insert_var_value (*T, t, lrand48 ()); -} - -struct tl_combinator_tree *tl_get_var_value (struct tree_var_value **T, struct tl_combinator_tree *var) { - struct tl_var_value t = {.ptr = var, .val = 0, .num_val = 0}; - struct tl_var_value r = tree_lookup_var_value (*T, t); - return r.ptr ? r.val : 0; -} - -int tl_get_var_value_num (struct tree_var_value **T, struct tl_combinator_tree *var) { - struct tl_var_value t = {.ptr = var, .val = 0}; - struct tl_var_value r = tree_lookup_var_value (*T, t); - return r.ptr ? r.num_val : 0; -} - -int namespace_level; - -struct tree_tl_var *vars[10]; -struct tree_tl_field *fields[10]; -struct tl_var *last_num_var[10]; - -int tl_is_type_name (const char *id, int len) { - if (len == 1 && *id == '#') { return 1;} - int ok = id[0] >= 'A' && id[0] <= 'Z'; - int i; - for (i = 0; i < len - 1; i++) if (id[i] == '.') { - ok = id[i + 1] >= 'A' && id[i + 1] <= 'Z'; - } - return ok; -} - -int tl_add_field (char *id) { - assert (namespace_level < 10); - assert (namespace_level >= 0); - if (tree_lookup_tl_field (fields[namespace_level], id)) { - return 0; - } - fields[namespace_level] = tree_insert_tl_field (fields[namespace_level], id, lrand48 ()); - return 1; -} - -void tl_clear_fields (void) { -// tree_act_tl_field (fields[namespace_level], (void *)free); - 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) { - struct tl_var *v = talloc (sizeof (*v)); - v->id = tstrdup (id); - v->type = type; - v->ptr = ptr; - v->flags = 0; - if (tree_lookup_tl_var (vars[namespace_level], v)) { - return 0; - } - vars[namespace_level] = tree_insert_tl_var (vars[namespace_level], v, lrand48 ()); - if (type) { - last_num_var[namespace_level] = v; - } - return v; -} - -void tl_del_var (struct tl_var *v) { -// free (v->id); - tfree (v, sizeof (*v)); -} - -void tl_clear_vars (void) { - tree_act_tl_var (vars[namespace_level], tl_del_var); - vars[namespace_level] = tree_clear_tl_var (vars[namespace_level]); - last_num_var[namespace_level] = 0; -} - -struct tl_var *tl_get_last_num_var (void) { - return last_num_var[namespace_level]; -} - -struct tl_var *tl_get_var (char *_id, int len) { - char *id = mystrdup (_id, len); - struct tl_var v = {.id = id}; - int i; - for (i = namespace_level; i >= 0; i--) { - struct tl_var *w = tree_lookup_tl_var (vars[i], &v); - if (w) { - tfree (id, len + 1); - return w; - } - } - tfree (id, len + 1); - return 0; -} - -void namespace_push (void) { - namespace_level ++; - assert (namespace_level < 10); - tl_clear_vars (); - tl_clear_fields (); -} - -void namespace_pop (void) { - namespace_level --; - assert (namespace_level >= 0); -} - -struct tl_type *tl_get_type (const char *_id, int len) { - char *id = mystrdup (_id, len); - struct tl_type _t = {.id = id}; - struct tl_type *r = tree_lookup_tl_type (tl_type_tree, &_t); - tfree (id, len + 1); - return r; -} - -struct tl_type *tl_add_type (const char *_id, int len, int params_num, long long params_types) { - char *id = talloc (len + 1); - memcpy (id, _id, len); - id[len] = 0; - struct tl_type _t = {.id = id}; - struct tl_type *_r = 0; - if ((_r = tree_lookup_tl_type (tl_type_tree, &_t))) { - tfree (id, len + 1); - if (params_num >= 0 && (_r->params_num != params_num || _r->params_types != params_types)) { - TL_ERROR ("Wrong params_num or types for type %s\n", _r->id); - return 0; - } - return _r; - } - struct tl_type *t = talloc (sizeof (*t)); - t->id = id; - t->print_id = tstrdup (t->id); - int i; - for (i = 0; i < len; i++) if (t->print_id[i] == '.' || t->print_id[i] == '#' || t->print_id[i] == ' ') { - t->print_id[i] = '$'; - } - t->name = 0; - t->constructors_num = 0; - t->constructors = 0; - t->flags = 0; - t->real_id = 0; - if (params_num >= 0) { - assert (params_num <= 64); - t->params_num = params_num; - t->params_types = params_types; - } else { - t->flags |= 4; - t->params_num = -1; - } - tl_type_tree = tree_insert_tl_type (tl_type_tree, t, lrand48 ()); - total_types_num ++; - return t; -} - -void tl_add_type_param (struct tl_type *t, int x) { - assert (t->flags & 4); - assert (t->params_num <= 64); - if (x) { - t->params_types |= (1ull << (t->params_num ++)); - } else { - t->params_num ++; - } -} - -int tl_type_set_params (struct tl_type *t, int x, long long y) { - if (t->flags & 4) { - t->params_num = x; - t->params_types = y; - t->flags &= ~4; - } else { - if (t->params_num != x || t->params_types != y) { - fprintf (stderr, "Wrong num of params (type %s)\n", t->id); - return 0; - } - } - return 1; -} - -void tl_type_finalize (struct tl_type *t) { - t->flags &= ~4; -} - -struct tl_constructor *tl_get_constructor (const char *_id, int len) { - char *id = mystrdup (_id, len); - struct tl_constructor _t = {.id = id}; - struct tl_constructor *r = tree_lookup_tl_constructor (tl_constructor_tree, &_t); - tfree (id, len + 1); - return r; -} - -struct tl_constructor *tl_add_constructor (struct tl_type *a, const char *_id, int len, int force_magic) { - assert (a); - if (a->flags & 1) { - TL_ERROR ("New constructor for type `%s` after final statement\n", a->id); - return 0; - } - int x = 0; - while (x < len && (_id[x] != '#' || force_magic)) { x++; } - char *id = talloc (x + 1); - memcpy (id, _id, x); - id[x] = 0; - - unsigned magic = 0; - if (x < len) { - 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); - } - assert (magic && magic != (unsigned)-1); - } - - len = x; - if (*id != '_') { - struct tl_constructor _t = {.id = id}; - if (tree_lookup_tl_constructor (tl_constructor_tree, &_t)) { - TL_ERROR ("Duplicate constructor id `%s`\n", id); - tfree (id, len + 1); - return 0; - } - } else { - assert (len == 1); - } - - struct tl_constructor *t = talloc (sizeof (*t)); - t->type = a; - t->name = magic; - t->id = id; - t->print_id = tstrdup (id); - t->real_id = 0; - - int i; - for (i = 0; i < len; i++) if (t->print_id[i] == '.' || t->print_id[i] == '#' || t->print_id[i] == ' ') { - t->print_id[i] = '$'; - } - - t->left = t->right = 0; - a->constructors = realloc (a->constructors, sizeof (void *) * (a->constructors_num + 1)); - assert (a->constructors); - a->constructors[a->constructors_num ++] = t; - if (*id != '_') { - tl_constructor_tree = tree_insert_tl_constructor (tl_constructor_tree, t, lrand48 ()); - } - total_constructors_num ++; - a->flags |= FLAG_DEFAULT_CONSTRUCTOR; - return t; -} - -struct tl_constructor *tl_get_function (const char *_id, int len) { - char *id = mystrdup (_id, len); - struct tl_constructor _t = {.id = id}; - struct tl_constructor *r = tree_lookup_tl_constructor (tl_function_tree, &_t); - tfree (id, len + 1); - return r; -} - -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); - memcpy (id, _id, x); - id[x] = 0; - - unsigned magic = 0; - if (x < len) { - 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); - } - assert (magic && magic != (unsigned)-1); - } - - len = x; - - struct tl_constructor _t = {.id = id}; - if (tree_lookup_tl_constructor (tl_function_tree, &_t)) { - TL_ERROR ("Duplicate function id `%s`\n", id); - tfree (id, len + 1); - return 0; - } - - struct tl_constructor *t = talloc (sizeof (*t)); - t->type = a; - t->name = magic; - t->id = id; - t->print_id = tstrdup (id); - t->real_id = 0; - - int i; - for (i = 0; i < len; i++) if (t->print_id[i] == '.' || t->print_id[i] == '#' || t->print_id[i] == ' ') { - t->print_id[i] = '$'; - } - - t->left = t->right = 0; - tl_function_tree = tree_insert_tl_constructor (tl_function_tree, t, lrand48 ()); - total_functions_num ++; - return t; -} - -static char buf[(1 << 20)]; -int buf_pos; - -struct tl_combinator_tree *alloc_ctree_node (void) { - struct tl_combinator_tree *T = talloc (sizeof (*T)); - assert (T); - memset (T, 0, sizeof (*T)); - return T; -} - -struct tl_combinator_tree *tl_tree_dup (struct tl_combinator_tree *T) { - if (!T) { return 0; } - struct tl_combinator_tree *S = talloc (sizeof (*S)); - memcpy (S, T, sizeof (*S)); - S->left = tl_tree_dup (T->left); - S->right = tl_tree_dup (T->right); - return S; -} - -struct tl_type *tl_tree_get_type (struct tl_combinator_tree *T) { - 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;} - assert (T->type == type_type); - } - assert (T->act == act_type || T->act == act_var || T->act == act_array); - return T->act == act_type ? T->data : 0; -} - -void tl_tree_set_len (struct tl_combinator_tree *T) { - TL_INIT (H); - H = T; - while (H->left) { - H->left->type_len = H->type_len + 1; - H = H->left; - } - assert (H->type == type_type); - struct tl_type *t = H->data; - assert (t); - assert (H->type_len == t->params_num); -} - -void tl_buf_reset (void) { - buf_pos = 0; -} - -void tl_buf_add_string (char *s, int len) { - if (len < 0) { len = strlen (s); } - buf[buf_pos ++] = ' '; - memcpy (buf + buf_pos, s, len); buf_pos += len; - buf[buf_pos] = 0; -} - -void tl_buf_add_string_nospace (char *s, int len) { - if (len < 0) { len = strlen (s); } -// if (buf_pos) { buf[buf_pos ++] = ' '; } - memcpy (buf + buf_pos, s, len); buf_pos += len; - buf[buf_pos] = 0; -} - -void tl_buf_add_string_q (char *s, int len, int x) { - if (x) { - tl_buf_add_string (s, len); - } else { - tl_buf_add_string_nospace (s, len); - } -} - - -void tl_buf_add_tree (struct tl_combinator_tree *T, int x) { - if (!T) { return; } - assert (T != (void *)-1l && T != (void *)-2l); - switch (T->act) { - case act_question_mark: - tl_buf_add_string_q ("?", -1, x); - return; - case act_type: - if ((T->flags & 1) && !(T->flags & 4)) { - tl_buf_add_string_q ("%", -1, x); - x = 0; - } - if (T->flags & 2) { - tl_buf_add_string_q ((char *)T->data, -1, x); - } else { - struct tl_type *t = T->data; - if (T->flags & 4) { - 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); - } - } - return; - case act_field: - if (T->data) { - tl_buf_add_string_q ((char *)T->data, -1, x); - x = 0; - tl_buf_add_string_q (":", -1, 0); - } - tl_buf_add_tree (T->left, x); - tl_buf_add_tree (T->right, 1); - return; - case act_union: - tl_buf_add_tree (T->left, x); - tl_buf_add_tree (T->right, 1); - return; - case act_var: - { - if (T->data == (void *)-1l) { return; } - struct tl_combinator_tree *v = T->data; - tl_buf_add_string_q ((char *)v->data, -1, x); - if (T->type == type_num && T->type_flags) { - static char _buf[30]; - sprintf (_buf, "+%lld", T->type_flags); - tl_buf_add_string_q (_buf, -1, 0); - } - } - return; - case act_arg: - tl_buf_add_tree (T->left, x); - tl_buf_add_tree (T->right, 1); - return; - case act_array: - if (T->left && !(T->left->flags & 128)) { - tl_buf_add_tree (T->left, x); - x = 0; - tl_buf_add_string_q ("*", -1, x); - } - tl_buf_add_string_q ("[", -1, x); - tl_buf_add_tree (T->right, 1); - tl_buf_add_string_q ("]", -1, 1); - return; - case act_plus: - tl_buf_add_tree (T->left, x); - tl_buf_add_string_q ("+", -1, 0); - tl_buf_add_tree (T->right, 0); - return; - case act_nat_const: - { - static char _buf[30]; - snprintf (_buf, 29, "%lld", T->type_flags); - tl_buf_add_string_q (_buf, -1, x); - return; - } - case act_opt_field: - { - struct tl_combinator_tree *v = T->left->data; - tl_buf_add_string_q ((char *)v->data, -1, x); - tl_buf_add_string_q (".", -1, 0); - static char _buf[30]; - 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: - 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) { - 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); - tl_buf_add_string ("=", -1); - tl_buf_add_tree (c->right, 1); - //fprintf (stderr, "%.*s\n", buf_pos, buf); - if (!c->name) { - c->name = compute_crc32 (buf, buf_pos); - } - return c->name; -} - -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]; - 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) { - fprintf (stderr, "%.*s\n", buf_pos, buf); - } -/* if (!c->name) { - c->name = compute_crc32 (buf, buf_pos); - }*/ - return c->name; -} - -int _tl_finish_subtree (struct tl_combinator_tree *R, int x, long long y) { - 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; - assert (t); - return tl_type_set_params (t, x, y); - } - 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) { - assert (R); - if (R->type != type_type) { - return 1; - } - if (R->type_len >= 0) { - if (R->type_len > 0) { - TL_ERROR ("Not enough params\n"); - return 0; - } - return 1; - } - return _tl_finish_subtree (R, 0, 0); -} - -struct tl_combinator_tree *tl_union (struct tl_combinator_tree *L, struct tl_combinator_tree *R) { - if (!L) { return R; } - if (!R) { return L; } - TL_INIT (v); - v = alloc_ctree_node (); - v->left = L; - v->right = R; - switch (L->type) { - case type_num: - if (R->type != type_num_value) { - TL_ERROR ("Union: type mistmatch\n"); - return 0; - } - tfree (v, sizeof (*v)); - L->type_flags += R->type_flags; - return L; - case type_num_value: - if (R->type != type_num_value && R->type != type_num) { - TL_ERROR ("Union: type mistmatch\n"); - return 0; - } - tfree (v, sizeof (*v)); - R->type_flags += L->type_flags; - return R; - case type_list_item: - case type_list: - if (R->type != type_list_item) { - TL_ERROR ("Union: type mistmatch\n"); - return 0; - } - v->type = type_list; - v->act = act_union; - return v; - case type_type: - if (L->type_len == 0) { - TL_ERROR ("Arguments number exceeds type arity\n"); - return 0; - } - if (R->type != type_num && R->type != type_type && R->type != type_num_value) { - TL_ERROR ("Union: type mistmatch\n"); - return 0; - } - if (R->type_len < 0) { - if (!tl_finish_subtree (R)) { - return 0; - } - } - if (R->type_len > 0) { - TL_ERROR ("Argument type must have full number of arguments\n"); - 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 = %lld, R->type = %s\n", L->flags, TL_TYPE (R->type)); - return 0; - } - v->type = type_type; - v->act = act_arg; - v->type_len = L->type_len > 0 ? L->type_len - 1 : -1; - v->type_flags = L->type_flags >> 1; - return v; - default: - 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) { - assert (T->type == type_term); - int i = 0; - while (i < T->nc && T->c[i]->type == type_percent) { i ++; s ++; } - assert (i < T->nc); - TL_INIT (L); - while (i < T->nc) { - TL_TRY (tl_parse_any_term (T->c[i], s), L); - s = 0; - i ++; - } - return L; -} - - -struct tl_combinator_tree *tl_parse_type_term (struct tree *T, int 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) { - 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) { - assert (T->type == type_subexpr); - assert (T->nc >= 1); - int i; - TL_INIT (L); - for (i = 0; i < T->nc; i++) { - TL_TRY (tl_parse_any_term (T->c[i], s), L); - s = 0; - } - return L; -} - -struct tl_combinator_tree *tl_parse_expr (struct tree *T, int s) { - assert (T->type == type_expr); - assert (T->nc >= 1); - int i; - TL_INIT (L); - for (i = 0; i < T->nc; i++) { - TL_TRY (tl_parse_subexpr (T->c[i], s), L); - s = 0; - } - return L; -} - -struct tl_combinator_tree *tl_parse_nat_const (struct tree *T, int s) { - assert (T->type == type_nat_const); - assert (!T->nc); - if (s > 0) { - 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; - L->type = type_num_value; - int i; - long long x = 0; - for (i = 0; i < T->len; i++) { - x = x * 10 + T->text[i] - '0'; - } - L->type_flags = x; - return L; -} - -struct tl_combinator_tree *tl_parse_ident (struct tree *T, int s) { - 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) { - 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 preceed with %%\n"); - TL_FAIL; - } else { - if (s) { - L->flags |= 1; - } - } - L->type_len = 0; - L->type_flags = 0; - L->data = v->ptr; - return L; - } - -/* if (!mystrcmp2 (T->text, T->len, "#") || !mystrcmp2 (T->text, T->len, "Type")) { - L = alloc_ctree_node (); - L->act = act_type; - L->flags |= 2; - L->data = tl_get_type (T->text, T->len); - assert (L->data); - L->type = type_type; - L->type_len = 0; - L->type_flags = 0; - return L; - }*/ - - struct tl_constructor *c = tl_get_constructor (T->text, T->len); - if (c) { - 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; - } - c->type->flags |= 1; - L = alloc_ctree_node (); - L->act = act_type; - L->flags |= 5; - L->data = c->type; - L->type = type_type; - L->type_len = c->type->params_num; - L->type_flags = c->type->params_types; - return L; - } - int x = tl_is_type_name (T->text, T->len); - if (x) { - struct tl_type *t = tl_add_type (T->text, T->len, -1, 0); - L = alloc_ctree_node (); - if (s) { - L->flags |= 1; - t->flags |= 8; - } - L->act = act_type; - L->data = t; - L->type = type_type; - L->type_len = t->params_num; - L->type_flags = t->params_types; - return L; - } else { - TL_ERROR ("Not a type/var ident `%.*s`\n", T->len, T->text); - return 0; - } -} - -struct tl_combinator_tree *tl_parse_any_term (struct tree *T, int s) { - switch (T->type) { - case type_type_term: - return tl_parse_type_term (T, s); - case type_nat_term: - return tl_parse_nat_term (T, s); - case type_term: - return tl_parse_term (T, s); - case type_expr: - return tl_parse_expr (T, s); - case type_subexpr: - return tl_parse_subexpr (T, s); - case type_nat_const: - return tl_parse_nat_const (T, s); - case type_type_ident: - case type_var_ident: - return tl_parse_ident (T, s); - default: - fprintf (stderr, "type = %d\n", T->type); - assert (0); - return 0; - } -} - -struct tl_combinator_tree *tl_parse_multiplicity (struct tree *T) { - 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) { - 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); - 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; - } else if (t && !strcmp (t->id, "Type")) { - tt = 0; - } - if (tt < 0) { - TL_ERROR ("Optargs can be only of type # or Type\n"); - TL_FAIL; - } - - int i; - for (i = 0; i < T->nc - 1; i++) { - if (T->c[i]->type != type_var_ident) { - TL_ERROR ("Variable name expected\n"); - TL_FAIL; - } - if (T->c[i]->len == 1 && *T->c[i]->text == '_') { - TL_ERROR ("Variables can not be unnamed\n"); - TL_FAIL; - } - } - TL_INIT (H); -// for (i = T->nc - 2; i >= (T->nc >= 2 ? 0 : -1); i--) { - for (i = 0; i <= T->nc - 2; i++) { - TL_INIT (S); S = alloc_ctree_node (); - S->left = (i == T->nc - 2) ? R : tl_tree_dup (R) ; S->right = 0; - S->type = type_list_item; - S->type_len = 0; - S->act = act_field; - S->data = i >= 0 ? mystrdup (T->c[i]->text, T->c[i]->len) : 0; - if (tt >= 0) { - assert (S->data); - tl_add_var (S->data, S, tt); - } - S->flags = 33; - H = tl_union (H, S); - } - return H; -} - -struct tl_combinator_tree *tl_parse_args (struct tree *T); -struct tl_combinator_tree *tl_parse_args2 (struct tree *T) { - assert (T); - assert (T->type == type_args2); - assert (T->nc >= 1); - TL_INIT (R); - TL_INIT (L); - int x = 0; - char *field_name = 0; - 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_FAIL; - } - x ++; - } - //fprintf (stderr, "%d %d\n", x, T->nc); - if (T->c[x]->type == type_multiplicity) { - L = tl_parse_multiplicity (T->c[x]); - if (!L) { TL_FAIL;} - x ++; - } else { - struct tl_var *v = tl_get_last_num_var (); - if (!v) { - TL_ERROR ("Expected multiplicity or nat var\n"); - TL_FAIL; - } - L = alloc_ctree_node (); - L->act = act_var; - L->type = type_num; - L->flags |= 128; - L->type_len = 0; - L->type_flags = 0; - L->data = v->ptr; - ((struct tl_combinator_tree *)(v->ptr))->flags |= 256; - } - namespace_push (); - while (x < T->nc) { - TL_TRY (tl_parse_args (T->c[x]), R); - x ++; - } - namespace_pop (); - struct tl_combinator_tree *S = alloc_ctree_node (); - S->type = type_type; - S->type_len = 0; - S->act = act_array; - S->left = L; - S->right = R; - //S->data = field_name; - - struct tl_combinator_tree *H = alloc_ctree_node (); - H->type = type_list_item; - H->act = act_field; - H->left = S; - 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) { - 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); - 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; - } else if (t && !strcmp (t->id, "Type")) { - tt = 0; - } - -/* if (tt >= 0 && T->nc == 1) { - TL_ERROR ("Variables can not be unnamed (type %d)\n", tt); - }*/ - int last = T->nc - 2; - int excl = 0; - if (last >= 0 && T->c[last]->type == type_exclam) { - excl ++; - tl_mark_vars (R); - last --; - } - if (last >= 0 && T->c[last]->type == type_optional_arg_def) { - assert (T->c[last]->nc == 2); - TL_INIT (E); E = alloc_ctree_node (); - E->type = type_type; - E->act = act_opt_field; - E->left = tl_parse_ident (T->c[last]->c[0], 0); - int i; - long long x = 0; - for (i = 0; i < T->c[last]->c[1]->len; i++) { - x = x * 10 + T->c[last]->c[1]->text[i] - '0'; - } - E->left->type_flags = x; - E->type_flags = R->type_flags; - E->type_len = R->type_len; - E->right = R; - R = E; - last --; - } - int i; - for (i = 0; i < last; i++) { - if (T->c[i]->type != type_var_ident && T->c[i]->type != type_var_ident_opt) { - TL_ERROR ("Variable name expected\n"); - TL_FAIL; - } -/* if (tt >= 0 && (T->nc == 1 || (T->c[i]->len == 1 && *T->c[i]->text == '_'))) { - TL_ERROR ("Variables can not be unnamed\n"); - TL_FAIL; - }*/ - } - TL_INIT (H); -// for (i = T->nc - 2; i >= (T->nc >= 2 ? 0 : -1); i--) { - for (i = (last >= 0 ? 0 : -1); i <= last; i++) { - TL_INIT (S); S = alloc_ctree_node (); - S->left = (i == last) ? R : tl_tree_dup (R) ; S->right = 0; - S->type = type_list_item; - S->type_len = 0; - S->act = act_field; - S->data = i >= 0 ? mystrdup (T->c[i]->text, T->c[i]->len) : 0; - if (excl) { - S->flags |= FLAG_EXCL; - } - if (S->data && (T->c[i]->len >= 2 || *T->c[i]->text != '_')) { - if (!tl_add_field (S->data)) { - TL_ERROR ("Duplicate field name %s\n", (char *)S->data); - TL_FAIL; - } - } - if (tt >= 0) { - //assert (S->data); - char *name = S->data; - if (!name) { - static char s[20]; - 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; -} - - -struct tl_combinator_tree *tl_parse_args (struct tree *T) { - assert (T->type == type_args); - assert (T->nc == 1); - switch (T->c[0]->type) { - case type_args1: - return tl_parse_args134 (T->c[0]); - case type_args2: - return tl_parse_args2 (T->c[0]); - case type_args3: - return tl_parse_args134 (T->c[0]); - case type_args4: - return tl_parse_args134 (T->c[0]); - default: - assert (0); - return 0; - } -} - -void tl_mark_vars (struct tl_combinator_tree *T) { - if (!T) { return; } - if (T->act == act_var) { - char *id = ((struct tl_combinator_tree *)(T->data))->data; - struct tl_var *v = tl_get_var (id, strlen (id)); - assert (v); - v->flags |= 1; - } - tl_mark_vars (T->left); - tl_mark_vars (T->right); -} - -struct tl_combinator_tree *tl_parse_result_type (struct tree *T) { - 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)) { - if (T->nc != 1) { - TL_ERROR ("Variable can not take params\n"); - TL_FAIL; - } - L = alloc_ctree_node (); - L->act = act_var; - L->type = type_type; - struct tl_var *v = tl_get_var (T->c[0]->text, T->c[0]->len); - if (v->type) { - TL_ERROR ("Type mistmatch\n"); - 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); - assert (t); - L->type_len = t->params_num; - L->type_flags = t->params_types; - L->data = t; - - int i; - for (i = 1; i < T->nc; i++) { - TL_TRY (tl_parse_any_term (T->c[i], 0), L); - 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)); - } - } - - if (!tl_finish_subtree (L)) { - TL_FAIL; - } - - tl_mark_vars (L); - return L; -} - -int __ok; -void tl_var_check_used (struct tl_var *v) { - __ok = __ok && (v->flags & 3); -} - -int tl_parse_combinator_decl (struct tree *T, int fun) { - assert (T->type == type_combinator_decl); - assert (T->nc >= 3); - namespace_level = 0; - tl_clear_vars (); - tl_clear_fields (); - TL_INIT (L); - TL_INIT (R); - - int i = 1; - while (i < T->nc - 2 && T->c[i]->type == type_opt_args) { - TL_TRY (tl_parse_opt_args (T->c[i]), L); - i++; - } - while (i < T->nc - 2 && T->c[i]->type == type_args) { - TL_TRY (tl_parse_args (T->c[i]), L); - i++; - } - assert (i == T->nc - 2 && T->c[i]->type == type_equals); - i ++; - - R = tl_parse_result_type (T->c[i]); - if (!R) { TL_FAIL; } - - struct tl_type *t = tl_tree_get_type (R); - if (!fun && !t) { - TL_ERROR ("Only functions can return variables\n"); - } - 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; - } - struct tl_constructor *c = !fun ? tl_add_constructor (t, T->c[0]->text, T->c[0]->len, 0) : tl_add_function (t, T->c[0]->text, T->c[0]->len, 0); - if (!c) { TL_FAIL; } - c->left = L; - c->right = R; - - if (!c->name) { - tl_count_combinator_name (c); - } - tl_print_combinator (c); - - return 1; -} - -void change_var_ptrs (struct tl_combinator_tree *O, struct tl_combinator_tree *D, struct tree_var_value **V) { - if (!O || !D) { - assert (!O && !D); - return; - } - 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) { - if (!O) { return (void *)-2l; }; - if (O->act == act_field && !*X) { - struct tl_type *t = tl_tree_get_type (O->left); - if (t && !strcmp (t->id, "#")) { - if (Y->type != type_num && Y->type != type_num_value) { - TL_ERROR ("change_var: Type mistmatch\n"); - return 0; - } else { - *X = O; - return (void *)-1l; - } - } - if (t && !strcmp (t->id, "Type")) { - if (Y->type != type_type || Y->type_len != 0) { - TL_ERROR ("change_var: Type mistmatch\n"); - return 0; - } else { - *X = O; - return (void *)-1l; - } - } - } - if (O->act == act_var) { - 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; - } - } - struct tl_combinator_tree *t; - t = change_first_var (O->left, X, Y); - if (!t) { return 0;} - if (t == (void *)-1l) { - t = change_first_var (O->right, X, Y); - if (!t) { return 0;} - if (t == (void *)-1l) { return (void *)-1l; } - if (t != (void *)-2l) { return t;} - return (void *)-1l; - } - if (t != (void *)-2l) { - O->left = t; - } - t = change_first_var (O->right, X, Y); - if (!t) { return 0;} - if (t == (void *)-1l) { - return O->left; - } - if (t != (void *)-2l) { - O->right = t; - } - return O; -} - - -int uniformize (struct tl_combinator_tree *L, struct tl_combinator_tree *R, struct tree_var_value **T); -struct tree_var_value **_T; -int __tok; -void check_nat_val (struct tl_var_value v) { - if (!__tok) { return; } - long long x = v.num_val; - struct tl_combinator_tree *L = v.val; - if (L->type == type_type) { return;} - while (1) { - if (L->type == type_num_value) { - if (x + L->type_flags < 0) { - __tok = 0; - return; - } else { - return; - } - } - 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); - if (!L) { return;} - } -} - -int check_constructors_equal (struct tl_combinator_tree *L, struct tl_combinator_tree *R, struct tree_var_value **T) { - if (!uniformize (L, R, T)) { return 0; } - __tok = 1; - _T = T; - tree_act_var_value (*T, check_nat_val); - return __tok; -} - -struct tl_combinator_tree *reduce_type (struct tl_combinator_tree *A, struct tl_type *t) { - assert (A); - if (A->type_len == t->params_num) { - assert (A->type_flags == t->params_types); - A->act = act_type; - A->type = type_type; - A->left = A->right = 0; - A->data = t; - return A; - } - A->left = reduce_type (A->left, t); - return A; -} - -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) { - assert (O->data); - if (!tl_get_var_value (X, O->data)) { - break; - } - if (O->type == type_type) { - O = tl_tree_dup (tl_get_var_value (X, O->data)); - } else { - long long n = tl_get_var_value_num (X, O->data); - struct tl_combinator_tree *T = tl_get_var_value (X, O->data); - O->data = T->data; - O->type = T->type; - O->act = T->act; - O->type_flags = O->type_flags + n + T->type_flags; - } - } - if (O->act == act_field) { - if (tl_get_var_value (X, O)) { return (void *)-1l; } - } - struct tl_combinator_tree *t; - t = change_value_var (O->left, X); - if (!t) { return 0;} - if (t == (void *)-1l) { - t = change_value_var (O->right, X); - if (!t) { return 0;} - if (t == (void *)-1l) { return (void *)-1l; } - if (t != (void *)-2l) { return t;} - return (void *)-1l; - } - if (t != (void *)-2l) { - O->left = t; - } - t = change_value_var (O->right, X); - if (!t) { return 0;} - if (t == (void *)-1l) { - return O->left; - } - if (t != (void *)-2l) { - O->right = t; - } - return O; -} - -int tl_parse_partial_type_app_decl (struct tree *T) { - 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"); - return 0; - } - - tl_type_finalize (t); - - struct tl_combinator_tree *L = tl_parse_ident (T->c[0], 0); - assert (L); - int i; - tl_buf_reset (); - int cc = T->nc - 1; - for (i = 1; i < T->nc; i++) { - TL_TRY (tl_parse_any_term (T->c[i], 0), L); - tl_buf_add_tree (L->right, 1); - } - - while (L->type_len) { - struct tl_combinator_tree *C = alloc_ctree_node (); - C->act = act_var; - C->type = (L->type_flags & 1) ? type_num : type_type; - C->type_len = 0; - C->type_flags = 0; - C->data = (void *)-1l; - L = tl_union (L, C); - if (!L) { return 0; } - } - - - 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); - 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; - TL_INIT (A); - 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); - - - if (!check_constructors_equal (B, L, &V)) { continue; } - B = reduce_type (B, nt); - A = change_value_var (A, &V); - if (A == (void *)-1l) { A = 0;} - B = change_value_var (B, &V); - 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) { - tl_count_combinator_name (r); - } - tl_print_combinator (r); - } - - return 1; -} - -int tl_parse_partial_comb_app_decl (struct tree *T, int fun) { - 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) { - TL_ERROR ("Can not make partial app for undefined combinator\n"); - return 0; - } - - //TL_INIT (K); - //static char buf[1000]; - //int x = sprintf (buf, "%s", c->id); - TL_INIT (L); - 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); - V = tree_clear_var_value (V); - - int i; - tl_buf_reset (); - for (i = 1; i < T->nc; i++) { - TL_INIT (X); - 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))) { - TL_FAIL; - } - L = Z; - if (!K) { - TL_ERROR ("Partial app: not enougth variables (i = %d)\n", i); - TL_FAIL; - } - if (!(Z = change_first_var (R, &K, X))) { - TL_FAIL; - } - assert (Z == R); - tl_buf_add_tree (X, 1); - } - - static char _buf[100000]; - snprintf (_buf, 100000, "%s%.*s", c->id, buf_pos, buf); -// fprintf (stderr, "Local id: %s\n", _buf); - - struct tl_constructor *r = !fun ? tl_add_constructor (c->type, _buf, strlen (_buf), 1) : tl_add_function (c->type, _buf, strlen (_buf), 1); - r->left = L; - r->right = R; - snprintf (_buf, 100000, "%s", c->id); - r->real_id = tstrdup (_buf); - if (!r->name) { - tl_count_combinator_name (r); - } - tl_print_combinator (r); - return 1; -} - - -int tl_parse_partial_app_decl (struct tree *T, int fun) { - 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 { - if (fun) { - TL_ERROR ("Partial type app in functions block\n"); - TL_FAIL; - } - return tl_parse_partial_type_app_decl (T->c[0]); - } -} - -int tl_parse_final_final (struct tree *T) { - 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; - return 1; - } else { - TL_ERROR ("Final statement for type `%.*s` before declaration\n", T->c[0]->len, T->c[0]->text); - TL_FAIL; - } -} - -int tl_parse_final_new (struct tree *T) { - 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; - } else { - return 1; - } -} - -int tl_parse_final_empty (struct tree *T) { - 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); - assert (t); - t->flags |= 1 | FLAG_EMPTY; - return 1; -} - -int tl_parse_final_decl (struct tree *T, int fun) { - 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]); - case type_final_final: - return tl_parse_final_final (T->c[0]); - case type_final_empty: - return tl_parse_final_empty (T->c[0]); - default: - assert (0); - return 0; - } -} - -int tl_parse_builtin_combinator_decl (struct tree *T, int fun) { - if (fun) { - TL_ERROR ("Builtin type can not be described in function block\n"); - return -1; - } - 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")) || - (!mystrcmp2 (T->c[0]->text, T->c[0]->len, "double") && !mystrcmp2 (T->c[1]->text, T->c[1]->len, "Double")) || - (!mystrcmp2 (T->c[0]->text, T->c[0]->len, "string") && !mystrcmp2 (T->c[1]->text, T->c[1]->len, "String"))) { - struct tl_type *t = tl_add_type (T->c[1]->text, T->c[1]->len, 0, 0); - if (!t) { - return 0; - } - struct tl_constructor *c = tl_add_constructor (t, T->c[0]->text, T->c[0]->len, 0); - if (!c) { - return 0; - } - - c->left = alloc_ctree_node (); - c->left->act = act_question_mark; - c->left->type = type_list_item; - - c->right = alloc_ctree_node (); - c->right->act = act_type; - c->right->data = t; - c->right->type = type_type; - - if (!c->name) { - tl_count_combinator_name (c); - } - tl_print_combinator (c); - } else { - TL_ERROR ("Unknown builting type `%.*s`\n", T->c[0]->len, T->c[0]->text); - return 0; - } - - return 1; -} - -int tl_parse_declaration (struct tree *T, int fun) { - 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); - case type_partial_app_decl: - return tl_parse_partial_app_decl (T->c[0], fun); - case type_final_decl: - return tl_parse_final_decl (T->c[0], fun); - case type_builtin_combinator_decl: - return tl_parse_builtin_combinator_decl (T->c[0], fun); - default: - assert (0); - return 0; - } -} - -int tl_parse_constr_declarations (struct tree *T) { - 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)); - } - return 1; -} - -int tl_parse_fun_declarations (struct tree *T) { - 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)); - } - return 1; -} - -int tl_tree_lookup_value (struct tl_combinator_tree *L, void *var, struct tree_var_value **T) { - if (!L) { - return -1; - } - if (L->act == act_var && L->data == var) { - return 0; - } - if (L->act == act_var) { - struct tl_combinator_tree *E = tl_get_var_value (T, L->data); - if (!E) { return -1;} - else { return tl_tree_lookup_value (E, var, T); } - } - if (tl_tree_lookup_value (L->left, var, T) >= 0) { return 1; } - if (tl_tree_lookup_value (L->right, var, T) >= 0) { return 1; } - return -1; -} - -int tl_tree_lookup_value_nat (struct tl_combinator_tree *L, void *var, long long x, struct tree_var_value **T) { - assert (L); - if (L->type == type_num_value) { return -1; } - assert (L->type == type_num); - assert (L->act == act_var); - if (L->data == var) { - return x == L->type_flags ? 0 : 1; - } else { - if (!tl_get_var_value (T, L->data)) { - return -1; - } - return tl_tree_lookup_value_nat (tl_get_var_value (T, L->data), var, x + tl_get_var_value_num (T, L->data), T); - } - -} - -int uniformize (struct tl_combinator_tree *L, struct tl_combinator_tree *R, struct tree_var_value **T) { - 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; -} - - -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)) { - TL_ERROR ("Type %s has no constructors\n", t->id); - __ok = 0; - return; - } - int i, j; - t->name = 0; - for (i = 0; i < t->constructors_num; i++) { - t->name ^= t->constructors[i]->name; - } - for (i = 0; i < t->constructors_num; i++) { - for (j = i + 1; j < t->constructors_num; j++) { - struct tree_var_value *v = 0; - if (check_constructors_equal (t->constructors[i]->right, t->constructors[j]->right, &v)) { - t->flags |= 16; - } - } - } - if ((t->flags & 24) == 24) { - TL_WARNING ("Warning: Type %s has overlapping costructors, but it is used with `%%`\n", t->id); - } - int z = 0; - int sid = 0; - for (i = 0; i < t->constructors_num; i++) if (*t->constructors[i]->id == '_') { - z ++; - sid = i; - } - if (z > 1) { - TL_ERROR ("Type %s has %d default constructors\n", t->id, z); - __ok = 0; - return; - } - if (z == 1 && (t->flags & 8)) { - TL_ERROR ("Type %s has default constructors and used bare\n", t->id); - __ok = 0; - return; - } - if (z) { - struct tl_constructor *c; - c = t->constructors[sid]; - t->constructors[sid] = t->constructors[t->constructors_num - 1]; - t->constructors[t->constructors_num - 1] = c; - } -} - -struct tl_program *tl_parse (struct tree *T) { - assert (T); - assert (T->type == type_tl_program); - int i; - tl_program_cur = talloc (sizeof (*tl_program_cur)); - tl_add_type ("#", 1, 0, 0); - tl_add_type ("Type", 4, 0, 0); - for (i = 0; i < T->nc; i++) { - if (T->c[i]->type == type_constr_declarations) { TL_TRY_PES (tl_parse_constr_declarations (T->c[i])); } - else { TL_TRY_PES (tl_parse_fun_declarations (T->c[i])) } - } - __ok = 1; - tree_act_tl_type (tl_type_tree, tl_type_check); - if (!__ok) { - return 0; - } - return tl_program_cur; -} - -int __f; -int num = 0; - -void wint (int a) { -// printf ("%d ", a); - assert (write (__f, &a, 4) == 4); -} - -void wdata (const void *x, int len) { - assert (write (__f, x, len) == len); -} - -void wstr (const char *s) { - if (s) { -// printf ("\"%s\" ", s); - if (schema_version < 1) { - wint (strlen (s)); - wdata (s, strlen (s)); - } else { - int x = strlen (s); - if (x <= 254) { - assert (write (__f, &x, 1) == 1); - } else { - fprintf (stderr, "String is too big...\n"); - assert (0); - } - wdata (s, x); - x ++; - int t = 0; - if (x & 3) { - wdata (&t, 4 - (x & 3)); - } - } - } else { -// printf (" "); - wint (0); - } -} - -void wll (long long a) { -// printf ("%lld ", a); - assert (write (__f, &a, 8) == 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 { - return count_list_size (T->left) + count_list_size (T->right); - } -} - -void write_type_flags (long long flags) { - int new_flags = 0; - if (flags & 1) { - new_flags |= FLAG_BARE; - } - if (flags & FLAG_DEFAULT_CONSTRUCTOR) { - new_flags |= FLAG_DEFAULT_CONSTRUCTOR; - } - wint (new_flags); -} - -void write_field_flags (long long flags) { - int new_flags = 0; - //fprintf (stderr, "%lld\n", flags); - if (flags & 1) { - new_flags |= FLAG_BARE; - } - if (flags & 32) { - new_flags |= FLAG_OPT_VAR; - } - if (flags & FLAG_EXCL) { - new_flags |= FLAG_EXCL; - } - if (flags & FLAG_OPT_FIELD) { - // new_flags |= FLAG_OPT_FIELD; - new_flags |= 2; - } - if (flags & (1 << 21)) { - new_flags |= 4; - } - wint (new_flags); -} - -void write_var_type_flags (long long flags) { - int new_flags = 0; - if (flags & 1) { - new_flags |= FLAG_BARE; - } - if (new_flags & FLAG_BARE) { - TL_ERROR ("Sorry, bare vars are not (yet ?) supported.\n"); - 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) { - 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 (schema_version == 1) { - wint (TLS_ARG); - } if (schema_version == 2) { - wint (TLS_ARG_V2); - } else { - wint (-3); - } - if (T->act == act_question_mark) { - if (schema_version >= 1) { - assert (0); - } else { - wint (-100); - } - return; - } - if (schema_version >= 1) { - } else { - wint (-99); - } - 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) { - f |= (1 << 20); - } - if (T->left->act == act_type && T->left->data && (!strcmp (((struct tl_type *)T->left->data)->id, "#") || !strcmp (((struct tl_type *)T->left->data)->id, "Type"))) { - write_field_flags (f | (1 << 21)); - wint (*last_var); - *last_var = (*last_var) + 1; - tl_set_var_value_num (v, T, 0, (*last_var) - 1); - } else { - write_field_flags (f); - if (schema_version <= 1) { - wint (-1); - } - } - write_tree (T->left, 0, v, last_var); -} - -void write_array (struct tl_combinator_tree *T, struct tree_var_value **v, int *last_var) { - if (schema_version == 1) { - wint (TLS_TREE_ARRAY); - } else if (schema_version == 2) { - wint (TLS_ARRAY); - } else { - wint (-8); - } - write_tree (T->left, 0, v, last_var); - write_tree (T->right, 0, v, last_var); -} - -void write_type_rec (struct tl_combinator_tree *T, int cc, struct tree_var_value **v, int *last_var) { - if (T->act == act_arg) { - write_type_rec (T->left, cc + 1, v, last_var); - if (schema_version >= 2) { - if (T->right->type == type_num_value || T->right->type == type_num) { - wint (TLS_EXPR_NAT); - } else { - wint (TLS_EXPR_TYPE); - } - } - write_tree (T->right, 0, v, last_var); - } else { - assert (T->act == act_var || T->act == act_type); - if (T->act == act_var) { - assert (!cc); - if (schema_version == 1) { - wint (TLS_TREE_TYPE_VAR); - } else if (schema_version == 2) { - wint (TLS_TYPE_VAR); - } else { - wint (-6); - } - wint (tl_get_var_value_num (v, T->data)); - write_var_type_flags (T->flags); - //wint (T->flags); - } else { - if (schema_version == 1) { - wint (TLS_TREE_TYPE); - } else if (schema_version == 2) { - wint (TLS_TYPE_EXPR); - } else { - wint (-7); - } - struct tl_type *t = T->data; - wint (t->name); - write_type_flags (T->flags); -// wint (T->flags); - wint (cc); -// fprintf (stderr, "cc = %d\n", cc); - } - } -} - -void write_opt_type (struct tl_combinator_tree *T, struct tree_var_value **v, int *last_var) { - if (schema_version >= 1) { - } else { - wint (-20); - } - 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: - if (T->act == act_array) { - write_array (T, v, last_var); - } else if (T->act == act_type || T->act == act_var || T->act == act_arg) { - write_type_rec (T, 0, v, last_var); - } else { - assert (0); - } - break; - default: - assert (0); - } -} - -void write_tree (struct tl_combinator_tree *T, int extra, struct tree_var_value **v, int *last_var) { - assert (T); - switch (T->type) { - case type_list_item: - case type_list: - if (schema_version >= 1) { - if (extra) { - wint (schema_version >= 2 ? TLS_COMBINATOR_RIGHT_V2 : TLS_COMBINATOR_RIGHT); - } - } else { - wint (extra ? -1 : -2); - } - wint (count_list_size (T)); - write_args (T, v, last_var); - break; - case type_num_value: - wint (schema_version >= 1 ? schema_version >= 2 ? (int)TLS_NAT_CONST : (int)TLS_TREE_NAT_CONST : -4); - if (schema_version >= 2) { - wint (T->type_flags); - } else { - wll (T->type_flags); - } - break; - case type_num: - wint (schema_version >= 1 ? schema_version >= 2 ? (int)TLS_NAT_VAR : (int)TLS_TREE_NAT_VAR : -5); - if (schema_version >= 2) { - wint (T->type_flags); - } else { - wll (T->type_flags); - } - wint (tl_get_var_value_num (v, T->data)); - break; - case type_type: - if (T->act == act_array) { - write_array (T, v, last_var); - } else if (T->act == act_type || T->act == act_var || T->act == act_arg) { - write_type_rec (T, 0, v, last_var); - } else { - assert (T->act == act_opt_field); - write_opt_type (T, v, last_var); - } - break; - default: - assert (0); - } -} - -void write_type (struct tl_type *t) { - wint (schema_version >= 1 ? TLS_TYPE : 1); - wint (t->name); - wstr (t->id); - wint (t->constructors_num); - wint (t->flags); - wint (t->params_num); - wll (t->params_types); -} - -int is_builtin_type (const char *id) { - return !strcmp (id, "int") || !strcmp (id, "long") || !strcmp (id, "double") || !strcmp (id, "string"); -} - -void write_combinator (struct tl_constructor *c) { - 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 (schema_version >= 1 && is_builtin_type (c->id)) { - wint (TLS_COMBINATOR_LEFT_BUILTIN); - } else { - if (schema_version >= 1) { - wint (TLS_COMBINATOR_LEFT); - } -// wint (count_list_size (c->left)); - write_tree (c->left, 0, &T, &x); - } - } else { - if (schema_version >= 1) { - wint (TLS_COMBINATOR_LEFT); - wint (0); - } else { - wint (-11); - } - } - if (schema_version >= 1) { - wint (schema_version >= 2 ? TLS_COMBINATOR_RIGHT_V2 : TLS_COMBINATOR_RIGHT); - } - write_tree (c->right, 1, &T, &x); -} - -void write_constructor (struct tl_constructor *c) { - wint (schema_version >= 1 ? TLS_COMBINATOR : 2); - write_combinator (c); -} - -void write_function (struct tl_constructor *c) { - wint (schema_version >= 1 ? TLS_COMBINATOR : 3); - write_combinator (c); -} - -void write_type_constructors (struct tl_type *t) { - int i; - for (i = 0; i < t->constructors_num; i++) { - write_constructor (t->constructors[i]); - } -} - -int MAGIC = 0x850230aa; -void write_types (int f) { - __f = f; - if (schema_version == 1) { - wint (TLS_SCHEMA); - } else if (schema_version == 2) { - wint (TLS_SCHEMA_V2); - } else { - wint (MAGIC); - } - if (schema_version >= 1) { - wint (0); - wint (time (0)); - } - num = 0; - if (schema_version >= 1) { - wint (total_types_num); - } - tree_act_tl_type (tl_type_tree, write_type); - if (schema_version >= 1) { - wint (total_constructors_num); - } - tree_act_tl_type (tl_type_tree, write_type_constructors); - if (schema_version >= 1) { - wint (total_functions_num); - } - tree_act_tl_constructor (tl_function_tree, write_function); -} diff --git a/tl-parser.h b/tl-parser.h deleted file mode 100644 index faa142b..0000000 --- a/tl-parser.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - This file is part of tgl-libary/tlc - - Tgl-library/tlc is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - Tgl-library/tlc 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this tgl-library/tlc. If not, see . - - Copyright Vitaly Valtman 2014 - - It is derivative work of VK/KittenPHP-DB-Engine (https://github.com/vk-com/kphp-kdb/) - Copyright 2012-2013 Vkontakte Ltd - 2012-2013 Vitaliy Valtman - -*/ - -#ifndef __TL_PARSER_NEW_H__ -#define __TL_PARSER_NEW_H__ -enum lex_type { - lex_error, - lex_char, - lex_triple_minus, - lex_uc_ident, - lex_lc_ident, - lex_eof, - lex_final, - lex_new, - lex_none, - lex_num, - lex_empty -}; - - -struct curlex { - char *ptr; - int len; - enum lex_type type; - int flags; -}; - -struct parse { - char *text; - int pos; - int len; - int line; - int line_pos; - struct curlex lex; -}; - - -enum tree_type { - type_tl_program, - type_fun_declarations, - type_constr_declarations, - type_declaration, - type_combinator_decl, - type_equals, - type_partial_app_decl, - type_final_decl, - type_full_combinator_id, - type_opt_args, - type_args, - type_args1, - type_args2, - type_args3, - type_args4, - type_boxed_type_ident, - type_subexpr, - type_partial_comb_app_decl, - type_partial_type_app_decl, - type_final_new, - type_final_final, - type_final_empty, -// type_type, - type_var_ident, - type_var_ident_opt, - type_multiplicity, - type_type_term, - type_term, - type_percent, - type_result_type, - type_expr, - type_nat_term, - type_combinator_id, - type_nat_const, - type_type_ident, - type_builtin_combinator_decl, - type_exclam, - type_optional_arg_def -}; - -struct tree { - char *text; - int len; - enum tree_type type; - int lex_line; - int lex_line_pos; - int flags; - int size; - int nc; - struct tree **c; -}; - - -#define TL_ACT(x) (x == act_var ? "act_var" : x == act_field ? "act_field" : x == act_plus ? "act_plus" : x == act_type ? "act_type" : x == act_nat_const ? "act_nat_const" : x == act_array ? "act_array" : x == act_question_mark ? "act_question_mark" : \ - x == act_union ? "act_union" : x == act_arg ? "act_arg" : x == act_opt_field ? "act_opt_field" : "act_unknown") - -#define TL_TYPE(x) (x == type_num ? "type_num" : x == type_type ? "type_type" : x == type_list_item ? "type_list_item" : x == type_list ? "type_list" : x == type_num_value ? "type_num_value" : "type_unknown") -enum combinator_tree_action { - act_var, - act_field, - act_plus, - act_type, - act_nat_const, - act_array, - act_question_mark, - act_union, - act_arg, - act_opt_field -}; - -enum combinator_tree_type { - type_num, - type_num_value, - type_type, - type_list_item, - type_list -}; - -struct tl_combinator_tree { - enum combinator_tree_action act; - struct tl_combinator_tree *left, *right; - char *name; - void *data; - long long flags; - enum combinator_tree_type type; - int type_len; - long long type_flags; -}; - - -struct tl_program { - int types_num; - int functions_num; - int constructors_num; - struct tl_type **types; - struct tl_function **functions; -// struct tl_constuctor **constructors; -}; - -struct tl_type { - char *id; - char *print_id; - char *real_id; - unsigned name; - int flags; - - int params_num; - long long params_types; - - int constructors_num; - struct tl_constructor **constructors; -}; - -struct tl_constructor { - char *id; - char *print_id; - char *real_id; - unsigned name; - struct tl_type *type; - - struct tl_combinator_tree *left; - struct tl_combinator_tree *right; -}; - -struct tl_var { - char *id; - struct tl_combinator_tree *ptr; - int type; - int flags; -}; - -struct parse *tl_init_parse_file (const char *fname); -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); - -#define FLAG_BARE 1 -#define FLAG_OPT_VAR (1 << 17) -#define FLAG_EXCL (1 << 18) -#define FLAG_OPT_FIELD (1 << 20) -#define FLAG_IS_VAR (1 << 21) -#define FLAG_DEFAULT_CONSTRUCTOR (1 << 25) -#define FLAG_EMPTY (1 << 10) - -#endif diff --git a/tl-tl.h b/tl-tl.h deleted file mode 100644 index 4ee6e2e..0000000 --- a/tl-tl.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - This file is part of VK/KittenPHP-DB-Engine. - - VK/KittenPHP-DB-Engine is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - VK/KittenPHP-DB-Engine 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with VK/KittenPHP-DB-Engine. If not, see . - - This program is released under the GPL with the additional exemption - that compiling, linking, and/or using OpenSSL is allowed. - You are free to remove this exemption from derived works. - - Copyright 2012-2013 Vkontakte Ltd - 2012-2013 Vitaliy Valtman -*/ - -#ifndef __TL_TL_H__ -#define __TL_TL_H__ - -#define TLS_SCHEMA 0xf19d9e38 -#define TLS_TYPE 0x12eb4386 -#define TLS_COMBINATOR 0x5c0a1ed5 -#define TLS_COMBINATOR_LEFT_BUILTIN 0xcd211f63 -#define TLS_COMBINATOR_LEFT 0x4c12c6d9 -#define TLS_COMBINATOR_RIGHT 0xd325b367 -#define TLS_ARG 0x46afe232 -#define TLS_TREE_NAT_CONST 0xc09f07d7 -#define TLS_TREE_NAT_VAR 0x90ea6f58 -#define TLS_TREE_TYPE_VAR 0x1caa237a -#define TLS_TREE_ARRAY 0x80479360 -#define TLS_TREE_TYPE 0x10f32190 - -#define TLS_SCHEMA_V2 0x3a2f9be2 -#define TLS_COMBINATOR_RIGHT_V2 0x2c064372 -#define TLS_ARG_V2 0x29dfe61b -#define TLS_EXPR_TYPE 0xecc9da78 -#define TLS_EXPR_NAT 0xdcb49bd8 - -#define TLS_NAT_CONST 0xdcb49bd8 -#define TLS_NAT_VAR 0x4e8a14f0 -#define TLS_TYPE_VAR 0x0142ceae -#define TLS_ARRAY 0xd9fb20de -#define TLS_TYPE_EXPR 0xc1863d08 -#endif diff --git a/tlc.c b/tlc.c deleted file mode 100644 index 451e612..0000000 --- a/tlc.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - This file is part of tgl-libary/tlc - - Tgl-library/tlc is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - Tgl-library/tlc 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this tgl-library/tlc. If not, see . - - Copyright Vitaly Valtman 2014 - - It is derivative work of VK/KittenPHP-DB-Engine (https://github.com/vk-com/kphp-kdb/) - Copyright 2012-2013 Vkontakte Ltd - 2012-2013 Vitaliy Valtman - -*/ - -#include -#include -#include - -#include "tl-parser.h" - -#include -#include -#include -#include - -#include -#include "config.h" -#include -#include - -int verbosity; -int output_expressions; -int schema_version = 2; -void usage (void) { - printf ("usage: tlc [-v] [-h] \n" - "\tTL compiler\n" - "\t-v\toutput statistical and debug information into stderr\n" - "\t-E\twhenever is possible output to stdout expressions\n" - "\t-e \texport serialized schema to file\n" - "\t-w\t custom version of serialized schema (0 - very old, 1 - old, 2 - current (default))\n" - ); - exit (2); -} - -int vkext_write (const char *filename) { - int f = open (filename, O_CREAT | O_WRONLY | O_TRUNC, 0640); - assert (f >= 0); - write_types (f); - close (f); - return 0; -} - -void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2))); -void logprintf (const char *format __attribute__ ((unused)), ...) { - va_list ap; - va_start (ap, format); - vfprintf (stderr, format, ap); - va_end (ap); -} - -void hexdump (int *in_ptr, int *in_end) { - int *ptr = in_ptr; - while (ptr < in_end) { printf (" %08x", *(ptr ++)); } - printf ("\n"); -} - -#ifdef HAVE_EXECINFO_H -void print_backtrace (void) { - void *buffer[255]; - const int calls = backtrace (buffer, sizeof (buffer) / sizeof (void *)); - backtrace_symbols_fd (buffer, calls, 1); -} -#else -void print_backtrace (void) { - if (write (1, "No libexec. Backtrace disabled\n", 32) < 0) { - // Sad thing - } -} -#endif - -void sig_segv_handler (int signum __attribute__ ((unused))) { - if (write (1, "SIGSEGV received\n", 18) < 0) { - // Sad thing - } - print_backtrace (); - exit (EXIT_FAILURE); -} - -void sig_abrt_handler (int signum __attribute__ ((unused))) { - if (write (1, "SIGABRT received\n", 18) < 0) { - // Sad thing - } - print_backtrace (); - exit (EXIT_FAILURE); -} - -int main (int argc, char **argv) { - signal (SIGSEGV, sig_segv_handler); - signal (SIGABRT, sig_abrt_handler); - int i; - char *vkext_file = 0; - while ((i = getopt (argc, argv, "Ehve:w:")) != -1) { - switch (i) { - case 'E': - output_expressions++; - break; - case 'h': - usage (); - return 2; - case 'e': - vkext_file = optarg; - break; - case 'w': - schema_version = atoi (optarg); - break; - case 'v': - verbosity++; - break; - } - } - - if (argc != optind + 1) { - usage (); - } - - - struct parse *P = tl_init_parse_file (argv[optind]); - if (!P) { - return 0; - } - struct tree *T; - if (!(T = tl_parse_lex (P))) { - fprintf (stderr, "Error in parse:\n"); - tl_print_parse_error (); - return 0; - } else { - if (verbosity) { - fprintf (stderr, "Parse ok\n"); - } - if (!tl_parse (T)) { - if (verbosity) { - fprintf (stderr, "Fail\n"); - } - return 1; - } else { - if (verbosity) { - fprintf (stderr, "Ok\n"); - } - } - } - if (vkext_file) { - vkext_write (vkext_file); - } - return 0; -} diff --git a/tree.h b/tree.h deleted file mode 100644 index 2f1c284..0000000 --- a/tree.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - This file is part of tgl-library - - This 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. - - This 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 this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - Copyright Vitaly Valtman 2013-2014 -*/ -#ifndef __TREE_H__ -#define __TREE_H__ -#include - -#include -#include -#include "tools.h" - -#pragma pack(push,4) -#define DEFINE_TREE(X_NAME, X_TYPE, X_CMP, X_UNSET) \ -struct tree_ ## X_NAME { \ - struct tree_ ## X_NAME *left, *right;\ - X_TYPE x;\ - int y;\ -};\ -\ -static struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\ - struct tree_ ## X_NAME *T = talloc (sizeof (*T));\ - T->x = x;\ - T->y = y;\ - T->left = T->right = 0;\ - return T;\ -}\ -\ -static void delete_tree_node_ ## X_NAME (struct tree_ ## X_NAME *T) {\ - tfree (T, sizeof (*T));\ -}\ -\ -static void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ## X_NAME **L, struct tree_ ## X_NAME **R) {\ - if (!T) {\ - *L = *R = 0;\ - } else {\ - int c = X_CMP (x, T->x);\ - if (c < 0) {\ - tree_split_ ## X_NAME (T->left, x, L, &T->left);\ - *R = T;\ - } else {\ - tree_split_ ## X_NAME (T->right, x, &T->right, R);\ - *L = T;\ - }\ - }\ -}\ -\ -static struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) __attribute__ ((warn_unused_result,unused));\ -static struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) {\ - if (!T) {\ - return new_tree_node_ ## X_NAME (x, y);\ - } else {\ - if (y > T->y) {\ - struct tree_ ## X_NAME *N = new_tree_node_ ## X_NAME (x, y);\ - tree_split_ ## X_NAME (T, x, &N->left, &N->right);\ - return N;\ - } else {\ - int c = X_CMP (x, T->x);\ - assert (c);\ - if (c < 0) { \ - T->left = tree_insert_ ## X_NAME (T->left, x, y);\ - } else { \ - T->right = tree_insert_ ## X_NAME (T->right, x, y);\ - } \ - return T; \ - }\ - }\ -}\ -\ -static struct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct tree_ ## X_NAME *R) {\ - if (!L || !R) {\ - return L ? L : R;\ - } else {\ - if (L->y > R->y) {\ - L->right = tree_merge_ ## X_NAME (L->right, R);\ - return L;\ - } else {\ - R->left = tree_merge_ ## X_NAME (L, R->left);\ - return R;\ - }\ - }\ -}\ -\ -static struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) __attribute__ ((warn_unused_result,unused));\ -static struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\ - assert (T);\ - int c = X_CMP (x, T->x);\ - if (!c) {\ - struct tree_ ## X_NAME *N = tree_merge_ ## X_NAME (T->left, T->right);\ - delete_tree_node_ ## X_NAME (T);\ - return N;\ - } else {\ - if (c < 0) { \ - T->left = tree_delete_ ## X_NAME (T->left, x); \ - } else { \ - T->right = tree_delete_ ## X_NAME (T->right, x); \ - } \ - return T; \ - }\ -}\ -\ -static X_TYPE tree_get_min_ ## X_NAME (struct tree_ ## X_NAME *t) __attribute__ ((unused));\ -static X_TYPE tree_get_min_ ## X_NAME (struct tree_ ## X_NAME *T) {\ - if (!T) { return X_UNSET; } \ - while (T->left) { T = T->left; }\ - return T->x; \ -} \ -\ -static X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) __attribute__ ((unused));\ -static X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\ - int c;\ - while (T && (c = X_CMP (x, T->x))) {\ - T = (c < 0 ? T->left : T->right);\ - }\ - return T ? T->x : X_UNSET;\ -}\ -\ -static void tree_act_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE)) __attribute__ ((unused));\ -static void tree_act_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE)) {\ - if (!T) { return; } \ - tree_act_ ## X_NAME (T->left, act); \ - act (T->x); \ - tree_act_ ## X_NAME (T->right, act); \ -}\ -\ -static void tree_act_ex_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE, void *), void *extra) __attribute__ ((unused));\ -static void tree_act_ex_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE, void *), void *extra) {\ - if (!T) { return; } \ - tree_act_ex_ ## X_NAME (T->left, act, extra); \ - act (T->x, extra); \ - tree_act_ex_ ## X_NAME (T->right, act, extra); \ -}\ -\ -static int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) __attribute__ ((unused));\ -static int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) { \ - if (!T) { return 0; }\ - return 1 + tree_count_ ## X_NAME (T->left) + tree_count_ ## X_NAME (T->right); \ -}\ -static void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) __attribute__ ((unused));\ -static void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \ - if (!T) { return; }\ - if (T->left) { \ - assert (T->left->y <= T->y);\ - assert (X_CMP (T->left->x, T->x) < 0); \ - }\ - if (T->right) { \ - assert (T->right->y <= T->y);\ - assert (X_CMP (T->right->x, T->x) > 0); \ - }\ - tree_check_ ## X_NAME (T->left); \ - tree_check_ ## X_NAME (T->right); \ -}\ -static struct tree_ ## X_NAME *tree_clear_ ## X_NAME (struct tree_ ## X_NAME *T) __attribute__ ((unused));\ -static struct tree_ ## X_NAME *tree_clear_ ## X_NAME (struct tree_ ## X_NAME *T) { \ - if (!T) { return 0; }\ - tree_clear_ ## X_NAME (T->left); \ - tree_clear_ ## X_NAME (T->right); \ - delete_tree_node_ ## X_NAME (T); \ - return 0; \ -} \ - -#define int_cmp(a,b) ((a) - (b)) -#pragma pack(pop) -#endif