int main( void ) { int i; println("is_empty: %d", lstack_is_empty()); for ( i = 0; i < 10; i++ ) { lstack_push( i + 1 ); } println("is_empty: %d", lstack_is_empty()); for ( i = 0; i < 10; i++ ) { lstack_pop(); } println("is_empty: %d", lstack_is_empty()); exit(0); }
void log_msg(int msg_log_level, time_t *rawtime, const char *source, const char *format, const va_list args) { char buffer[20], lls_buffer[10]; log_entry *ent = malloc(sizeof(log_entry)); if(ent == NULL) { pthread_mutex_lock(&mxs); fprintf(log_stream, "in log_msg: memory allocation failed: (%s)\n", strerror(errno)); pthread_mutex_unlock(&mxs); goto ON_ERROR; } memset(ent, 0, sizeof(log_entry)); ent->severity = msg_log_level; vsprintf(ent->event, format, args); strcpy(ent->source, source); ent->rawtime = rawtime; if(lstack_push(&log_stack, ent) != 0) { pthread_mutex_lock(&mxs); fprintf(log_stream, "in log_msg: enqueue log entry failed (size %d)\n", lstack_size(&log_stack)); pthread_mutex_unlock(&mxs); free(ent); goto ON_ERROR; } return; ON_ERROR: strftime(buffer, 20, "%F %H:%M:%S", localtime(rawtime)); log_level_string(lls_buffer, msg_log_level); pthread_mutex_lock(&mxs); fprintf(log_stream, "[%s: %s] ", lls_buffer, buffer); vfprintf(log_stream, format, args); pthread_mutex_unlock(&mxs); free(rawtime); }
int lts_sjson_decode(lts_str_t *src, lts_pool_t *pool, lts_sjson_t *output) { static uint8_t invisible[] = {'\t', '\n', '\r', '\x20'}; DEFINE_LSTACK(obj_stack); int in_bracket = FALSE; int current_stat = SJSON_EXP_START; lts_str_t current_key = lts_null_string; lts_sjson_kv_t *json_kv = NULL; lts_sjson_li_node_t *li_node = NULL; lts_sjson_list_t *json_list = NULL; lts_sjson_t *json_obj = NULL; // 过滤不可见字符 (void)lts_str_filter_multi(src, invisible, ARRAY_COUNT(invisible)); *output = lts_empty_json; for (size_t i = 0; i < src->len; ++i) { switch (current_stat) { case SJSON_EXP_START: { if ('{' != src->data[i]) { errno = LTS_E_INVALID_FORMAT; return -1; } current_stat = SJSON_EXP_K_QUOT_START_OR_END; // only continue; } case SJSON_EXP_K_QUOT_START_OR_END: { if ('"' == src->data[i]) { current_stat = SJSON_EXP_K_QUOT_END; current_key.data = &src->data[i + 1]; current_key.len = 0; } else if ('}' == src->data[i]) { // 空对象 if (lstack_is_empty(&obj_stack)) { current_stat = SJSON_EXP_NOTHING; // only } else { current_stat = SJSON_EXP_COMMA_OR_END; // only lstack_pop(&obj_stack); } } else { errno = LTS_E_INVALID_FORMAT; return -1; } continue; } case SJSON_EXP_K_QUOT_START: { if ('"' == src->data[i]) { current_stat = SJSON_EXP_K_QUOT_END; current_key.data = &src->data[i + 1]; current_key.len = 0; } continue; } case SJSON_EXP_K_QUOT_END: { if ('"' == src->data[i]) { current_stat = SJSON_EXP_COLON; // only } else { ++current_key.len; } continue; } case SJSON_EXP_NOTHING: { errno = LTS_E_INVALID_FORMAT; return -1; } case SJSON_EXP_COLON: { if (':' != src->data[i]) { errno = LTS_E_INVALID_FORMAT; return -1; } current_stat = SJSON_EXP_V_MAP_OR_QUOT_OR_BRACKET_START; // only continue; } case SJSON_EXP_V_MAP_OR_QUOT_OR_BRACKET_START: { if ('"' == src->data[i]) { current_stat = SJSON_EXP_V_QUOT_END; json_kv = (lts_sjson_kv_t *)lts_palloc(pool, sizeof(*json_kv)); if (NULL == json_kv) { errno = LTS_E_NOMEM; return -1; } lts_str_copy(&json_kv->_obj_node.key, ¤t_key); json_kv->val.data = &src->data[i + 1]; json_kv->val.len = 0; json_kv->_obj_node.node_type = STRING_VALUE; json_kv->_obj_node.tnode = RB_NODE; } else if ('[' == src->data[i]) { in_bracket = TRUE; current_stat = SJSON_EXP_V_QUOT_START; // only json_list = (lts_sjson_list_t *)lts_palloc(pool, sizeof(*json_list)); if (NULL == json_list) { errno = LTS_E_NOMEM; return -1; } lts_str_copy(&json_list->_obj_node.key, ¤t_key); list_set_empty(&json_list->val); json_list->_obj_node.node_type = LIST_VALUE; json_list->_obj_node.tnode = RB_NODE; } else if ('{' == src->data[i]) { lts_sjson_t *new_obj; current_stat = SJSON_EXP_K_QUOT_START_OR_END; // only new_obj = (lts_sjson_t *)lts_palloc(pool, sizeof(*json_obj)); if (NULL == new_obj) { errno = LTS_E_NOMEM; return -1; } lts_str_copy(&new_obj->_obj_node.key, ¤t_key); new_obj->val = RB_ROOT; new_obj->_obj_node.node_type = OBJ_VALUE; new_obj->_obj_node.tnode = RB_NODE; // 挂到树上 if (lstack_is_empty(&obj_stack)) { json_obj = output; } else { json_obj = CONTAINER_OF( lstack_top(&obj_stack), lts_sjson_t, _stk_node ); } __lts_sjson_search(&json_obj->val, &new_obj->_obj_node, TRUE); // 压栈 lstack_push(&obj_stack, &new_obj->_stk_node); json_obj = NULL; } else { errno = LTS_E_INVALID_FORMAT; return -1; } continue; } case SJSON_EXP_V_QUOT_START: { if ('"' != src->data[i]) { errno = LTS_E_INVALID_FORMAT; return -1; } if (! in_bracket) { abort(); } current_stat = SJSON_EXP_V_QUOT_END; li_node = (lts_sjson_li_node_t *)lts_palloc(pool, sizeof(*li_node)); if (NULL == li_node) { errno = LTS_E_NOMEM; return -1; } li_node->val.data = &src->data[i + 1]; li_node->val.len = 0; continue; } case SJSON_EXP_V_QUOT_END: { if (in_bracket) { if ('"' == src->data[i]) { current_stat = SJSON_EXP_COMMA_OR_BRACKET_END; // only list_add_node(&json_list->val, &li_node->node); li_node = NULL; } else { ++li_node->val.len; } } else { if ('"' == src->data[i]) { current_stat = SJSON_EXP_COMMA_OR_END; // only if (lstack_is_empty(&obj_stack)) { json_obj = output; } else { json_obj = CONTAINER_OF( lstack_top(&obj_stack), lts_sjson_t, _stk_node ); } __lts_sjson_search(&json_obj->val, &json_kv->_obj_node, TRUE); json_kv = NULL; } else { ++json_kv->val.len; } } continue; } case SJSON_EXP_COMMA_OR_BRACKET_END: { // 必定在bracket中 if (! in_bracket) { abort(); } if (',' == src->data[i]) { current_stat = SJSON_EXP_V_QUOT_START; // only } else if (']' == src->data[i]) { in_bracket = FALSE; current_stat = SJSON_EXP_COMMA_OR_END; // only if (lstack_is_empty(&obj_stack)) { json_obj = output; } else { json_obj = CONTAINER_OF( lstack_top(&obj_stack), lts_sjson_t, _stk_node ); } __lts_sjson_search(&json_obj->val, &json_list->_obj_node, TRUE); json_list = NULL; } else { errno = LTS_E_INVALID_FORMAT; return -1; } continue; } case SJSON_EXP_COMMA_OR_END: { // 必定不在bracket中 if (in_bracket) { abort(); } if (',' == src->data[i]) { current_stat = SJSON_EXP_K_QUOT_START_OR_END; } else if ('}' == src->data[i]) { if (lstack_is_empty(&obj_stack)) { current_stat = SJSON_EXP_NOTHING; } else { current_stat = SJSON_EXP_COMMA_OR_END; lstack_pop(&obj_stack); } } else { errno = LTS_E_INVALID_FORMAT; return -1; } continue; } default: { abort(); }} } return (SJSON_EXP_NOTHING == current_stat) ? 0 : -1; }