/*============================================================================== * - msgQ_send() * * - try to send a message to a msgQ, this maybe block the call task */ OS_STATUS msgQ_send (MSG_QUE *pMsgQ, const void *buffer, uint32 buf_len, uint32 timeout) { int cpsr_c; OS_STATUS status = OS_STATUS_ERROR; DL_NODE *pMsgNode = NULL; OS_TCB *pWaitTcb = NULL; cpsr_c = CPU_LOCK(); again: if (pMsgQ->cur_num < pMsgQ->max_num) { /* there is some space */ pMsgQ->cur_num++; G_p_current_tcb->delay_ticks = 0; /* * alloc a messege node and add it into messge list */ pMsgNode = malloc(sizeof(DL_NODE) + pMsgQ->max_len); memcpy((void *)(pMsgNode + 1), buffer, MIN(buf_len, pMsgQ->max_len)); dlist_add(&pMsgQ->msg_list, pMsgNode); /* * get a wait for Receive task and put it into readyQ */ pWaitTcb = (OS_TCB *)dlist_get(&pMsgQ->wait_recv_list); if (pWaitTcb != NULL) { readyQ_put(pWaitTcb); } status = OS_STATUS_OK; } else { /* there is no space */ if (timeout != 0) { readyQ_remove (G_p_current_tcb); G_p_current_tcb->delay_ticks = timeout; G_p_current_tcb->status = TASK_STATUS_PEND_MSG_S; /* msg send pend */ G_p_current_tcb->pend_obj = pMsgQ; dlist_add (&pMsgQ->wait_send_list, (DL_NODE *)G_p_current_tcb); CONTEXT_SWITCH(); if (G_p_current_tcb->delay_ticks != 0) { timeout = G_p_current_tcb->delay_ticks; /* recalculate timeout value */ goto again; } } } CPU_UNLOCK(cpsr_c); return status; }
/*============================================================================== * - semC_take() * * - take a semC. this function maybe block the call task */ OS_STATUS semC_take (SEM_CNT *pSemC, uint32 timeout) { int cpsr_c; OS_STATUS status = OS_STATUS_ERROR; cpsr_c = CPU_LOCK(); again: if (pSemC->count > 0) { pSemC->count--; G_p_current_tcb->delay_ticks = 0; status = OS_STATUS_OK; } else { if (timeout != 0) { readyQ_remove (G_p_current_tcb); G_p_current_tcb->delay_ticks = timeout; G_p_current_tcb->status = TASK_STATUS_PEND_SEM_C; G_p_current_tcb->pend_obj = pSemC; dlist_add (&pSemC->wait_list, (DL_NODE *)G_p_current_tcb); CONTEXT_SWITCH(); if (G_p_current_tcb->delay_ticks != 0) { timeout = G_p_current_tcb->delay_ticks; /* recalculate timeout value */ goto again; } } } CPU_UNLOCK(cpsr_c); return status; }
dstrlist* dsplit_on_cs(const dstring* text, const char* on, size_t max) { dstrlist* result = dlist_new(); int slen = strlen(on); unsigned int i, j, k = 0; if (max == 1) { dlist_add(result, text); return result; } else if (max <= 0) { max = text->len; } j = 0; i = dposcs(text, on, 0); while(i != -1) { dlist_push(result, dsub(text, j, i - j)); k++; j = i + slen; if (k + 1 == max) { dlist_push(result, dsub(text, j, text->len - j)); return result; } i = dposcs(text, on, j); } dlist_push(result, dsub(text, j, text->len - j)); return result; }
dlist * wm_get_stack(Display *dpy) { dlist *l = 0; unsigned char *data; int status, real_format; Atom real_type; unsigned long items_read, items_left, i; if (WM_PERSONALITY == WM_PERSONALITY_NETWM) status = XGetWindowProperty(dpy, DefaultRootWindow(dpy), _NET_CLIENT_LIST, 0L, 8192L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &data); else status = XGetWindowProperty(dpy, DefaultRootWindow(dpy), _WIN_CLIENT_LIST, 0L, 8192L, False, XA_CARDINAL, &real_type, &real_format, &items_read, &items_left, &data); if(status != Success) return 0; for(i = 0; i < items_read; i++) { l = dlist_add(l, (void *)((long *)data)[i]); } XFree(data); return l; }
/*============================================================================== * - msgQ_init() * * - init MSG_QUE struct, and add it to msgQ_list */ MSG_QUE *msgQ_init (MSG_QUE *pNewMsgQ, uint32 max_num, uint32 max_len) { int cpsr_c; if (max_num == 0 || max_len == 0) { return NULL; } if (pNewMsgQ == NULL) { pNewMsgQ = malloc(sizeof(MSG_QUE)); } if (pNewMsgQ != NULL) { pNewMsgQ->max_num = max_num; pNewMsgQ->max_len = max_len; pNewMsgQ->cur_num = 0; dlist_init(&pNewMsgQ->msg_list); dlist_init(&pNewMsgQ->wait_send_list); dlist_init(&pNewMsgQ->wait_recv_list); cpsr_c = CPU_LOCK(); dlist_add(&_G_msgQ_list, (DL_NODE *)pNewMsgQ); CPU_UNLOCK(cpsr_c); } return pNewMsgQ; }
/*============================================================================== * - _album_add_file() * * - search all file in <path> dir, and add extern with <ext> to list */ static int _album_add_file (const char *path, const char *ext) { yaffs_DIR *d; yaffs_dirent *de; int i; PIC_NAME_NODE *pNewPic = NULL; int file_name_len; d = yaffs_opendir(path); for(i = 0; (de = yaffs_readdir(d)) != NULL; i++) { file_name_len = strlen (de->d_name); if (strlen(path) + file_name_len < PATH_LEN_MAX && /* file name not too long */ strcmp (de->d_name + file_name_len - strlen(ext), ext) == 0) { pNewPic = malloc (sizeof (PIC_NAME_NODE)); if (pNewPic != NULL) { strcpy(pNewPic->name, path); strcat(pNewPic->name, de->d_name); dlist_add (&_G_pic_list, (DL_NODE *)pNewPic); } } } yaffs_closedir(d); return i; }
static int dlist_int_test() { printf("double list test ... MAX=%d\n", MAX); int arr[MAX]; int i; int sum = 0; int max = INT_MIN; printf("MAX = %d\n", MAX); struct dlist *list = dlist_init(); if (list) { /* * init arr */ for (i = 0; i < MAX; i++) { arr[i] = i; } /* * dlist_add/dlist_length test */ for (i = 0; i < MAX; i++) { dlist_add(list, arr + i); assert(dlist_length(list) == i + 1); } /* * dlist_serch test */ for (i = 0; i < MAX; i++) { assert(dlist_search(list, arr + i) == DLIST_RET_OK); } /* * dlist_printf test */ assert(dlist_printf(list, user_printf) == DLIST_RET_OK); assert(dlist_foreach(list, sum_cb, &sum) == DLIST_RET_OK); assert(dlist_foreach(list, max_cb, &max) == DLIST_RET_OK); /* * dlist_delete test */ for (i = MAX - 1; i >= 0; i--) { assert(dlist_length(list) == i + 1); assert(dlist_delete(list, arr + i) == DLIST_RET_OK); assert(dlist_length(list) == i); } /* * dlist_destroy test */ assert(dlist_destroy(list) == DLIST_RET_OK); } printf("sum = %d\n", sum); printf("max = %d\n", max); return 0; }
inline int hash_add(hash_table_t *table, void *data) { unsigned int index; if (table == NULL) return -1; index = table->hashfunc(table->size, data); return dlist_add(&table->table[index], data); }
/*============================================================================== * - cbi_register() * * - register a cbi into list */ OS_STATUS cbi_register (GUI_CBI *pCBI) { #if 0 dlist_add (&_G_cbi_list, (DL_NODE *)pCBI); /* insert tail */ #else dlist_insert (&_G_cbi_list, NULL, (DL_NODE *)pCBI); /* insert head */ #endif return OS_STATUS_OK; }
/*============================================================================== * - msgQ_receive() * * - try to receive a message from a msgQ, this maybe block the call task */ OS_STATUS msgQ_receive (MSG_QUE *pMsgQ, void *buffer, uint32 buf_len, uint32 timeout) { int cpsr_c; OS_STATUS status = OS_STATUS_ERROR; DL_NODE *pMsgNode = NULL; OS_TCB *pWaitTcb = NULL; cpsr_c = CPU_LOCK(); again: if (pMsgQ->cur_num > 0) { /* have message(s) */ pMsgQ->cur_num--; G_p_current_tcb->delay_ticks = 0; /* * copy message context to msg_list */ pMsgNode = dlist_get(&pMsgQ->msg_list); memcpy(buffer, (void *)(pMsgNode + 1), MIN(buf_len, pMsgQ->max_len)); free(pMsgNode); /* * if there are some task wait for send, alive one of them */ pWaitTcb = (OS_TCB *)dlist_get(&pMsgQ->wait_send_list); if (pWaitTcb != NULL) { readyQ_put(pWaitTcb); } status = OS_STATUS_OK; } else { /* no message */ if (timeout != 0) { readyQ_remove (G_p_current_tcb); G_p_current_tcb->delay_ticks = timeout; G_p_current_tcb->status = TASK_STATUS_PEND_MSG_R; /* msg receive pend */ G_p_current_tcb->pend_obj = pMsgQ; dlist_add (&pMsgQ->wait_recv_list, (DL_NODE *)G_p_current_tcb); CONTEXT_SWITCH(); if (G_p_current_tcb->delay_ticks != 0) { timeout = G_p_current_tcb->delay_ticks; /* recalculate timeout value */ goto again; } } } CPU_UNLOCK(cpsr_c); return status; }
int single_login(single_login_t *sl, single_login_func_t cb, char *ip, int port, char *user, char *pwd, void *param) { if (sl == NULL || ip == NULL || port <= 0 || port >= 65535) return -1; int loginid = -1; char ip_port[32] = ""; single_login_info_t *node; snprintf(ip_port, sizeof(ip_port), "%s:%d", ip, port); single_login_func_t login_func = (cb == NULL) ? default_login_func : cb; pthread_mutex_lock(&sl->mtx); /* lookup ip:port, if exist, return the loginid directly */ if (dlist_entry(sl->list, cmp_ipport, (void *)ip_port, (void **)&node) == 0) { loginid = node->loginid; node->user_num++; pthread_mutex_unlock(&sl->mtx); return loginid; } /* login */ loginid = login_func(ip, port, user, pwd, param); if (loginid == -1) { pthread_mutex_unlock(&sl->mtx); return -1; } node = calloc(1, sizeof(single_login_info_t)); if (node == NULL) { close(loginid); pthread_mutex_unlock(&sl->mtx); return -1; } snprintf(node->ip_port, sizeof(node->ip_port), "%s:%d", ip, port); node->loginid = loginid; node->user_num = 1; node->param = param; if (dlist_add(&sl->list, (void *)node) == -1) { close(loginid); free(node); pthread_mutex_unlock(&sl->mtx); return -1; } pthread_mutex_unlock(&sl->mtx); return loginid; }
/*============================================================================== * - cmd_add() * * - add a new command to command list */ void cmd_add (CMD_INF *new_cmd_info) { CMD_NODE *new_cmd_node = NULL; CMD_MANAGE_LOCK(); new_cmd_node = (CMD_NODE *)malloc(sizeof(CMD_NODE)); if (new_cmd_info != NULL) { new_cmd_node->cmd_info = new_cmd_info; dlist_add (&_G_cmd_list, (DL_NODE *)new_cmd_node); } CMD_MANAGE_UNLOCK(); }
static int dlist_char_test() { char str[] = "dlist"; char str2[] = "thinking"; struct dlist *list = dlist_init(); assert(list != NULL); return_val_if_fail(dlist_length(list) == 0, -1); char *pstr = NULL; dlist_add(list, str); return_val_if_fail(dlist_length(list) == 1, -1); dlist_add(list, str2); dlist_add(list, pstr = strdup("test")); dlist_foreach(list, string_toupper_cb, NULL); dlist_printf(list, string_printf); dlist_destroy(list); list = NULL; free(pstr); return 0; }
dlist * dlist_dup(dlist *l) { dlist *n = 0; l = dlist_first(l); while(l) { n = dlist_add(n, l->data); l = l->next; } return n; }
Dlist_data * dlist_add_str(Dlist *dl, char *str) { char *new_str; if (str == NULL) return NULL; new_str = strdup(str); if (unlikely(new_str == NULL)) return NULL; return dlist_add(dl, (void *)new_str); }
void* htable_store(htable_t* ht, void* node) { htable_node_t* tnode = (htable_node_t*)node; dlist_t* bucket = get_bucket(ht, tnode); dlist_node_t* old_node = dlist_find(bucket, node, ht->do_compare); if (old_node) { dlist_remove(bucket, old_node); } tnode->bucket = bucket; dlist_add(bucket, node); return old_node; }
//实现用户输入一组单词,记录字符串,然后将这些字符串排列组合拼接然后显示 int dlist_test() { dlist list; char *input_string; char temp1[32]; char temp2[32]; char *result; int input_enable = 1; int i,j; dlist_init(&list); //dlist_set_compare(&list, _int_comp); printf("please input word, press 0 stop\n"); do { input_string = malloc(32); memset(input_string, 0, 32); scanf("%s",input_string); if(input_string[0] == '0') { input_enable = 0; break; } dlist_add(&list,input_string); }while(input_enable); printf("list.count = %d\n",list.count); for(i = 0; i < list.count; i++) { for(j = 0; j < list.count; j++) { if(i == j) continue; memset(temp1, 0, 32); strcpy(temp1,dlist_get_data(&list, i)); memset(temp2, 0, 32); strcpy(temp2,dlist_get_data(&list, j)); result = (char *)strcat(temp1,temp2); printf("%s\n",result); memset(temp1, 0, 32); strcpy(temp1,dlist_get_data(&list, i)); result = (char *)strcat(temp2,temp1); printf("%s\n",result); } } dlist_clean_data(&list);//in order to prevent memory leaks return 0; }
dlist * dlist_find_all(dlist *l, dlist_match_func match, void *data) { dlist *n = 0; l = dlist_first(l); while(l) { if(match(l, data)) n = dlist_add(n, l->data); l = l->next; } return n; }
int dlist_insert(dlist *list, void *data) { list_node *tmp, *t; if (!list) return FAILURE; if (list->compare == NULL) { return dlist_add(list, data); } t = (list_node *)malloc(sizeof(list_node)); if (!t) return FAILURE; t->data = data; t->prev = 0; t->next = 0; tmp = list->tail; while (tmp) { if (list->compare(data, tmp->data) >= 0) { t->next = tmp->next; t->prev = tmp; tmp->next = t; if (tmp == list->tail) { list->tail = t; } break; } tmp = tmp->prev; } if (!tmp) { t->next = list->head; list->head = t; if (!list->tail) { list->tail = t; } } list->count++; return SUCCESS; }
static dlist * update_clients(MainWin *mw, dlist *clients, Bool *touched) { dlist *stack, *iter; stack = dlist_first(wm_get_stack(mw->dpy)); iter = clients = dlist_first(clients); if(touched) *touched = False; /* Terminate clients that are no longer managed */ while(iter) { ClientWin *cw = (ClientWin *)iter->data; if(! dlist_find_data(stack, (void *)cw->client.window)) { dlist *tmp = iter->next; clientwin_destroy((ClientWin *)iter->data, True); clients = dlist_remove(iter); iter = tmp; if(touched) *touched = True; continue; } clientwin_update(cw); iter = iter->next; } /* Add new clients */ for(iter = dlist_first(stack); iter; iter = iter->next) { ClientWin *cw = (ClientWin*)dlist_find(clients, clientwin_cmp_func, iter->data); if(! cw && (Window)iter->data != mw->window) { cw = clientwin_create(mw, (Window)iter->data); if(! cw) continue; clients = dlist_add(clients, cw); clientwin_update(cw); if(touched) *touched = True; } } dlist_free(stack); return clients; }
static dlist * entry_set(dlist *config, const char *section, char *key, char *value) { dlist *iter = dlist_first(config); ConfigEntry *entry; for(; iter; iter = iter->next) { entry = (ConfigEntry *)iter->data; if(! strcasecmp(entry->section, section) && ! strcasecmp(entry->key, key)) { free(key); free(entry->value); entry->value = value; return config; } } entry = entry_new(section, key, value); return dlist_add(config, entry); }
static dlist * update_clients(MainWin *mw, dlist *clients) { dlist *stack, *iter; stack = dlist_first(wm_get_stack(mw->dpy)); iter = clients = dlist_first(clients); while(iter) { ClientWin *cw = (ClientWin *)iter->data; if(! dlist_find_data(stack, (void *)cw->client.window)) { dlist *tmp = iter->next; clientwin_destroy((ClientWin *)iter->data); clients = dlist_remove(iter); iter = tmp; continue; } clientwin_update(cw); iter = iter->next; } for(iter = dlist_first(stack); iter; iter = iter->next) { ClientWin *cw = (ClientWin*)dlist_find(clients, clientwin_cmp_func, iter->data); if(! cw) { cw = clientwin_create(mw, (Window)iter->data); if(! cw) continue; clients = dlist_add(clients, cw); clientwin_update(cw); } } dlist_free(stack); return clients; }
/*============================================================================== * - _list_dir() * * - refresh the directory list nodes */ static int _list_dir (const char *path, DL_LIST *pDirList) { int i; yaffs_DIR *d; yaffs_dirent *de; DIR_LIST_NODE *pListNode = NULL; char full_name[PATH_LEN_MAX]; d = yaffs_opendir(path); /* free previous list nodes */ pListNode = (DIR_LIST_NODE *)dlist_get (pDirList); while (pListNode != NULL) { free (pListNode); pListNode = (DIR_LIST_NODE *)dlist_get (&_G_dir_list); } if (!d) { return 0; } /* alloc new list nodes */ for(i = 0; (de = yaffs_readdir(d)) != NULL; i++) { pListNode = malloc (sizeof (DIR_LIST_NODE)); if (pListNode != NULL) { strcpy(pListNode->name, de->d_name); strcpy(full_name, path); strcat(full_name, de->d_name); if (yaffs_is_dir (full_name)) { strcat(pListNode->name, "/"); } dlist_add (pDirList, (DL_NODE *)pListNode); } } yaffs_closedir(d); return i; }
static device_t *add_device(device_cfg_t *cfg, driver_t *driver) { device_t *p; p = calloc(1, sizeof(device_t)); if (p == NULL) return NULL; p->id = cfg->id; snprintf(p->ip, sizeof(p->ip), cfg->ip); p->port = cfg->port; snprintf(p->user, sizeof(p->user), cfg->user); snprintf(p->pwd, sizeof(p->pwd), cfg->pwd); p->channels = dlist_init(); if (dlist_add(&driver->devices, (void *)p) == -1) { free(p); return NULL; } //printf("add device: %d-%d\n", driver->type, p->id); return p; }
static int add_task(void *data, void *param) { rec_driver_t driver; channel_t *channel = (channel_t *)data; if (channel->rec != 1) return -1; driver.type = channel->storage_type; if (hash_entry(driver_table, (void *)&driver, cmp_func_driver, (void *)channel->storage_type, (void **)&channel->rec_driver) == -1) { syslog(LOG_DEBUG, "none rec driver: %d", channel->storage_type); channel->rec = 0; return -1; } if (channel->id == 1) snprintf(channel->rec_name, sizeof(channel->rec_name), "IPC_%04d", ((device_t *)channel->pdevice)->id); else snprintf(channel->rec_name, sizeof(channel->rec_name), "IPC_%04d-%d", ((device_t *)channel->pdevice)->id, channel->id); ((rec_driver_t *)channel->rec_driver)->record_callback = record_callback; set_nonestate(channel->rec_state); channel->rec_error = 0; if (dlist_add(&rec_task_list, (void *)channel) == -1) { channel->rec = 0; return -1; } syslog(LOG_DEBUG, "add rec task:%d %s", channel->storage_type, channel->rec_name); return 0; }
/*============================================================================== * - semC_init() * * - init a semC struct, add it to semC_list */ SEM_CNT *semC_init(SEM_CNT *pNewSemC, uint32 init_count, uint32 max_count) { int cpsr_c; if (max_count == 0) { return NULL; } if (pNewSemC == NULL) { pNewSemC = malloc(sizeof(SEM_CNT)); } if (pNewSemC != NULL) { pNewSemC->count = init_count; pNewSemC->max_count = max_count; dlist_init(&pNewSemC->wait_list); cpsr_c = CPU_LOCK(); dlist_add (&_G_semC_list, (DL_NODE *)pNewSemC); CPU_UNLOCK(cpsr_c); } return pNewSemC; }
/*============================================================================== * - _get_cmd_line() * * - get user typed string from uart0 */ int _get_cmd_line (char *s) { int i = 0; /* readed char number so far */ int c; /* temp read char */ char tab_matched_cmd[PATH_LEN_MAX] = ""; int have_tab = 0; _SHELL_HISTORY_NODE *p_history_index = NULL; _SHELL_HISTORY_NODE *p_history_node = NULL; static DL_LIST history_list = {NULL, NULL}; static int history_num = 0; while (i < _CMD_LEN_MAX) { c = serial_getc(); /* check Tab key */ if ((c != '\t') && have_tab) { int s_len = strlen (s); int prefix_len; prefix_len = _get_last_cmd_len (s); strcpy (&s[s_len - prefix_len], tab_matched_cmd); i = strlen (s); have_tab = 0; } switch (c) { case '\r': /* Enter */ s[i] = '\0'; serial_putc('\n'); goto got_it; case '\b': /* Backspace */ if (i >= 1) { serial_puts("\b \b"); i--; } break; case '\t': /* Tab */ have_tab = 1; s[i] = '\0'; #if 0 /* erase */ while (i--) serial_puts("\b \b"); i = cmd_tab(s, tab_matched_cmd); serial_puts(tab_matched_cmd); #else { extern int yaffs_tab (const char *prefix, char *cmd_line); int prefix_len; int erase_chars; prefix_len = _get_last_cmd_len (s); erase_chars = i - (strlen (s) - prefix_len); if (erase_chars == i) { i = cmd_tab(s, tab_matched_cmd); } else { i -= erase_chars; i += yaffs_tab(&s[i], tab_matched_cmd); } while (erase_chars--) serial_puts("\b \b"); serial_puts(tab_matched_cmd); } #endif break; /* ignore */ case '\033': /* Esc Up Down Right Left */ if (serial_tstc() && (serial_getc() == '[')) { if (serial_tstc()) { c = serial_getc(); switch (c) { case 'A': /* Up */ if (p_history_index == NULL) { p_history_index = (_SHELL_HISTORY_NODE *)DL_LAST(&history_list); } else { p_history_index = (_SHELL_HISTORY_NODE *)DL_PREVIOUS(p_history_index); } i = _load_history (s, i, p_history_index); break; case 'B': /* Down */ if (p_history_index != NULL) { p_history_index = (_SHELL_HISTORY_NODE *)DL_NEXT(p_history_index); } i = _load_history (s, i, p_history_index); break; case 'C': /* Right */ break; case 'D': /* Left */ break; default: break; } } } break; default: /* other */ s[i++] = c; serial_putc(c); break; } } /* user command line length more than 1023 */ if (i == _CMD_LEN_MAX) { s[_CMD_LEN_MAX - 1] = '\0'; i--; } got_it: /* this command is not NULL and not equal last command */ if ((i != 0) && ((DL_EMPTY(&history_list)) || (strcmp (s, ((_SHELL_HISTORY_NODE *)DL_LAST(&history_list))->cmd_line))) ) { if (history_num < _HISTORY_MAX) { p_history_node = malloc (sizeof (_SHELL_HISTORY_NODE)); history_num++; } else { p_history_node = (_SHELL_HISTORY_NODE*)dlist_get(&history_list); } strcpy (p_history_node->cmd_line, s); dlist_add (&history_list, (DL_NODE *)p_history_node); } return i; }
int patch_main(int argc UNUSED_PARAM, char **argv) { int opts; int reverse, state = 0; char *oldname = NULL, *newname = NULL; char *opt_p, *opt_i; long oldlen = oldlen; /* for compiler */ long newlen = newlen; /* for compiler */ INIT_TT(); opts = getopt32(argv, FLAG_STR, &opt_p, &opt_i); argv += optind; reverse = opts & FLAG_REVERSE; TT.prefix = (opts & FLAG_PATHLEN) ? xatoi(opt_p) : 0; // can be negative! TT.filein = TT.fileout = -1; if (opts & FLAG_INPUT) { xmove_fd(xopen_stdin(opt_i), STDIN_FILENO); } else { if (argv[0] && argv[1]) { xmove_fd(xopen_stdin(argv[1]), STDIN_FILENO); } } if (argv[0]) { oldname = xstrdup(argv[0]); newname = xstrdup(argv[0]); } // Loop through the lines in the patch for(;;) { char *patchline; patchline = xmalloc_fgetline(stdin); if (!patchline) break; // Other versions of patch accept damaged patches, // so we need to also. if (!*patchline) { free(patchline); patchline = xstrdup(" "); } // Are we assembling a hunk? if (state >= 2) { if (*patchline==' ' || *patchline=='+' || *patchline=='-') { dlist_add(&TT.current_hunk, patchline); if (*patchline != '+') oldlen--; if (*patchline != '-') newlen--; // Context line? if (*patchline==' ' && state==2) TT.context++; else state=3; // If we've consumed all expected hunk lines, apply the hunk. if (!oldlen && !newlen) state = apply_one_hunk(); continue; } fail_hunk(); state = 0; continue; } // Open a new file? if (!strncmp("--- ", patchline, 4) || !strncmp("+++ ", patchline, 4)) { char *s, **name = reverse ? &newname : &oldname; int i; if (*patchline == '+') { name = reverse ? &oldname : &newname; state = 1; } finish_oldfile(); if (!argv[0]) { free(*name); // Trim date from end of filename (if any). We don't care. for (s = patchline+4; *s && *s!='\t'; s++) if (*s=='\\' && s[1]) s++; i = atoi(s); if (i>1900 && i<=1970) *name = xstrdup("/dev/null"); else { *s = 0; *name = xstrdup(patchline+4); } } // We defer actually opening the file because svn produces broken // patches that don't signal they want to create a new file the // way the patch man page says, so you have to read the first hunk // and _guess_. // Start a new hunk? Usually @@ -oldline,oldlen +newline,newlen @@ // but a missing ,value means the value is 1. } else if (state == 1 && !strncmp("@@ -", patchline, 4)) { int i; char *s = patchline+4; // Read oldline[,oldlen] +newline[,newlen] TT.oldlen = oldlen = TT.newlen = newlen = 1; TT.oldline = strtol(s, &s, 10); if (*s == ',') TT.oldlen = oldlen = strtol(s+1, &s, 10); TT.newline = strtol(s+2, &s, 10); if (*s == ',') TT.newlen = newlen = strtol(s+1, &s, 10); if (oldlen < 1 && newlen < 1) bb_error_msg_and_die("Really? %s", patchline); TT.context = 0; state = 2; // If this is the first hunk, open the file. if (TT.filein == -1) { int oldsum, newsum, empty = 0; char *name; oldsum = TT.oldline + oldlen; newsum = TT.newline + newlen; name = reverse ? oldname : newname; // We're deleting oldname if new file is /dev/null (before -p) // or if new hunk is empty (zero context) after patching if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) { name = reverse ? newname : oldname; empty++; } // handle -p path truncation. for (i=0, s = name; *s;) { if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) break; if (*s++ != '/') continue; while (*s == '/') s++; i++; name = s; } if (empty) { // File is empty after the patches have been applied state = 0; if (option_mask32 & FLAG_RMEMPTY) { // If flag -E or --remove-empty-files is set printf("removing %s\n", name); xunlink(name); } else { printf("patching file %s\n", name); xclose(xopen(name, O_WRONLY | O_TRUNC)); } // If we've got a file to open, do so. } else if (!(option_mask32 & FLAG_PATHLEN) || i <= TT.prefix) { struct stat statbuf; // If the old file was null, we're creating a new one. if (!strcmp(oldname, "/dev/null") || !oldsum) { printf("creating %s\n", name); s = strrchr(name, '/'); if (s) { *s = 0; bb_make_directory(name, -1, FILEUTILS_RECUR); *s = '/'; } TT.filein = xopen(name, O_CREAT|O_EXCL|O_RDWR); } else { printf("patching file %s\n", name); TT.filein = xopen(name, O_RDONLY); } TT.tempname = xasprintf("%sXXXXXX", name); TT.fileout = xmkstemp(TT.tempname); // Set permissions of output file fstat(TT.filein, &statbuf); fchmod(TT.fileout, statbuf.st_mode); TT.linenum = 0; TT.hunknum = 0; } } TT.hunknum++; continue; } // If we didn't continue above, discard this line. free(patchline); } finish_oldfile(); if (ENABLE_FEATURE_CLEAN_UP) { free(oldname); free(newname); } return TT.exitval; }
static int apply_one_hunk(void) { struct double_list *plist, *buf = NULL, *check; int matcheof = 0, reverse = option_mask32 & FLAG_REVERSE, backwarn = 0; /* Do we try "dummy" revert to check whether * to silently skip this hunk? Used to implement -N. */ int dummy_revert = 0; // Break doubly linked list so we can use singly linked traversal function. TT.current_hunk->prev->next = NULL; // Match EOF if there aren't as many ending context lines as beginning for (plist = TT.current_hunk; plist; plist = plist->next) { if (plist->data[0]==' ') matcheof++; else matcheof = 0; if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); } matcheof = !matcheof || matcheof < TT.context; if (PATCH_DEBUG) fdprintf(2,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N'); // Loop through input data searching for this hunk. Match all context // lines and all lines to be removed until we've found the end of a // complete hunk. plist = TT.current_hunk; buf = NULL; if (reverse ? TT.oldlen : TT.newlen) for (;;) { char *data = xmalloc_reads(TT.filein, NULL); TT.linenum++; // Figure out which line of hunk to compare with next. (Skip lines // of the hunk we'd be adding.) while (plist && *plist->data == "+-"[reverse]) { if (data && !strcmp(data, plist->data+1)) { if (!backwarn) { backwarn = TT.linenum; if (option_mask32 & FLAG_IGNORE) { dummy_revert = 1; reverse ^= 1; continue; } } } plist = plist->next; } // Is this EOF? if (!data) { if (PATCH_DEBUG) fdprintf(2, "INEOF\n"); // Does this hunk need to match EOF? if (!plist && matcheof) break; if (backwarn) fdprintf(2,"Possibly reversed hunk %d at %ld\n", TT.hunknum, TT.linenum); // File ended before we found a place for this hunk. fail_hunk(); goto done; } if (PATCH_DEBUG) fdprintf(2, "IN: %s\n", data); check = dlist_add(&buf, data); // Compare this line with next expected line of hunk. // todo: teach the strcmp() to ignore whitespace. // A match can fail because the next line doesn't match, or because // we hit the end of a hunk that needed EOF, and this isn't EOF. // If match failed, flush first line of buffered data and // recheck buffered data for a new match until we find one or run // out of buffer. for (;;) { if (!plist || strcmp(check->data, plist->data+1)) { // Match failed. Write out first line of buffered data and // recheck remaining buffered data for a new match. if (PATCH_DEBUG) fdprintf(2, "NOT: %s\n", plist->data); TT.state = 3; check = buf; buf = buf->next; check->prev->next = buf; buf->prev = check->prev; do_line(check); plist = TT.current_hunk; // If we've reached the end of the buffer without confirming a // match, read more lines. if (check == buf) { buf = NULL; break; } check = buf; } else { if (PATCH_DEBUG) fdprintf(2, "MAYBE: %s\n", plist->data); // This line matches. Advance plist, detect successful match. plist = plist->next; if (!plist && !matcheof) goto out; check = check->next; if (check == buf) break; } } } out: // We have a match. Emit changed data. TT.state = "-+"[reverse ^ dummy_revert]; dlist_free(TT.current_hunk, do_line); TT.current_hunk = NULL; TT.state = 1; done: if (buf) { buf->prev->next = NULL; dlist_free(buf, do_line); } return TT.state; }
static status_t get_next_dirent(nspace *vol, vnode *dir, struct diri *iter, ino_t *vnid, char *filename, int len) { struct _dirent_info_ info; status_t result; do { result = _next_dirent_(iter, &info, filename, len); if (result < 0) return result; // only hide volume label entries in the root directory } while ((info.mode & FAT_VOLUME) && (dir->vnid == vol->root_vnode.vnid)); if (!strcmp(filename, ".")) { // assign vnode based on parent if (vnid) *vnid = dir->vnid; } else if (!strcmp(filename, "..")) { // assign vnode based on parent of parent if (vnid) *vnid = dir->dir_vnid; } else { if (vnid) { ino_t loc = (IS_DATA_CLUSTER(info.cluster)) ? GENERATE_DIR_CLUSTER_VNID(dir->vnid, info.cluster) : GENERATE_DIR_INDEX_VNID(dir->vnid, info.sindex); bool added_to_vcache = false; /* if it matches a loc in the lookup table, we are done. */ result = vcache_loc_to_vnid(vol, loc, vnid); if (result == ENOENT) { /* ...else check if it matches any vnid's in the lookup table */ if (find_vnid_in_vcache(vol, loc) == B_OK) { /* if it does, create a random one since we can't reuse * existing vnid's */ *vnid = generate_unique_vnid(vol); /* and add it to the vcache */ if ((result = add_to_vcache(vol, *vnid, loc)) < 0) return result; added_to_vcache = true; } else { /* otherwise we are free to use it */ *vnid = loc; } } else if (result != B_OK) { dprintf("get_next_dirent: unknown error (%s)\n", strerror(result)); return result; } if (info.mode & FAT_SUBDIR) { if (dlist_find(vol, info.cluster) == -1LL) { if ((result = dlist_add(vol, *vnid)) < 0) { if (added_to_vcache) remove_from_vcache(vol, *vnid); return result; } } } } } DPRINTF(2, ("get_next_dirent: found %s (vnid %Lx)\n", filename, vnid != NULL ? *vnid : (ino_t)0)); return B_NO_ERROR; }