Added support for direct queries enter
This commit is contained in:
parent
42bde8003d
commit
88d420583d
249
auto-static.c
249
auto-static.c
@ -18,50 +18,231 @@
|
|||||||
Copyright Vitaly Valtman 2014
|
Copyright Vitaly Valtman 2014
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int skip_double (void) {
|
#include "mtproto-common.h"
|
||||||
if (in_ptr + 2 <= in_end) {
|
#include <string.h>
|
||||||
in_ptr += 2;
|
|
||||||
return 0;
|
static int cur_token_len;
|
||||||
} else {
|
static char *cur_token;
|
||||||
return -1;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_offset (void) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < multiline_offset; i++) {
|
||||||
|
printf (" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int skip_long (void) {
|
|
||||||
if (in_ptr + 2 <= in_end) {
|
static char *buffer_pos, *buffer_end;
|
||||||
in_ptr += 2;
|
|
||||||
return 0;
|
static int is_wspc (char c) {
|
||||||
} else {
|
return c <= 32 && c > 0;
|
||||||
return -1;
|
}
|
||||||
|
|
||||||
|
static void skip_wspc (void) {
|
||||||
|
while (buffer_pos < buffer_end && is_wspc (*buffer_pos)) {
|
||||||
|
buffer_pos ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int skip_int (void) {
|
|
||||||
if (in_ptr + 1 <= in_end) {
|
static int is_letter (char c) {
|
||||||
in_ptr += 1;
|
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-';
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 ++;
|
||||||
|
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 {
|
} else {
|
||||||
return -1;
|
if (c) {
|
||||||
|
cur_token = buffer_pos ++;
|
||||||
|
cur_token_len = 1;
|
||||||
|
} else {
|
||||||
|
cur_token_len = -3;
|
||||||
|
cur_token_real_len = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int skip_string (void) {
|
|
||||||
if (in_ptr == in_end) { return -1; }
|
int tglf_extf_autocomplete (const char *text, int text_len, int index, char **R, char *data, int data_len) {
|
||||||
unsigned len = *(unsigned char *)in_ptr;
|
if (index == -1) {
|
||||||
if (len == 0xff) { return -1; }
|
buffer_pos = data;
|
||||||
if (len < 0xfe) {
|
buffer_end = data + data_len;
|
||||||
unsigned size = (len + 4) >> 2;
|
autocomplete_mode = 0;
|
||||||
if (in_ptr + size <= in_end) {
|
local_next_token ();
|
||||||
in_ptr += size;
|
autocomplete_function_any ();
|
||||||
return 0;
|
}
|
||||||
|
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 {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
len = (*(unsigned *)in_ptr) >> 8;
|
return autocomplete_fun (text, len, index, R);
|
||||||
unsigned size = (len + 7) >> 2;
|
|
||||||
if (in_ptr + size <= in_end) {
|
|
||||||
in_ptr += size;
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
6
auto.h
6
auto.h
@ -20,13 +20,15 @@
|
|||||||
#ifndef __AUTO_H__
|
#ifndef __AUTO_H__
|
||||||
#define __AUTO_H__
|
#define __AUTO_H__
|
||||||
|
|
||||||
struct tl_type {
|
struct tl_type_descr {
|
||||||
unsigned name;
|
unsigned name;
|
||||||
char *id;
|
char *id;
|
||||||
|
int params_num;
|
||||||
|
long long params_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct paramed_type {
|
struct paramed_type {
|
||||||
struct tl_type *type;
|
struct tl_type_descr *type;
|
||||||
struct paramed_type **params;
|
struct paramed_type **params;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
875
generate.c
875
generate.c
File diff suppressed because it is too large
Load Diff
17
interface.c
17
interface.c
@ -340,7 +340,8 @@ enum command_argument {
|
|||||||
ca_string_end,
|
ca_string_end,
|
||||||
ca_string,
|
ca_string,
|
||||||
ca_modifier,
|
ca_modifier,
|
||||||
ca_command
|
ca_command,
|
||||||
|
ca_extf
|
||||||
};
|
};
|
||||||
|
|
||||||
struct command {
|
struct command {
|
||||||
@ -411,6 +412,7 @@ enum command_argument get_complete_mode (void) {
|
|||||||
int l = 0;
|
int l = 0;
|
||||||
char *r = next_token (&l);
|
char *r = next_token (&l);
|
||||||
if (!r) { return ca_command; }
|
if (!r) { return ca_command; }
|
||||||
|
if (*r == '(') { return ca_extf; }
|
||||||
while (r && r[0] == '[' && r[l - 1] == ']') {
|
while (r && r[0] == '[' && r[l - 1] == ']') {
|
||||||
r = next_token (&l);
|
r = next_token (&l);
|
||||||
if (!r) { return ca_command; }
|
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);
|
index = complete_string_list (modifiers, index, text, len, &R);
|
||||||
if (c) { rl_line_buffer[rl_point] = c; }
|
if (c) { rl_line_buffer[rl_point] = c; }
|
||||||
return R;
|
return R;
|
||||||
|
case ca_extf:
|
||||||
|
index = tglf_extf_autocomplete (text, len, index, &R, rl_line_buffer, rl_point);
|
||||||
|
return R;
|
||||||
default:
|
default:
|
||||||
if (c) { rl_line_buffer[rl_point] = c; }
|
if (c) { rl_line_buffer[rl_point] = c; }
|
||||||
return 0;
|
return 0;
|
||||||
@ -1026,6 +1031,12 @@ void print_card_gw (void *extra, int success, int size, int *card) {
|
|||||||
print_end ();
|
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 = {
|
struct tgl_update_callback upd_cb = {
|
||||||
.new_msg = print_message_gw,
|
.new_msg = print_message_gw,
|
||||||
.marked_read = mark_read_upd,
|
.marked_read = mark_read_upd,
|
||||||
@ -1114,7 +1125,9 @@ void interpreter (char *line UU) {
|
|||||||
RET; \
|
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);
|
tgl_do_update_contact_list (print_user_list_gw, 0);
|
||||||
} else if (IS_WORD ("dialog_list")) {
|
} else if (IS_WORD ("dialog_list")) {
|
||||||
tgl_do_get_dialog_list (print_dialog_list_gw, 0);
|
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;
|
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) {
|
static inline void clear_packet (void) {
|
||||||
packet_ptr = packet_buffer;
|
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 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);
|
int tgl_pad_rsa_encrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *E);
|
||||||
|
29
queries.c
29
queries.c
@ -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);
|
vlogprintf (E_DEBUG, "Msg_id is %lld %p\n", q->msg_id, q);
|
||||||
q->methods = methods;
|
q->methods = methods;
|
||||||
|
q->type = methods->type;
|
||||||
q->DC = DC;
|
q->DC = DC;
|
||||||
q->flags = flags & QUERY_FORCE_SEND;
|
q->flags = flags & QUERY_FORCE_SEND;
|
||||||
if (queries_tree) {
|
if (queries_tree) {
|
||||||
@ -271,11 +272,11 @@ void tglq_query_result (long long id UU) {
|
|||||||
}
|
}
|
||||||
queries_tree = tree_delete_query (queries_tree, q);
|
queries_tree = tree_delete_query (queries_tree, q);
|
||||||
if (q->methods && q->methods->on_answer) {
|
if (q->methods && q->methods->on_answer) {
|
||||||
if (q->methods->type) {
|
if (q->type) {
|
||||||
int *save = in_ptr;
|
int *save = in_ptr;
|
||||||
vlogprintf (E_DEBUG, "in_ptr = %p, end_ptr = %p\n", in_ptr, in_end);
|
vlogprintf (E_DEBUG, "in_ptr = %p, end_ptr = %p\n", in_ptr, in_end);
|
||||||
if (skip_type_any (q->methods->type) < 0) {
|
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->methods->type->type->id);
|
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);
|
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) {
|
static void set_flag_4 (void *_D, int success) {
|
||||||
struct tgl_dc *D = _D;
|
struct tgl_dc *D = _D;
|
||||||
assert (success);
|
assert (success);
|
||||||
|
@ -48,6 +48,7 @@ struct query {
|
|||||||
struct event *ev;
|
struct event *ev;
|
||||||
struct tgl_dc *DC;
|
struct tgl_dc *DC;
|
||||||
struct tgl_session *session;
|
struct tgl_session *session;
|
||||||
|
struct paramed_type *type;
|
||||||
void *extra;
|
void *extra;
|
||||||
void *callback;
|
void *callback;
|
||||||
void *callback_extra;
|
void *callback_extra;
|
||||||
|
5
tgl.h
5
tgl.h
@ -312,4 +312,9 @@ double tglt_get_double_time (void);
|
|||||||
void tgl_insert_empty_user (int id);
|
void tgl_insert_empty_user (int id);
|
||||||
void tgl_insert_empty_chat (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
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user