static int sh_usr_uid(uint32_t *r0, uint32_t r1) { uint32_t p1, p2; uint32_t uidSize; uint32_t i; uint8_t null = '\0'; uint8_t * id_str; // Read parameter block if (!shReadWord(r1, &p1)) return 0; if (!shReadWord(r1+4, &p2)) return 0; id_str = get_uid_string(); uidSize = strlen((const char *)id_str) - 4; // Validate parameters if (p1 == NULL) return 1; if (p2 != (uidSize+1)) return 1; // +1 for null string terminator // skip " $ $ $ length" id_str += 4; // Write data to target for (i = 0; i < uidSize; i++) { if (!shWriteBytes(p1++, id_str, 1)) return 0; id_str++; } // Write null terminator to target if (!shWriteBytes(p1, &null, 1)) return 0; *r0 = 0; // Successful return 1; }
void redraw_file_info_dialog(void) { const dir_entry_t *entry; char perm_buf[26]; char size_buf[56]; char buf[256]; #ifndef _WIN32 char id_buf[26]; #endif int curr_y; uint64_t size; int size_not_precise; assert(view != NULL); if(resize_for_menu_like() != 0) { return; } werase(menu_win); entry = &view->dir_entry[view->list_pos]; size = 0; if(entry->type == FT_DIR) { char full_path[PATH_MAX]; get_current_full_path(view, sizeof(full_path), full_path); tree_get_data(curr_stats.dirsize_cache, full_path, &size); } if(size == 0) { size = entry->size; } size_not_precise = friendly_size_notation(size, sizeof(size_buf), size_buf); curr_y = 2; curr_y += print_item("Path: ", entry->origin, curr_y); curr_y += print_item("Name: ", entry->name, curr_y); mvwaddstr(menu_win, curr_y, 2, "Size: "); mvwaddstr(menu_win, curr_y, 8, size_buf); if(size_not_precise) { snprintf(size_buf, sizeof(size_buf), " (%" PRId64 " bytes)", size); waddstr(menu_win, size_buf); } curr_y += 2; curr_y += show_file_type(view, curr_y); curr_y += show_mime_type(view, curr_y); #ifndef _WIN32 get_perm_string(perm_buf, sizeof(perm_buf), entry->mode); curr_y += print_item("Permissions: ", perm_buf, curr_y); #else copy_str(perm_buf, sizeof(perm_buf), attr_str_long(entry->attrs)); curr_y += print_item("Attributes: ", perm_buf, curr_y); #endif format_time(entry->mtime, buf, sizeof(buf)); curr_y += print_item("Modified: ", buf, curr_y); format_time(entry->atime, buf, sizeof(buf)); curr_y += print_item("Accessed: ", buf, curr_y); format_time(entry->ctime, buf, sizeof(buf)); #ifndef _WIN32 curr_y += print_item("Changed: ", buf, curr_y); #else curr_y += print_item("Created: ", buf, curr_y); #endif #ifndef _WIN32 get_uid_string(entry, 0, sizeof(id_buf), id_buf); curr_y += print_item("Owner: ", id_buf, curr_y); get_gid_string(entry, 0, sizeof(id_buf), id_buf); curr_y += print_item("Group: ", id_buf, curr_y); #endif /* Fake use after last assignment. */ (void)curr_y; box(menu_win, 0, 0); checked_wmove(menu_win, 0, 3); wprint(menu_win, " File Information "); wrefresh(menu_win); was_redraw = 1; }
__task void main_task(void) { // State processing uint16_t flags; // LED uint8_t dap_led_value = 1; uint8_t cdc_led_value = 1; uint8_t msd_led_value = 1; // USB uint32_t usb_state_count; // thread running after usb connected started uint8_t thread_started = 0; // button state char button_activated; // string containing unique ID uint8_t * id_str; // Get a reference to this task main_task_id = os_tsk_self(); // leds gpio_init(); usbd_init(); swd_init(); // Turn on LED gpio_set_dap_led(1); gpio_set_cdc_led(1); gpio_set_msd_led(1); // Setup reset button gpio_enable_button_flag(main_task_id, FLAGS_MAIN_RESET); button_activated = 1; // USB usbd_connect(0); usb_busy = USB_IDLE; usb_busy_count = 0; usb_state = USB_CONNECTING; usb_state_count = USB_CONNECT_DELAY; // Update HTML version information file update_html_file(); // Start timer tasks os_tsk_create_user(timer_task_30mS, TIMER_TASK_30_PRIORITY, (void *)stk_timer_30_task, TIMER_TASK_30_STACK); // Target running target_set_state(RESET_RUN_WITH_DEBUG); // start semihost task semihost_init(); semihost_enable(); while(1) { os_evt_wait_or( FLAGS_MAIN_RESET // Put target in reset state | FLAGS_MAIN_90MS // 90mS tick | FLAGS_MAIN_30MS // 30mS tick | FLAGS_MAIN_POWERDOWN // Power down interface | FLAGS_MAIN_DISABLEDEBUG // Power down interface | FLAGS_MAIN_USB_DISCONNECT, // Disable target debug NO_TIMEOUT); // Find out what event happened flags = os_evt_get(); if (flags & FLAGS_MAIN_USB_DISCONNECT) { usb_busy = USB_IDLE; // USB not busy usb_state_count = 4; usb_state = USB_DISCONNECT_CONNECT; // disconnect the usb } if (flags & FLAGS_MAIN_RESET) { cdc_led_state = LED_OFF; gpio_set_cdc_led(0); //usbd_cdc_ser_flush(); if (send_uID) { // set the target in reset to not receive char on the serial port target_set_state(RESET_HOLD); // send uid id_str = get_uid_string(); USBD_CDC_ACM_DataSend(id_str, strlen((const char *)id_str)); send_uID = 0; } // Reset target target_set_state(RESET_RUN); cdc_led_state = LED_FLASH; gpio_set_cdc_led(1); button_activated = 0; } if (flags & FLAGS_MAIN_POWERDOWN) { // Stop semihost task semihost_disable(); // Disable debug target_set_state(NO_DEBUG); // Disconnect USB usbd_connect(0); // Turn off LED gpio_set_dap_led(0); gpio_set_cdc_led(0); gpio_set_msd_led(0); // TODO: put the interface chip in sleep mode while (1) { } } if (flags & FLAGS_MAIN_DISABLEDEBUG) { // Stop semihost task semihost_disable(); // Disable debug target_set_state(NO_DEBUG); } if (flags & FLAGS_MAIN_90MS) { if (!button_activated) { gpio_enable_button_flag(main_task_id, FLAGS_MAIN_RESET); button_activated = 1; } // Update USB busy status switch (usb_busy) { case USB_ACTIVE: if (DECZERO(usb_busy_count) == 0) { usb_busy=USB_IDLE; } break; case USB_IDLE: default: break; } // Update USB connect status switch (usb_state) { case USB_DISCONNECTING: // Wait until USB is idle before disconnecting if (usb_busy == USB_IDLE) { usbd_connect(0); usb_state = USB_DISCONNECTED; } break; case USB_DISCONNECT_CONNECT: // Wait until USB is idle before disconnecting if ((usb_busy == USB_IDLE) && (DECZERO(usb_state_count) == 0)) { usbd_connect(0); usb_state = USB_CONNECTING; // Update HTML file update_html_file(); } break; case USB_CONNECTING: // Wait before connecting if (DECZERO(usb_state_count) == 0) { usbd_connect(1); usb_state = USB_CHECK_CONNECTED; } break; case USB_CHECK_CONNECTED: if(usbd_configured()) { if (!thread_started) { os_tsk_create_user(hid_process, DAP_TASK_PRIORITY, (void *)stk_dap_task, DAP_TASK_STACK); serial_task_id = os_tsk_create_user(serial_process, SERIAL_TASK_PRIORITY, (void *)stk_serial_task, SERIAL_TASK_STACK); thread_started = 1; } usb_state = USB_CONNECTED; } break; case USB_CONNECTED: case USB_DISCONNECTED: default: break; } } // 30mS tick used for flashing LED when USB is busy if (flags & FLAGS_MAIN_30MS) { if (dap_led_usb_activity && ((dap_led_state == LED_FLASH) || (dap_led_state == LED_FLASH_PERMANENT))) { // Flash DAP LED ONCE if (dap_led_value) { dap_led_value = 0; } else { dap_led_value = 1; // Turn on if (dap_led_state == LED_FLASH) { dap_led_usb_activity = 0; } } // Update hardware gpio_set_dap_led(dap_led_value); } if (msd_led_usb_activity && ((msd_led_state == LED_FLASH) || (msd_led_state == LED_FLASH_PERMANENT))) { // Flash MSD LED ONCE if (msd_led_value) { msd_led_value = 0; } else { msd_led_value = 1; // Turn on if (msd_led_state == LED_FLASH) { msd_led_usb_activity = 0; } } // Update hardware gpio_set_msd_led(msd_led_value); } if (cdc_led_usb_activity && ((cdc_led_state == LED_FLASH) || (cdc_led_state == LED_FLASH_PERMANENT))) { // Flash CDC LED ONCE if (cdc_led_value) { cdc_led_value = 0; } else { cdc_led_value = 1; // Turn on if (cdc_led_state == LED_FLASH) { cdc_led_usb_activity = 0; } } // Update hardware gpio_set_cdc_led(cdc_led_value); } } } }
/* Expands macros in the *format string advancing the pointer as it goes. The * opt represents conditional expression state, should be zero for non-recursive * calls. Returns newly allocated string, which should be freed by the * caller. */ static char * parse_view_macros(FileView *view, const char **format, const char macros[], int opt) { const dir_entry_t *const entry = &view->dir_entry[view->list_pos]; char *result = strdup(""); size_t len = 0; char c; int nexpansions = 0; while((c = **format) != '\0') { size_t width = 0; int left_align = 0; char buf[PATH_MAX]; const char *const next = ++*format; int skip, ok; if(c != '%' || (!char_is_one_of(macros, *next) && !isdigit(*next))) { if(strappendch(&result, &len, c) != 0) { break; } continue; } if(*next == '-') { left_align = 1; ++*format; } while(isdigit(**format)) { width = width*10 + *(*format)++ - '0'; } c = *(*format)++; skip = 0; ok = 1; switch(c) { case 't': format_entry_name(entry, sizeof(buf), buf); break; case 'A': #ifndef _WIN32 get_perm_string(buf, sizeof(buf), entry->mode); #else snprintf(buf, sizeof(buf), "%s", attr_str_long(entry->attrs)); #endif break; case 'u': get_uid_string(entry, 0, sizeof(buf), buf); break; case 'g': get_gid_string(entry, 0, sizeof(buf), buf); break; case 's': friendly_size_notation(entry->size, sizeof(buf), buf); break; case 'E': { uint64_t size = 0; if(view->selected_files > 0) { int i; for(i = 0; i < view->list_rows; i++) { if(view->dir_entry[i].selected) { size += get_file_size_by_entry(view, i); } } } /* Make exception for VISUAL_MODE, since it can contain empty * selection when cursor is on ../ directory. */ else if(!vle_mode_is(VISUAL_MODE)) { size = get_file_size_by_entry(view, view->list_pos); } friendly_size_notation(size, sizeof(buf), buf); } break; case 'd': { struct tm *tm_ptr = localtime(&entry->mtime); strftime(buf, sizeof(buf), cfg.time_format, tm_ptr); } break; case '-': skip = expand_num(buf, sizeof(buf), view->filtered); break; case 'l': skip = expand_num(buf, sizeof(buf), view->list_pos + 1); break; case 'L': skip = expand_num(buf, sizeof(buf), view->list_rows + view->filtered); break; case 'S': skip = expand_num(buf, sizeof(buf), view->list_rows); break; case '%': snprintf(buf, sizeof(buf), "%%"); break; case '[': { char *const opt_str = parse_view_macros(view, format, macros, 1); copy_str(buf, sizeof(buf), opt_str); free(opt_str); break; } case ']': if(opt) { if(nexpansions == 0) { replace_string(&result, ""); } return result; } else { LOG_INFO_MSG("Unmatched %]", c); ok = 0; } break; default: LOG_INFO_MSG("Unexpected %%-sequence: %%%c", c); ok = 0; break; } if(!ok) { *format = next; if(strappendch(&result, &len, '%') != 0) { break; } continue; } check_expanded_str(buf, skip, &nexpansions); stralign(buf, width, ' ', left_align); if(strappend(&result, &len, buf) != 0) { break; } } /* Unmatched %[. */ if(opt) { (void)strprepend(&result, &len, "%["); } return result; }
/* Formats status line in the "old way" (before introduction of 'statusline' * option). */ static void update_stat_window_old(FileView *view, int lazy_redraw) { const dir_entry_t *const entry = &view->dir_entry[view->list_pos]; char name_buf[160*2 + 1]; char perm_buf[26]; char size_buf[56]; char id_buf[52]; int x; int cur_x; size_t print_width; char *filename; x = getmaxx(stdscr); wresize(stat_win, 1, x); wbkgdset(stat_win, COLOR_PAIR(cfg.cs.pair[STATUS_LINE_COLOR]) | cfg.cs.color[STATUS_LINE_COLOR].attr); filename = get_current_file_name(view); print_width = utf8_strsnlen(filename, 20 + MAX(0, x - 83)); snprintf(name_buf, MIN(sizeof(name_buf), print_width + 1), "%s", filename); friendly_size_notation(entry->size, sizeof(size_buf), size_buf); get_uid_string(entry, 0, sizeof(id_buf), id_buf); if(id_buf[0] != '\0') strcat(id_buf, ":"); get_gid_string(entry, 0, sizeof(id_buf) - strlen(id_buf), id_buf + strlen(id_buf)); #ifndef _WIN32 get_perm_string(perm_buf, sizeof(perm_buf), entry->mode); #else snprintf(perm_buf, sizeof(perm_buf), "%s", attr_str_long(entry->attrs)); #endif werase(stat_win); cur_x = 2; checked_wmove(stat_win, 0, cur_x); wprint(stat_win, name_buf); cur_x += 22; if(x > 83) cur_x += x - 83; mvwaddstr(stat_win, 0, cur_x, size_buf); cur_x += 12; mvwaddstr(stat_win, 0, cur_x, perm_buf); cur_x += 11; snprintf(name_buf, sizeof(name_buf), "%d %s filtered", view->filtered, (view->filtered == 1) ? "file" : "files"); if(view->filtered > 0) mvwaddstr(stat_win, 0, x - (strlen(name_buf) + 2), name_buf); if(cur_x + strlen(id_buf) + 1 > x - (strlen(name_buf) + 2)) break_at(id_buf, ':'); if(cur_x + strlen(id_buf) + 1 > x - (strlen(name_buf) + 2)) id_buf[0] = '\0'; mvwaddstr(stat_win, 0, cur_x, id_buf); if(lazy_redraw) { wnoutrefresh(stat_win); } else { wrefresh(stat_win); } }
__task void main_task(void) { // State processing uint16_t flags; // LED uint8_t dap_led_value = 1; uint8_t cdc_led_value = 1; uint8_t msd_led_value = 1; // USB uint32_t usb_state_count; // thread running after usb connected started uint8_t thread_started = 0; // button state char button_activated; // string containing unique ID uint8_t * id_str; // Initialize our serial mailbox os_mbx_init(&serial_mailbox, sizeof(serial_mailbox)); // Get a reference to this task main_task_id = os_tsk_self(); // leds gpio_init(); // Turn off LED gpio_set_dap_led(1); gpio_set_cdc_led(1); gpio_set_msd_led(1); #ifdef BOARD_UBLOX_C027 PORT_SWD_SETUP(); // wait until reset output to the target is pulled high while (!PIN_nRESET_IN()) { /* wait doing nothing */ } os_dly_wait(4); // if the reset input from button is low then enter isp programming mode if (!(LPC_GPIO->B[19/*RESET_PIN*/ + (1/*RESET_PORT*/ << 5)] & 1)) { enter_isp(); } #endif usbd_init(); swd_init(); // Setup reset button gpio_enable_button_flag(main_task_id, FLAGS_MAIN_RESET); button_activated = 1; // USB usbd_connect(0); usb_busy = USB_IDLE; usb_busy_count = 0; usb_state = USB_CONNECTING; usb_state_count = USB_CONNECT_DELAY; // Update HTML version information file update_html_file(); // Start timer tasks os_tsk_create_user(timer_task_30mS, TIMER_TASK_30_PRIORITY, (void *)stk_timer_30_task, TIMER_TASK_30_STACK); #ifndef BOARD_UBLOX_C027 // Target running //target_set_state(RESET_RUN_WITH_DEBUG); #endif #ifdef BOARD_NRF51822AA // Target running target_set_state(RESET_RUN); #endif // start semihost task semihost_init(); semihost_enable(); while(1) { os_evt_wait_or( FLAGS_MAIN_RESET // Put target in reset state | FLAGS_MAIN_90MS // 90mS tick | FLAGS_MAIN_30MS // 30mS tick | FLAGS_MAIN_POWERDOWN // Power down interface | FLAGS_MAIN_DISABLEDEBUG // Power down interface #ifdef USE_USB_EJECT_INSERT | FLAGS_MAIN_USB_DISCONNECT // Disable target debug | FLAGS_MAIN_USB_MEDIA_EJECT, // Eject file system #else | FLAGS_MAIN_USB_DISCONNECT, // Disable target debug #endif NO_TIMEOUT); // Find out what event happened flags = os_evt_get(); if (flags & FLAGS_MAIN_USB_DISCONNECT) { usb_busy = USB_IDLE; // USB not busy usb_state_count = 4; usb_state = USB_DISCONNECT_CONNECT; // disconnect the usb } #ifdef USE_USB_EJECT_INSERT if (flags & FLAGS_MAIN_USB_MEDIA_EJECT) { EjectInsertMediaMode = EJECT_INSERT_WAIT_TO_EJECT; EjectInsertMediaCounter = EJECT_INSERT_DELAY_500MS; } #endif if (flags & FLAGS_MAIN_RESET) { cdc_led_state = LED_OFF; gpio_set_cdc_led(0); //usbd_cdc_ser_flush(); if (send_uID) { // set the target in reset to not receive char on the serial port target_set_state(RESET_HOLD); // send uid id_str = get_uid_string(); USBD_CDC_ACM_DataSend(id_str, strlen((const char *)id_str)); send_uID = 0; } // Reset target target_set_state(RESET_RUN); cdc_led_state = LED_FLASH; gpio_set_cdc_led(1); button_activated = 0; } if (flags & FLAGS_MAIN_POWERDOWN) { // Stop semihost task semihost_disable(); // Disable debug target_set_state(NO_DEBUG); // Disconnect USB usbd_connect(0); // Turn off LED gpio_set_dap_led(0); gpio_set_cdc_led(0); gpio_set_msd_led(0); // TODO: put the interface chip in sleep mode while (1) { } } if (flags & FLAGS_MAIN_DISABLEDEBUG) { // Stop semihost task semihost_disable(); // Disable debug target_set_state(NO_DEBUG); } if (flags & FLAGS_MAIN_90MS) { if (!button_activated) { gpio_enable_button_flag(main_task_id, FLAGS_MAIN_RESET); button_activated = 1; } #ifdef USE_USB_EJECT_INSERT if (EjectInsertMediaMode == EJECT_INSERT_WAIT_TO_EJECT) { if (--EjectInsertMediaCounter == 0) { // Have waited ~0.5 second, time to eject media EjectInsertMediaMode = EJECT_INSERT_WAIT_TO_INSERT; EjectInsertMediaCounter = EJECT_INSERT_DELAY_500MS; USBD_MSC_MediaReady = __FALSE; } } if ((EjectInsertMediaMode == EJECT_INSERT_WAIT_TO_INSERT) && !USBD_MSC_MediaReadyEx) { // The host computer have questioned the state and received // the message that the media has been removed if (--EjectInsertMediaCounter == 0) { // Have waited ~0.5 seconds after ejecting, time to insert media EjectInsertMediaMode = EJECT_INSERT_INACTIVE; USBD_MSC_MediaReady = __TRUE; } } #endif // Update USB busy status switch (usb_busy) { case USB_ACTIVE: if (DECZERO(usb_busy_count) == 0) { usb_busy=USB_IDLE; } break; case USB_IDLE: default: break; } // Update USB connect status switch (usb_state) { case USB_DISCONNECTING: // Wait until USB is idle before disconnecting if (usb_busy == USB_IDLE) { usbd_connect(0); usb_state = USB_DISCONNECTED; } break; case USB_DISCONNECT_CONNECT: // Wait until USB is idle before disconnecting if ((usb_busy == USB_IDLE) && (DECZERO(usb_state_count) == 0)) { usbd_connect(0); usb_state = USB_CONNECTING; // Update HTML file update_html_file(); // Delay the connecting state before reconnecting to the host - improved usage with VMs usb_state_count = 10; //(90ms * 10 = 900ms) } break; case USB_CONNECTING: // Wait before connecting if (DECZERO(usb_state_count) == 0) { usbd_connect(1); usb_state = USB_CHECK_CONNECTED; } break; case USB_CHECK_CONNECTED: if(usbd_configured()) { if (!thread_started) { os_tsk_create_user(hid_process, DAP_TASK_PRIORITY, (void *)stk_dap_task, DAP_TASK_STACK); serial_task_id = os_tsk_create_user(serial_process, SERIAL_TASK_PRIORITY, (void *)stk_serial_task, SERIAL_TASK_STACK); thread_started = 1; } usb_state = USB_CONNECTED; } break; case USB_CONNECTED: case USB_DISCONNECTED: default: break; } } // 30mS tick used for flashing LED when USB is busy if (flags & FLAGS_MAIN_30MS) { if (dap_led_usb_activity && ((dap_led_state == LED_FLASH) || (dap_led_state == LED_FLASH_PERMANENT))) { // Flash DAP LED ONCE if (dap_led_value) { dap_led_value = 0; } else { dap_led_value = 1; // Turn on if (dap_led_state == LED_FLASH) { dap_led_usb_activity = 0; } } // Update hardware gpio_set_dap_led(dap_led_value); } if (msd_led_usb_activity && ((msd_led_state == LED_FLASH) || (msd_led_state == LED_FLASH_PERMANENT))) { // Flash MSD LED ONCE if (msd_led_value) { msd_led_value = 0; } else { msd_led_value = 1; // Turn on if (msd_led_state == LED_FLASH) { msd_led_usb_activity = 0; } } // Update hardware gpio_set_msd_led(msd_led_value); } if (cdc_led_usb_activity && ((cdc_led_state == LED_FLASH) || (cdc_led_state == LED_FLASH_PERMANENT))) { // Flash CDC LED ONCE if (cdc_led_value) { cdc_led_value = 0; } else { cdc_led_value = 1; // Turn on if (cdc_led_state == LED_FLASH) { cdc_led_usb_activity = 0; } } // Update hardware gpio_set_cdc_led(cdc_led_value); } } } }
/* Expands macros in the *format string advancing the pointer as it goes. The * opt represents conditional expression state, should be zero for non-recursive * calls. Returns newly allocated string, which should be freed by the * caller. */ static LineWithAttrs parse_view_macros(view_t *view, const char **format, const char macros[], int opt) { const dir_entry_t *const curr = get_current_entry(view); LineWithAttrs result = { .line = strdup(""), .attrs = strdup("") }; char c; int nexpansions = 0; int has_expander = 0; if(curr == NULL) { return result; } while((c = **format) != '\0') { size_t width = 0; int left_align = 0; char buf[PATH_MAX + 1]; const char *const next = ++*format; int skip, ok; if(c != '%' || (!char_is_one_of(macros, *next) && !isdigit(*next) && (*next != '=' || has_expander))) { if(strappendch(&result.line, &result.line_len, c) != 0) { break; } continue; } if(*next == '=') { (void)sync_attrs(&result, 0); if(strappend(&result.line, &result.line_len, "%=") != 0 || strappendch(&result.attrs, &result.attrs_len, '=') != 0) { break; } ++*format; has_expander = 1; continue; } if(*next == '-') { left_align = 1; ++*format; } while(isdigit(**format)) { width = width*10 + *(*format)++ - '0'; } c = *(*format)++; skip = 0; ok = 1; buf[0] = '\0'; switch(c) { case 'a': friendly_size_notation(get_free_space(curr_view->curr_dir), sizeof(buf), buf); break; case 't': format_entry_name(curr, NF_FULL, sizeof(buf), buf); break; case 'T': if(curr->type == FT_LINK) { char full_path[PATH_MAX + 1]; char link_path[PATH_MAX + 1]; //add by sim1 get_full_path_of(curr, sizeof(full_path), full_path); //mod by sim1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< if(get_link_target(full_path, link_path, sizeof(link_path)) != 0) { copy_str(buf, sizeof(buf), "Failed to resolve link"); } else { snprintf(buf, sizeof(buf), " -> %s", link_path); } //mod by sim1 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> } break; case 'f': get_short_path_of(view, curr, NF_FULL, 0, sizeof(buf), buf); break; case 'A': #ifndef _WIN32 get_perm_string(buf, sizeof(buf), curr->mode); #else copy_str(buf, sizeof(buf), attr_str_long(curr->attrs)); #endif break; case 'u': get_uid_string(curr, 0, sizeof(buf), buf); break; case 'g': get_gid_string(curr, 0, sizeof(buf), buf); break; case 's': friendly_size_notation(fentry_get_size(view, curr), sizeof(buf), buf); break; //add by sim1 ************************************************ case 'r': { char path[PATH_MAX] = {0}; get_full_path_at(view, view->list_pos, sizeof(path), path); (void)get_rating_string(buf, sizeof(buf), path); } break; case 'n': { int nitems = !fentry_is_dir(curr) ? 0 : (int)fentry_get_nitems(view, curr); snprintf(buf, sizeof(buf), "%d", nitems); } break; //add by sim1 ************************************************ case 'E': { uint64_t size = 0U; typedef int (*iter_f)(view_t *view, dir_entry_t **entry); /* No current element for visual mode, since it can contain truly * empty selection when cursor is on ../ directory. */ iter_f iter = vle_mode_is(VISUAL_MODE) ? &iter_selected_entries : &iter_selection_or_current; dir_entry_t *entry = NULL; while(iter(view, &entry)) { size += fentry_get_size(view, entry); } friendly_size_notation(size, sizeof(buf), buf); } break; case 'd': { struct tm *tm_ptr = localtime(&curr->mtime); strftime(buf, sizeof(buf), cfg.time_format, tm_ptr); } break; case '-': case 'x': skip = expand_num(buf, sizeof(buf), view->filtered); break; case 'l': skip = expand_num(buf, sizeof(buf), view->list_pos + 1); break; case 'L': skip = expand_num(buf, sizeof(buf), view->list_rows + view->filtered); break; case 'S': skip = expand_num(buf, sizeof(buf), view->list_rows); break; case '%': copy_str(buf, sizeof(buf), "%"); break; case 'z': copy_str(buf, sizeof(buf), get_tip()); break; case 'D': if(curr_stats.number_of_windows == 1) { view_t *const other = (view == curr_view) ? other_view : curr_view; //mod by sim1 //copy_str(buf, sizeof(buf), replace_home_part(other->curr_dir)); snprintf(buf, sizeof(buf), " ‖ %s", replace_home_part(other->curr_dir)); } break; case '[': { LineWithAttrs opt = parse_view_macros(view, format, macros, 1); copy_str(buf, sizeof(buf), opt.line); free(opt.line); char *attrs = opt.attrs; if(sync_attrs(&result, 0) && opt.attrs_len > 0U) { if(*attrs != ' ') { result.attrs[result.attrs_len - 1U] = *attrs; } ++attrs; } strappend(&result.attrs, &result.attrs_len, attrs); free(opt.attrs); break; } case ']': if(opt) { if(nexpansions == 0) { replace_string(&result.line, ""); replace_string(&result.attrs, ""); result.line_len = 0U; result.attrs_len = 0U; } if(sync_attrs(&result, 0)) { result.attrs[--result.attrs_len] = '\0'; } return result; } LOG_INFO_MSG("Unmatched %%]"); ok = 0; break; case '{': { /* Try to find matching closing bracket * TODO: implement the way to escape it, so that the expr may contain * closing brackets */ const char *e = strchr(*format, '}'); char *expr = NULL, *resstr = NULL; var_t res = var_false(); ParsingErrors parsing_error; /* If there's no matching closing bracket, just add the opening one * literally */ if(e == NULL) { ok = 0; break; } /* Create a NULL-terminated copy of the given expr. * TODO: we could temporarily use buf for that, to avoid extra * allocation, but explicitly named variable reads better. */ expr = calloc(e - (*format) + 1 /* NUL-term */, 1); memcpy(expr, *format, e - (*format)); /* Try to parse expr, and convert the res to string if succeed. */ parsing_error = parse(expr, 0, &res); if(parsing_error == PE_NO_ERROR) { resstr = var_to_str(res); } if(resstr != NULL) { copy_str(buf, sizeof(buf), resstr); } else { copy_str(buf, sizeof(buf), "<Invalid expr>"); } var_free(res); free(resstr); free(expr); *format = e + 1 /* closing bracket */; } break; case '*': if(width > 9) { snprintf(buf, sizeof(buf), "%%%d*", (int)width); width = 0; break; } (void)sync_attrs(&result, 1); result.attrs[result.attrs_len - 1] = '0' + width; width = 0; break; default: LOG_INFO_MSG("Unexpected %%-sequence: %%%c", c); ok = 0; break; } if(char_is_one_of("tTAugsEd", c) && fentry_is_fake(curr)) { buf[0] = '\0'; } if(!ok) { *format = next; if(strappendch(&result.line, &result.line_len, '%') != 0) { break; } continue; } check_expanded_str(buf, skip, &nexpansions); stralign(buf, width, ' ', left_align); if(strappend(&result.line, &result.line_len, buf) != 0) { break; } } /* Unmatched %[. */ if(opt) { (void)strprepend(&result.line, &result.line_len, "%["); } if(sync_attrs(&result, 0)) { result.attrs[--result.attrs_len] = '\0'; } return result; } /* Makes sure that result->attrs has at least as many elements as result->line * contains characters + extra_width. Returns non-zero if result->attrs has * extra characters compared to result->line. */ static int sync_attrs(LineWithAttrs *result, int extra_width) { const size_t nchars = utf8_strsw(result->line) + extra_width; if(result->attrs_len < nchars) { char *const new_attrs = format_str("%s%*s", result->attrs, (int)(nchars - result->attrs_len), ""); free(result->attrs); result->attrs = new_attrs; result->attrs_len = nchars; } return (result->attrs_len > nchars); } /* Prints number into the buffer. Returns non-zero if numeric value is * "empty" (zero). */ static int expand_num(char buf[], size_t buf_len, int val) { snprintf(buf, buf_len, "%d", val); return (val == 0); }
/* Formats status line in the "old way" (before introduction of 'statusline' * option). */ static void update_stat_window_old(view_t *view, int lazy_redraw) { const dir_entry_t *const curr = get_current_entry(view); char name_buf[160*2 + 1]; char perm_buf[26]; char size_buf[64]; char id_buf[52]; int x; int cur_x; size_t print_width; char *filename; if(curr == NULL || fentry_is_fake(curr)) { werase(stat_win); refresh_window(stat_win, lazy_redraw); return; } x = getmaxx(stdscr); wresize(stat_win, 1, x); ui_set_bg(stat_win, &cfg.cs.color[STATUS_LINE_COLOR], cfg.cs.pair[STATUS_LINE_COLOR]); filename = get_current_file_name(view); print_width = utf8_strsnlen(filename, 20 + MAX(0, x - 83)); copy_str(name_buf, MIN(sizeof(name_buf), print_width + 1), filename); friendly_size_notation(fentry_get_size(view, curr), sizeof(size_buf), size_buf); get_uid_string(curr, 0, sizeof(id_buf), id_buf); if(id_buf[0] != '\0') strcat(id_buf, ":"); get_gid_string(curr, 0, sizeof(id_buf) - strlen(id_buf), id_buf + strlen(id_buf)); #ifndef _WIN32 get_perm_string(perm_buf, sizeof(perm_buf), curr->mode); #else copy_str(perm_buf, sizeof(perm_buf), attr_str_long(curr->attrs)); #endif werase(stat_win); cur_x = 2; checked_wmove(stat_win, 0, cur_x); wprint(stat_win, name_buf); cur_x += 22; if(x > 83) cur_x += x - 83; mvwaddstr(stat_win, 0, cur_x, size_buf); cur_x += 12; mvwaddstr(stat_win, 0, cur_x, perm_buf); cur_x += 11; snprintf(name_buf, sizeof(name_buf), "%d %s filtered", view->filtered, (view->filtered == 1) ? "file" : "files"); if(view->filtered > 0) mvwaddstr(stat_win, 0, x - (strlen(name_buf) + 2), name_buf); if(cur_x + strlen(id_buf) + 1 > x - (strlen(name_buf) + 2)) break_at(id_buf, ':'); if(cur_x + strlen(id_buf) + 1 > x - (strlen(name_buf) + 2)) id_buf[0] = '\0'; mvwaddstr(stat_win, 0, cur_x, id_buf); refresh_window(stat_win, lazy_redraw); }