void tree_free(Tree *t, void (*fun)(void *value)) { /* La pile système n'est pas utilisée pour libérer l'arbre, il est préférable d'utiliser une structure de pile ici */ List *stack; Tree *tmp; if(t == NULL) return; /* On remonte jusqu'au noeud père */ ROOT(t); if((stack = list_new()) == NULL || list_add_node(stack, t) == NULL) fatal_error("tree_free"); /* Tant qu'il reste un noeud */ while((t = list_shift_node(stack)) != NULL) for(; t != NULL; t = tmp) { if(t->children != NULL && list_add_node(stack, t->children) == NULL) fatal_error("tree_free"); if(fun != NULL) fun(t->value); tmp = t->next; free(t); } list_free(stack, NULL); return; }
void tree_foreach_node(Tree *t, void (*fun)(Tree *node)) { List *stack; ROOT(t); if((stack = list_new()) == NULL || list_add_node(stack, t) == NULL) fatal_error("tree_foreach_node"); while((t = list_shift_node(stack)) != NULL) for(; t != NULL; t = t->children) { t->depth = t->father == NULL ? 0 : t->father->depth + 1; if(t->next != NULL && list_add_node(stack, t->next) == NULL) fatal_error("tree_foreach_node"); if(fun != NULL) fun(t); } list_free(stack, NULL); return; }
ListNode *list_add(ListNode *list_node) { ListNode *new_list_node; if (list_node == 0) { return 0; } new_list_node = (ListNode *)malloc(sizeof(ListNode)); new_list_node->data = 0; return list_add_node(list_node, new_list_node); }
bool asm_loop(int fd, t_cmd **op_start, t_cmd **op_end, char **label_index) { char *str; t_cmd *current_op; while ((str = get_next_line(fd))) { current_op = xmalloc(sizeof(t_cmd)); current_op->line = str; if (parse_line(str, current_op, label_index, FALSE)) { list_add_node(op_start, op_end, current_op); if (current_op->cmd_code == -1 && current_op->arg.argv[1]) { current_op = xmalloc(sizeof(t_cmd)); parse_line(str, current_op, label_index,TRUE); list_add_node(op_start, op_end, current_op); } } else free(current_op); } return (SUCCES); }
long DLLCALL listMerge(link_list_t* list, const link_list_t* src, list_node_t* after) { long count=0; list_node_t* node=NULL; list_node_t* src_node; if(src==NULL) return(-1); for(src_node=src->first; src_node!=NULL; src_node=src_node->next, count++) if((node=list_add_node(list, src_node, node==NULL ? after:node))==NULL) return(count); return(count); }
list_node_t* DLLCALL listAddNode(link_list_t* list, void* data, list_node_tag_t tag, list_node_t* after) { list_node_t* node; if(list==NULL) return(NULL); if((node=(list_node_t*)malloc(sizeof(list_node_t)))==NULL) return(NULL); memset(node,0,sizeof(list_node_t)); node->data = data; node->tag = tag; return(list_add_node(list,node,after)); }
void each_line(list_t* list){ FILE * fh; char * line = 0; size_t len = 0; char * tmp; fh = fopen(WORDS_FILE, "r"); if (fh) { while (getline(&line, &len, fh) != -1){ tmp = malloc(sizeof(char) * len); strcpy(tmp, line); chomp(tmp,len); list_add_node(&list, (void*) tmp); } fclose(fh); } else { perror("each_line"); exit(-1); } }
void list_add(list_t list, void *data) { node_t node = node_new_data(data); list_add_node(list, node); }
/** * @param system a pointer to a ppd_system struct that contains * all the information for managing the system. * @return true when adding an item succeeds and false when it does not **/ BOOLEAN add_item(struct ppd_system * system) { char idInput[IDLEN + EXTRA_CHARS], nameInput[NAMELEN + EXTRA_CHARS], descInput[DESCLEN + EXTRA_CHARS], priceInput[PRICELEN + EXTRA_CHARS]; char *token, **endPtr = NULL; int dollarsToSave, centsToSave, idToIncrement; BOOLEAN inputSuccess = FALSE; struct ppd_node *current; struct ppd_stock search; current = system->item_list->head; memset(&search, 0, sizeof(struct ppd_stock)); strcpy(search.id, current->data->id); /** * Small loop to find the highest id and copies it. **/ while(current != NULL) { if(item_cmp_id(current->data, &search) > 0) { strcpy(search.id, current->data->id); } current = current->next; } /** * Retrieves the number from the highest id and increments it by 1. **/ token = strtok(search.id, ID_DELIM); idToIncrement = (int)strtol(token, endPtr, 10); ++idToIncrement; /** * Checks the ID, and for up to a maximum of 9999 ID's in the linked list, * adds the correct amount of 0's to the front, depending on its size. **/ if(idToIncrement < 10) { sprintf(idInput, "I000%d", idToIncrement); printf("The new ID for your product is: %s\n", idInput); } else if(idToIncrement < 100) { sprintf(idInput, "I00%d", idToIncrement); printf("The new ID for your product is: %s\n", idInput); } else if(idToIncrement < 1000) { sprintf(idInput, "I0%d", idToIncrement); printf("The new ID for your product is: %s\n", idInput); } else if(idToIncrement <= 9999) { sprintf(idInput, "I%d", idToIncrement); printf("The new ID for your product is: %s\n", idInput); } else { printf("Error: can only have a total of 9999 items in the list\n"); printf("Returning to menu\n"); return FALSE; } token = NULL; /** * Loop until a name has been entered correctly. **/ printf("Please enter the name of the item: "); printf("Press crtl + d or enter on a new line at any time to cancel.\n"); while(!inputSuccess) { if(fgets(nameInput, NAMELEN + EXTRA_CHARS, stdin) == NULL) { printf("Returning to menu\n"); return FALSE; } if(nameInput[0] == '\n') { printf("Returning to menu.\n"); return FALSE; } if(nameInput[strlen(nameInput)-1] != '\n') { printf("Error: input too long\n"); printf("Please enter a name less than %d characters long", NAMELEN); read_rest_of_line(); continue; } nameInput[strlen(nameInput)-1] = '\0'; inputSuccess = TRUE; } inputSuccess = FALSE; /** * Loop until a description has been entered correctly. **/ printf("Please enter a description of the item you are adding: "); while(!inputSuccess) { if(fgets(descInput, DESCLEN + EXTRA_CHARS, stdin) == NULL) { printf("Returning to menu\n"); return FALSE; } if(descInput[0] == '\n') { printf("Returning to menu.\n"); return FALSE; } if(descInput[strlen(descInput)-1] != '\n') { printf("Error: input too long\n"); printf("Please enter a description less than %d", DESCLEN); printf(" characters long"); read_rest_of_line(); continue; } descInput[strlen(descInput)-1] = '\0'; inputSuccess = TRUE; } inputSuccess = FALSE; token = NULL; endPtr = NULL; /** * Loop until a price that can be made up by Australian currency, and is * less than $100. **/ printf("The price of an item must be less than $100, seperated by a '.', "); printf("and two digits must be entered for the cents value.\n"); printf("Please enter the price of the item you are adding: "); while(!inputSuccess) { if(fgets(priceInput, PRICELEN + EXTRA_CHARS, stdin) == NULL) { printf("Returning to menu\n"); return FALSE; } if(priceInput[0] == '\n') { printf("Returning to menu.\n"); return FALSE; } if(priceInput[strlen(priceInput)-1] != '\n') { printf("Error: input too long\n"); printf("Please enter a name less than %d long", PRICELEN); read_rest_of_line(); continue; } token = strtok(priceInput, CURRENCY_DELIM); dollarsToSave = (int)strtol(token, endPtr, 10); if(strlen(token) > 2) { printf("Error: price must be less than $100\n"); printf("Please enter a price less than $100\n"); continue; } token = strtok(NULL, CURRENCY_DELIM); centsToSave = (int)strtol(token, endPtr, 10); if(strlen(token) != 3 || (centsToSave % CENT_FIVE_CENTS) != 0) { printf("Error: You must enter exatly two digits for cents.\n"); printf("Eg: 20.00, or 9.60\n"); printf("Please enter a price less than $100 that conforms to "); printf("these standards\n"); continue; } inputSuccess = TRUE; } /** * Allocate the memory for the new node, now that all information has been * gathered. **/ current = malloc(sizeof(struct ppd_node)); current->data = malloc(sizeof(struct ppd_stock)); if(current == NULL || current->data == NULL) { printf("The memory alocation failed\n"); printf("Returning to menu\n"); free(current->data); free(current); return FALSE; } /** * Copy information into the node, **/ current->next = NULL; strcpy(current->data->id, idInput); strcpy(current->data->name, nameInput); strcpy(current->data->desc, descInput); current->data->price.dollars = dollarsToSave; current->data->price.cents = centsToSave; current->data->on_hand = DEFAULT_STOCK_LEVEL; /** * Pass the node to the list_add_system function, check for problems, * free memory if adding fails. **/ if(list_add_node(system->item_list, current) == FALSE) { printf("The node failed to load\n"); printf("This was not meant to happen\n"); free(current->data); free(current); return FALSE; } printf("New item: %s|%s|%s|%d.%d|%d\n", idInput, nameInput, descInput, dollarsToSave, centsToSave, DEFAULT_STOCK_LEVEL); printf("has been successfully added!\n"); return TRUE; }
/** * @param system a pointer to a @ref ppd_system struct that contains * all the data in the system we are manipulating * @param coins_name the name of the coins file * @param stock name the name of the stock file **/ BOOLEAN load_data(struct ppd_system * system , const char * coins_name, const char * stock_name) { FILE * coin_file, * stock_file; char coin_line[COIN_MAX_LINE_LEN + 1], stock_line[STOCK_MAX_LINE_LEN + 1]; struct ppd_node *newNode = NULL; struct coin *cashPtr = system->cash_register; /* check to make sure file names are not empty or NULL */ if(strcmp(coins_name, " ") == 0 || coins_name == NULL) { printf("Error: coin file name not found\n"); return FALSE; } if(strcmp(stock_name, " ") == 0 || coins_name == NULL) { printf("Error: stock file name not found\n"); return FALSE; } /* load the coin file. */ system->coin_file_name = coins_name; coin_file = fopen(system->coin_file_name, "r"); if(coin_file == NULL) { printf("Error: could not load coin file\n"); return FALSE; } while(fgets(coin_line, COIN_MAX_LINE_LEN + 1, coin_file) != NULL) { if(load_coin_data(cashPtr, coin_line) == FALSE) { printf("Returning to menu\n"); fclose(coin_file); return FALSE; } } printf("\n\n"); printf("Coin data successfuly loaded in\n"); fclose(coin_file); /* stock file handeling */ system->stock_file_name = stock_name; stock_file = fopen(system->stock_file_name, "r"); if(stock_file == NULL) { printf("Error: could not load stock file\n"); return FALSE; } while(fgets(stock_line, STOCK_MAX_LINE_LEN + 1, stock_file) != NULL) { newNode = load_item_file(stock_line); if(newNode == NULL) { printf("Returning to menu.\n\n"); fclose(stock_file); return FALSE; } if(list_add_node(system->item_list, newNode) == FALSE) { printf("Returning to menu.\n\n"); return FALSE; } } printf("Stock file successfuly loaded in \n\n"); fclose(stock_file); return TRUE; }
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; }
void list_add(list_t inst, void* val) { node_t n; //printf("Add %p\n", val); n = node_init(val); list_add_node(inst, n); }