Commit 88d42058 authored by Vysheng's avatar Vysheng

Added support for direct queries enter

parent 42bde800
......@@ -18,50 +18,231 @@
Copyright Vitaly Valtman 2014
*/
int skip_double (void) {
if (in_ptr + 2 <= in_end) {
in_ptr += 2;
return 0;
} else {
return -1;
#include "mtproto-common.h"
#include <string.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;
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);
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;
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;
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));
R->type = malloc (sizeof (*R->type));
memcpy (R->type, P->type, sizeof (*P->type));
R->type->id = strdup (P->type->id);
if (P->type->params_num) {
R->params = malloc (sizeof (void *) * P->type->params_num);
int i;
for (i = 0; i < P->type->params_num; i++) {
R->params[i] = paramed_type_dup (P->params[i]);
}
}
return R;
}
int skip_long (void) {
if (in_ptr + 2 <= in_end) {
in_ptr += 2;
return 0;
} else {
return -1;
static void print_offset (void) {
int i;
for (i = 0; i < multiline_offset; i++) {
printf (" ");
}
}
int skip_int (void) {
if (in_ptr + 1 <= in_end) {
in_ptr += 1;
return 0;
} else {
return -1;
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 ++;
}
}
int skip_string (void) {
if (in_ptr == in_end) { return -1; }
unsigned len = *(unsigned char *)in_ptr;
if (len == 0xff) { return -1; }
if (len < 0xfe) {
unsigned size = (len + 4) >> 2;
if (in_ptr + size <= in_end) {
in_ptr += size;
return 0;
static int is_letter (char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-';
}
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 {
return -1;
cur_token_real_len = buffer_pos - cur_token;
cur_token_len = -3;
}
return;
} else if (c == '"') {
cur_token_quoted = 1;
cur_token = buffer_pos ++;
while (buffer_pos < buffer_end && *buffer_pos != '"') {
buffer_pos ++;
}
if (*buffer_pos == '"') {
buffer_pos ++;
cur_token_len = buffer_pos - cur_token - 2;
cur_token ++;
} else {
cur_token_len = -2;
}
return;
} else {
len = (*(unsigned *)in_ptr) >> 8;
unsigned size = (len + 7) >> 2;
if (in_ptr + size <= in_end) {
in_ptr += size;
return 0;
if (c) {
cur_token = buffer_pos ++;
cur_token_len = 1;
} else {
cur_token_len = -3;
cur_token_real_len = 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 ();
autocomplete_function_any ();
}
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);
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)\
char *tglf_extf_fetch (struct paramed_type *T) {
out_buf_pos = 0;
fetch_type_any (T);
return out_buf;
}
......@@ -20,13 +20,15 @@
#ifndef __AUTO_H__
#define __AUTO_H__
struct tl_type {
struct tl_type_descr {
unsigned name;
char *id;
int params_num;
long long params_types;
};
struct paramed_type {
struct tl_type *type;
struct tl_type_descr *type;
struct paramed_type **params;
};
......
......@@ -20,6 +20,7 @@
Copyright 2012-2013 Vkontakte Ltd
2012-2013 Vitaliy Valtman
*/
#define _GNU_SOURCE
#include <stdio.h>
......@@ -64,6 +65,19 @@ void tl_type_insert_by_name (struct tl_type *t) {
type_tree = tree_insert_tl_type (type_tree, t, lrand48 ());
}
int is_empty (struct tl_type *t) {
if (t->name == NAME_INT || t->name == NAME_LONG || t->name == NAME_DOUBLE || t->name == NAME_STRING) { return 1; }
if (t->constructors_num != 1) { return 0; }
int count = 0;
int i;
struct tl_combinator *c = t->constructors[0];
for (i = 0; i < c->args_num; i++) {
if (!(c->args[i]->flags & FLAG_OPT_VAR)) { count ++; }
}
return count == 1;
}
static char buf[1 << 20];
int buf_size;
int *buf_ptr = (int *)buf;
......@@ -216,7 +230,7 @@ struct tl_tree *read_num_const (int *var_num) {
}
int gen_uni (struct tl_tree *t, char *cur_name, int *vars, int first) {
int gen_uni_skip (struct tl_tree *t, char *cur_name, int *vars, int first) {
assert (t);
int x = TL_TREE_METHODS (t)->type (t);
int l = 0;
......@@ -236,7 +250,7 @@ int gen_uni (struct tl_tree *t, char *cur_name, int *vars, int first) {
}
for (i = 0; i < t1->children_num; i++) {
sprintf (cur_name + L, "->params[%d]", i);
gen_uni (t1->children[i], cur_name, vars, 0);
gen_uni_skip (t1->children[i], cur_name, vars, 0);
cur_name[L] = 0;
}
return 0;
......@@ -248,11 +262,11 @@ int gen_uni (struct tl_tree *t, char *cur_name, int *vars, int first) {
t2 = (void *)t;
sprintf (cur_name + L, "->params[0]");
y = gen_uni (t2->multiplicity, cur_name, vars, 0);
y = gen_uni_skip (t2->multiplicity, cur_name, vars, 0);
cur_name[L] = 0;
sprintf (cur_name + L, "->params[1]");
y += gen_uni (t2->args[0]->type, cur_name, vars, 0);
y += gen_uni_skip (t2->args[0]->type, cur_name, vars, 0);
cur_name[L] = 0;
return 0;
case NODE_TYPE_VAR_TYPE:
......@@ -305,9 +319,9 @@ int gen_create (struct tl_tree *t, int *vars, int offset) {
print_offset (offset + 2);
t1 = (void *)t;
if (t1->self.flags & FLAG_BARE) {
printf (".type = &(struct tl_type) {.name = 0x%08x, .id = \"Bare_%s\"},\n", ~t1->type->name, t1->type->id);
printf (".type = &(struct tl_type_descr) {.name = 0x%08x, .id = \"Bare_%s\", .params_num = %d, .params_types = %lld},\n", ~t1->type->name, t1->type->id, t1->type->arity, t1->type->params_types);
} else {
printf (".type = &(struct tl_type) {.name = 0x%08x, .id = \"%s\"},\n", t1->type->name, t1->type->id);
printf (".type = &(struct tl_type_descr) {.name = 0x%08x, .id = \"%s\", .params_num = %d, .params_types = %lld},\n", t1->type->name, t1->type->id, t1->type->arity, t1->type->params_types);
}
if (t1->children_num) {
print_offset (offset + 2);
......@@ -334,7 +348,7 @@ int gen_create (struct tl_tree *t, int *vars, int offset) {
printf ("&(struct paramed_type){\n");
print_offset (offset + 2);
t2 = (void *)t;
printf (".type = &(struct tl_type) {.name = NAME_ARRAY, .id = \"array\"},\n");
printf (".type = &(struct tl_type_descr) {.name = NAME_ARRAY, .id = \"array\", .params_num = 2, .params_types = 1},\n");
print_offset (offset + 2);
printf (".params = (struct paramed_type **){\n");
gen_create (t2->multiplicity, vars, offset + 4);
......@@ -360,7 +374,7 @@ int gen_create (struct tl_tree *t, int *vars, int offset) {
}
}
int gen_field_fetch (struct arg *arg, int *vars, int num) {
int gen_field_skip (struct arg *arg, int *vars, int num) {
assert (arg);
char *offset = " ";
int o = 0;
......@@ -378,12 +392,12 @@ int gen_field_fetch (struct arg *arg, int *vars, int num) {
} else {
assert (t == NAME_VAR_NUM);
if (vars[arg->var_num] == 0) {
printf ("%sstruct paramed_type *var%d = INT2PTR (*in_ptr);\n", offset, arg->var_num);
printf ("%sif (skip_int () < 0) { return -1;}\n", offset);
printf ("%sif (in_remaining () < 4) { return -1;}\n", offset);
printf ("%sstruct paramed_type *var%d = INT2PTR (fetch_int ());\n", offset, arg->var_num);
vars[arg->var_num] = 2;
} else if (vars[arg->var_num] == 2) {
printf ("%sif (vars%d != INT2PTR (*in_ptr)) { return -1; }\n", offset, arg->var_num);
printf ("%sif (skip_int () < 0) { return -1;}\n", offset);
printf ("%sif (in_remaining () < 4) { return -1;}\n", offset);
printf ("%sif (vars%d != INT2PTR (fetch_int ())) { return -1; }\n", offset, arg->var_num);
} else {
assert (0);
return -1;
......@@ -423,49 +437,491 @@ int gen_field_fetch (struct arg *arg, int *vars, int num) {
return 0;
}
void gen_constructor_fetch (struct tl_combinator *c) {
int gen_field_fetch (struct arg *arg, int *vars, int num, int empty) {
assert (arg);
char *offset = " ";
int o = 0;
if (arg->exist_var_num >= 0) {
printf (" if (PTR2INT (var%d) & (1 << %d)) {\n", arg->exist_var_num, arg->exist_var_bit);
offset = " ";
o = 2;
}
if (!empty) {
printf("%sif (multiline_output >= 2) { print_offset (); }\n", offset);
}
if (arg->id && strlen (arg->id) && !empty) {
printf ("%sif (!disable_field_names) { eprintf (\" %s :\"); }\n", offset, arg->id);
}
if (arg->var_num >= 0) {
assert (TL_TREE_METHODS (arg->type)->type (arg->type) == NODE_TYPE_TYPE);
int t = ((struct tl_tree_type *)arg->type)->type->name;
if (t == NAME_VAR_TYPE) {
fprintf (stderr, "Not supported yet\n");
assert (0);
} else {
assert (t == NAME_VAR_NUM);
if (vars[arg->var_num] == 0) {
printf ("%sif (in_remaining () < 4) { return -1;}\n", offset);
printf ("%seprintf (\" %%d\", prefetch_int ());\n", offset);
printf ("%sstruct paramed_type *var%d = INT2PTR (fetch_int ());\n", offset, arg->var_num);
vars[arg->var_num] = 2;
} else if (vars[arg->var_num] == 2) {
printf ("%sif (in_remaining () < 4) { return -1;}\n", offset);
printf ("%seprintf (\" %%d\", prefetch_int ());\n", offset);
printf ("%sif (vars%d != INT2PTR (fetch_int ())) { return -1; }\n", offset, arg->var_num);
} else {
assert (0);
return -1;
}
}
} else {
int t = TL_TREE_METHODS (arg->type)->type (arg->type);
if (t == NODE_TYPE_TYPE || t == NODE_TYPE_VAR_TYPE) {
printf ("%sstruct paramed_type *field%d = \n", offset, num);
assert (gen_create (arg->type, vars, 2 + o) >= 0);
printf (";\n");
int bare = arg->flags & FLAG_BARE;
if (!bare && t == NODE_TYPE_TYPE) {
bare = ((struct tl_tree_type *)arg->type)->self.flags & FLAG_BARE;
}
if (!bare) {
printf ("%sif (fetch_type_%s (field%d) < 0) { return -1;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num);
} else {
printf ("%sif (fetch_type_bare_%s (field%d) < 0) { return -1;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num);
}
} else {
assert (t == NODE_TYPE_ARRAY);
printf ("%sint multiplicity%d = PTR2INT (\n", offset, num);
assert (gen_create (((struct tl_tree_array *)arg->type)->multiplicity, vars, 2 + o) >= 0);
printf ("%s);\n", offset);
printf ("%sstruct paramed_type *field%d = \n", offset, num);
assert (gen_create (((struct tl_tree_array *)arg->type)->args[0]->type, vars, 2 + o) >= 0);
printf (";\n");
printf ("%seprintf (\" [\");\n", offset);
printf ("%sif (multiline_output >= 1) { eprintf (\"\\n\"); }\n", offset);
printf ("%sif (multiline_output >= 1) { multiline_offset += multiline_offset_size;}\n", offset);
printf ("%swhile (multiplicity%d -- > 0) {\n", offset, num);
printf ("%s if (multiline_output >= 1) { print_offset (); }\n", offset);
printf ("%s if (fetch_type_%s (field%d) < 0) { return -1;}\n", offset, "any", num);
printf ("%s if (multiline_output >= 1) { eprintf (\"\\n\"); }\n", offset);
printf ("%s}\n", offset);
printf ("%sif (multiline_output >= 1) { multiline_offset -= multiline_offset_size; print_offset ();}\n", offset);
printf ("%seprintf (\" ]\");\n", offset);
}
}
if (!empty) {
printf("%sif (multiline_output >= 2) { eprintf (\"\\n\"); }\n", offset);
}
if (arg->exist_var_num >= 0) {
printf (" }\n");
}
return 0;
}
int gen_field_store (struct arg *arg, int *vars, int num, int from_func) {
assert (arg);
char *offset = " ";
int o = 0;
if (arg->exist_var_num >= 0) {
printf (" if (PTR2INT (var%d) & (1 << %d)) {\n", arg->exist_var_num, arg->exist_var_bit);
offset = " ";
o = 2;
}
char *fail = from_func ? "0" : "-1";
char *expect = from_func ? "expect_token_ptr" : "expect_token";
if (arg->id && strlen (arg->id) > 0) {
printf ("%sif (cur_token_len >= 0 && cur_token_len == %d && !cur_token_quoted && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", offset, (int)(strlen (arg->id)), arg->id);
printf ("%s local_next_token ();\n", offset);
printf ("%s %s (\":\", 1);\n", offset, expect);
printf ("%s}\n", offset);
}
if (arg->var_num >= 0) {
printf ("%sif (cur_token_len < 0) { return %s; }\n", offset, fail);
assert (TL_TREE_METHODS (arg->type)->type (arg->type) == NODE_TYPE_TYPE);
int t = ((struct tl_tree_type *)arg->type)->type->name;
if (t == NAME_VAR_TYPE) {
fprintf (stderr, "Not supported yet\n");
assert (0);
} else {
assert (t == NAME_VAR_NUM);
if (vars[arg->var_num] == 0) {
printf ("%sif (!is_int ()) { return %s;}\n", offset, fail);
printf ("%sstruct paramed_type *var%d = INT2PTR (get_int ());\n", offset, arg->var_num);
printf ("%sout_int (get_int ());\n", offset);
printf ("%sassert (var%d);\n", offset, arg->var_num);
printf ("%slocal_next_token ();\n", offset);
vars[arg->var_num] = 2;
} else if (vars[arg->var_num] == 2) {
printf ("%sif (!is_int ()) { return %s;}\n", offset, fail);
printf ("%sif (vars%d != INT2PTR (get_int ())) { return %s; }\n", offset, arg->var_num, fail);
printf ("%sout_int (get_int ());\n", offset);
printf ("%slocal_next_token ();\n", offset);
} else {
assert (0);
return -1;
}
}
} else {
int t = TL_TREE_METHODS (arg->type)->type (arg->type);
if (t == NODE_TYPE_TYPE || t == NODE_TYPE_VAR_TYPE) {
printf ("%sstruct paramed_type *field%d = \n", offset, num);
assert (gen_create (arg->type, vars, 2 + o) >= 0);
printf (";\n");
int bare = arg->flags & FLAG_BARE;
if (!bare && t == NODE_TYPE_TYPE) {
bare = ((struct tl_tree_type *)arg->type)->self.flags & FLAG_BARE;
}
if (!bare) {
printf ("%sif (store_type_%s (field%d) < 0) { return %s;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num, fail);
} else {
printf ("%sif (store_type_bare_%s (field%d) < 0) { return %s;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num, fail);
}
} else {
printf ("%s%s (\"[\", 1);\n", offset, expect);
assert (t == NODE_TYPE_ARRAY);
printf ("%sint multiplicity%d = PTR2INT (\n", offset, num);
assert (gen_create (((struct tl_tree_array *)arg->type)->multiplicity, vars, 2 + o) >= 0);
printf ("%s);\n", offset);
printf ("%sstruct paramed_type *field%d = \n", offset, num);
assert (gen_create (((struct tl_tree_array *)arg->type)->args[0]->type, vars, 2 + o) >= 0);
printf (";\n");
printf ("%swhile (multiplicity%d -- > 0) {\n", offset, num);
printf ("%s if (store_type_%s (field%d) < 0) { return %s;}\n", offset, "any", num, fail);
printf ("%s}\n", offset);
printf ("%s%s (\"]\", 1);\n", offset, expect);
}
}
if (arg->exist_var_num >= 0) {
printf (" }\n");
}
return 0;
}
int gen_field_autocomplete (struct arg *arg, int *vars, int num, int from_func) {
assert (arg);
char *offset = " ";
int o = 0;
if (arg->exist_var_num >= 0) {
printf (" if (PTR2INT (var%d) & (1 << %d)) {\n", arg->exist_var_num, arg->exist_var_bit);
offset = " ";
o = 2;
}
char *fail = from_func ? "0" : "-1";
char *expect = from_func ? "expect_token_ptr_autocomplete" : "expect_token_autocomplete";
if (arg->id && strlen (arg->id) > 0) {
printf ("%sif (cur_token_len == -3 && cur_token_real_len <= %d && !cur_token_quoted && !memcmp (cur_token, \"%s\", cur_token_real_len)) {\n", offset, (int)(strlen (arg->id)), arg->id);
printf ("%s set_autocomplete_string (\"%s\");\n", offset, arg->id);
printf ("%s return %s;\n", offset, fail);
printf ("%s}\n", offset);
printf ("%sif (cur_token_len >= 0 && cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", offset, (int)(strlen (arg->id)), arg->id);
printf ("%s local_next_token ();\n", offset);
printf ("%s %s (\":\", 1);\n", offset, expect);
printf ("%s}\n", offset);
}
if (arg->var_num >= 0) {
printf ("%sif (cur_token_len < 0) { return %s; }\n", offset, fail);
assert (TL_TREE_METHODS (arg->type)->type (arg->type) == NODE_TYPE_TYPE);
int t = ((struct tl_tree_type *)arg->type)->type->name;
if (t == NAME_VAR_TYPE) {
fprintf (stderr, "Not supported yet\n");
assert (0);
} else {
assert (t == NAME_VAR_NUM);
if (vars[arg->var_num] == 0) {
printf ("%sif (!is_int ()) { return %s;}\n", offset, fail);
printf ("%sstruct paramed_type *var%d = INT2PTR (get_int ());\n", offset, arg->var_num);
printf ("%sassert (var%d);\n", offset, arg->var_num);
printf ("%slocal_next_token ();\n", offset);
vars[arg->var_num] = 2;
} else if (vars[arg->var_num] == 2) {
printf ("%sif (!is_int ()) { return %s;}\n", offset, fail);
printf ("%sif (vars%d != INT2PTR (get_int ())) { return %s; }\n", offset, arg->var_num, fail);
printf ("%slocal_next_token ();\n", offset);
} else {
assert (0);
return -1;
}
}
} else {
int t = TL_TREE_METHODS (arg->type)->type (arg->type);
if (t == NODE_TYPE_TYPE || t == NODE_TYPE_VAR_TYPE) {
printf ("%sstruct paramed_type *field%d = \n", offset, num);
assert (gen_create (arg->type, vars, 2 + o) >= 0);
printf (";\n");
int bare = arg->flags & FLAG_BARE;
if (!bare && t == NODE_TYPE_TYPE) {
bare = ((struct tl_tree_type *)arg->type)->self.flags & FLAG_BARE;
}
if (!bare) {
printf ("%sif (autocomplete_type_%s (field%d) < 0) { return %s;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num, fail);
} else {
printf ("%sif (autocomplete_type_bare_%s (field%d) < 0) { return %s;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num, fail);
}
} else {
printf ("%s%s (\"[\", 1);\n", offset, expect);
assert (t == NODE_TYPE_ARRAY);
printf ("%sint multiplicity%d = PTR2INT (\n", offset, num);
assert (gen_create (((struct tl_tree_array *)arg->type)->multiplicity, vars, 2 + o) >= 0);
printf ("%s);\n", offset);
printf ("%sstruct paramed_type *field%d = \n", offset, num);
assert (gen_create (((struct tl_tree_array *)arg->type)->args[0]->type, vars, 2 + o) >= 0);
printf (";\n");
printf ("%swhile (multiplicity%d -- > 0) {\n", offset, num);
printf ("%s if (autocomplete_type_%s (field%d) < 0) { return %s;}\n", offset, "any", num, fail);
printf ("%s}\n", offset);
printf ("%s%s (\"]\", 1);\n", offset, expect);
}
}
if (arg->exist_var_num >= 0) {
printf (" }\n");
}
return 0;
}
void gen_constructor_skip (struct tl_combinator *c) {
printf ("int skip_constructor_%s (struct paramed_type *T) {\n", c->print_id);
int i;
for (i = 0; i < c->args_num; i++) if (c->args[i]->flags & FLAG_EXCL) {
printf (" return -1;\n");
printf ("}\n");
return;
}
static char s[10000];
sprintf (s, "T");
int *vars = malloc0 (c->var_num * 4);;
gen_uni (c->result, s, vars, 1);
gen_uni_skip (c->result, s, vars, 1);
if (c->name == NAME_INT) {
printf (" if (skip_int () < 0) { return -1; }\n");
printf (" if (in_remaining () < 4) { return -1;}\n");
printf (" fetch_int ();\n");
printf (" return 0;\n");
printf ("}\n");
return;
} else if (c->name == NAME_LONG) {
printf (" if (skip_long () < 0) { return -1; }\n");
printf (" if (in_remaining () < 8) { return -1;}\n");
printf (" fetch_long ();\n");
printf (" return 0;\n");
printf ("}\n");
return;
} else if (c->name == NAME_STRING) {
printf (" if (skip_string () < 0) { return -1; }\n");
printf (" int l = prefetch_strlen ();\n");
printf (" if (l < 0) { return -1;}\n");
printf (" fetch_str (l);\n");
printf (" return 0;\n");
printf ("}\n");
return;
} else if (c->name == NAME_DOUBLE) {
printf (" if (skip_double () < 0) { return -1; }\n");
printf (" if (in_remaining () < 8) { return -1;}\n");
printf (" fetch_double ();\n");
printf (" return 0;\n");
printf ("}\n");
return;
}
for (i = 0; i < c->args_num; i++) if (!(c->args[i]->flags & FLAG_OPT_VAR)) {
assert (gen_field_skip (c->args[i], vars, i + 1) >= 0);
}
free (vars);
printf (" return 0;\n");
printf ("}\n");
}
void gen_constructor_fetch (struct tl_combinator *c) {
printf ("int fetch_constructor_%s (struct paramed_type *T) {\n", c->print_id);
int i;
for (i = 0; i < c->args_num; i++) if (c->args[i]->flags & FLAG_EXCL) {
printf (" return -1;\n");
printf ("}\n");
return;
}
static char s[10000];
sprintf (s, "T");
int *vars = malloc0 (c->var_num * 4);;
gen_uni_skip (c->result, s, vars, 1);
if (c->name == NAME_INT) {
printf (" if (in_remaining () < 4) { return -1;}\n");
printf (" eprintf (\" %%d\", fetch_int ());\n");
printf (" return 0;\n");
printf ("}\n");
return;
} else if (c->name == NAME_LONG) {
printf (" if (in_remaining () < 8) { return -1;}\n");
printf (" eprintf (\" %%lld\", fetch_long ());\n");
printf (" return 0;\n");
printf ("}\n");
return;
} else if (c->name == NAME_STRING) {
printf (" static char buf[1 << 22];\n");
printf (" int l = prefetch_strlen ();\n");
printf (" if (l < 0 || (l >= (1 << 22) - 2)) { return -1; }\n");
printf (" memcpy (buf, fetch_str (l), l);\n");
printf (" buf[l] = 0;\n");
printf (" eprintf (\" \\\"%%s\\\"\", buf);\n");
printf (" return 0;\n");
printf ("}\n");
return;
} else if (c->name == NAME_DOUBLE) {
printf (" if (in_remaining () < 8) { return -1;}\n");
printf (" eprintf (\" %%lf\", fetch_double ());\n");
printf (" return 0;\n");
printf ("}\n");
return;
}
assert (c->result->methods->type (c->result) == NODE_TYPE_TYPE);
int empty = is_empty (((struct tl_tree_type *)c->result)->type);
if (!empty) {
printf (" eprintf (\" %s\");\n", c->id);
printf (" if (multiline_output >= 2) { eprintf (\"\\n\"); }\n");
}
for (i = 0; i < c->args_num; i++) if (!(c->args[i]->flags & FLAG_OPT_VAR)) {
assert (gen_field_fetch (c->args[i], vars, i + 1) >= 0);
assert (gen_field_fetch (c->args[i], vars, i + 1, empty) >= 0);
}
free (vars);
printf (" return 0;\n");
printf ("}\n");
}
void gen_type_fetch (struct tl_type *t) {
void gen_constructor_store (struct tl_combinator *c) {
printf ("int store_constructor_%s (struct paramed_type *T) {\n", c->print_id);
int i;
for (i = 0; i < c->args_num; i++) if (c->args[i]->flags & FLAG_EXCL) {
printf (" return -1;\n");
printf ("}\n");
return;
}
static char s[10000];
sprintf (s, "T");
int *vars = malloc0 (c->var_num * 4);;
gen_uni_skip (c->result, s, vars, 1);
if (c->name == NAME_INT) {
printf (" if (is_int ()) {\n");
printf (" out_int (get_int ());\n");
printf (" local_next_token ();\n");
printf (" return 0;\n");
printf (" } else {\n");
printf (" return -1;\n");
printf (" }\n");
printf ("}\n");
return;
} else if (c->name == NAME_LONG) {
printf (" if (is_int ()) {\n");
printf (" out_long (get_int ());\n");
printf (" local_next_token ();\n");
printf (" return 0;\n");
printf (" } else {\n");
printf (" return -1;\n");
printf (" }\n");
printf ("}\n");
return;
} else if (c->name == NAME_STRING) {
printf (" if (cur_token_len >= 0) {\n");
printf (" out_cstring (cur_token, cur_token_len);\n");
printf (" local_next_token ();\n");
printf (" return 0;\n");
printf (" } else {\n");
printf (" return -1;\n");
printf (" }\n");
printf ("}\n");
return;
} else if (c->name == NAME_DOUBLE) {
printf (" if (is_double ()) {\n");
printf (" out_double (get_double());\n");
printf (" local_next_token ();\n");
printf (" return 0;\n");
printf (" } else {\n");
printf (" return -1;\n");
printf (" }\n");
printf ("}\n");
return;
}
for (i = 0; i < c->args_num; i++) if (!(c->args[i]->flags & FLAG_OPT_VAR)) {
assert (gen_field_store (c->args[i], vars, i + 1, 0) >= 0);
}
free (vars);
printf (" return 0;\n");
printf ("}\n");
}
void gen_constructor_autocomplete (struct tl_combinator *c) {
printf ("int autocomplete_constructor_%s (struct paramed_type *T) {\n", c->print_id);
int i;
for (i = 0; i < c->args_num; i++) if (c->args[i]->flags & FLAG_EXCL) {
printf (" return -1;\n");
printf ("}\n");
return;
}
static char s[10000];
sprintf (s, "T");
int *vars = malloc0 (c->var_num * 4);;
gen_uni_skip (c->result, s, vars, 1);
if (c->name == NAME_INT) {
printf (" if (is_int ()) {\n");
printf (" local_next_token ();\n");
printf (" return 0;\n");
printf (" } else {\n");
printf (" return -1;\n");
printf (" }\n");
printf ("}\n");
return;
} else if (c->name == NAME_LONG) {
printf (" if (is_int ()) {\n");
printf (" local_next_token ();\n");
printf (" return 0;\n");
printf (" } else {\n");
printf (" return -1;\n");
printf (" }\n");
printf ("}\n");
return;
} else if (c->name == NAME_STRING) {
printf (" if (cur_token_len >= 0) {\n");
printf (" local_next_token ();\n");
printf (" return 0;\n");
printf (" } else {\n");
printf (" return -1;\n");
printf (" }\n");
printf ("}\n");
return;
} else if (c->name == NAME_DOUBLE) {
printf (" if (is_double ()) {\n");
printf (" local_next_token ();\n");
printf (" return 0;\n");
printf (" } else {\n");
printf (" return -1;\n");
printf (" }\n");
printf ("}\n");
return;
}
for (i = 0; i < c->args_num; i++) if (!(c->args[i]->flags & FLAG_OPT_VAR)) {
assert (gen_field_autocomplete (c->args[i], vars, i + 1, 0) >= 0);
}
free (vars);
printf (" return 0;\n");
printf ("}\n");
}
void gen_type_skip (struct tl_type *t) {
printf ("int skip_type_%s (struct paramed_type *T) {\n", t->print_id);
printf (" int magic = *in_ptr;\n");
printf (" if (skip_int () < 0) { return -1; }\n");
printf (" if (in_remaining () < 4) { return -1;}\n");
printf (" int magic = fetch_int ();\n");
printf (" switch (magic) {\n");
int i;
for (i = 0; i < t->constructors_num; i++) {
......@@ -475,15 +931,204 @@ void gen_type_fetch (struct tl_type *t) {
printf (" }\n");
printf ("}\n");
printf ("int skip_type_bare_%s (struct paramed_type *T) {\n", t->print_id);
printf (" int *save = in_ptr;\n");
if (t->constructors_num > 1) {
printf (" int *save_in_ptr = in_ptr;\n");
for (i = 0; i < t->constructors_num; i++) {
printf (" if (skip_constructor_%s (T) >= 0) { return 0; }\n", t->constructors[i]->print_id);
printf (" in_ptr = save_in_ptr;\n");
}
} else {
for (i = 0; i < t->constructors_num; i++) {
printf (" if (skip_constructor_%s (T) >= 0) { return 0; }\n", t->constructors[i]->print_id);
}
}
printf (" return -1;\n");
printf ("}\n");
}
void gen_type_fetch (struct tl_type *t) {
int empty = is_empty (t);;
printf ("int fetch_type_%s (struct paramed_type *T) {\n", t->print_id);
printf (" if (in_remaining () < 4) { return -1;}\n");
if (!empty) {
printf (" if (multiline_output >= 2) { multiline_offset += multiline_offset_size; }\n");
printf (" eprintf (\" (\");\n");
}
printf (" int magic = fetch_int ();\n");
printf (" int res = -1;\n");
printf (" switch (magic) {\n");
int i;
for (i = 0; i < t->constructors_num; i++) {
printf (" if (skip_constructor_%s (T) >= 0) { return 0; }\n", t->constructors[i]->print_id);
printf (" in_ptr = save;\n");
printf (" case 0x%08x: res = fetch_constructor_%s (T); break;\n", t->constructors[i]->name, t->constructors[i]->print_id);
}
printf (" default: return -1;\n");
printf (" }\n");
if (!empty) {
printf (" if (res >= 0) {\n");
printf (" if (multiline_output >= 2) { multiline_offset -= multiline_offset_size; print_offset (); }\n");
printf (" eprintf (\" )\");\n");
//printf (" if (multiline_output >= 2) { printf (\"\\n\"); }\n");
printf (" }\n");
}
printf (" return res;\n");
printf ("}\n");
printf ("int fetch_type_bare_%s (struct paramed_type *T) {\n", t->print_id);
if (t->constructors_num > 1) {
printf (" int *save_in_ptr = in_ptr;\n");
if (!empty) {
printf (" if (multiline_output >= 2) { multiline_offset += multiline_offset_size; }\n");
}
for (i = 0; i < t->constructors_num; i++) {
printf (" if (skip_constructor_%s (T) >= 0) { in_ptr = save_in_ptr; %sassert (!fetch_constructor_%s (T)); %sreturn 0; }\n", t->constructors[i]->print_id, empty ? "" : "eprintf (\" (\"); ", t->constructors[i]->print_id , empty ? "" : "if (multiline_output >= 2) { multiline_offset -= multiline_offset_size; print_offset (); } eprintf (\" )\");");
printf (" in_ptr = save_in_ptr;\n");
}
} else {
for (i = 0; i < t->constructors_num; i++) {
if (!empty) {
printf (" if (multiline_output >= 2) { multiline_offset += multiline_offset_size; }\n");
printf (" eprintf (\" (\");\n");
}
printf (" if (fetch_constructor_%s (T) >= 0) { %sreturn 0; }\n", t->constructors[i]->print_id, empty ? "" : "if (multiline_output >= 2) { multiline_offset -= multiline_offset_size; print_offset (); } eprintf (\" )\");" );
}
}
printf (" return -1;\n");
printf ("}\n");
}
void gen_type_store (struct tl_type *t) {
int empty = is_empty (t);;
int k = 0;
for (k = 0; k < 2; k++) {
printf ("int store_type_%s%s (struct paramed_type *T) {\n", k == 0 ? "" : "bare_", t->print_id);
if (empty) {
printf (" if (store_constructor_%s (T) < 0) { return -1; }\n", t->constructors[0]->print_id);
printf (" return 0;\n");
printf ("}\n");
} else {
printf (" expect_token (\"(\", 1);\n");
printf (" if (cur_token_len < 0) { return -1; }\n");
printf (" if (cur_token_len < 0) { return -1; }\n");
int i;
for (i = 0; i < t->constructors_num; i++) {
printf (" if (cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", (int)strlen (t->constructors[i]->id), t->constructors[i]->id);
if (!k) {
printf (" out_int (0x%08x);\n", t->constructors[i]->name);
}
printf (" local_next_token ();\n");
printf (" if (store_constructor_%s (T) < 0) { return -1; }\n", t->constructors[i]->print_id);
printf (" expect_token (\")\", 1);\n");
printf (" return 0;\n");
printf (" }\n");
}
/*if (t->constructors_num == 1) {
printf (" if (!force) {\n");
if (!k) {
printf (" out_int (0x%08x);\n", t->constructors[0]->name);
}
printf (" if (store_constructor_%s (T) < 0) { return -1; }\n", t->constructors[0]->print_id);
printf (" expect_token (\")\", 1);\n");
printf (" return 0;\n");
printf (" }\n");
}*/
printf (" return -1;\n");
printf ("}\n");
}
}
}
void gen_type_autocomplete (struct tl_type *t) {
int empty = is_empty (t);;
int k = 0;
for (k = 0; k < 2; k++) {
printf ("int autocomplete_type_%s%s (struct paramed_type *T) {\n", k == 0 ? "" : "bare_", t->print_id);
if (empty) {
printf (" if (autocomplete_constructor_%s (T) < 0) { return -1; }\n", t->constructors[0]->print_id);
printf (" return 0;\n");
printf ("}\n");
} else {
printf (" expect_token_autocomplete (\"(\", 1);\n");
printf (" if (cur_token_len == -3) { set_autocomplete_type (do_autocomplete_type_%s); return -1; }\n", t->print_id);
printf (" if (cur_token_len < 0) { return -1; }\n");
int i;
for (i = 0; i < t->constructors_num; i++) {
printf (" if (cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", (int)strlen (t->constructors[i]->id), t->constructors[i]->id);
printf (" local_next_token ();\n");
printf (" if (autocomplete_constructor_%s (T) < 0) { return -1; }\n", t->constructors[i]->print_id);
printf (" expect_token_autocomplete (\")\", 1);\n");
printf (" return 0;\n");
printf (" }\n");
}
/*if (t->constructors_num == 1) {
printf (" if (!force) {\n");
printf (" if (autocomplete_constructor_%s (T) < 0) { return -1; }\n", t->constructors[0]->print_id);
printf (" expect_token_autocomplete (\")\", 1);\n");
printf (" return 0;\n");
printf (" }\n");
}*/
printf (" return -1;\n");
printf ("}\n");
}
}
}
void gen_function_store (struct tl_combinator *f) {
printf ("struct paramed_type *store_function_%s (void) {\n", f->print_id);
int i;
for (i = 0; i < f->args_num; i++) if (f->args[i]->flags & FLAG_EXCL) {
printf (" return 0;\n");
printf ("}\n");
return;
}
int *vars = malloc0 (f->var_num * 4);;
for (i = 0; i < f->args_num; i++) if (!(f->args[i]->flags & FLAG_OPT_VAR)) {
assert (gen_field_store (f->args[i], vars, i + 1, 1) >= 0);
}
printf (" struct paramed_type *R = \n");
assert (gen_create (f->result, vars, 2) >= 0);
printf (";\n");
free (vars);
printf (" return paramed_type_dup (R);\n");
printf ("}\n");
}
void gen_function_autocomplete (struct tl_combinator *f) {
printf ("struct paramed_type *autocomplete_function_%s (void) {\n", f->print_id);
int i;
for (i = 0; i < f->args_num; i++) if (f->args[i]->flags & FLAG_EXCL) {
printf (" return 0;\n");
printf ("}\n");
return;
}
int *vars = malloc0 (f->var_num * 4);;
for (i = 0; i < f->args_num; i++) if (!(f->args[i]->flags & FLAG_OPT_VAR)) {
assert (gen_field_autocomplete (f->args[i], vars, i + 1, 1) >= 0);
}
free (vars);
printf (" return (void *)1;\n");
printf ("}\n");
}
void gen_type_do_autocomplete (struct tl_type *t) {
printf ("int do_autocomplete_type_%s (const char *text, int text_len, int index, char **R) {\n", t->print_id);
printf (" index ++;\n");
int i;
for (i = 0; i < t->constructors_num; i++) {
printf (" if (index == %d) { if (!strncmp (text, \"%s\", text_len)) { *R = tstrdup (\"%s\"); return index; } else { index ++; }}\n", i, t->constructors[i]->id, t->constructors[i]->id);
}
printf (" *R = 0;\n");
printf (" return 0;\n");
printf ("}\n");
}
struct tl_tree *read_num_var (int *var_num) {
struct tl_tree_var_num *T = malloc0 (sizeof (*T));
T->self.flags = 0;
......@@ -667,6 +1312,11 @@ int read_args_list (struct arg **args, int args_num, int *var_num) {
args[i]->var_num = -1;
}
int x = args[i]->flags & 6;
args[i]->flags &= ~6;
if (x & 2) { args[i]->flags |= 4; }
if (x & 4) { args[i]->flags |= 2; }
if (args[i]->var_num >= *var_num) {
*var_num = args[i]->var_num + 1;
}
......@@ -839,49 +1489,6 @@ int parse_tlo_file (void) {
}
assert (buf_ptr == buf_end);
/*
static void *IP[10000];
if (gen_function_fetch (IP, 100) < 0) {
return -2;
}
for (i = 0; i < tn; i++) {
if (tps[i]->extra < tps[i]->constructors_num) {
tl_config_back ();
return -1;
}
}
int j;
for (i = 0; i < tn; i++) {
for (j = 0; j < tps[i]->constructors_num; j ++) {
if (gen_constructor_store (tps[i]->constructors[j], IP, 10000) < 0) {
return -2;
}
if (gen_constructor_fetch (tps[i]->constructors[j], IP, 10000) < 0) {
return -2;
}
}
}
for (i = 0; i < fn; i++) {
if (gen_function_store (fns[i], IP, 10000) < 0) {
return -2;
}
}
if (tl_config_name) {
ADD_PFREE (strlen (tl_config_name));
zzstrfree (tl_config_name);
}
tl_config_name = 0;
config_crc64 = new_crc64;
tl_config_version = new_tl_config_version ;
tl_config_date = new_tl_config_date;
int i;
int types_num = get_int ();
for (i = 0; i < types_num; i++) {
if (parse_type () < 0) { return -1; }
}*/
int j;
for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type")) {
......@@ -895,59 +1502,153 @@ int parse_tlo_file (void) {
printf ("#include \"auto.h\"\n");
printf ("#include <assert.h>\n");
printf ("extern int *tgl_in_ptr, *tgl_in_end;\n");
printf ("#define in_ptr tgl_in_ptr\n");
printf ("#define in_end tgl_in_end\n");
printf ("#include \"auto-static.c\"\n");
for (i = 0; i < tn; i++) {
for (j = 0; j < tps[i]->constructors_num; j ++) {
gen_constructor_skip (tps[i]->constructors[j]);
gen_constructor_store (tps[i]->constructors[j]);
gen_constructor_fetch (tps[i]->constructors[j]);
gen_constructor_autocomplete (tps[i]->constructors[j]);
}
}
for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type")) {
gen_type_skip (tps[i]);
gen_type_store (tps[i]);
gen_type_fetch (tps[i]);
gen_type_autocomplete (tps[i]);
gen_type_do_autocomplete (tps[i]);
}
for (i = 0; i < fn; i++) {
gen_function_store (fns[i]);
gen_function_autocomplete (fns[i]);
}
/*for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#') {
printf ("struct tl_type tl_type_%s = {\n", tps[i]->id);
printf (" .name = 0x%08x,\n", tps[i]->name);
printf (" .id = \"%s\"\n", tps[i]->id);
printf ("};\n");
}*/
printf ("int skip_type_any (struct paramed_type *T) {\n");
printf (" switch (T->type->name) {\n");
for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type")) {
for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type") && tps[i]->name) {
printf (" case 0x%08x: return skip_type_%s (T);\n", tps[i]->name, tps[i]->print_id);
printf (" case 0x%08x: return skip_type_bare_%s (T);\n", ~tps[i]->name, tps[i]->print_id);
}
printf (" default: return -1; }\n");
printf ("}\n");
printf ("int store_type_any (struct paramed_type *T) {\n");
printf (" switch (T->type->name) {\n");
for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type") && tps[i]->name) {
printf (" case 0x%08x: return store_type_%s (T);\n", tps[i]->name, tps[i]->print_id);
printf (" case 0x%08x: return store_type_bare_%s (T);\n", ~tps[i]->name, tps[i]->print_id);
}
printf (" default: return -1; }\n");
printf ("}\n");
printf ("int fetch_type_any (struct paramed_type *T) {\n");
printf (" switch (T->type->name) {\n");
for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type") && tps[i]->name) {
printf (" case 0x%08x: return fetch_type_%s (T);\n", tps[i]->name, tps[i]->print_id);
printf (" case 0x%08x: return fetch_type_bare_%s (T);\n", ~tps[i]->name, tps[i]->print_id);
}
printf (" default: return -1; }\n");
printf ("}\n");
printf ("int autocomplete_type_any (struct paramed_type *T) {\n");
printf (" switch (T->type->name) {\n");
for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type") && tps[i]->name) {
printf (" case 0x%08x: return autocomplete_type_%s (T);\n", tps[i]->name, tps[i]->print_id);
printf (" case 0x%08x: return autocomplete_type_bare_%s (T);\n", ~tps[i]->name, tps[i]->print_id);
}
printf (" default: return -1; }\n");
printf ("}\n");
printf ("struct paramed_type *store_function_any (void) {\n");
printf (" if (cur_token_len != 1 || *cur_token != '(') { return 0; }\n");
printf (" local_next_token ();\n");
printf (" if (cur_token_len == 1 || *cur_token == '.') { \n");
printf (" local_next_token ();\n");
printf (" if (cur_token_len != 1 || *cur_token != '=') { return 0; }\n");
printf (" local_next_token ();\n");
printf (" };\n");
printf (" if (cur_token_len < 0) { return 0; }\n");
for (i = 0; i < fn; i++) {
printf (" if (cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", (int)strlen (fns[i]->id), fns[i]->id);
printf (" out_int (0x%08x);\n", fns[i]->name);
printf (" local_next_token ();\n");
printf (" struct paramed_type *P = store_function_%s ();\n", fns[i]->print_id);
printf (" if (!P) { return 0; }\n");
printf (" if (cur_token_len != 1 || *cur_token != ')') { return 0; }\n");
printf (" local_next_token ();\n");
printf (" return P;\n");
printf (" }\n");
}
printf (" return 0;\n");
printf ("}\n");
printf ("int do_autocomplete_function (const char *text, int text_len, int index, char **R) {\n");
printf (" index ++;\n");
int i;
for (i = 0; i < fn; i++) {
printf (" if (index == %d) { if (!strncmp (text, \"%s\", text_len)) { *R = tstrdup (\"%s\"); return index; } else { index ++; }}\n", i, fns[i]->id, fns[i]->id);
}
printf (" *R = 0;\n");
printf (" return 0;\n");
printf ("}\n");
printf ("struct paramed_type *autocomplete_function_any (void) {\n");
printf (" expect_token_ptr_autocomplete (\"(\", 1);\n");
printf (" if (cur_token_len == -3) { set_autocomplete_type (do_autocomplete_function); }\n");
printf (" if (cur_token_len < 0) { return 0; }\n");
for (i = 0; i < fn; i++) {
printf (" if (cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", (int)strlen (fns[i]->id), fns[i]->id);
printf (" local_next_token ();\n");
printf (" struct paramed_type *P = autocomplete_function_%s ();\n", fns[i]->print_id);
printf (" if (!P) { return 0; }\n");
printf (" expect_token_ptr_autocomplete (\")\", 1);\n");
printf (" return P;\n");
printf (" }\n");
}
printf (" return 0;\n");
printf ("}\n");
} else {
for (i = 0; i < tn; i++) {
for (j = 0; j < tps[i]->constructors_num; j ++) {
printf ("int skip_constructor_%s (struct paramed_type *T);\n", tps[i]->constructors[j]->print_id);
printf ("int store_constructor_%s (struct paramed_type *T);\n", tps[i]->constructors[j]->print_id);
printf ("int fetch_constructor_%s (struct paramed_type *T);\n", tps[i]->constructors[j]->print_id);
printf ("int autocomplete_constructor_%s (struct paramed_type *T);\n", tps[i]->constructors[j]->print_id);
}
}
for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type")) {
printf ("int skip_type_%s (struct paramed_type *T);\n", tps[i]->print_id);
printf ("int skip_type_bare_%s (struct paramed_type *T);\n", tps[i]->print_id);
printf ("int store_type_%s (struct paramed_type *T);\n", tps[i]->print_id);
printf ("int store_type_bare_%s (struct paramed_type *T);\n", tps[i]->print_id);
printf ("int fetch_type_%s (struct paramed_type *T);\n", tps[i]->print_id);
printf ("int fetch_type_bare_%s (struct paramed_type *T);\n", tps[i]->print_id);
printf ("int autocomplete_type_%s (struct paramed_type *T);\n", tps[i]->print_id);
printf ("int do_autocomplete_type_%s (const char *text, int len, int index, char **R);\n", tps[i]->print_id);
printf ("int autocomplete_type_bare_%s (struct paramed_type *T);\n", tps[i]->print_id);
}
for (i = 0; i < fn; i++) {
printf ("struct paramed_type *store_function_%s (void);\n", fns[i]->print_id);
printf ("struct paramed_type *autocomplete_function_%s (void);\n", fns[i]->print_id);
}
printf ("int skip_type_any (struct paramed_type *T);\n");
printf ("int store_type_any (struct paramed_type *T);\n");
printf ("int fetch_type_any (struct paramed_type *T);\n");
printf ("int autocomplete_type_any (struct paramed_type *T);\n");
printf ("struct paramed_type *store_function_any (void);\n");
printf ("struct paramed_type *autocomplete_function_any (void);\n");
/*for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#') {
printf ("extern struct tl_type tl_type_%s;\n", tps[i]->id);
}*/
for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type")) {
printf ("static struct tl_type tl_type_%s __attribute__ ((unused));\n", tps[i]->print_id);
printf ("static struct tl_type tl_type_%s = {\n", tps[i]->print_id);
printf ("static struct tl_type_descr tl_type_%s __attribute__ ((unused));\n", tps[i]->print_id);
printf ("static struct tl_type_descr tl_type_%s = {\n", tps[i]->print_id);
printf (" .name = 0x%08x,\n", tps[i]->name);
printf (" .id = \"%s\"\n", tps[i]->id);
printf (" .id = \"%s\"\n,", tps[i]->id);
printf (" .params_num = %d,\n", tps[i]->arity);
printf (" .params_types = %lld\n", tps[i]->params_types);
printf ("};\n");
printf ("static struct tl_type tl_type_bare_%s __attribute__ ((unused));\n", tps[i]->print_id);
printf ("static struct tl_type tl_type_bare_%s = {\n", tps[i]->print_id);
printf ("static struct tl_type_descr tl_type_bare_%s __attribute__ ((unused));\n", tps[i]->print_id);
printf ("static struct tl_type_descr tl_type_bare_%s = {\n", tps[i]->print_id);
printf (" .name = 0x%08x,\n", ~tps[i]->name);
printf (" .id = \"Bare_%s\"\n", tps[i]->id);
printf (" .id = \"Bare_%s\",\n", tps[i]->id);
printf (" .params_num = %d,\n", tps[i]->arity);
printf (" .params_types = %lld\n", tps[i]->params_types);
printf ("};\n");
}
}
......
......@@ -340,7 +340,8 @@ enum command_argument {
ca_string_end,
ca_string,
ca_modifier,
ca_command
ca_command,
ca_extf
};
struct command {
......@@ -411,6 +412,7 @@ enum command_argument get_complete_mode (void) {
int l = 0;
char *r = next_token (&l);
if (!r) { return ca_command; }
if (*r == '(') { return ca_extf; }
while (r && r[0] == '[' && r[l - 1] == ']') {
r = next_token (&l);
if (!r) { return ca_command; }
......@@ -537,6 +539,9 @@ char *command_generator (const char *text, int state) {
index = complete_string_list (modifiers, index, text, len, &R);
if (c) { rl_line_buffer[rl_point] = c; }
return R;
case ca_extf:
index = tglf_extf_autocomplete (text, len, index, &R, rl_line_buffer, rl_point);
return R;
default:
if (c) { rl_line_buffer[rl_point] = c; }
return 0;
......@@ -1026,6 +1031,12 @@ void print_card_gw (void *extra, int success, int size, int *card) {
print_end ();
}
void callback_extf (void *extra, int success, char *buf) {
print_start ();
printf ("%s\n", buf);
print_end ();
}
struct tgl_update_callback upd_cb = {
.new_msg = print_message_gw,
.marked_read = mark_read_upd,
......@@ -1114,7 +1125,9 @@ void interpreter (char *line UU) {
RET; \
}
if (IS_WORD ("contact_list")) {
if (command && *command == '(') {
tgl_do_send_extf (line, strlen (line), callback_extf, 0);
} else if (IS_WORD ("contact_list")) {
tgl_do_update_contact_list (print_user_list_gw, 0);
} else if (IS_WORD ("dialog_list")) {
tgl_do_get_dialog_list (print_dialog_list_gw, 0);
......
......@@ -146,6 +146,12 @@ static inline void out_long (long long x) {
packet_ptr += 2;
}
static inline void out_double (double x) {
assert (packet_ptr + 2 <= packet_buffer + PACKET_BUFFER_SIZE);
*(double *)packet_ptr = x;
packet_ptr += 2;
}
static inline void clear_packet (void) {
packet_ptr = packet_buffer;
}
......@@ -347,6 +353,10 @@ static inline void fetch256 (void *buf) {
}
}
static inline int in_remaining (void) {
return 4 * (in_end - in_ptr);
}
//int get_random_bytes (unsigned char *buf, int n);
int tgl_pad_rsa_encrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *E);
......
......@@ -162,6 +162,7 @@ struct query *tglq_send_query_ex (struct tgl_dc *DC, int ints, void *data, struc
}
vlogprintf (E_DEBUG, "Msg_id is %lld %p\n", q->msg_id, q);
q->methods = methods;
q->type = methods->type;
q->DC = DC;
q->flags = flags & QUERY_FORCE_SEND;
if (queries_tree) {
......@@ -271,11 +272,11 @@ void tglq_query_result (long long id UU) {
}
queries_tree = tree_delete_query (queries_tree, q);
if (q->methods && q->methods->on_answer) {
if (q->methods->type) {
if (q->type) {
int *save = in_ptr;
vlogprintf (E_DEBUG, "in_ptr = %p, end_ptr = %p\n", in_ptr, in_end);
if (skip_type_any (q->methods->type) < 0) {
vlogprintf (E_ERROR, "Skipped %ld int out of %ld (type %s)\n", (long)(in_ptr - save), (long)(in_end - save), q->methods->type->type->id);
if (skip_type_any (q->type) < 0) {
vlogprintf (E_ERROR, "Skipped %ld int out of %ld (type %s)\n", (long)(in_ptr - save), (long)(in_end - save), q->type->type->id);
assert (0);
}
......@@ -3431,6 +3432,28 @@ void tgl_do_import_card (int size, int *card, void (*callback)(void *callback_ex
}
/* }}} */
static int ext_query_on_answer (struct query *q UU) {
if (q->callback) {
char *buf = tglf_extf_fetch (q->type);
((void (*)(void *, int, char *))q->callback) (q->callback_extra, 1, buf);
}
return 0;
}
static struct query_methods ext_query_methods = {
.on_answer = ext_query_on_answer,
};
void tgl_do_send_extf (char *data, int data_len, void (*callback)(void *callback_extra, int success, char *buf), void *callback_extra) {
clear_packet ();
ext_query_methods.type = tglf_extf_store (data, data_len);
if (ext_query_methods.type) {
tglq_send_query (tgl_state.DC_working, packet_ptr - packet_buffer, packet_buffer, &ext_query_methods, 0, callback, callback_extra);
}
}
static void set_flag_4 (void *_D, int success) {
struct tgl_dc *D = _D;
assert (success);
......
......@@ -48,6 +48,7 @@ struct query {
struct event *ev;
struct tgl_dc *DC;
struct tgl_session *session;
struct paramed_type *type;
void *extra;
void *callback;
void *callback_extra;
......
......@@ -312,4 +312,9 @@ double tglt_get_double_time (void);
void tgl_insert_empty_user (int id);
void tgl_insert_empty_chat (int id);
int tglf_extf_autocomplete (const char *text, int text_len, int index, char **R, char *data, int data_len);
struct paramed_type *tglf_extf_store (const char *data, int data_len);
void tgl_do_send_extf (char *data, int data_len, void (*callback)(void *callback_extra, int success, char *data), void *callback_extra);
char *tglf_extf_fetch (struct paramed_type *T);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment