Deleted unneeded files
This commit is contained in:
parent
a9b5fbe642
commit
ee45b627ae
@ -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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
440
auto-static.c
440
auto-static.c
@ -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 <string.h>
|
||||
|
||||
#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
|
48
auto.h
48
auto.h
@ -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
|
102
binlog.h
102
binlog.h
@ -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
|
@ -1,73 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#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;
|
||||
}
|
3077
tl-parser.c
3077
tl-parser.c
File diff suppressed because it is too large
Load Diff
206
tl-parser.h
206
tl-parser.h
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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
|
52
tl-tl.h
52
tl-tl.h
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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
|
165
tlc.c
165
tlc.c
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "tl-parser.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include "config.h"
|
||||
#include <execinfo.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
int verbosity;
|
||||
int output_expressions;
|
||||
int schema_version = 2;
|
||||
void usage (void) {
|
||||
printf ("usage: tlc [-v] [-h] <TL-schema-file>\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 <file>\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;
|
||||
}
|
179
tree.h
179
tree.h
@ -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 <stdio.h>
|
||||
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#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
|
Loading…
x
Reference in New Issue
Block a user