Formatting
This commit is contained in:
@ -20,6 +20,7 @@ extern "C" {
|
|||||||
bool mgos_ota_http_client_init(void);
|
bool mgos_ota_http_client_init(void);
|
||||||
|
|
||||||
void mgos_ota_http_start(struct update_context *ctx, const char *url);
|
void mgos_ota_http_start(struct update_context *ctx, const char *url);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -21,14 +21,18 @@ static void fw_download_handler(struct mg_connection *c, int ev, void *p,
|
|||||||
struct update_context *ctx = (struct update_context *)user_data;
|
struct update_context *ctx = (struct update_context *)user_data;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
struct mg_str *loc;
|
struct mg_str *loc;
|
||||||
|
|
||||||
(void)p;
|
(void)p;
|
||||||
|
|
||||||
switch (ev) {
|
switch (ev) {
|
||||||
case MG_EV_CONNECT: {
|
case MG_EV_CONNECT: {
|
||||||
int result = *((int *)p);
|
int result = *((int *)p);
|
||||||
if (result != 0) LOG(LL_ERROR, ("connect error: %d", result));
|
if (result != 0) {
|
||||||
|
LOG(LL_ERROR, ("connect error: %d", result));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MG_EV_RECV: {
|
case MG_EV_RECV: {
|
||||||
if (ctx->file_size == 0) {
|
if (ctx->file_size == 0) {
|
||||||
LOG(LL_DEBUG, ("Looking for HTTP header"));
|
LOG(LL_DEBUG, ("Looking for HTTP header"));
|
||||||
@ -48,6 +52,7 @@ static void fw_download_handler(struct mg_connection *c, int ev, void *p,
|
|||||||
/* NUL-terminate the URL. Every header must be followed by \r\n,
|
/* NUL-terminate the URL. Every header must be followed by \r\n,
|
||||||
* so there is deifnitely space there. */
|
* so there is deifnitely space there. */
|
||||||
((char *)loc->p)[loc->len] = '\0';
|
((char *)loc->p)[loc->len] = '\0';
|
||||||
|
|
||||||
/* We were told to look elsewhere. Detach update context from this
|
/* We were told to look elsewhere. Detach update context from this
|
||||||
* connection so that it doesn't get finalized when it's closed. */
|
* connection so that it doesn't get finalized when it's closed. */
|
||||||
mgos_ota_http_start(ctx, loc->p);
|
mgos_ota_http_start(ctx, loc->p);
|
||||||
@ -82,7 +87,9 @@ static void fw_download_handler(struct mg_connection *c, int ev, void *p,
|
|||||||
mbuf_remove(io, io->len);
|
mbuf_remove(io, io->len);
|
||||||
|
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
if (is_write_finished(ctx)) res = updater_finalize(ctx);
|
if (is_write_finished(ctx)) {
|
||||||
|
res = updater_finalize(ctx);
|
||||||
|
}
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
/* Need more data, everything is OK */
|
/* Need more data, everything is OK */
|
||||||
break;
|
break;
|
||||||
@ -97,14 +104,21 @@ static void fw_download_handler(struct mg_connection *c, int ev, void *p,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MG_EV_CLOSE: {
|
|
||||||
if (ctx == NULL) break;
|
|
||||||
|
|
||||||
if (is_write_finished(ctx)) updater_finalize(ctx);
|
case MG_EV_CLOSE: {
|
||||||
|
if (ctx == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_write_finished(ctx)) {
|
||||||
|
updater_finalize(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_update_finished(ctx)) {
|
if (!is_update_finished(ctx)) {
|
||||||
/* Update failed or connection was terminated by server */
|
/* Update failed or connection was terminated by server */
|
||||||
if (ctx->status_msg == NULL) ctx->status_msg = "Update failed";
|
if (ctx->status_msg == NULL) {
|
||||||
|
ctx->status_msg = "Update failed";
|
||||||
|
}
|
||||||
ctx->result = -1;
|
ctx->result = -1;
|
||||||
} else if (is_reboot_required(ctx)) {
|
} else if (is_reboot_required(ctx)) {
|
||||||
LOG(LL_INFO, ("Rebooting device"));
|
LOG(LL_INFO, ("Rebooting device"));
|
||||||
@ -147,7 +161,9 @@ void mgos_ota_http_start(struct update_context *ctx, const char *url) {
|
|||||||
struct mg_connection *c = mg_connect_http_opt(
|
struct mg_connection *c = mg_connect_http_opt(
|
||||||
mgos_get_mgr(), fw_download_handler, ctx, opts, url, extra_headers, NULL);
|
mgos_get_mgr(), fw_download_handler, ctx, opts, url, extra_headers, NULL);
|
||||||
|
|
||||||
if (extra_headers != ehb) free(extra_headers);
|
if (extra_headers != ehb) {
|
||||||
|
free(extra_headers);
|
||||||
|
}
|
||||||
|
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
LOG(LL_ERROR, ("Failed to connect to %s", url));
|
LOG(LL_ERROR, ("Failed to connect to %s", url));
|
||||||
@ -163,9 +179,14 @@ void mgos_ota_http_start(struct update_context *ctx, const char *url) {
|
|||||||
|
|
||||||
static void mgos_ota_timer_cb(void *arg) {
|
static void mgos_ota_timer_cb(void *arg) {
|
||||||
const struct mgos_config_update *mcu = mgos_sys_config_get_update();
|
const struct mgos_config_update *mcu = mgos_sys_config_get_update();
|
||||||
if (mcu->url == NULL) return;
|
|
||||||
|
if (mcu->url == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
struct update_context *ctx = updater_context_create();
|
struct update_context *ctx = updater_context_create();
|
||||||
if (ctx == NULL) return;
|
if (ctx == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
ctx->ignore_same_version = true;
|
ctx->ignore_same_version = true;
|
||||||
ctx->fctx.commit_timeout = mcu->commit_timeout;
|
ctx->fctx.commit_timeout = mcu->commit_timeout;
|
||||||
mgos_ota_http_start(ctx, mcu->url);
|
mgos_ota_http_start(ctx, mcu->url);
|
||||||
@ -175,6 +196,7 @@ static void mgos_ota_timer_cb(void *arg) {
|
|||||||
|
|
||||||
bool mgos_ota_http_client_init(void) {
|
bool mgos_ota_http_client_init(void) {
|
||||||
const struct mgos_config_update *mcu = mgos_sys_config_get_update();
|
const struct mgos_config_update *mcu = mgos_sys_config_get_update();
|
||||||
|
|
||||||
if (mcu->url != NULL && mcu->interval > 0) {
|
if (mcu->url != NULL && mcu->interval > 0) {
|
||||||
LOG(LL_INFO,
|
LOG(LL_INFO,
|
||||||
("Updates from %s, every %d seconds", mcu->url, mcu->interval));
|
("Updates from %s, every %d seconds", mcu->url, mcu->interval));
|
||||||
|
@ -14,6 +14,7 @@ extern "C" {
|
|||||||
|
|
||||||
#if MGOS_ENABLE_UPDATER
|
#if MGOS_ENABLE_UPDATER
|
||||||
bool mgos_ota_http_server_init(void);
|
bool mgos_ota_http_server_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -18,7 +18,10 @@
|
|||||||
static void handle_update_post(struct mg_connection *c, int ev, void *p) {
|
static void handle_update_post(struct mg_connection *c, int ev, void *p) {
|
||||||
struct mg_http_multipart_part *mp = (struct mg_http_multipart_part *)p;
|
struct mg_http_multipart_part *mp = (struct mg_http_multipart_part *)p;
|
||||||
struct update_context * ctx = (struct update_context *)c->user_data;
|
struct update_context * ctx = (struct update_context *)c->user_data;
|
||||||
if (ctx == NULL && ev != MG_EV_HTTP_MULTIPART_REQUEST) return;
|
|
||||||
|
if (ctx == NULL && ev != MG_EV_HTTP_MULTIPART_REQUEST) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (ev) {
|
switch (ev) {
|
||||||
case MG_EV_HTTP_MULTIPART_REQUEST: {
|
case MG_EV_HTTP_MULTIPART_REQUEST: {
|
||||||
ctx = updater_context_create();
|
ctx = updater_context_create();
|
||||||
@ -30,6 +33,7 @@ static void handle_update_post(struct mg_connection *c, int ev, void *p) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MG_EV_HTTP_PART_BEGIN: {
|
case MG_EV_HTTP_PART_BEGIN: {
|
||||||
LOG(LL_DEBUG, ("MG_EV_HTTP_PART_BEGIN: %p %s %s", ctx, mp->var_name,
|
LOG(LL_DEBUG, ("MG_EV_HTTP_PART_BEGIN: %p %s %s", ctx, mp->var_name,
|
||||||
mp->file_name));
|
mp->file_name));
|
||||||
@ -39,6 +43,7 @@ static void handle_update_post(struct mg_connection *c, int ev, void *p) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MG_EV_HTTP_PART_DATA: {
|
case MG_EV_HTTP_PART_DATA: {
|
||||||
LOG(LL_DEBUG, ("MG_EV_HTTP_PART_DATA: %p %s %s %d", ctx, mp->var_name,
|
LOG(LL_DEBUG, ("MG_EV_HTTP_PART_DATA: %p %s %s %d", ctx, mp->var_name,
|
||||||
mp->file_name, (int)mp->data.len));
|
mp->file_name, (int)mp->data.len));
|
||||||
@ -57,11 +62,14 @@ static void handle_update_post(struct mg_connection *c, int ev, void *p) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MG_EV_HTTP_PART_END: {
|
case MG_EV_HTTP_PART_END: {
|
||||||
LOG(LL_DEBUG, ("MG_EV_HTTP_PART_END: %p %s %s %d", ctx, mp->var_name,
|
LOG(LL_DEBUG, ("MG_EV_HTTP_PART_END: %p %s %s %d", ctx, mp->var_name,
|
||||||
mp->file_name, mp->status));
|
mp->file_name, mp->status));
|
||||||
/* Part finished with an error. REQUEST_END will follow. */
|
/* Part finished with an error. REQUEST_END will follow. */
|
||||||
if (mp->status < 0) break;
|
if (mp->status < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (mp->file_name[0] == '\0') {
|
if (mp->file_name[0] == '\0') {
|
||||||
/* It's a non-file form variable. Value is in ctx->file_name. */
|
/* It's a non-file form variable. Value is in ctx->file_name. */
|
||||||
LOG(LL_DEBUG, ("Got var: %s=%s", mp->var_name, ctx->file_name));
|
LOG(LL_DEBUG, ("Got var: %s=%s", mp->var_name, ctx->file_name));
|
||||||
@ -75,14 +83,19 @@ static void handle_update_post(struct mg_connection *c, int ev, void *p) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MG_EV_HTTP_MULTIPART_REQUEST_END: {
|
case MG_EV_HTTP_MULTIPART_REQUEST_END: {
|
||||||
LOG(LL_DEBUG,
|
LOG(LL_DEBUG,
|
||||||
("MG_EV_HTTP_MULTIPART_REQUEST_END: %p %d", ctx, mp->status));
|
("MG_EV_HTTP_MULTIPART_REQUEST_END: %p %d", ctx, mp->status));
|
||||||
/* Whatever happens, this is the last thing we do. */
|
/* Whatever happens, this is the last thing we do. */
|
||||||
c->flags |= MG_F_SEND_AND_CLOSE;
|
c->flags |= MG_F_SEND_AND_CLOSE;
|
||||||
|
|
||||||
if (ctx == NULL) break;
|
if (ctx == NULL) {
|
||||||
if (is_write_finished(ctx)) updater_finalize(ctx);
|
break;
|
||||||
|
}
|
||||||
|
if (is_write_finished(ctx)) {
|
||||||
|
updater_finalize(ctx);
|
||||||
|
}
|
||||||
if (!is_update_finished(ctx)) {
|
if (!is_update_finished(ctx)) {
|
||||||
ctx->result = -1;
|
ctx->result = -1;
|
||||||
ctx->status_msg = "Update aborted";
|
ctx->status_msg = "Update aborted";
|
||||||
@ -113,7 +126,9 @@ static void handle_update_post(struct mg_connection *c, int ev, void *p) {
|
|||||||
struct mg_connection *s_update_request_conn;
|
struct mg_connection *s_update_request_conn;
|
||||||
|
|
||||||
static void mgos_ota_result_cb(struct update_context *ctx) {
|
static void mgos_ota_result_cb(struct update_context *ctx) {
|
||||||
if (ctx != updater_context_get_current()) return;
|
if (ctx != updater_context_get_current()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (s_update_request_conn != NULL) {
|
if (s_update_request_conn != NULL) {
|
||||||
int code = (ctx->result > 0 ? 200 : 500);
|
int code = (ctx->result > 0 ? 200 : 500);
|
||||||
mg_send_response_line(s_update_request_conn, code,
|
mg_send_response_line(s_update_request_conn, code,
|
||||||
@ -145,6 +160,7 @@ static void update_handler(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MG_EV_HTTP_REQUEST: {
|
case MG_EV_HTTP_REQUEST: {
|
||||||
struct http_message *hm = (struct http_message *)ev_data;
|
struct http_message *hm = (struct http_message *)ev_data;
|
||||||
if (updater_context_get_current() != NULL) {
|
if (updater_context_get_current() != NULL) {
|
||||||
@ -192,7 +208,6 @@ static void update_handler(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
ctx->fctx.commit_timeout = commit_timeout;
|
ctx->fctx.commit_timeout = commit_timeout;
|
||||||
ctx->result_cb = mgos_ota_result_cb;
|
ctx->result_cb = mgos_ota_result_cb;
|
||||||
mgos_ota_http_start(ctx, url);
|
mgos_ota_http_start(ctx, url);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mg_send_response_line(c, 400,
|
mg_send_response_line(c, 400,
|
||||||
"Content-Type: text/plain\r\n"
|
"Content-Type: text/plain\r\n"
|
||||||
@ -203,6 +218,7 @@ static void update_handler(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
free(buf);
|
free(buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MG_EV_CLOSE: {
|
case MG_EV_CLOSE: {
|
||||||
if (s_update_request_conn == c) {
|
if (s_update_request_conn == c) {
|
||||||
/* Client went away while waiting for response. */
|
/* Client went away while waiting for response. */
|
||||||
@ -216,7 +232,9 @@ static void update_handler(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
|
|
||||||
static void update_action_handler(struct mg_connection *c, int ev, void *p,
|
static void update_action_handler(struct mg_connection *c, int ev, void *p,
|
||||||
void *user_data) {
|
void *user_data) {
|
||||||
if (ev != MG_EV_HTTP_REQUEST) return;
|
if (ev != MG_EV_HTTP_REQUEST) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
struct http_message *hm = (struct http_message *)p;
|
struct http_message *hm = (struct http_message *)p;
|
||||||
bool is_commit = (mg_vcmp(&hm->uri, "/update/commit") == 0);
|
bool is_commit = (mg_vcmp(&hm->uri, "/update/commit") == 0);
|
||||||
bool ok =
|
bool ok =
|
||||||
@ -226,7 +244,9 @@ static void update_action_handler(struct mg_connection *c, int ev, void *p,
|
|||||||
"Connection: close");
|
"Connection: close");
|
||||||
mg_printf(c, "\r\n%s\r\n", (ok ? "Ok" : "Error"));
|
mg_printf(c, "\r\n%s\r\n", (ok ? "Ok" : "Error"));
|
||||||
c->flags |= MG_F_SEND_AND_CLOSE;
|
c->flags |= MG_F_SEND_AND_CLOSE;
|
||||||
if (ok && !is_commit) mgos_system_restart_after(100);
|
if (ok && !is_commit) {
|
||||||
|
mgos_system_restart_after(100);
|
||||||
|
}
|
||||||
(void)user_data;
|
(void)user_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
static struct mg_rpc_request_info *s_update_req;
|
static struct mg_rpc_request_info *s_update_req;
|
||||||
|
|
||||||
static void mg_rpc_updater_result(struct update_context *ctx) {
|
static void mg_rpc_updater_result(struct update_context *ctx) {
|
||||||
if (s_update_req == NULL) return;
|
if (s_update_req == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
mg_rpc_send_errorf(s_update_req, (ctx->result > 0 ? 0 : -1), ctx->status_msg);
|
mg_rpc_send_errorf(s_update_req, (ctx->result > 0 ? 0 : -1), ctx->status_msg);
|
||||||
s_update_req = NULL;
|
s_update_req = NULL;
|
||||||
}
|
}
|
||||||
@ -41,7 +43,9 @@ static void handle_update_req(struct mg_rpc_request_info *ri, void *cb_arg,
|
|||||||
|
|
||||||
json_scanf(args.p, args.len, ri->args_fmt, &url_tok, &commit_timeout);
|
json_scanf(args.p, args.len, ri->args_fmt, &url_tok, &commit_timeout);
|
||||||
|
|
||||||
if (url_tok.len == 0 || url_tok.type != JSON_TYPE_STRING) goto clean;
|
if (url_tok.len == 0 || url_tok.type != JSON_TYPE_STRING) {
|
||||||
|
goto clean;
|
||||||
|
}
|
||||||
|
|
||||||
LOG(LL_DEBUG, ("URL: %.*s commit_timeout: %d", url_tok.len, url_tok.ptr,
|
LOG(LL_DEBUG, ("URL: %.*s commit_timeout: %d", url_tok.len, url_tok.ptr,
|
||||||
commit_timeout));
|
commit_timeout));
|
||||||
@ -73,7 +77,9 @@ static void handle_update_req(struct mg_rpc_request_info *ri, void *cb_arg,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
if (blob_url != NULL) free(blob_url);
|
if (blob_url != NULL) {
|
||||||
|
free(blob_url);
|
||||||
|
}
|
||||||
LOG(LL_ERROR, ("Failed to start update: %s", reply));
|
LOG(LL_ERROR, ("Failed to start update: %s", reply));
|
||||||
mg_rpc_send_errorf(ri, -1, reply);
|
mg_rpc_send_errorf(ri, -1, reply);
|
||||||
ri = NULL;
|
ri = NULL;
|
||||||
@ -116,6 +122,7 @@ static void handle_create_snapshot_req(struct mg_rpc_request_info *ri,
|
|||||||
struct mg_str args) {
|
struct mg_str args) {
|
||||||
const char *err_msg = NULL;
|
const char *err_msg = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (mgos_upd_is_committed()) {
|
if (mgos_upd_is_committed()) {
|
||||||
ret = mgos_upd_create_snapshot();
|
ret = mgos_upd_create_snapshot();
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
@ -164,6 +171,7 @@ static void handle_get_boot_state_req(struct mg_rpc_request_info *ri,
|
|||||||
struct mg_rpc_frame_info *fi,
|
struct mg_rpc_frame_info *fi,
|
||||||
struct mg_str args) {
|
struct mg_str args) {
|
||||||
struct mgos_upd_boot_state bs;
|
struct mgos_upd_boot_state bs;
|
||||||
|
|
||||||
if (!mgos_upd_boot_get_state(&bs)) {
|
if (!mgos_upd_boot_get_state(&bs)) {
|
||||||
mg_rpc_send_errorf(ri, -1, NULL);
|
mg_rpc_send_errorf(ri, -1, NULL);
|
||||||
} else {
|
} else {
|
||||||
@ -184,6 +192,7 @@ static void handle_set_boot_state_req(struct mg_rpc_request_info *ri,
|
|||||||
struct mg_str args) {
|
struct mg_str args) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct mgos_upd_boot_state bs;
|
struct mgos_upd_boot_state bs;
|
||||||
|
|
||||||
if (mgos_upd_boot_get_state(&bs)) {
|
if (mgos_upd_boot_get_state(&bs)) {
|
||||||
int commit_timeout = -1;
|
int commit_timeout = -1;
|
||||||
if (json_scanf(args.p, args.len, ri->args_fmt, &bs.active_slot,
|
if (json_scanf(args.p, args.len, ri->args_fmt, &bs.active_slot,
|
||||||
@ -209,7 +218,10 @@ static void handle_set_boot_state_req(struct mg_rpc_request_info *ri,
|
|||||||
|
|
||||||
bool mgos_rpc_service_ota_init(void) {
|
bool mgos_rpc_service_ota_init(void) {
|
||||||
struct mg_rpc *mg_rpc = mgos_rpc_get_global();
|
struct mg_rpc *mg_rpc = mgos_rpc_get_global();
|
||||||
if (mg_rpc == NULL) return true;
|
|
||||||
|
if (mg_rpc == NULL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
mg_rpc_add_handler(mg_rpc, "OTA.Update", "{url: %T, commit_timeout: %d}",
|
mg_rpc_add_handler(mg_rpc, "OTA.Update", "{url: %T, commit_timeout: %d}",
|
||||||
handle_update_req, NULL);
|
handle_update_req, NULL);
|
||||||
mg_rpc_add_handler(mg_rpc, "OTA.Commit", "", handle_commit_req, NULL);
|
mg_rpc_add_handler(mg_rpc, "OTA.Commit", "", handle_commit_req, NULL);
|
||||||
|
@ -6,10 +6,12 @@ static struct channel_t s_channels[CHANNEL_MAX];
|
|||||||
static int s_num_channels = 0;
|
static int s_num_channels = 0;
|
||||||
|
|
||||||
static bool valid_gpio(const int gpio) {
|
static bool valid_gpio(const int gpio) {
|
||||||
if (gpio == -1)
|
if (gpio == -1) {
|
||||||
return true;
|
return true;
|
||||||
if (gpio < GPIO_MIN || gpio > GPIO_MAX)
|
}
|
||||||
|
if (gpio < GPIO_MIN || gpio > GPIO_MAX) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +59,9 @@ bool channel_init(const char *fn) {
|
|||||||
int led = -1, relay = -1, button = -1;
|
int led = -1, relay = -1, button = -1;
|
||||||
|
|
||||||
LOG(LL_DEBUG, ("[%d]: [%.*s]", idx, val.len, val.ptr));
|
LOG(LL_DEBUG, ("[%d]: [%.*s]", idx, val.len, val.ptr));
|
||||||
if (val.len==0 || !val.ptr)
|
if (val.len == 0 || !val.ptr) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (json_scanf(val.ptr, val.len, "{led:%d, relay:%d, button:%d}", &led, &relay, &button) != 3) {
|
if (json_scanf(val.ptr, val.len, "{led:%d, relay:%d, button:%d}", &led, &relay, &button) != 3) {
|
||||||
LOG(LL_ERROR, ("Incomplete Channel JSON: require 'led' and 'relay' and 'button' fields"));
|
LOG(LL_ERROR, ("Incomplete Channel JSON: require 'led' and 'relay' and 'button' fields"));
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -88,8 +91,9 @@ bool channel_init(const char *fn) {
|
|||||||
ret = true;
|
ret = true;
|
||||||
exit:
|
exit:
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (statusled!=-1)
|
if (statusled != -1) {
|
||||||
statusled_init(statusled, statusled_invert);
|
statusled_init(statusled, statusled_invert);
|
||||||
|
}
|
||||||
|
|
||||||
s_num_channels = idx + 1;
|
s_num_channels = idx + 1;
|
||||||
LOG(LL_INFO, ("Configuring %d channels", s_num_channels));
|
LOG(LL_INFO, ("Configuring %d channels", s_num_channels));
|
||||||
@ -113,14 +117,19 @@ exit:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name) free(name);
|
if (name) {
|
||||||
if (json) free(json);
|
free(name);
|
||||||
|
}
|
||||||
|
if (json) {
|
||||||
|
free(json);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t channel_gpio_by_idx(int idx) {
|
uint8_t channel_gpio_by_idx(int idx) {
|
||||||
if (idx<0 || idx>=s_num_channels)
|
if (idx < 0 || idx >= s_num_channels) {
|
||||||
return GPIO_INVALID;
|
return GPIO_INVALID;
|
||||||
|
}
|
||||||
return s_channels[idx].button_gpio;
|
return s_channels[idx].button_gpio;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,31 +137,36 @@ uint8_t channel_idx_by_gpio(int gpio) {
|
|||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
for (i = 0; i < channel_get_total(); i++) {
|
for (i = 0; i < channel_get_total(); i++) {
|
||||||
if (gpio == s_channels[i].button_gpio)
|
if (gpio == s_channels[i].button_gpio) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return GPIO_INVALID;
|
return GPIO_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void channel_set(int idx, bool state) {
|
void channel_set(int idx, bool state) {
|
||||||
double now = mg_time();
|
double now = mg_time();
|
||||||
|
|
||||||
if (idx<0 || idx>=channel_get_total())
|
if (idx < 0 || idx >= channel_get_total()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
s_channels[idx].button_last_change = now;
|
s_channels[idx].button_last_change = now;
|
||||||
s_channels[idx].relay_state = state;
|
s_channels[idx].relay_state = state;
|
||||||
if (s_channels[idx].relay_gpio!=GPIO_INVALID)
|
if (s_channels[idx].relay_gpio != GPIO_INVALID) {
|
||||||
mgos_gpio_write(s_channels[idx].relay_gpio, state);
|
mgos_gpio_write(s_channels[idx].relay_gpio, state);
|
||||||
if (s_channels[idx].led_gpio!=GPIO_INVALID)
|
}
|
||||||
|
if (s_channels[idx].led_gpio != GPIO_INVALID) {
|
||||||
mgos_gpio_write(s_channels[idx].led_gpio, state);
|
mgos_gpio_write(s_channels[idx].led_gpio, state);
|
||||||
|
}
|
||||||
|
|
||||||
mqtt_publish_stat("channel", "{idx: %d, relay_state: %d}", idx, channel_get(idx));
|
mqtt_publish_stat("channel", "{idx: %d, relay_state: %d}", idx, channel_get(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool channel_get(int idx) {
|
bool channel_get(int idx) {
|
||||||
if (idx<0 || idx>=channel_get_total())
|
if (idx < 0 || idx >= channel_get_total()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return s_channels[idx].relay_state == 1;
|
return s_channels[idx].relay_state == 1;
|
||||||
}
|
}
|
||||||
|
10
src/mqtt.c
10
src/mqtt.c
@ -25,10 +25,12 @@ static void mqtt_broadcast_cmd_id() {
|
|||||||
memset(sta_ip, 0, sizeof(sta_ip));
|
memset(sta_ip, 0, sizeof(sta_ip));
|
||||||
memset(ap_ip, 0, sizeof(ap_ip));
|
memset(ap_ip, 0, sizeof(ap_ip));
|
||||||
|
|
||||||
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_STA, &ip_info))
|
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_STA, &ip_info)) {
|
||||||
mgos_net_ip_to_str(&ip_info.ip, sta_ip);
|
mgos_net_ip_to_str(&ip_info.ip, sta_ip);
|
||||||
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_AP, &ip_info))
|
}
|
||||||
|
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_AP, &ip_info)) {
|
||||||
mgos_net_ip_to_str(&ip_info.ip, ap_ip);
|
mgos_net_ip_to_str(&ip_info.ip, ap_ip);
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(resp, sizeof(resp) - 1, "{\"deviceid\": \"%s\", \"macaddress\": \"%s\", \"sta_ip\": \"%s\", \"ap_ip\": \"%s\", \"app\": \"%s\", \"arch\": \"%s\", \"uptime\": %lu}",
|
snprintf(resp, sizeof(resp) - 1, "{\"deviceid\": \"%s\", \"macaddress\": \"%s\", \"sta_ip\": \"%s\", \"ap_ip\": \"%s\", \"app\": \"%s\", \"arch\": \"%s\", \"uptime\": %lu}",
|
||||||
mgos_sys_config_get_device_id(),
|
mgos_sys_config_get_device_id(),
|
||||||
@ -45,8 +47,9 @@ static void mqtt_cb(struct mg_connection *nc, const char *topic, int topic_len,
|
|||||||
LOG(LL_INFO, ("Received topic='%.*s' msg='%.*s'", topic_len, topic, msg_len, msg));
|
LOG(LL_INFO, ("Received topic='%.*s' msg='%.*s'", topic_len, topic, msg_len, msg));
|
||||||
statusled_blink();
|
statusled_blink();
|
||||||
|
|
||||||
if (topic_len >= (int) strlen(MQTT_TOPIC_BROADCAST_CMD) && 0 == strncmp(MQTT_TOPIC_BROADCAST_CMD, topic, strlen(MQTT_TOPIC_BROADCAST_CMD)))
|
if (topic_len >= (int)strlen(MQTT_TOPIC_BROADCAST_CMD) && 0 == strncmp(MQTT_TOPIC_BROADCAST_CMD, topic, strlen(MQTT_TOPIC_BROADCAST_CMD))) {
|
||||||
mqtt_broadcast_cmd_id();
|
mqtt_broadcast_cmd_id();
|
||||||
|
}
|
||||||
(void)nc;
|
(void)nc;
|
||||||
(void)ud;
|
(void)ud;
|
||||||
}
|
}
|
||||||
@ -62,7 +65,6 @@ static void mqtt_ev(struct mg_connection *nc, int ev, void *ev_data, void *user_
|
|||||||
(void)user_data;
|
(void)user_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mqtt_publish_stat(const char *stat, const char *fmt, ...) {
|
void mqtt_publish_stat(const char *stat, const char *fmt, ...) {
|
||||||
char topic[80];
|
char topic[80];
|
||||||
char msg[200];
|
char msg[200];
|
||||||
|
@ -45,8 +45,9 @@ static void rpc_channel_toggle_handler(struct mg_rpc_request_info *ri, void *cb_
|
|||||||
|
|
||||||
rpc_log(ri, args);
|
rpc_log(ri, args);
|
||||||
|
|
||||||
if (!rpc_args_to_idx_and_gpio(ri, args, &idx, &gpio))
|
if (!rpc_args_to_idx_and_gpio(ri, args, &idx, &gpio)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
channel_handler(gpio, NULL);
|
channel_handler(gpio, NULL);
|
||||||
mg_rpc_send_responsef(ri, "{idx: %d, relay_state: %d}", idx, channel_get(idx));
|
mg_rpc_send_responsef(ri, "{idx: %d, relay_state: %d}", idx, channel_get(idx));
|
||||||
@ -64,8 +65,9 @@ static void rpc_channel_get_handler(struct mg_rpc_request_info *ri, void *cb_arg
|
|||||||
|
|
||||||
rpc_log(ri, args);
|
rpc_log(ri, args);
|
||||||
|
|
||||||
if (!rpc_args_to_idx_and_gpio(ri, args, &idx, &gpio))
|
if (!rpc_args_to_idx_and_gpio(ri, args, &idx, &gpio)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mg_rpc_send_responsef(ri, "{idx: %d, relay_state: %d}", idx, channel_get(idx));
|
mg_rpc_send_responsef(ri, "{idx: %d, relay_state: %d}", idx, channel_get(idx));
|
||||||
ri = NULL;
|
ri = NULL;
|
||||||
@ -114,6 +116,7 @@ static void rpc_channel_set_handler(struct mg_rpc_request_info *ri, void *cb_arg
|
|||||||
|
|
||||||
void rpc_init() {
|
void rpc_init() {
|
||||||
struct mg_rpc *c = mgos_rpc_get_global();
|
struct mg_rpc *c = mgos_rpc_get_global();
|
||||||
|
|
||||||
mg_rpc_add_handler(c, "Channel.Toggle", "{idx: %d}", rpc_channel_toggle_handler, NULL);
|
mg_rpc_add_handler(c, "Channel.Toggle", "{idx: %d}", rpc_channel_toggle_handler, NULL);
|
||||||
mg_rpc_add_handler(c, "Channel.Get", "{idx: %d}", rpc_channel_get_handler, NULL);
|
mg_rpc_add_handler(c, "Channel.Get", "{idx: %d}", rpc_channel_get_handler, NULL);
|
||||||
mg_rpc_add_handler(c, "Channel.Set", "{idx: %d, value: %d}", rpc_channel_set_handler, NULL);
|
mg_rpc_add_handler(c, "Channel.Set", "{idx: %d, value: %d}", rpc_channel_set_handler, NULL);
|
||||||
|
@ -11,8 +11,9 @@ static void statusled_off_cb(void *arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void statusled_blink() {
|
void statusled_blink() {
|
||||||
if (statusled_gpio == GPIO_INVALID)
|
if (statusled_gpio == GPIO_INVALID) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mgos_gpio_write(statusled_gpio, !statusled_off_state);
|
mgos_gpio_write(statusled_gpio, !statusled_off_state);
|
||||||
if (statusled_timer_id) {
|
if (statusled_timer_id) {
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#define vsnprintf cs_win_vsnprintf
|
#define vsnprintf cs_win_vsnprintf
|
||||||
int cs_win_snprintf(char *str, size_t size, const char *format, ...);
|
int cs_win_snprintf(char *str, size_t size, const char *format, ...);
|
||||||
int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap);
|
int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap);
|
||||||
|
|
||||||
#if _MSC_VER >= 1700
|
#if _MSC_VER >= 1700
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#else
|
#else
|
||||||
@ -114,7 +115,10 @@ struct fstate {
|
|||||||
static int append_to_path(struct frozen *f, const char *str, int size) {
|
static int append_to_path(struct frozen *f, const char *str, int size) {
|
||||||
int n = f->path_len;
|
int n = f->path_len;
|
||||||
int left = sizeof(f->path) - n - 1;
|
int left = sizeof(f->path) - n - 1;
|
||||||
if (size > left) size = left;
|
|
||||||
|
if (size > left) {
|
||||||
|
size = left;
|
||||||
|
}
|
||||||
memcpy(f->path + n, str, size);
|
memcpy(f->path + n, str, size);
|
||||||
f->path[n + size] = '\0';
|
f->path[n + size] = '\0';
|
||||||
f->path_len += size;
|
f->path_len += size;
|
||||||
@ -131,13 +135,13 @@ static int parse_value(struct frozen *f);
|
|||||||
|
|
||||||
#define EXPECT(cond, err_code) \
|
#define EXPECT(cond, err_code) \
|
||||||
do { \
|
do { \
|
||||||
if (!(cond)) return (err_code); \
|
if (!(cond)) { return (err_code); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TRY(expr) \
|
#define TRY(expr) \
|
||||||
do { \
|
do { \
|
||||||
int _n = expr; \
|
int _n = expr; \
|
||||||
if (_n < 0) return _n; \
|
if (_n < 0) { return _n; } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define END_OF_STRING (-1)
|
#define END_OF_STRING (-1)
|
||||||
@ -151,7 +155,9 @@ static int is_space(int ch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void skip_whitespaces(struct frozen *f) {
|
static void skip_whitespaces(struct frozen *f) {
|
||||||
while (f->cur < f->end && is_space(*f->cur)) f->cur++;
|
while (f->cur < f->end && is_space(*f->cur)) {
|
||||||
|
f->cur++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cur(struct frozen *f) {
|
static int cur(struct frozen *f) {
|
||||||
@ -161,6 +167,7 @@ static int cur(struct frozen *f) {
|
|||||||
|
|
||||||
static int test_and_skip(struct frozen *f, int expected) {
|
static int test_and_skip(struct frozen *f, int expected) {
|
||||||
int ch = cur(f);
|
int ch = cur(f);
|
||||||
|
|
||||||
if (ch == expected) {
|
if (ch == expected) {
|
||||||
f->cur++;
|
f->cur++;
|
||||||
return 0;
|
return 0;
|
||||||
@ -188,6 +195,7 @@ static int get_escape_len(const char *s, int len) {
|
|||||||
is_hex_digit(s[3]) && is_hex_digit(s[4])
|
is_hex_digit(s[3]) && is_hex_digit(s[4])
|
||||||
? 5
|
? 5
|
||||||
: JSON_STRING_INVALID;
|
: JSON_STRING_INVALID;
|
||||||
|
|
||||||
case '"':
|
case '"':
|
||||||
case '\\':
|
case '\\':
|
||||||
case '/':
|
case '/':
|
||||||
@ -197,6 +205,7 @@ static int get_escape_len(const char *s, int len) {
|
|||||||
case 'r':
|
case 'r':
|
||||||
case 't':
|
case 't':
|
||||||
return len < 2 ? JSON_STRING_INCOMPLETE : 1;
|
return len < 2 ? JSON_STRING_INCOMPLETE : 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return JSON_STRING_INVALID;
|
return JSON_STRING_INVALID;
|
||||||
}
|
}
|
||||||
@ -218,12 +227,16 @@ static int parse_identifier(struct frozen *f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int get_utf8_char_len(unsigned char ch) {
|
static int get_utf8_char_len(unsigned char ch) {
|
||||||
if ((ch & 0x80) == 0) return 1;
|
if ((ch & 0x80) == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
switch (ch & 0xf0) {
|
switch (ch & 0xf0) {
|
||||||
case 0xf0:
|
case 0xf0:
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
case 0xe0:
|
case 0xe0:
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@ -232,6 +245,7 @@ static int get_utf8_char_len(unsigned char ch) {
|
|||||||
/* string = '"' { quoted_printable_chars } '"' */
|
/* string = '"' { quoted_printable_chars } '"' */
|
||||||
static int parse_string(struct frozen *f) {
|
static int parse_string(struct frozen *f) {
|
||||||
int n, ch = 0, len = 0;
|
int n, ch = 0, len = 0;
|
||||||
|
|
||||||
TRY(test_and_skip(f, '"'));
|
TRY(test_and_skip(f, '"'));
|
||||||
{
|
{
|
||||||
SET_STATE(f, f->cur, "", 0);
|
SET_STATE(f, f->cur, "", 0);
|
||||||
@ -248,7 +262,8 @@ static int parse_string(struct frozen *f) {
|
|||||||
CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr);
|
CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr);
|
||||||
f->cur++;
|
f->cur++;
|
||||||
break;
|
break;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ch == '"' ? 0 : JSON_STRING_INCOMPLETE;
|
return ch == '"' ? 0 : JSON_STRING_INCOMPLETE;
|
||||||
@ -257,24 +272,35 @@ static int parse_string(struct frozen *f) {
|
|||||||
/* number = [ '-' ] digit+ [ '.' digit+ ] [ ['e'|'E'] ['+'|'-'] digit+ ] */
|
/* number = [ '-' ] digit+ [ '.' digit+ ] [ ['e'|'E'] ['+'|'-'] digit+ ] */
|
||||||
static int parse_number(struct frozen *f) {
|
static int parse_number(struct frozen *f) {
|
||||||
int ch = cur(f);
|
int ch = cur(f);
|
||||||
|
|
||||||
SET_STATE(f, f->cur, "", 0);
|
SET_STATE(f, f->cur, "", 0);
|
||||||
if (ch == '-') f->cur++;
|
if (ch == '-') {
|
||||||
|
f->cur++;
|
||||||
|
}
|
||||||
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
|
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
|
||||||
EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
|
EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
|
||||||
while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
|
while (f->cur < f->end && is_digit(f->cur[0])) {
|
||||||
|
f->cur++;
|
||||||
|
}
|
||||||
if (f->cur < f->end && f->cur[0] == '.') {
|
if (f->cur < f->end && f->cur[0] == '.') {
|
||||||
f->cur++;
|
f->cur++;
|
||||||
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
|
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
|
||||||
EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
|
EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
|
||||||
while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
|
while (f->cur < f->end && is_digit(f->cur[0])) {
|
||||||
|
f->cur++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) {
|
if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) {
|
||||||
f->cur++;
|
f->cur++;
|
||||||
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
|
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
|
||||||
if ((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++;
|
if ((f->cur[0] == '+' || f->cur[0] == '-')) {
|
||||||
|
f->cur++;
|
||||||
|
}
|
||||||
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
|
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
|
||||||
EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
|
EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
|
||||||
while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
|
while (f->cur < f->end && is_digit(f->cur[0])) {
|
||||||
|
f->cur++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
truncate_path(f, fstate.path_len);
|
truncate_path(f, fstate.path_len);
|
||||||
CALL_BACK(f, JSON_TYPE_NUMBER, fstate.ptr, f->cur - fstate.ptr);
|
CALL_BACK(f, JSON_TYPE_NUMBER, fstate.ptr, f->cur - fstate.ptr);
|
||||||
@ -285,6 +311,7 @@ static int parse_number(struct frozen *f) {
|
|||||||
static int parse_array(struct frozen *f) {
|
static int parse_array(struct frozen *f) {
|
||||||
int i = 0, current_path_len;
|
int i = 0, current_path_len;
|
||||||
char buf[20];
|
char buf[20];
|
||||||
|
|
||||||
CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0);
|
CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0);
|
||||||
TRY(test_and_skip(f, '['));
|
TRY(test_and_skip(f, '['));
|
||||||
{
|
{
|
||||||
@ -299,7 +326,9 @@ static int parse_array(struct frozen *f) {
|
|||||||
f->cur_name_len = strlen(buf) - 2 /*braces*/;
|
f->cur_name_len = strlen(buf) - 2 /*braces*/;
|
||||||
TRY(parse_value(f));
|
TRY(parse_value(f));
|
||||||
truncate_path(f, current_path_len);
|
truncate_path(f, current_path_len);
|
||||||
if (cur(f) == ',') f->cur++;
|
if (cur(f) == ',') {
|
||||||
|
f->cur++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TRY(test_and_skip(f, ']'));
|
TRY(test_and_skip(f, ']'));
|
||||||
truncate_path(f, fstate.path_len);
|
truncate_path(f, fstate.path_len);
|
||||||
@ -312,10 +341,15 @@ static int parse_array(struct frozen *f) {
|
|||||||
static int expect(struct frozen *f, const char *s, int len,
|
static int expect(struct frozen *f, const char *s, int len,
|
||||||
enum json_token_type tok_type) {
|
enum json_token_type tok_type) {
|
||||||
int i, n = left(f);
|
int i, n = left(f);
|
||||||
|
|
||||||
SET_STATE(f, f->cur, "", 0);
|
SET_STATE(f, f->cur, "", 0);
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (i >= n) return JSON_STRING_INCOMPLETE;
|
if (i >= n) {
|
||||||
if (f->cur[i] != s[i]) return JSON_STRING_INVALID;
|
return JSON_STRING_INCOMPLETE;
|
||||||
|
}
|
||||||
|
if (f->cur[i] != s[i]) {
|
||||||
|
return JSON_STRING_INVALID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
f->cur += len;
|
f->cur += len;
|
||||||
truncate_path(f, fstate.path_len);
|
truncate_path(f, fstate.path_len);
|
||||||
@ -333,21 +367,27 @@ static int parse_value(struct frozen *f) {
|
|||||||
case '"':
|
case '"':
|
||||||
TRY(parse_string(f));
|
TRY(parse_string(f));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '{':
|
case '{':
|
||||||
TRY(parse_object(f));
|
TRY(parse_object(f));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
TRY(parse_array(f));
|
TRY(parse_array(f));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
TRY(expect(f, "null", 4, JSON_TYPE_NULL));
|
TRY(expect(f, "null", 4, JSON_TYPE_NULL));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
TRY(expect(f, "true", 4, JSON_TYPE_TRUE));
|
TRY(expect(f, "true", 4, JSON_TYPE_TRUE));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
TRY(expect(f, "false", 5, JSON_TYPE_FALSE));
|
TRY(expect(f, "false", 5, JSON_TYPE_FALSE));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
case '0':
|
case '0':
|
||||||
case '1':
|
case '1':
|
||||||
@ -361,6 +401,7 @@ static int parse_value(struct frozen *f) {
|
|||||||
case '9':
|
case '9':
|
||||||
TRY(parse_number(f));
|
TRY(parse_number(f));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID;
|
return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID;
|
||||||
}
|
}
|
||||||
@ -371,6 +412,7 @@ static int parse_value(struct frozen *f) {
|
|||||||
/* key = identifier | string */
|
/* key = identifier | string */
|
||||||
static int parse_key(struct frozen *f) {
|
static int parse_key(struct frozen *f) {
|
||||||
int ch = cur(f);
|
int ch = cur(f);
|
||||||
|
|
||||||
if (is_alpha(ch)) {
|
if (is_alpha(ch)) {
|
||||||
TRY(parse_identifier(f));
|
TRY(parse_identifier(f));
|
||||||
} else if (ch == '"') {
|
} else if (ch == '"') {
|
||||||
@ -385,6 +427,7 @@ static int parse_key(struct frozen *f) {
|
|||||||
static int parse_pair(struct frozen *f) {
|
static int parse_pair(struct frozen *f) {
|
||||||
int current_path_len;
|
int current_path_len;
|
||||||
const char *tok;
|
const char *tok;
|
||||||
|
|
||||||
skip_whitespaces(f);
|
skip_whitespaces(f);
|
||||||
tok = f->cur;
|
tok = f->cur;
|
||||||
TRY(parse_key(f));
|
TRY(parse_key(f));
|
||||||
@ -407,7 +450,9 @@ static int parse_object(struct frozen *f) {
|
|||||||
SET_STATE(f, f->cur - 1, ".", 1);
|
SET_STATE(f, f->cur - 1, ".", 1);
|
||||||
while (cur(f) != '}') {
|
while (cur(f) != '}') {
|
||||||
TRY(parse_pair(f));
|
TRY(parse_pair(f));
|
||||||
if (cur(f) == ',') f->cur++;
|
if (cur(f) == ',') {
|
||||||
|
f->cur++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TRY(test_and_skip(f, '}'));
|
TRY(test_and_skip(f, '}'));
|
||||||
truncate_path(f, fstate.path_len);
|
truncate_path(f, fstate.path_len);
|
||||||
@ -417,12 +462,17 @@ static int parse_object(struct frozen *f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int doit(struct frozen *f) {
|
static int doit(struct frozen *f) {
|
||||||
if (f->cur == 0 || f->end < f->cur) return JSON_STRING_INVALID;
|
if (f->cur == 0 || f->end < f->cur) {
|
||||||
if (f->end == f->cur) return JSON_STRING_INCOMPLETE;
|
return JSON_STRING_INVALID;
|
||||||
|
}
|
||||||
|
if (f->end == f->cur) {
|
||||||
|
return JSON_STRING_INCOMPLETE;
|
||||||
|
}
|
||||||
return parse_value(f);
|
return parse_value(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int json_escape(struct json_out *out, const char *p, size_t len) WEAK;
|
int json_escape(struct json_out *out, const char *p, size_t len) WEAK;
|
||||||
|
|
||||||
int json_escape(struct json_out *out, const char *p, size_t len) {
|
int json_escape(struct json_out *out, const char *p, size_t len) {
|
||||||
size_t i, cl, n = 0;
|
size_t i, cl, n = 0;
|
||||||
const char *hex_digits = "0123456789abcdef";
|
const char *hex_digits = "0123456789abcdef";
|
||||||
@ -452,20 +502,25 @@ int json_escape(struct json_out *out, const char *p, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int json_printer_buf(struct json_out *out, const char *buf, size_t len) WEAK;
|
int json_printer_buf(struct json_out *out, const char *buf, size_t len) WEAK;
|
||||||
|
|
||||||
int json_printer_buf(struct json_out *out, const char *buf, size_t len) {
|
int json_printer_buf(struct json_out *out, const char *buf, size_t len) {
|
||||||
size_t avail = out->u.buf.size - out->u.buf.len;
|
size_t avail = out->u.buf.size - out->u.buf.len;
|
||||||
size_t n = len < avail ? len : avail;
|
size_t n = len < avail ? len : avail;
|
||||||
|
|
||||||
memcpy(out->u.buf.buf + out->u.buf.len, buf, n);
|
memcpy(out->u.buf.buf + out->u.buf.len, buf, n);
|
||||||
out->u.buf.len += n;
|
out->u.buf.len += n;
|
||||||
if (out->u.buf.size > 0) {
|
if (out->u.buf.size > 0) {
|
||||||
size_t idx = out->u.buf.len;
|
size_t idx = out->u.buf.len;
|
||||||
if (idx >= out->u.buf.size) idx = out->u.buf.size - 1;
|
if (idx >= out->u.buf.size) {
|
||||||
|
idx = out->u.buf.size - 1;
|
||||||
|
}
|
||||||
out->u.buf.buf[idx] = '\0';
|
out->u.buf.buf[idx] = '\0';
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int json_printer_file(struct json_out *out, const char *buf, size_t len) WEAK;
|
int json_printer_file(struct json_out *out, const char *buf, size_t len) WEAK;
|
||||||
|
|
||||||
int json_printer_file(struct json_out *out, const char *buf, size_t len) {
|
int json_printer_file(struct json_out *out, const char *buf, size_t len) {
|
||||||
return fwrite(buf, 1, len, out->u.fp);
|
return fwrite(buf, 1, len, out->u.fp);
|
||||||
}
|
}
|
||||||
@ -508,14 +563,19 @@ static unsigned char hexdec(const char *s) {
|
|||||||
static int b64enc(struct json_out *out, const unsigned char *p, int n) {
|
static int b64enc(struct json_out *out, const unsigned char *p, int n) {
|
||||||
char buf[4];
|
char buf[4];
|
||||||
int i, len = 0;
|
int i, len = 0;
|
||||||
|
|
||||||
for (i = 0; i < n; i += 3) {
|
for (i = 0; i < n; i += 3) {
|
||||||
int a = p[i], b = i + 1 < n ? p[i + 1] : 0, c = i + 2 < n ? p[i + 2] : 0;
|
int a = p[i], b = i + 1 < n ? p[i + 1] : 0, c = i + 2 < n ? p[i + 2] : 0;
|
||||||
buf[0] = b64idx(a >> 2);
|
buf[0] = b64idx(a >> 2);
|
||||||
buf[1] = b64idx((a & 3) << 4 | (b >> 4));
|
buf[1] = b64idx((a & 3) << 4 | (b >> 4));
|
||||||
buf[2] = b64idx((b & 15) << 2 | (c >> 6));
|
buf[2] = b64idx((b & 15) << 2 | (c >> 6));
|
||||||
buf[3] = b64idx(c & 63);
|
buf[3] = b64idx(c & 63);
|
||||||
if (i + 1 >= n) buf[2] = '=';
|
if (i + 1 >= n) {
|
||||||
if (i + 2 >= n) buf[3] = '=';
|
buf[2] = '=';
|
||||||
|
}
|
||||||
|
if (i + 2 >= n) {
|
||||||
|
buf[3] = '=';
|
||||||
|
}
|
||||||
len += out->printer(out, buf, sizeof(buf));
|
len += out->printer(out, buf, sizeof(buf));
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
@ -524,6 +584,7 @@ static int b64enc(struct json_out *out, const unsigned char *p, int n) {
|
|||||||
static int b64dec(const char *src, int n, char *dst) {
|
static int b64dec(const char *src, int n, char *dst) {
|
||||||
const char *end = src + n;
|
const char *end = src + n;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
while (src + 3 < end) {
|
while (src + 3 < end) {
|
||||||
int a = b64rev(src[0]), b = b64rev(src[1]), c = b64rev(src[2]),
|
int a = b64rev(src[0]), b = b64rev(src[1]), c = b64rev(src[2]),
|
||||||
d = b64rev(src[3]);
|
d = b64rev(src[3]);
|
||||||
@ -540,10 +601,12 @@ static int b64dec(const char *src, int n, char *dst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int json_vprintf(struct json_out *out, const char *fmt, va_list xap) WEAK;
|
int json_vprintf(struct json_out *out, const char *fmt, va_list xap) WEAK;
|
||||||
|
|
||||||
int json_vprintf(struct json_out *out, const char *fmt, va_list xap) {
|
int json_vprintf(struct json_out *out, const char *fmt, va_list xap) {
|
||||||
int len = 0;
|
int len = 0;
|
||||||
const char *quote = "\"", *null = "null";
|
const char *quote = "\"", *null = "null";
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_copy(ap, xap);
|
va_copy(ap, xap);
|
||||||
|
|
||||||
while (*fmt != '\0') {
|
while (*fmt != '\0') {
|
||||||
@ -644,7 +707,9 @@ int json_vprintf(struct json_out *out, const char *fmt, va_list xap) {
|
|||||||
while (need_len < 0) {
|
while (need_len < 0) {
|
||||||
free(pbuf);
|
free(pbuf);
|
||||||
size *= 2;
|
size *= 2;
|
||||||
if ((pbuf = (char *) malloc(size)) == NULL) break;
|
if ((pbuf = (char *)malloc(size)) == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
va_copy(ap_copy, ap);
|
va_copy(ap_copy, ap);
|
||||||
need_len = vsnprintf(pbuf, size, fmt2, ap_copy);
|
need_len = vsnprintf(pbuf, size, fmt2, ap_copy);
|
||||||
va_end(ap_copy);
|
va_end(ap_copy);
|
||||||
@ -684,13 +749,16 @@ int json_vprintf(struct json_out *out, const char *fmt, va_list xap) {
|
|||||||
case 'd':
|
case 'd':
|
||||||
(void)va_arg(ap, int);
|
(void)va_arg(ap, int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'f':
|
case 'f':
|
||||||
(void)va_arg(ap, double);
|
(void)va_arg(ap, double);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
(void)va_arg(ap, void *);
|
(void)va_arg(ap, void *);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* many types are promoted to int */
|
/* many types are promoted to int */
|
||||||
(void)va_arg(ap, int);
|
(void)va_arg(ap, int);
|
||||||
@ -725,9 +793,11 @@ int json_vprintf(struct json_out *out, const char *fmt, va_list xap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int json_printf(struct json_out *out, const char *fmt, ...) WEAK;
|
int json_printf(struct json_out *out, const char *fmt, ...) WEAK;
|
||||||
|
|
||||||
int json_printf(struct json_out *out, const char *fmt, ...) {
|
int json_printf(struct json_out *out, const char *fmt, ...) {
|
||||||
int n;
|
int n;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
n = json_vprintf(out, fmt, ap);
|
n = json_vprintf(out, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
@ -735,12 +805,14 @@ int json_printf(struct json_out *out, const char *fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int json_printf_array(struct json_out *out, va_list *ap) WEAK;
|
int json_printf_array(struct json_out *out, va_list *ap) WEAK;
|
||||||
|
|
||||||
int json_printf_array(struct json_out *out, va_list *ap) {
|
int json_printf_array(struct json_out *out, va_list *ap) {
|
||||||
int len = 0;
|
int len = 0;
|
||||||
char * arr = va_arg(*ap, char *);
|
char * arr = va_arg(*ap, char *);
|
||||||
size_t i, arr_size = va_arg(*ap, size_t);
|
size_t i, arr_size = va_arg(*ap, size_t);
|
||||||
size_t elem_size = va_arg(*ap, size_t);
|
size_t elem_size = va_arg(*ap, size_t);
|
||||||
const char *fmt = va_arg(*ap, char *);
|
const char *fmt = va_arg(*ap, char *);
|
||||||
|
|
||||||
len += json_printf(out, "[", 1);
|
len += json_printf(out, "[", 1);
|
||||||
for (i = 0; arr != NULL && i < arr_size / elem_size; i++) {
|
for (i = 0; arr != NULL && i < arr_size / elem_size; i++) {
|
||||||
union {
|
union {
|
||||||
@ -749,7 +821,9 @@ int json_printf_array(struct json_out *out, va_list *ap) {
|
|||||||
} val;
|
} val;
|
||||||
memcpy(&val, arr + i * elem_size,
|
memcpy(&val, arr + i * elem_size,
|
||||||
elem_size > sizeof(val) ? sizeof(val) : elem_size);
|
elem_size > sizeof(val) ? sizeof(val) : elem_size);
|
||||||
if (i > 0) len += json_printf(out, ", ");
|
if (i > 0) {
|
||||||
|
len += json_printf(out, ", ");
|
||||||
|
}
|
||||||
if (strchr(fmt, 'f') != NULL) {
|
if (strchr(fmt, 'f') != NULL) {
|
||||||
len += json_printf(out, fmt, val.d);
|
len += json_printf(out, fmt, val.d);
|
||||||
} else {
|
} else {
|
||||||
@ -763,8 +837,10 @@ int json_printf_array(struct json_out *out, va_list *ap) {
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
int cs_win_vsnprintf(char *str, size_t size, const char *format,
|
int cs_win_vsnprintf(char *str, size_t size, const char *format,
|
||||||
va_list ap) WEAK;
|
va_list ap) WEAK;
|
||||||
|
|
||||||
int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
|
int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
|
||||||
int res = _vsnprintf(str, size, format, ap);
|
int res = _vsnprintf(str, size, format, ap);
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (res >= size) {
|
if (res >= size) {
|
||||||
str[size - 1] = '\0';
|
str[size - 1] = '\0';
|
||||||
@ -773,18 +849,22 @@ int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cs_win_snprintf(char *str, size_t size, const char *format, ...) WEAK;
|
int cs_win_snprintf(char *str, size_t size, const char *format, ...) WEAK;
|
||||||
|
|
||||||
int cs_win_snprintf(char *str, size_t size, const char *format, ...) {
|
int cs_win_snprintf(char *str, size_t size, const char *format, ...) {
|
||||||
int res;
|
int res;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
res = vsnprintf(str, size, format, ap);
|
res = vsnprintf(str, size, format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
int json_walk(const char *json_string, int json_string_length,
|
int json_walk(const char *json_string, int json_string_length,
|
||||||
json_walk_callback_t callback, void *callback_data) WEAK;
|
json_walk_callback_t callback, void *callback_data) WEAK;
|
||||||
|
|
||||||
int json_walk(const char *json_string, int json_string_length,
|
int json_walk(const char *json_string, int json_string_length,
|
||||||
json_walk_callback_t callback, void *callback_data) {
|
json_walk_callback_t callback, void *callback_data) {
|
||||||
struct frozen frozen;
|
struct frozen frozen;
|
||||||
@ -820,9 +900,11 @@ static void json_scanf_array_elem_cb(void *callback_data, const char *name,
|
|||||||
|
|
||||||
int json_scanf_array_elem(const char *s, int len, const char *path, int idx,
|
int json_scanf_array_elem(const char *s, int len, const char *path, int idx,
|
||||||
struct json_token *token) WEAK;
|
struct json_token *token) WEAK;
|
||||||
|
|
||||||
int json_scanf_array_elem(const char *s, int len, const char *path, int idx,
|
int json_scanf_array_elem(const char *s, int len, const char *path, int idx,
|
||||||
struct json_token *token) {
|
struct json_token *token) {
|
||||||
struct scan_array_info info;
|
struct scan_array_info info;
|
||||||
|
|
||||||
info.token = token;
|
info.token = token;
|
||||||
memset(token, 0, sizeof(*token));
|
memset(token, 0, sizeof(*token));
|
||||||
snprintf(info.path, sizeof(info.path), "%s[%d]", path, idx);
|
snprintf(info.path, sizeof(info.path), "%s[%d]", path, idx);
|
||||||
@ -840,23 +922,30 @@ struct json_scanf_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int json_unescape(const char *src, int slen, char *dst, int dlen) WEAK;
|
int json_unescape(const char *src, int slen, char *dst, int dlen) WEAK;
|
||||||
|
|
||||||
int json_unescape(const char *src, int slen, char *dst, int dlen) {
|
int json_unescape(const char *src, int slen, char *dst, int dlen) {
|
||||||
char * send = (char *)src + slen, *dend = dst + dlen, *orig_dst = dst, *p;
|
char * send = (char *)src + slen, *dend = dst + dlen, *orig_dst = dst, *p;
|
||||||
const char *esc1 = "\"\\/bfnrt", *esc2 = "\"\\/\b\f\n\r\t";
|
const char *esc1 = "\"\\/bfnrt", *esc2 = "\"\\/\b\f\n\r\t";
|
||||||
|
|
||||||
while (src < send) {
|
while (src < send) {
|
||||||
if (*src == '\\') {
|
if (*src == '\\') {
|
||||||
if (++src >= send) return JSON_STRING_INCOMPLETE;
|
if (++src >= send) {
|
||||||
|
return JSON_STRING_INCOMPLETE;
|
||||||
|
}
|
||||||
if (*src == 'u') {
|
if (*src == 'u') {
|
||||||
/* TODO(lsm): \uXXXX escapes drag utf8 lib... Do it at some stage */
|
/* TODO(lsm): \uXXXX escapes drag utf8 lib... Do it at some stage */
|
||||||
return JSON_STRING_INVALID;
|
return JSON_STRING_INVALID;
|
||||||
} else if ((p = (char *)strchr(esc1, *src)) != NULL) {
|
} else if ((p = (char *)strchr(esc1, *src)) != NULL) {
|
||||||
if (dst < dend) *dst = esc2[p - esc1];
|
if (dst < dend) {
|
||||||
|
*dst = esc2[p - esc1];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return JSON_STRING_INVALID;
|
return JSON_STRING_INVALID;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (dst < dend) *dst = *src;
|
if (dst < dend) {
|
||||||
|
*dst = *src;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dst++;
|
dst++;
|
||||||
src++;
|
src++;
|
||||||
@ -894,14 +983,17 @@ static void json_scanf_cb(void *callback_data, const char *name,
|
|||||||
case sizeof(char):
|
case sizeof(char):
|
||||||
*(char *)info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0);
|
*(char *)info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sizeof(int):
|
case sizeof(int):
|
||||||
*(int *)info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0);
|
*(int *)info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* should never be here */
|
/* should never be here */
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'M': {
|
case 'M': {
|
||||||
union {
|
union {
|
||||||
void * p;
|
void * p;
|
||||||
@ -911,6 +1003,7 @@ static void json_scanf_cb(void *callback_data, const char *name,
|
|||||||
u.f(token->ptr, token->len, info->user_data);
|
u.f(token->ptr, token->len, info->user_data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'Q': {
|
case 'Q': {
|
||||||
char **dst = (char **)info->target;
|
char **dst = (char **)info->target;
|
||||||
if (token->type == JSON_TYPE_NULL) {
|
if (token->type == JSON_TYPE_NULL) {
|
||||||
@ -926,6 +1019,7 @@ static void json_scanf_cb(void *callback_data, const char *name,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'H': {
|
case 'H': {
|
||||||
char **dst = (char **)info->user_data;
|
char **dst = (char **)info->user_data;
|
||||||
int i, len = token->len / 2;
|
int i, len = token->len / 2;
|
||||||
@ -939,6 +1033,7 @@ static void json_scanf_cb(void *callback_data, const char *name,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'V': {
|
case 'V': {
|
||||||
char **dst = (char **)info->target;
|
char **dst = (char **)info->target;
|
||||||
int len = token->len * 4 / 3 + 2;
|
int len = token->len * 4 / 3 + 2;
|
||||||
@ -950,10 +1045,12 @@ static void json_scanf_cb(void *callback_data, const char *name,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'T':
|
case 'T':
|
||||||
info->num_conversions++;
|
info->num_conversions++;
|
||||||
*(struct json_token *)info->target = *token;
|
*(struct json_token *)info->target = *token;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Before scanf, copy into tmp buffer in order to 0-terminate it */
|
/* Before scanf, copy into tmp buffer in order to 0-terminate it */
|
||||||
if (token->len < (int)sizeof(buf)) {
|
if (token->len < (int)sizeof(buf)) {
|
||||||
@ -966,6 +1063,7 @@ static void json_scanf_cb(void *callback_data, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int json_vscanf(const char *s, int len, const char *fmt, va_list ap) WEAK;
|
int json_vscanf(const char *s, int len, const char *fmt, va_list ap) WEAK;
|
||||||
|
|
||||||
int json_vscanf(const char *s, int len, const char *fmt, va_list ap) {
|
int json_vscanf(const char *s, int len, const char *fmt, va_list ap) {
|
||||||
char path[JSON_MAX_PATH_LEN] = "", fmtbuf[20];
|
char path[JSON_MAX_PATH_LEN] = "", fmtbuf[20];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -977,7 +1075,9 @@ int json_vscanf(const char *s, int len, const char *fmt, va_list ap) {
|
|||||||
strcat(path, ".");
|
strcat(path, ".");
|
||||||
i++;
|
i++;
|
||||||
} else if (fmt[i] == '}') {
|
} else if (fmt[i] == '}') {
|
||||||
if ((p = strrchr(path, '.')) != NULL) *p = '\0';
|
if ((p = strrchr(path, '.')) != NULL) {
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
} else if (fmt[i] == '%') {
|
} else if (fmt[i] == '%') {
|
||||||
info.target = va_arg(ap, void *);
|
info.target = va_arg(ap, void *);
|
||||||
@ -987,12 +1087,14 @@ int json_vscanf(const char *s, int len, const char *fmt, va_list ap) {
|
|||||||
case 'V':
|
case 'V':
|
||||||
case 'H':
|
case 'H':
|
||||||
info.user_data = va_arg(ap, void *);
|
info.user_data = va_arg(ap, void *);
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case 'B':
|
case 'B':
|
||||||
case 'Q':
|
case 'Q':
|
||||||
case 'T':
|
case 'T':
|
||||||
i += 2;
|
i += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
const char *delims = ", \t\r\n]}";
|
const char *delims = ", \t\r\n]}";
|
||||||
int conv_len = strcspn(fmt + i + 1, delims) + 1;
|
int conv_len = strcspn(fmt + i + 1, delims) + 1;
|
||||||
@ -1006,7 +1108,9 @@ int json_vscanf(const char *s, int len, const char *fmt, va_list ap) {
|
|||||||
} else if (is_alpha(fmt[i]) || get_utf8_char_len(fmt[i]) > 1) {
|
} else if (is_alpha(fmt[i]) || get_utf8_char_len(fmt[i]) > 1) {
|
||||||
const char *delims = ": \r\n\t";
|
const char *delims = ": \r\n\t";
|
||||||
int key_len = strcspn(&fmt[i], delims);
|
int key_len = strcspn(&fmt[i], delims);
|
||||||
if ((p = strrchr(path, '.')) != NULL) p[1] = '\0';
|
if ((p = strrchr(path, '.')) != NULL) {
|
||||||
|
p[1] = '\0';
|
||||||
|
}
|
||||||
sprintf(path + strlen(path), "%.*s", key_len, &fmt[i]);
|
sprintf(path + strlen(path), "%.*s", key_len, &fmt[i]);
|
||||||
i += key_len + strspn(fmt + i + key_len, delims);
|
i += key_len + strspn(fmt + i + key_len, delims);
|
||||||
} else {
|
} else {
|
||||||
@ -1017,9 +1121,11 @@ int json_vscanf(const char *s, int len, const char *fmt, va_list ap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int json_scanf(const char *str, int len, const char *fmt, ...) WEAK;
|
int json_scanf(const char *str, int len, const char *fmt, ...) WEAK;
|
||||||
|
|
||||||
int json_scanf(const char *str, int len, const char *fmt, ...) {
|
int json_scanf(const char *str, int len, const char *fmt, ...) {
|
||||||
int result;
|
int result;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
result = json_vscanf(str, len, fmt, ap);
|
result = json_vscanf(str, len, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
@ -1027,9 +1133,11 @@ int json_scanf(const char *str, int len, const char *fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int json_vfprintf(const char *file_name, const char *fmt, va_list ap) WEAK;
|
int json_vfprintf(const char *file_name, const char *fmt, va_list ap) WEAK;
|
||||||
|
|
||||||
int json_vfprintf(const char *file_name, const char *fmt, va_list ap) {
|
int json_vfprintf(const char *file_name, const char *fmt, va_list ap) {
|
||||||
int res = -1;
|
int res = -1;
|
||||||
FILE *fp = fopen(file_name, "wb");
|
FILE *fp = fopen(file_name, "wb");
|
||||||
|
|
||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
struct json_out out = JSON_OUT_FILE(fp);
|
struct json_out out = JSON_OUT_FILE(fp);
|
||||||
res = json_vprintf(&out, fmt, ap);
|
res = json_vprintf(&out, fmt, ap);
|
||||||
@ -1040,9 +1148,11 @@ int json_vfprintf(const char *file_name, const char *fmt, va_list ap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int json_fprintf(const char *file_name, const char *fmt, ...) WEAK;
|
int json_fprintf(const char *file_name, const char *fmt, ...) WEAK;
|
||||||
|
|
||||||
int json_fprintf(const char *file_name, const char *fmt, ...) {
|
int json_fprintf(const char *file_name, const char *fmt, ...) {
|
||||||
int result;
|
int result;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
result = json_vfprintf(file_name, fmt, ap);
|
result = json_vfprintf(file_name, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
@ -1050,9 +1160,11 @@ int json_fprintf(const char *file_name, const char *fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *json_fread(const char *path) WEAK;
|
char *json_fread(const char *path) WEAK;
|
||||||
|
|
||||||
char *json_fread(const char *path) {
|
char *json_fread(const char *path) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
|
|
||||||
if ((fp = fopen(path, "rb")) == NULL) {
|
if ((fp = fopen(path, "rb")) == NULL) {
|
||||||
} else if (fseek(fp, 0, SEEK_END) != 0) {
|
} else if (fseek(fp, 0, SEEK_END) != 0) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -1083,7 +1195,10 @@ struct json_setf_data {
|
|||||||
|
|
||||||
static int get_matched_prefix_len(const char *s1, const char *s2) {
|
static int get_matched_prefix_len(const char *s1, const char *s2) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (s1[i] && s2[i] && s1[i] == s2[i]) i++;
|
|
||||||
|
while (s1[i] && s2[i] && s1[i] == s2[i]) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1091,10 +1206,15 @@ static void json_vsetf_cb(void *userdata, const char *name, size_t name_len,
|
|||||||
const char *path, const struct json_token *t) {
|
const char *path, const struct json_token *t) {
|
||||||
struct json_setf_data *data = (struct json_setf_data *)userdata;
|
struct json_setf_data *data = (struct json_setf_data *)userdata;
|
||||||
int off, len = get_matched_prefix_len(path, data->json_path);
|
int off, len = get_matched_prefix_len(path, data->json_path);
|
||||||
if (t->ptr == NULL) return;
|
|
||||||
|
if (t->ptr == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
off = t->ptr - data->base;
|
off = t->ptr - data->base;
|
||||||
// printf("--%d %s %d\n", t->type, path, off);
|
// printf("--%d %s %d\n", t->type, path, off);
|
||||||
if (len > data->matched) data->matched = len;
|
if (len > data->matched) {
|
||||||
|
data->matched = len;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is no exact path match, set the mutation position to tbe end
|
* If there is no exact path match, set the mutation position to tbe end
|
||||||
@ -1132,9 +1252,11 @@ static void json_vsetf_cb(void *userdata, const char *name, size_t name_len,
|
|||||||
|
|
||||||
int json_vsetf(const char *s, int len, struct json_out *out,
|
int json_vsetf(const char *s, int len, struct json_out *out,
|
||||||
const char *json_path, const char *json_fmt, va_list ap) WEAK;
|
const char *json_path, const char *json_fmt, va_list ap) WEAK;
|
||||||
|
|
||||||
int json_vsetf(const char *s, int len, struct json_out *out,
|
int json_vsetf(const char *s, int len, struct json_out *out,
|
||||||
const char *json_path, const char *json_fmt, va_list ap) {
|
const char *json_path, const char *json_fmt, va_list ap) {
|
||||||
struct json_setf_data data;
|
struct json_setf_data data;
|
||||||
|
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
data.json_path = json_path;
|
data.json_path = json_path;
|
||||||
data.base = s;
|
data.base = s;
|
||||||
@ -1148,8 +1270,12 @@ int json_vsetf(const char *s, int len, struct json_out *out,
|
|||||||
/* Trim comma after the value that begins at object/array start */
|
/* Trim comma after the value that begins at object/array start */
|
||||||
if (s[data.prev - 1] == '{' || s[data.prev - 1] == '[') {
|
if (s[data.prev - 1] == '{' || s[data.prev - 1] == '[') {
|
||||||
int i = data.end;
|
int i = data.end;
|
||||||
while (i < len && is_space(s[i])) i++;
|
while (i < len && is_space(s[i])) {
|
||||||
if (s[i] == ',') data.end = i + 1; /* Point after comma */
|
i++;
|
||||||
|
}
|
||||||
|
if (s[i] == ',') {
|
||||||
|
data.end = i + 1; /* Point after comma */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
json_printf(out, "%.*s", len - data.end, s + data.end);
|
json_printf(out, "%.*s", len - data.end, s + data.end);
|
||||||
} else {
|
} else {
|
||||||
@ -1164,7 +1290,9 @@ int json_vsetf(const char *s, int len, struct json_out *out,
|
|||||||
if (s[data.prev - 1] != '{' && s[data.prev - 1] != '[' && depth == 0) {
|
if (s[data.prev - 1] != '{' && s[data.prev - 1] != '[' && depth == 0) {
|
||||||
json_printf(out, ",");
|
json_printf(out, ",");
|
||||||
}
|
}
|
||||||
if (off > 0 && json_path[off - 1] != '.') break;
|
if (off > 0 && json_path[off - 1] != '.') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
json_printf(out, "%.*Q:", 1, json_path + off);
|
json_printf(out, "%.*Q:", 1, json_path + off);
|
||||||
off += n;
|
off += n;
|
||||||
if (json_path[off] != '\0') {
|
if (json_path[off] != '\0') {
|
||||||
@ -1191,10 +1319,12 @@ int json_vsetf(const char *s, int len, struct json_out *out,
|
|||||||
|
|
||||||
int json_setf(const char *s, int len, struct json_out *out,
|
int json_setf(const char *s, int len, struct json_out *out,
|
||||||
const char *json_path, const char *json_fmt, ...) WEAK;
|
const char *json_path, const char *json_fmt, ...) WEAK;
|
||||||
|
|
||||||
int json_setf(const char *s, int len, struct json_out *out,
|
int json_setf(const char *s, int len, struct json_out *out,
|
||||||
const char *json_path, const char *json_fmt, ...) {
|
const char *json_path, const char *json_fmt, ...) {
|
||||||
int result;
|
int result;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, json_fmt);
|
va_start(ap, json_fmt);
|
||||||
result = json_vsetf(s, len, out, json_path, json_fmt, ap);
|
result = json_vsetf(s, len, out, json_path, json_fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
@ -1208,7 +1338,9 @@ struct prettify_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void indent(struct json_out *out, int level) {
|
static void indent(struct json_out *out, int level) {
|
||||||
while (level-- > 0) out->printer(out, " ", 2);
|
while (level-- > 0) {
|
||||||
|
out->printer(out, " ", 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_key(struct prettify_data *pd, const char *path,
|
static void print_key(struct prettify_data *pd, const char *path,
|
||||||
@ -1218,7 +1350,9 @@ static void print_key(struct prettify_data *pd, const char *path,
|
|||||||
pd->last_token != JSON_TYPE_OBJECT_START) {
|
pd->last_token != JSON_TYPE_OBJECT_START) {
|
||||||
pd->out->printer(pd->out, ",", 1);
|
pd->out->printer(pd->out, ",", 1);
|
||||||
}
|
}
|
||||||
if (path[0] != '\0') pd->out->printer(pd->out, "\n", 1);
|
if (path[0] != '\0') {
|
||||||
|
pd->out->printer(pd->out, "\n", 1);
|
||||||
|
}
|
||||||
indent(pd->out, pd->level);
|
indent(pd->out, pd->level);
|
||||||
if (path[0] != '\0' && path[strlen(path) - 1] != ']') {
|
if (path[0] != '\0' && path[strlen(path) - 1] != ']') {
|
||||||
pd->out->printer(pd->out, "\"", 1);
|
pd->out->printer(pd->out, "\"", 1);
|
||||||
@ -1231,6 +1365,7 @@ static void print_key(struct prettify_data *pd, const char *path,
|
|||||||
static void prettify_cb(void *userdata, const char *name, size_t name_len,
|
static void prettify_cb(void *userdata, const char *name, size_t name_len,
|
||||||
const char *path, const struct json_token *t) {
|
const char *path, const struct json_token *t) {
|
||||||
struct prettify_data *pd = (struct prettify_data *)userdata;
|
struct prettify_data *pd = (struct prettify_data *)userdata;
|
||||||
|
|
||||||
switch (t->type) {
|
switch (t->type) {
|
||||||
case JSON_TYPE_OBJECT_START:
|
case JSON_TYPE_OBJECT_START:
|
||||||
case JSON_TYPE_ARRAY_START:
|
case JSON_TYPE_ARRAY_START:
|
||||||
@ -1239,6 +1374,7 @@ static void prettify_cb(void *userdata, const char *name, size_t name_len,
|
|||||||
1);
|
1);
|
||||||
pd->level++;
|
pd->level++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSON_TYPE_OBJECT_END:
|
case JSON_TYPE_OBJECT_END:
|
||||||
case JSON_TYPE_ARRAY_END:
|
case JSON_TYPE_ARRAY_END:
|
||||||
pd->level--;
|
pd->level--;
|
||||||
@ -1250,16 +1386,22 @@ static void prettify_cb(void *userdata, const char *name, size_t name_len,
|
|||||||
}
|
}
|
||||||
pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_END ? "]" : "}", 1);
|
pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_END ? "]" : "}", 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSON_TYPE_NUMBER:
|
case JSON_TYPE_NUMBER:
|
||||||
case JSON_TYPE_NULL:
|
case JSON_TYPE_NULL:
|
||||||
case JSON_TYPE_TRUE:
|
case JSON_TYPE_TRUE:
|
||||||
case JSON_TYPE_FALSE:
|
case JSON_TYPE_FALSE:
|
||||||
case JSON_TYPE_STRING:
|
case JSON_TYPE_STRING:
|
||||||
print_key(pd, path, name, name_len);
|
print_key(pd, path, name, name_len);
|
||||||
if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1);
|
if (t->type == JSON_TYPE_STRING) {
|
||||||
|
pd->out->printer(pd->out, "\"", 1);
|
||||||
|
}
|
||||||
pd->out->printer(pd->out, t->ptr, t->len);
|
pd->out->printer(pd->out, t->ptr, t->len);
|
||||||
if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1);
|
if (t->type == JSON_TYPE_STRING) {
|
||||||
|
pd->out->printer(pd->out, "\"", 1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1267,16 +1409,20 @@ static void prettify_cb(void *userdata, const char *name, size_t name_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int json_prettify(const char *s, int len, struct json_out *out) WEAK;
|
int json_prettify(const char *s, int len, struct json_out *out) WEAK;
|
||||||
|
|
||||||
int json_prettify(const char *s, int len, struct json_out *out) {
|
int json_prettify(const char *s, int len, struct json_out *out) {
|
||||||
struct prettify_data pd = { out, 0, JSON_TYPE_INVALID };
|
struct prettify_data pd = { out, 0, JSON_TYPE_INVALID };
|
||||||
|
|
||||||
return json_walk(s, len, prettify_cb, &pd);
|
return json_walk(s, len, prettify_cb, &pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int json_prettify_file(const char *file_name) WEAK;
|
int json_prettify_file(const char *file_name) WEAK;
|
||||||
|
|
||||||
int json_prettify_file(const char *file_name) {
|
int json_prettify_file(const char *file_name) {
|
||||||
int res = -1;
|
int res = -1;
|
||||||
char *s = json_fread(file_name);
|
char *s = json_fread(file_name);
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
if (s != NULL && (fp = fopen(file_name, "wb")) != NULL) {
|
if (s != NULL && (fp = fopen(file_name, "wb")) != NULL) {
|
||||||
struct json_out out = JSON_OUT_FILE(fp);
|
struct json_out out = JSON_OUT_FILE(fp);
|
||||||
res = json_prettify(s, strlen(s), &out);
|
res = json_prettify(s, strlen(s), &out);
|
||||||
@ -1313,14 +1459,18 @@ static void next_set_key(struct next_data *d, const char *name, int name_len,
|
|||||||
d->key->len = 0;
|
d->key->len = 0;
|
||||||
d->key->ptr = NULL;
|
d->key->ptr = NULL;
|
||||||
}
|
}
|
||||||
if (d->idx != NULL) *d->idx = atoi(name);
|
if (d->idx != NULL) {
|
||||||
|
*d->idx = atoi(name);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Object. Set key and make index -1 */
|
/* Object. Set key and make index -1 */
|
||||||
if (d->key != NULL) {
|
if (d->key != NULL) {
|
||||||
d->key->ptr = name;
|
d->key->ptr = name;
|
||||||
d->key->len = name_len;
|
d->key->len = name_len;
|
||||||
}
|
}
|
||||||
if (d->idx != NULL) *d->idx = -1;
|
if (d->idx != NULL) {
|
||||||
|
*d->idx = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1328,11 +1478,22 @@ static void next_cb(void *userdata, const char *name, size_t name_len,
|
|||||||
const char *path, const struct json_token *t) {
|
const char *path, const struct json_token *t) {
|
||||||
struct next_data *d = (struct next_data *)userdata;
|
struct next_data *d = (struct next_data *)userdata;
|
||||||
const char * p = path + d->path_len;
|
const char * p = path + d->path_len;
|
||||||
if (d->found) return;
|
|
||||||
if (d->path_len >= (int) strlen(path)) return;
|
if (d->found) {
|
||||||
if (strncmp(d->path, path, d->path_len) != 0) return;
|
return;
|
||||||
if (strchr(p + 1, '.') != NULL) return; /* More nested objects - skip */
|
}
|
||||||
if (strchr(p + 1, '[') != NULL) return; /* Ditto for arrays */
|
if (d->path_len >= (int)strlen(path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (strncmp(d->path, path, d->path_len) != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (strchr(p + 1, '.') != NULL) {
|
||||||
|
return; /* More nested objects - skip */
|
||||||
|
}
|
||||||
|
if (strchr(p + 1, '[') != NULL) {
|
||||||
|
return; /* Ditto for arrays */
|
||||||
|
}
|
||||||
// {OBJECT,ARRAY}_END types do not pass name, _START does. Save key.
|
// {OBJECT,ARRAY}_END types do not pass name, _START does. Save key.
|
||||||
if (t->type == JSON_TYPE_OBJECT_START || t->type == JSON_TYPE_ARRAY_START) {
|
if (t->type == JSON_TYPE_OBJECT_START || t->type == JSON_TYPE_ARRAY_START) {
|
||||||
// printf("SAV %s %d %p\n", path, t->type, t->ptr);
|
// printf("SAV %s %d %p\n", path, t->type, t->ptr);
|
||||||
@ -1342,7 +1503,9 @@ static void next_cb(void *userdata, const char *name, size_t name_len,
|
|||||||
if (t->type != JSON_TYPE_OBJECT_END && t->type != JSON_TYPE_ARRAY_END) {
|
if (t->type != JSON_TYPE_OBJECT_END && t->type != JSON_TYPE_ARRAY_END) {
|
||||||
next_set_key(d, name, name_len, p[0] == '[');
|
next_set_key(d, name, name_len, p[0] == '[');
|
||||||
}
|
}
|
||||||
if (d->val != NULL) *d->val = *t;
|
if (d->val != NULL) {
|
||||||
|
*d->val = *t;
|
||||||
|
}
|
||||||
d->handle = (void *)t->ptr;
|
d->handle = (void *)t->ptr;
|
||||||
d->found = 1;
|
d->found = 1;
|
||||||
}
|
}
|
||||||
@ -1354,12 +1517,14 @@ static void *json_next(const char *s, int len, void *handle, const char *path,
|
|||||||
struct json_token tmpkey, *k = key == NULL ? &tmpkey : key;
|
struct json_token tmpkey, *k = key == NULL ? &tmpkey : key;
|
||||||
int tmpidx, *pidx = i == NULL ? &tmpidx : i;
|
int tmpidx, *pidx = i == NULL ? &tmpidx : i;
|
||||||
struct next_data data = { handle, path, strlen(path), 0, k, v, pidx };
|
struct next_data data = { handle, path, strlen(path), 0, k, v, pidx };
|
||||||
|
|
||||||
json_walk(s, len, next_cb, &data);
|
json_walk(s, len, next_cb, &data);
|
||||||
return data.found ? data.handle : NULL;
|
return data.found ? data.handle : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *json_next_key(const char *s, int len, void *handle, const char *path,
|
void *json_next_key(const char *s, int len, void *handle, const char *path,
|
||||||
struct json_token *key, struct json_token *val) WEAK;
|
struct json_token *key, struct json_token *val) WEAK;
|
||||||
|
|
||||||
void *json_next_key(const char *s, int len, void *handle, const char *path,
|
void *json_next_key(const char *s, int len, void *handle, const char *path,
|
||||||
struct json_token *key, struct json_token *val) {
|
struct json_token *key, struct json_token *val) {
|
||||||
return json_next(s, len, handle, path, key, val, NULL);
|
return json_next(s, len, handle, path, key, val, NULL);
|
||||||
@ -1367,6 +1532,7 @@ void *json_next_key(const char *s, int len, void *handle, const char *path,
|
|||||||
|
|
||||||
void *json_next_elem(const char *s, int len, void *handle, const char *path,
|
void *json_next_elem(const char *s, int len, void *handle, const char *path,
|
||||||
int *idx, struct json_token *val) WEAK;
|
int *idx, struct json_token *val) WEAK;
|
||||||
|
|
||||||
void *json_next_elem(const char *s, int len, void *handle, const char *path,
|
void *json_next_elem(const char *s, int len, void *handle, const char *path,
|
||||||
int *idx, struct json_token *val) {
|
int *idx, struct json_token *val) {
|
||||||
return json_next(s, len, handle, path, NULL, val, idx);
|
return json_next(s, len, handle, path, NULL, val, idx);
|
||||||
|
@ -18,6 +18,7 @@ bool mgos_gpio_set_button_handler(int pin, enum mgos_gpio_pull_type pull_type, e
|
|||||||
s_handler_cb_arg = arg;
|
s_handler_cb_arg = arg;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
(void)debounce_ms;
|
(void)debounce_ms;
|
||||||
(void)int_mode;
|
(void)int_mode;
|
||||||
(void)pull_type;
|
(void)pull_type;
|
||||||
@ -25,7 +26,7 @@ bool mgos_gpio_set_button_handler(int pin, enum mgos_gpio_pull_type pull_type, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
void mgos_gpio_inject(int pin) {
|
void mgos_gpio_inject(int pin) {
|
||||||
if (s_handler_cb)
|
if (s_handler_cb) {
|
||||||
s_handler_cb(pin, s_handler_cb_arg);
|
s_handler_cb(pin, s_handler_cb_arg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -12,18 +12,23 @@ int log_print_prefix(enum cs_log_level l, const char *func, const char *file) {
|
|||||||
case LL_ERROR:
|
case LL_ERROR:
|
||||||
strncpy(ll_str, "ERROR", sizeof(ll_str));
|
strncpy(ll_str, "ERROR", sizeof(ll_str));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LL_WARN:
|
case LL_WARN:
|
||||||
strncpy(ll_str, "WARN", sizeof(ll_str));
|
strncpy(ll_str, "WARN", sizeof(ll_str));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LL_INFO:
|
case LL_INFO:
|
||||||
strncpy(ll_str, "INFO", sizeof(ll_str));
|
strncpy(ll_str, "INFO", sizeof(ll_str));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LL_DEBUG:
|
case LL_DEBUG:
|
||||||
strncpy(ll_str, "DEBUG", sizeof(ll_str));
|
strncpy(ll_str, "DEBUG", sizeof(ll_str));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LL_VERBOSE_DEBUG:
|
case LL_VERBOSE_DEBUG:
|
||||||
strncpy(ll_str, "VERB", sizeof(ll_str));
|
strncpy(ll_str, "VERB", sizeof(ll_str));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // LL_NONE
|
default: // LL_NONE
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ int log_print_prefix(enum cs_log_level l, const char *func, const char *file);
|
|||||||
|
|
||||||
#define LOG(l, x) \
|
#define LOG(l, x) \
|
||||||
do { \
|
do { \
|
||||||
if (log_print_prefix(l, __func__, __FILE__)) printf x; \
|
if (log_print_prefix(l, __func__, __FILE__)) { printf x; } \
|
||||||
printf("\r\n"); \
|
printf("\r\n"); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -24,12 +24,12 @@ void mgos_mqtt_sub(char *t, sub_handler_t cb, void *ud) {
|
|||||||
void mgos_mqtt_inject(char *topic, char *msg) {
|
void mgos_mqtt_inject(char *topic, char *msg) {
|
||||||
LOG(LL_INFO, ("Injecting topic='%s' msg='%s'", topic, msg));
|
LOG(LL_INFO, ("Injecting topic='%s' msg='%s'", topic, msg));
|
||||||
mqtt_sub_count++;
|
mqtt_sub_count++;
|
||||||
if (s_handler)
|
if (s_handler) {
|
||||||
s_handler(NULL, topic, strlen(topic), msg, strlen(msg), s_handler_ud);
|
s_handler(NULL, topic, strlen(topic), msg, strlen(msg), s_handler_ud);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mgos_mqtt_add_global_handler(mqtt_event_handler_t handler, void *ud) {
|
void mgos_mqtt_add_global_handler(mqtt_event_handler_t handler, void *ud) {
|
||||||
s_global_handler = handler;
|
s_global_handler = handler;
|
||||||
s_global_handler_ud = ud;
|
s_global_handler_ud = ud;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/common.h"
|
#line 1 "mongoose/src/common.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004-2013 Sergey Lyubka
|
* Copyright (c) 2004-2013 Sergey Lyubka
|
||||||
* Copyright (c) 2013-2015 Cesanta Software Limited
|
* Copyright (c) 2013-2015 Cesanta Software Limited
|
||||||
@ -418,6 +419,7 @@ unsigned int sleep(unsigned int seconds);
|
|||||||
#if !(defined(__cplusplus) && __cplusplus >= 201103L) && \
|
#if !(defined(__cplusplus) && __cplusplus >= 201103L) && \
|
||||||
!(defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L)
|
!(defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L)
|
||||||
long long strtoll(const char *, char **, int);
|
long long strtoll(const char *, char **, int);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef int sock_t;
|
typedef int sock_t;
|
||||||
@ -492,6 +494,7 @@ typedef struct stat cs_stat_t;
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_esp32.h"
|
#line 1 "common/platforms/platform_esp32.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -537,6 +540,7 @@ typedef struct stat cs_stat_t;
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_esp8266.h"
|
#line 1 "common/platforms/platform_esp8266.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -596,6 +600,7 @@ typedef struct stat cs_stat_t;
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_cc3100.h"
|
#line 1 "common/platforms/platform_cc3100.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -645,6 +650,7 @@ int inet_pton(int af, const char *src, void *dst);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_cc3200.h"
|
#line 1 "common/platforms/platform_cc3200.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -770,6 +776,7 @@ int stat(const char *pathname, struct stat *st);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_msp432.h"
|
#line 1 "common/platforms/platform_msp432.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -819,6 +826,7 @@ extern "C" {
|
|||||||
struct SlTimeval_t;
|
struct SlTimeval_t;
|
||||||
#define timeval SlTimeval_t
|
#define timeval SlTimeval_t
|
||||||
int gettimeofday(struct timeval *t, void *tz);
|
int gettimeofday(struct timeval *t, void *tz);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TI's libc does not have stat & friends, add them. */
|
/* TI's libc does not have stat & friends, add them. */
|
||||||
@ -839,6 +847,7 @@ struct stat {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int _stat(const char *pathname, struct stat *st);
|
int _stat(const char *pathname, struct stat *st);
|
||||||
|
|
||||||
#define stat(a, b) _stat(a, b)
|
#define stat(a, b) _stat(a, b)
|
||||||
|
|
||||||
#define __S_IFMT 0170000
|
#define __S_IFMT 0170000
|
||||||
@ -878,6 +887,7 @@ int _stat(const char *pathname, struct stat *st);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_tm4c129.h"
|
#line 1 "common/platforms/platform_tm4c129.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -938,6 +948,7 @@ typedef struct stat cs_stat_t;
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_mbed.h"
|
#line 1 "common/platforms/platform_mbed.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1022,6 +1033,7 @@ in_addr_t inet_addr(const char *cp);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_nrf51.h"
|
#line 1 "common/platforms/platform_nrf51.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1052,6 +1064,7 @@ in_addr_t inet_addr(const char *cp);
|
|||||||
#else
|
#else
|
||||||
struct timeval;
|
struct timeval;
|
||||||
int gettimeofday(struct timeval *tp, void *tzp);
|
int gettimeofday(struct timeval *tp, void *tzp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define INT64_FMT PRId64
|
#define INT64_FMT PRId64
|
||||||
@ -1067,6 +1080,7 @@ int gettimeofday(struct timeval *tp, void *tzp);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_nrf52.h"
|
#line 1 "common/platforms/platform_nrf52.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1114,6 +1128,7 @@ int gettimeofday(struct timeval *tp, void *tzp);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/simplelink/cs_simplelink.h"
|
#line 1 "common/platforms/simplelink/cs_simplelink.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1145,6 +1160,7 @@ int gettimeofday(struct timeval *tp, void *tzp);
|
|||||||
#include <ti/drivers/net/wifi/sl_socket.h>
|
#include <ti/drivers/net/wifi/sl_socket.h>
|
||||||
#include <ti/drivers/net/wifi/netapp.h>
|
#include <ti/drivers/net/wifi/netapp.h>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* We want to disable SL_INC_STD_BSD_API_NAMING, so we include user.h ourselves
|
/* We want to disable SL_INC_STD_BSD_API_NAMING, so we include user.h ourselves
|
||||||
* and undef it. */
|
* and undef it. */
|
||||||
#define PROVISIONING_API_H_
|
#define PROVISIONING_API_H_
|
||||||
@ -1422,6 +1438,7 @@ typedef uint32_t in_addr_t;
|
|||||||
#ifndef BUFSIZ
|
#ifndef BUFSIZ
|
||||||
#define BUFSIZ 4096
|
#define BUFSIZ 4096
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Explicitly disabling MG_ENABLE_THREADS for WinCE
|
* Explicitly disabling MG_ENABLE_THREADS for WinCE
|
||||||
* because they are enabled for _WIN32 by default
|
* because they are enabled for _WIN32 by default
|
||||||
@ -1485,6 +1502,7 @@ const char *strerror();
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_nxp_lpc.h"
|
#line 1 "common/platforms/platform_nxp_lpc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1541,6 +1559,7 @@ typedef struct stat cs_stat_t;
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_nxp_kinetis.h"
|
#line 1 "common/platforms/platform_nxp_kinetis.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1575,6 +1594,7 @@ typedef struct stat cs_stat_t;
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_pic32.h"
|
#line 1 "common/platforms/platform_pic32.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1615,6 +1635,7 @@ char *inet_ntoa(struct in_addr in);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/platform_stm32.h"
|
#line 1 "common/platforms/platform_stm32.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1656,6 +1677,7 @@ typedef struct stat cs_stat_t;
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/platforms/lwip/mg_lwip.h"
|
#line 1 "common/platforms/lwip/mg_lwip.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1715,6 +1737,7 @@ struct mg_connection;
|
|||||||
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr);
|
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr);
|
||||||
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
|
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
|
||||||
int interval, int count);
|
int interval, int count);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For older version of LWIP */
|
/* For older version of LWIP */
|
||||||
@ -1728,6 +1751,7 @@ void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/cs_md5.h"
|
#line 1 "common/cs_md5.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1764,6 +1788,7 @@ void cs_md5_final(unsigned char *md, cs_md5_ctx *c);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/cs_sha1.h"
|
#line 1 "common/cs_sha1.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1792,6 +1817,7 @@ typedef struct {
|
|||||||
|
|
||||||
void cs_sha1_init(cs_sha1_ctx *);
|
void cs_sha1_init(cs_sha1_ctx *);
|
||||||
void cs_sha1_update(cs_sha1_ctx *, const unsigned char *data, uint32_t len);
|
void cs_sha1_update(cs_sha1_ctx *, const unsigned char *data, uint32_t len);
|
||||||
|
|
||||||
void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *);
|
void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *);
|
||||||
void cs_hmac_sha1(const unsigned char *key, size_t key_len,
|
void cs_hmac_sha1(const unsigned char *key, size_t key_len,
|
||||||
const unsigned char *text, size_t text_len,
|
const unsigned char *text, size_t text_len,
|
||||||
@ -1806,6 +1832,7 @@ void cs_hmac_sha1(const unsigned char *key, size_t key_len,
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/cs_time.h"
|
#line 1 "common/cs_time.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1839,6 +1866,7 @@ double cs_timegm(const struct tm *tm);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/mg_str.h"
|
#line 1 "common/mg_str.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1913,6 +1941,7 @@ const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/mbuf.h"
|
#line 1 "common/mbuf.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015 Cesanta Software Limited
|
* Copyright (c) 2015 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -1995,6 +2024,7 @@ void mbuf_trim(struct mbuf *);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/base64.h"
|
#line 1 "common/base64.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -2044,6 +2074,7 @@ int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "common/str_util.h"
|
#line 1 "common/str_util.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015 Cesanta Software Limited
|
* Copyright (c) 2015 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -2090,6 +2121,7 @@ extern "C" {
|
|||||||
size_t c_strnlen(const char *s, size_t maxlen);
|
size_t c_strnlen(const char *s, size_t maxlen);
|
||||||
int c_snprintf(char *buf, size_t buf_size, const char *format, ...);
|
int c_snprintf(char *buf, size_t buf_size, const char *format, ...);
|
||||||
int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);
|
int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the first occurrence of find in s, where the search is limited to the
|
* Find the first occurrence of find in s, where the search is limited to the
|
||||||
* first slen characters of s.
|
* first slen characters of s.
|
||||||
@ -2111,14 +2143,17 @@ void cs_from_hex(char *to, const char *p, size_t len);
|
|||||||
|
|
||||||
#if CS_ENABLE_STRDUP
|
#if CS_ENABLE_STRDUP
|
||||||
char *strdup(const char *src);
|
char *strdup(const char *src);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CS_ENABLE_TO64
|
#if CS_ENABLE_TO64
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simple string -> int64 conversion routine.
|
* Simple string -> int64 conversion routine.
|
||||||
*/
|
*/
|
||||||
int64_t cs_to64(const char *s);
|
int64_t cs_to64(const char *s);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2188,6 +2223,7 @@ int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
|
|||||||
#line 1 "common/queue.h"
|
#line 1 "common/queue.h"
|
||||||
#endif
|
#endif
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1991, 1993
|
* Copyright (c) 1991, 1993
|
||||||
* The Regents of the University of California. All rights reserved.
|
* The Regents of the University of California. All rights reserved.
|
||||||
@ -2334,6 +2370,7 @@ struct qm_trace {
|
|||||||
#endif /* QUEUE_MACRO_DEBUG */
|
#endif /* QUEUE_MACRO_DEBUG */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In C++ there can be structure lists and class lists:
|
* In C++ there can be structure lists and class lists:
|
||||||
*/
|
*/
|
||||||
@ -2423,8 +2460,8 @@ struct { \
|
|||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
QUEUE_TYPEOF(type) * curelm = SLIST_FIRST(head); \
|
QUEUE_TYPEOF(type) * curelm = SLIST_FIRST(head); \
|
||||||
while (SLIST_NEXT(curelm, field) != (elm)) \
|
while (SLIST_NEXT(curelm, field) != (elm)) { \
|
||||||
curelm = SLIST_NEXT(curelm, field); \
|
curelm = SLIST_NEXT(curelm, field); } \
|
||||||
SLIST_REMOVE_AFTER(curelm, field); \
|
SLIST_REMOVE_AFTER(curelm, field); \
|
||||||
} \
|
} \
|
||||||
TRASHIT(*oldnext); \
|
TRASHIT(*oldnext); \
|
||||||
@ -2514,14 +2551,14 @@ struct { \
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
||||||
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
|
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL) { \
|
||||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
(head)->stqh_last = &STAILQ_NEXT((elm), field); } \
|
||||||
STAILQ_NEXT((tqelm), field) = (elm); \
|
STAILQ_NEXT((tqelm), field) = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) { \
|
||||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
(head)->stqh_last = &STAILQ_NEXT((elm), field); } \
|
||||||
STAILQ_FIRST((head)) = (elm); \
|
STAILQ_FIRST((head)) = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@ -2545,8 +2582,8 @@ struct { \
|
|||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
QUEUE_TYPEOF(type) * curelm = STAILQ_FIRST(head); \
|
QUEUE_TYPEOF(type) * curelm = STAILQ_FIRST(head); \
|
||||||
while (STAILQ_NEXT(curelm, field) != (elm)) \
|
while (STAILQ_NEXT(curelm, field) != (elm)) { \
|
||||||
curelm = STAILQ_NEXT(curelm, field); \
|
curelm = STAILQ_NEXT(curelm, field); } \
|
||||||
STAILQ_REMOVE_AFTER(head, curelm, field); \
|
STAILQ_REMOVE_AFTER(head, curelm, field); \
|
||||||
} \
|
} \
|
||||||
TRASHIT(*oldnext); \
|
TRASHIT(*oldnext); \
|
||||||
@ -2554,14 +2591,14 @@ struct { \
|
|||||||
|
|
||||||
#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
|
#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
|
||||||
if ((STAILQ_NEXT(elm, field) = \
|
if ((STAILQ_NEXT(elm, field) = \
|
||||||
STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
|
STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) { \
|
||||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
(head)->stqh_last = &STAILQ_NEXT((elm), field); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
||||||
if ((STAILQ_FIRST((head)) = \
|
if ((STAILQ_FIRST((head)) = \
|
||||||
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) { \
|
||||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
(head)->stqh_last = &STAILQ_FIRST((head)); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_SWAP(head1, head2, type) do { \
|
#define STAILQ_SWAP(head1, head2, type) do { \
|
||||||
@ -2571,10 +2608,10 @@ struct { \
|
|||||||
(head1)->stqh_last = (head2)->stqh_last; \
|
(head1)->stqh_last = (head2)->stqh_last; \
|
||||||
STAILQ_FIRST(head2) = swap_first; \
|
STAILQ_FIRST(head2) = swap_first; \
|
||||||
(head2)->stqh_last = swap_last; \
|
(head2)->stqh_last = swap_last; \
|
||||||
if (STAILQ_EMPTY(head1)) \
|
if (STAILQ_EMPTY(head1)) { \
|
||||||
(head1)->stqh_last = &STAILQ_FIRST(head1); \
|
(head1)->stqh_last = &STAILQ_FIRST(head1); } \
|
||||||
if (STAILQ_EMPTY(head2)) \
|
if (STAILQ_EMPTY(head2)) { \
|
||||||
(head2)->stqh_last = &STAILQ_FIRST(head2); \
|
(head2)->stqh_last = &STAILQ_FIRST(head2); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
@ -2614,20 +2651,20 @@ struct { \
|
|||||||
#define QMD_LIST_CHECK_HEAD(head, field) do { \
|
#define QMD_LIST_CHECK_HEAD(head, field) do { \
|
||||||
if (LIST_FIRST((head)) != NULL && \
|
if (LIST_FIRST((head)) != NULL && \
|
||||||
LIST_FIRST((head))->field.le_prev != \
|
LIST_FIRST((head))->field.le_prev != \
|
||||||
&LIST_FIRST((head))) \
|
&LIST_FIRST((head))) { \
|
||||||
panic("Bad list head %p first->prev != head", (head)); \
|
panic("Bad list head %p first->prev != head", (head)); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define QMD_LIST_CHECK_NEXT(elm, field) do { \
|
#define QMD_LIST_CHECK_NEXT(elm, field) do { \
|
||||||
if (LIST_NEXT((elm), field) != NULL && \
|
if (LIST_NEXT((elm), field) != NULL && \
|
||||||
LIST_NEXT((elm), field)->field.le_prev != \
|
LIST_NEXT((elm), field)->field.le_prev != \
|
||||||
&((elm)->field.le_next)) \
|
&((elm)->field.le_next)) { \
|
||||||
panic("Bad link elm %p next->prev != elm", (elm)); \
|
panic("Bad link elm %p next->prev != elm", (elm)); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define QMD_LIST_CHECK_PREV(elm, field) do { \
|
#define QMD_LIST_CHECK_PREV(elm, field) do { \
|
||||||
if (*(elm)->field.le_prev != (elm)) \
|
if (*(elm)->field.le_prev != (elm)) { \
|
||||||
panic("Bad link elm %p prev->next != elm", (elm)); \
|
panic("Bad link elm %p prev->next != elm", (elm)); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define QMD_LIST_CHECK_HEAD(head, field)
|
#define QMD_LIST_CHECK_HEAD(head, field)
|
||||||
@ -2665,9 +2702,9 @@ struct { \
|
|||||||
|
|
||||||
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||||
QMD_LIST_CHECK_NEXT(listelm, field); \
|
QMD_LIST_CHECK_NEXT(listelm, field); \
|
||||||
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
|
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) { \
|
||||||
LIST_NEXT((listelm), field)->field.le_prev = \
|
LIST_NEXT((listelm), field)->field.le_prev = \
|
||||||
&LIST_NEXT((elm), field); \
|
&LIST_NEXT((elm), field); } \
|
||||||
LIST_NEXT((listelm), field) = (elm); \
|
LIST_NEXT((listelm), field) = (elm); \
|
||||||
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -2682,8 +2719,8 @@ struct { \
|
|||||||
|
|
||||||
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||||
QMD_LIST_CHECK_HEAD((head), field); \
|
QMD_LIST_CHECK_HEAD((head), field); \
|
||||||
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) { \
|
||||||
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
|
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); } \
|
||||||
LIST_FIRST((head)) = (elm); \
|
LIST_FIRST((head)) = (elm); \
|
||||||
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -2700,9 +2737,9 @@ struct { \
|
|||||||
QMD_SAVELINK(oldprev, (elm)->field.le_prev); \
|
QMD_SAVELINK(oldprev, (elm)->field.le_prev); \
|
||||||
QMD_LIST_CHECK_NEXT(elm, field); \
|
QMD_LIST_CHECK_NEXT(elm, field); \
|
||||||
QMD_LIST_CHECK_PREV(elm, field); \
|
QMD_LIST_CHECK_PREV(elm, field); \
|
||||||
if (LIST_NEXT((elm), field) != NULL) \
|
if (LIST_NEXT((elm), field) != NULL) { \
|
||||||
LIST_NEXT((elm), field)->field.le_prev = \
|
LIST_NEXT((elm), field)->field.le_prev = \
|
||||||
(elm)->field.le_prev; \
|
(elm)->field.le_prev; } \
|
||||||
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||||
TRASHIT(*oldnext); \
|
TRASHIT(*oldnext); \
|
||||||
TRASHIT(*oldprev); \
|
TRASHIT(*oldprev); \
|
||||||
@ -2712,10 +2749,10 @@ struct { \
|
|||||||
QUEUE_TYPEOF(type) * swap_tmp = LIST_FIRST(head1); \
|
QUEUE_TYPEOF(type) * swap_tmp = LIST_FIRST(head1); \
|
||||||
LIST_FIRST((head1)) = LIST_FIRST((head2)); \
|
LIST_FIRST((head1)) = LIST_FIRST((head2)); \
|
||||||
LIST_FIRST((head2)) = swap_tmp; \
|
LIST_FIRST((head2)) = swap_tmp; \
|
||||||
if ((swap_tmp = LIST_FIRST((head1))) != NULL) \
|
if ((swap_tmp = LIST_FIRST((head1))) != NULL) { \
|
||||||
swap_tmp->field.le_prev = &LIST_FIRST((head1)); \
|
swap_tmp->field.le_prev = &LIST_FIRST((head1)); } \
|
||||||
if ((swap_tmp = LIST_FIRST((head2))) != NULL) \
|
if ((swap_tmp = LIST_FIRST((head2))) != NULL) { \
|
||||||
swap_tmp->field.le_prev = &LIST_FIRST((head2)); \
|
swap_tmp->field.le_prev = &LIST_FIRST((head2)); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2759,25 +2796,25 @@ struct { \
|
|||||||
#define QMD_TAILQ_CHECK_HEAD(head, field) do { \
|
#define QMD_TAILQ_CHECK_HEAD(head, field) do { \
|
||||||
if (!TAILQ_EMPTY(head) && \
|
if (!TAILQ_EMPTY(head) && \
|
||||||
TAILQ_FIRST((head))->field.tqe_prev != \
|
TAILQ_FIRST((head))->field.tqe_prev != \
|
||||||
&TAILQ_FIRST((head))) \
|
&TAILQ_FIRST((head))) { \
|
||||||
panic("Bad tailq head %p first->prev != head", (head)); \
|
panic("Bad tailq head %p first->prev != head", (head)); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define QMD_TAILQ_CHECK_TAIL(head, field) do { \
|
#define QMD_TAILQ_CHECK_TAIL(head, field) do { \
|
||||||
if (*(head)->tqh_last != NULL) \
|
if (*(head)->tqh_last != NULL) { \
|
||||||
panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \
|
panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
|
#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
|
||||||
if (TAILQ_NEXT((elm), field) != NULL && \
|
if (TAILQ_NEXT((elm), field) != NULL && \
|
||||||
TAILQ_NEXT((elm), field)->field.tqe_prev != \
|
TAILQ_NEXT((elm), field)->field.tqe_prev != \
|
||||||
&((elm)->field.tqe_next)) \
|
&((elm)->field.tqe_next)) { \
|
||||||
panic("Bad link elm %p next->prev != elm", (elm)); \
|
panic("Bad link elm %p next->prev != elm", (elm)); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define QMD_TAILQ_CHECK_PREV(elm, field) do { \
|
#define QMD_TAILQ_CHECK_PREV(elm, field) do { \
|
||||||
if (*(elm)->field.tqe_prev != (elm)) \
|
if (*(elm)->field.tqe_prev != (elm)) { \
|
||||||
panic("Bad link elm %p prev->next != elm", (elm)); \
|
panic("Bad link elm %p prev->next != elm", (elm)); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define QMD_TAILQ_CHECK_HEAD(head, field)
|
#define QMD_TAILQ_CHECK_HEAD(head, field)
|
||||||
@ -2849,9 +2886,9 @@ struct { \
|
|||||||
|
|
||||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
QMD_TAILQ_CHECK_NEXT(listelm, field); \
|
QMD_TAILQ_CHECK_NEXT(listelm, field); \
|
||||||
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
|
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL) { \
|
||||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||||
&TAILQ_NEXT((elm), field); \
|
&TAILQ_NEXT((elm), field); } \
|
||||||
else { \
|
else { \
|
||||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||||
QMD_TRACE_HEAD(head); \
|
QMD_TRACE_HEAD(head); \
|
||||||
@ -2874,11 +2911,11 @@ struct { \
|
|||||||
|
|
||||||
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
QMD_TAILQ_CHECK_HEAD(head, field); \
|
QMD_TAILQ_CHECK_HEAD(head, field); \
|
||||||
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) { \
|
||||||
TAILQ_FIRST((head))->field.tqe_prev = \
|
TAILQ_FIRST((head))->field.tqe_prev = \
|
||||||
&TAILQ_NEXT((elm), field); \
|
&TAILQ_NEXT((elm), field); } \
|
||||||
else \
|
else{ \
|
||||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
(head)->tqh_last = &TAILQ_NEXT((elm), field); } \
|
||||||
TAILQ_FIRST((head)) = (elm); \
|
TAILQ_FIRST((head)) = (elm); \
|
||||||
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
||||||
QMD_TRACE_HEAD(head); \
|
QMD_TRACE_HEAD(head); \
|
||||||
@ -2908,9 +2945,9 @@ struct { \
|
|||||||
QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
|
QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
|
||||||
QMD_TAILQ_CHECK_NEXT(elm, field); \
|
QMD_TAILQ_CHECK_NEXT(elm, field); \
|
||||||
QMD_TAILQ_CHECK_PREV(elm, field); \
|
QMD_TAILQ_CHECK_PREV(elm, field); \
|
||||||
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
if ((TAILQ_NEXT((elm), field)) != NULL) { \
|
||||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||||
(elm)->field.tqe_prev; \
|
(elm)->field.tqe_prev; } \
|
||||||
else { \
|
else { \
|
||||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||||
QMD_TRACE_HEAD(head); \
|
QMD_TRACE_HEAD(head); \
|
||||||
@ -2928,20 +2965,21 @@ struct { \
|
|||||||
(head1)->tqh_last = (head2)->tqh_last; \
|
(head1)->tqh_last = (head2)->tqh_last; \
|
||||||
(head2)->tqh_first = swap_first; \
|
(head2)->tqh_first = swap_first; \
|
||||||
(head2)->tqh_last = swap_last; \
|
(head2)->tqh_last = swap_last; \
|
||||||
if ((swap_first = (head1)->tqh_first) != NULL) \
|
if ((swap_first = (head1)->tqh_first) != NULL) { \
|
||||||
swap_first->field.tqe_prev = &(head1)->tqh_first; \
|
swap_first->field.tqe_prev = &(head1)->tqh_first; } \
|
||||||
else \
|
else{ \
|
||||||
(head1)->tqh_last = &(head1)->tqh_first; \
|
(head1)->tqh_last = &(head1)->tqh_first; } \
|
||||||
if ((swap_first = (head2)->tqh_first) != NULL) \
|
if ((swap_first = (head2)->tqh_first) != NULL) { \
|
||||||
swap_first->field.tqe_prev = &(head2)->tqh_first; \
|
swap_first->field.tqe_prev = &(head2)->tqh_first; } \
|
||||||
else \
|
else{ \
|
||||||
(head2)->tqh_last = &(head2)->tqh_first; \
|
(head2)->tqh_last = &(head2)->tqh_first; } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#endif /* !_SYS_QUEUE_H_ */
|
#endif /* !_SYS_QUEUE_H_ */
|
||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/features.h"
|
#line 1 "mongoose/src/features.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -3125,6 +3163,7 @@ struct { \
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/net_if.h"
|
#line 1 "mongoose/src/net_if.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -3213,6 +3252,7 @@ struct mg_iface *mg_if_create_iface(const struct mg_iface_vtable *vtable,
|
|||||||
struct mg_iface *mg_find_iface(struct mg_mgr *mgr,
|
struct mg_iface *mg_find_iface(struct mg_mgr *mgr,
|
||||||
const struct mg_iface_vtable *vtable,
|
const struct mg_iface_vtable *vtable,
|
||||||
struct mg_iface *from);
|
struct mg_iface *from);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deliver a new TCP connection. Returns NULL in case on error (unable to
|
* Deliver a new TCP connection. Returns NULL in case on error (unable to
|
||||||
* create connection, in which case interface state should be discarded.
|
* create connection, in which case interface state should be discarded.
|
||||||
@ -3225,8 +3265,10 @@ void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
|
|||||||
|
|
||||||
/* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */
|
/* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */
|
||||||
void mg_if_connect_cb(struct mg_connection *nc, int err);
|
void mg_if_connect_cb(struct mg_connection *nc, int err);
|
||||||
|
|
||||||
/* Callback that reports that data has been put on the wire. */
|
/* Callback that reports that data has been put on the wire. */
|
||||||
void mg_if_sent_cb(struct mg_connection *nc, int num_sent);
|
void mg_if_sent_cb(struct mg_connection *nc, int num_sent);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receive callback.
|
* Receive callback.
|
||||||
* if `own` is true, buf must be heap-allocated and ownership is transferred
|
* if `own` is true, buf must be heap-allocated and ownership is transferred
|
||||||
@ -3234,6 +3276,7 @@ void mg_if_sent_cb(struct mg_connection *nc, int num_sent);
|
|||||||
* Core will acknowledge consumption by calling iface::recved.
|
* Core will acknowledge consumption by calling iface::recved.
|
||||||
*/
|
*/
|
||||||
void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own);
|
void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receive callback.
|
* Receive callback.
|
||||||
* buf must be heap-allocated and ownership is transferred to the core.
|
* buf must be heap-allocated and ownership is transferred to the core.
|
||||||
@ -3258,6 +3301,7 @@ void mg_if_timer(struct mg_connection *c, double now);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/ssl_if.h"
|
#line 1 "mongoose/src/ssl_if.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 Cesanta Software Limited
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -3316,6 +3360,7 @@ int mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/net.h"
|
#line 1 "mongoose/src/net.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -3437,6 +3482,7 @@ struct mg_connection {
|
|||||||
void *user_data; /* User-specific data */
|
void *user_data; /* User-specific data */
|
||||||
union {
|
union {
|
||||||
void *v;
|
void *v;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the C standard is fussy about fitting function pointers into
|
* the C standard is fussy about fitting function pointers into
|
||||||
* void pointers, since some archs might have fat pointers for functions.
|
* void pointers, since some archs might have fat pointers for functions.
|
||||||
@ -3533,6 +3579,7 @@ void mg_mgr_free(struct mg_mgr *);
|
|||||||
time_t mg_mgr_poll(struct mg_mgr *, int milli);
|
time_t mg_mgr_poll(struct mg_mgr *, int milli);
|
||||||
|
|
||||||
#if MG_ENABLE_BROADCAST
|
#if MG_ENABLE_BROADCAST
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Passes a message of a given length to all connections.
|
* Passes a message of a given length to all connections.
|
||||||
*
|
*
|
||||||
@ -3547,6 +3594,7 @@ time_t mg_mgr_poll(struct mg_mgr *, int milli);
|
|||||||
*/
|
*/
|
||||||
void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data,
|
void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data,
|
||||||
size_t len);
|
size_t len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3610,6 +3658,7 @@ struct mg_bind_opts {
|
|||||||
const char **error_string; /* Placeholder for the error string */
|
const char **error_string; /* Placeholder for the error string */
|
||||||
struct mg_iface *iface; /* Interface instance */
|
struct mg_iface *iface; /* Interface instance */
|
||||||
#if MG_ENABLE_SSL
|
#if MG_ENABLE_SSL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SSL settings.
|
* SSL settings.
|
||||||
*
|
*
|
||||||
@ -3617,11 +3666,13 @@ struct mg_bind_opts {
|
|||||||
* present to tunnel dispatcher (for tunneled connections).
|
* present to tunnel dispatcher (for tunneled connections).
|
||||||
*/
|
*/
|
||||||
const char *ssl_cert;
|
const char *ssl_cert;
|
||||||
|
|
||||||
/* Private key corresponding to the certificate. If ssl_cert is set but
|
/* Private key corresponding to the certificate. If ssl_cert is set but
|
||||||
* ssl_key is not, ssl_cert is used. */
|
* ssl_key is not, ssl_cert is used. */
|
||||||
const char *ssl_key;
|
const char *ssl_key;
|
||||||
/* CA bundle used to verify client certificates or tunnel dispatchers. */
|
/* CA bundle used to verify client certificates or tunnel dispatchers. */
|
||||||
const char *ssl_ca_cert;
|
const char *ssl_ca_cert;
|
||||||
|
|
||||||
/* Colon-delimited list of acceptable cipher suites.
|
/* Colon-delimited list of acceptable cipher suites.
|
||||||
* Names depend on the library used, for example:
|
* Names depend on the library used, for example:
|
||||||
*
|
*
|
||||||
@ -3645,6 +3696,7 @@ struct mg_bind_opts {
|
|||||||
struct mg_connection *mg_bind(struct mg_mgr *mgr, const char *address,
|
struct mg_connection *mg_bind(struct mg_mgr *mgr, const char *address,
|
||||||
MG_CB(mg_event_handler_t handler,
|
MG_CB(mg_event_handler_t handler,
|
||||||
void *user_data));
|
void *user_data));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates a listening connection.
|
* Creates a listening connection.
|
||||||
*
|
*
|
||||||
@ -3676,21 +3728,25 @@ struct mg_connect_opts {
|
|||||||
struct mg_iface *iface; /* Interface instance */
|
struct mg_iface *iface; /* Interface instance */
|
||||||
const char *nameserver; /* DNS server to use, NULL for default */
|
const char *nameserver; /* DNS server to use, NULL for default */
|
||||||
#if MG_ENABLE_SSL
|
#if MG_ENABLE_SSL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SSL settings.
|
* SSL settings.
|
||||||
* Client certificate to present to the server.
|
* Client certificate to present to the server.
|
||||||
*/
|
*/
|
||||||
const char *ssl_cert;
|
const char *ssl_cert;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Private key corresponding to the certificate.
|
* Private key corresponding to the certificate.
|
||||||
* If ssl_cert is set but ssl_key is not, ssl_cert is used.
|
* If ssl_cert is set but ssl_key is not, ssl_cert is used.
|
||||||
*/
|
*/
|
||||||
const char *ssl_key;
|
const char *ssl_key;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify server certificate using this CA bundle. If set to "*", then SSL
|
* Verify server certificate using this CA bundle. If set to "*", then SSL
|
||||||
* is enabled but no cert verification is performed.
|
* is enabled but no cert verification is performed.
|
||||||
*/
|
*/
|
||||||
const char *ssl_ca_cert;
|
const char *ssl_ca_cert;
|
||||||
|
|
||||||
/* Colon-delimited list of acceptable cipher suites.
|
/* Colon-delimited list of acceptable cipher suites.
|
||||||
* Names depend on the library used, for example:
|
* Names depend on the library used, for example:
|
||||||
*
|
*
|
||||||
@ -3703,6 +3759,7 @@ struct mg_connect_opts {
|
|||||||
* If NULL, a reasonable default is used.
|
* If NULL, a reasonable default is used.
|
||||||
*/
|
*/
|
||||||
const char *ssl_cipher_suites;
|
const char *ssl_cipher_suites;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Server name verification. If ssl_ca_cert is set and the certificate has
|
* Server name verification. If ssl_ca_cert is set and the certificate has
|
||||||
* passed verification, its subject will be verified against this string.
|
* passed verification, its subject will be verified against this string.
|
||||||
@ -3711,6 +3768,7 @@ struct mg_connect_opts {
|
|||||||
* name verification.
|
* name verification.
|
||||||
*/
|
*/
|
||||||
const char *ssl_server_name;
|
const char *ssl_server_name;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PSK identity and key. Identity is a NUL-terminated string and key is a hex
|
* PSK identity and key. Identity is a NUL-terminated string and key is a hex
|
||||||
* string. Key must be either 16 or 32 bytes (32 or 64 hex digits) for AES-128
|
* string. Key must be either 16 or 32 bytes (32 or 64 hex digits) for AES-128
|
||||||
@ -3786,6 +3844,7 @@ struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
|
|||||||
struct mg_connect_opts opts);
|
struct mg_connect_opts opts);
|
||||||
|
|
||||||
#if MG_ENABLE_SSL && MG_NET_IF != MG_NET_IF_SIMPLELINK
|
#if MG_ENABLE_SSL && MG_NET_IF != MG_NET_IF_SIMPLELINK
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: This function is deprecated. Please, use SSL options in
|
* Note: This function is deprecated. Please, use SSL options in
|
||||||
* mg_connect_opt.
|
* mg_connect_opt.
|
||||||
@ -3802,6 +3861,7 @@ struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
|
|||||||
*/
|
*/
|
||||||
const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
|
const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
|
||||||
const char *ca_cert);
|
const char *ca_cert);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3837,6 +3897,7 @@ int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
|
|||||||
int mg_socketpair(sock_t[2], int sock_type);
|
int mg_socketpair(sock_t[2], int sock_type);
|
||||||
|
|
||||||
#if MG_ENABLE_SYNC_RESOLVER
|
#if MG_ENABLE_SYNC_RESOLVER
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert domain name into IP address.
|
* Convert domain name into IP address.
|
||||||
*
|
*
|
||||||
@ -3848,6 +3909,7 @@ int mg_socketpair(sock_t[2], int sock_type);
|
|||||||
* Return 1 on success, 0 on failure.
|
* Return 1 on success, 0 on failure.
|
||||||
*/
|
*/
|
||||||
int mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
|
int mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3911,6 +3973,7 @@ double mg_time(void);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/uri.h"
|
#line 1 "mongoose/src/uri.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -3981,6 +4044,7 @@ int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/util.h"
|
#line 1 "mongoose/src/util.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -4042,6 +4106,7 @@ int mg_base64_decode(const unsigned char *s, int len, char *dst);
|
|||||||
void mg_base64_encode(const unsigned char *src, int src_len, char *dst);
|
void mg_base64_encode(const unsigned char *src, int src_len, char *dst);
|
||||||
|
|
||||||
#if MG_ENABLE_FILESYSTEM
|
#if MG_ENABLE_FILESYSTEM
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs a 64-bit `stat()` call against a given file.
|
* Performs a 64-bit `stat()` call against a given file.
|
||||||
*
|
*
|
||||||
@ -4086,6 +4151,7 @@ size_t mg_fwrite(const void *ptr, size_t size, size_t count, FILE *f);
|
|||||||
#endif /* MG_ENABLE_FILESYSTEM */
|
#endif /* MG_ENABLE_FILESYSTEM */
|
||||||
|
|
||||||
#if MG_ENABLE_THREADS
|
#if MG_ENABLE_THREADS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Starts a new detached thread.
|
* Starts a new detached thread.
|
||||||
* Arguments and semantics are the same as pthead's `pthread_create()`.
|
* Arguments and semantics are the same as pthead's `pthread_create()`.
|
||||||
@ -4093,6 +4159,7 @@ size_t mg_fwrite(const void *ptr, size_t size, size_t count, FILE *f);
|
|||||||
* that is passed to the thread function.
|
* that is passed to the thread function.
|
||||||
*/
|
*/
|
||||||
void *mg_start_thread(void *(*thread_func)(void *), void *thread_func_param);
|
void *mg_start_thread(void *(*thread_func)(void *), void *thread_func_param);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void mg_set_close_on_exec(sock_t);
|
void mg_set_close_on_exec(sock_t);
|
||||||
@ -4100,6 +4167,7 @@ void mg_set_close_on_exec(sock_t);
|
|||||||
#define MG_SOCK_STRINGIFY_IP 1
|
#define MG_SOCK_STRINGIFY_IP 1
|
||||||
#define MG_SOCK_STRINGIFY_PORT 2
|
#define MG_SOCK_STRINGIFY_PORT 2
|
||||||
#define MG_SOCK_STRINGIFY_REMOTE 4
|
#define MG_SOCK_STRINGIFY_REMOTE 4
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Converts a connection's local or remote address into string.
|
* Converts a connection's local or remote address into string.
|
||||||
*
|
*
|
||||||
@ -4116,9 +4184,11 @@ void mg_set_close_on_exec(sock_t);
|
|||||||
*/
|
*/
|
||||||
int mg_conn_addr_to_str(struct mg_connection *c, char *buf, size_t len,
|
int mg_conn_addr_to_str(struct mg_connection *c, char *buf, size_t len,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
#if MG_NET_IF == MG_NET_IF_SOCKET
|
#if MG_NET_IF == MG_NET_IF_SOCKET
|
||||||
/* Legacy interface. */
|
/* Legacy interface. */
|
||||||
void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
|
void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4130,6 +4200,7 @@ int mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
|
|||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
#if MG_ENABLE_HEXDUMP
|
#if MG_ENABLE_HEXDUMP
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates a human-readable hexdump of memory chunk.
|
* Generates a human-readable hexdump of memory chunk.
|
||||||
*
|
*
|
||||||
@ -4152,6 +4223,7 @@ void mg_hexdumpf(FILE *fp, const void *buf, int len);
|
|||||||
*/
|
*/
|
||||||
void mg_hexdump_connection(struct mg_connection *nc, const char *path,
|
void mg_hexdump_connection(struct mg_connection *nc, const char *path,
|
||||||
const void *buf, int num_bytes, int ev);
|
const void *buf, int num_bytes, int ev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4192,6 +4264,7 @@ struct mg_str mg_url_encode(const struct mg_str src);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/http.h"
|
#line 1 "mongoose/src/http.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -4361,6 +4434,7 @@ struct mg_ssi_call_ctx {
|
|||||||
void mg_set_protocol_http_websocket(struct mg_connection *nc);
|
void mg_set_protocol_http_websocket(struct mg_connection *nc);
|
||||||
|
|
||||||
#if MG_ENABLE_HTTP_WEBSOCKET
|
#if MG_ENABLE_HTTP_WEBSOCKET
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send websocket handshake to the server.
|
* Send websocket handshake to the server.
|
||||||
*
|
*
|
||||||
@ -4537,6 +4611,7 @@ extern void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[],
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/http_server.h"
|
#line 1 "mongoose/src/http_server.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* === Server API reference
|
* === Server API reference
|
||||||
*/
|
*/
|
||||||
@ -4657,6 +4732,7 @@ int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,
|
|||||||
size_t dst_len);
|
size_t dst_len);
|
||||||
|
|
||||||
#if MG_ENABLE_FILESYSTEM
|
#if MG_ENABLE_FILESYSTEM
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This structure defines how `mg_serve_http()` works.
|
* This structure defines how `mg_serve_http()` works.
|
||||||
* Best practice is to set only required settings, and leave the rest as NULL.
|
* Best practice is to set only required settings, and leave the rest as NULL.
|
||||||
@ -4759,6 +4835,7 @@ struct mg_serve_http_opts {
|
|||||||
const char *ip_acl;
|
const char *ip_acl;
|
||||||
|
|
||||||
#if MG_ENABLE_HTTP_URL_REWRITES
|
#if MG_ENABLE_HTTP_URL_REWRITES
|
||||||
|
|
||||||
/* URL rewrites.
|
/* URL rewrites.
|
||||||
*
|
*
|
||||||
* Comma-separated list of `uri_pattern=url_file_or_directory_path` rewrites.
|
* Comma-separated list of `uri_pattern=url_file_or_directory_path` rewrites.
|
||||||
@ -5055,6 +5132,7 @@ void mg_send_head(struct mg_connection *n, int status_code,
|
|||||||
void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
|
void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
|
||||||
|
|
||||||
#if MG_ENABLE_HTTP_URL_REWRITES
|
#if MG_ENABLE_HTTP_URL_REWRITES
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Proxies a given request to a given upstream http server. The path prefix
|
* Proxies a given request to a given upstream http server. The path prefix
|
||||||
* in `mount` will be stripped of the path requested to the upstream server,
|
* in `mount` will be stripped of the path requested to the upstream server,
|
||||||
@ -5068,6 +5146,7 @@ void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
|
|||||||
void mg_http_reverse_proxy(struct mg_connection *nc,
|
void mg_http_reverse_proxy(struct mg_connection *nc,
|
||||||
const struct http_message *hm, struct mg_str mount,
|
const struct http_message *hm, struct mg_str mount,
|
||||||
struct mg_str upstream);
|
struct mg_str upstream);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -5080,6 +5159,7 @@ void mg_http_reverse_proxy(struct mg_connection *nc,
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/http_client.h"
|
#line 1 "mongoose/src/http_client.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* === Client API reference
|
* === Client API reference
|
||||||
*/
|
*/
|
||||||
@ -5145,6 +5225,7 @@ int mg_http_create_digest_auth_header(char *buf, size_t buf_len,
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/mqtt.h"
|
#line 1 "mongoose/src/mqtt.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -5376,6 +5457,7 @@ int mg_mqtt_vmatch_topic_expression(const char *exp, struct mg_str topic);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/mqtt_server.h"
|
#line 1 "mongoose/src/mqtt_server.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -5483,6 +5565,7 @@ struct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk,
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/dns.h"
|
#line 1 "mongoose/src/dns.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -5650,6 +5733,7 @@ void mg_set_protocol_dns(struct mg_connection *nc);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/dns_server.h"
|
#line 1 "mongoose/src/dns_server.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -5747,6 +5831,7 @@ void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/resolv.h"
|
#line 1 "mongoose/src/resolv.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Cesanta Software Limited
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -5831,6 +5916,7 @@ int mg_resolve_from_hosts_file(const char *host, union socket_address *usa);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/coap.h"
|
#line 1 "mongoose/src/coap.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015 Cesanta Software Limited
|
* Copyright (c) 2015 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -5999,6 +6085,7 @@ uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io);
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/sntp.h"
|
#line 1 "mongoose/src/sntp.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016 Cesanta Software Limited
|
* Copyright (c) 2016 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -6056,6 +6143,7 @@ struct mg_connection *mg_sntp_get_time(struct mg_mgr *mgr,
|
|||||||
#ifdef MG_MODULE_LINES
|
#ifdef MG_MODULE_LINES
|
||||||
#line 1 "mongoose/src/socks.h"
|
#line 1 "mongoose/src/socks.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017 Cesanta Software Limited
|
* Copyright (c) 2017 Cesanta Software Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
|
@ -5,5 +5,3 @@ int test_buttons() {
|
|||||||
channel_init("testdata/testconfig1.json");
|
channel_init("testdata/testconfig1.json");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user