Changeset 4378

Show
Ignore:
Timestamp:
09/20/06 17:59:39 (2 years ago)
Author:
morris
Message:

Add globbing

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • wire/trunk/NEWS

    r4373 r4378  
    33 
    441.1.2 
     5- Add globbing, e.g. /get *.mp3 
    56- Clear the chat action indicator when scrolling to the bottom of a window 
    67 
  • wire/trunk/wire/client.c

    r4197 r4378  
    10831083        file->name      = wi_retain(wi_string_last_path_component(file->path)); 
    10841084 
    1085         wi_list_append_data(wr_files, file); 
     1085        wi_array_add_data(wr_files, file); 
    10861086        wi_release(file); 
    10871087} 
     
    10901090 
    10911091static void wr_msg_411(wi_array_t *arguments) { 
    1092         wi_list_node_t          *node; 
    10931092        wr_file_t                       *file; 
    10941093        wi_file_offset_t        free; 
    1095         unsigned int           max_length = 0; 
     1094        uint32_t                       i, count, max_length = 0; 
    10961095 
    10971096        if(wr_ls_state == WR_LS_LISTING) { 
    10981097                free = wi_string_uint64(WI_ARRAY(arguments, 1)); 
     1098                count = wi_array_count(wr_files); 
    10991099 
    11001100                wr_printf_prefix(WI_STR("Listing of %@ (%@ available):"), wr_files_ld, wr_files_string_for_size(free)); 
    11011101 
    1102                 if(wi_list_count(wr_files) == 0) { 
     1102                if(count == 0) { 
    11031103                        wr_printf_block(WI_STR("(empty)")); 
    11041104                } else { 
    1105                         WI_LIST_FOREACH(wr_files, node, file) 
     1105                        for(i = 0; i < count; i++) { 
     1106                                file = WI_ARRAY(wr_files, i); 
    11061107                                max_length = WI_MAX(max_length, wi_string_length(file->name)); 
    1107  
    1108                         WI_LIST_FOREACH(wr_files, node, file) 
     1108                        } 
     1109 
     1110                        for(i = 0; i < count; i++) { 
     1111                                file = WI_ARRAY(wr_files, i); 
    11091112                                wr_print_file(file, false, max_length); 
     1113                        } 
    11101114                } 
    11111115        } 
     
    11231127        file->name      = wi_retain(wi_string_last_path_component(file->path)); 
    11241128 
    1125         wi_list_append_data(wr_files, file); 
     1129        wi_array_add_data(wr_files, file); 
    11261130        wi_release(file); 
    11271131} 
     
    11301134 
    11311135static void wr_msg_421(wi_array_t *arguments) { 
    1132         wi_list_node_t  *node; 
    11331136        wr_file_t               *file; 
    1134         unsigned int    max_length = 0; 
     1137        uint32_t                i, count, max_length = 0; 
     1138 
     1139        count = wi_array_count(wr_files); 
    11351140 
    11361141        wr_printf_prefix(WI_STR("Search results:")); 
    11371142 
    1138         if(wi_list_count(wr_files) == 0) { 
     1143        if(count == 0) { 
    11391144                wr_printf_block(WI_STR("(none)")); 
    11401145        } else { 
    1141                 WI_LIST_FOREACH(wr_files, node, file) 
     1146                for(i = 0; i < count; i++) { 
     1147                        file = WI_ARRAY(wr_files, i); 
    11421148                        max_length = WI_MAX(max_length, wi_string_length(file->name)); 
    1143  
    1144                 WI_LIST_FOREACH(wr_files, node, file) 
    1145                         wr_print_file(file, true, max_length); 
    1146         } 
    1147 
     1149                } 
     1150 
     1151                for(i = 0; i < count; i++) { 
     1152                        file = WI_ARRAY(wr_files, i); 
     1153                        wr_print_file(file, false, max_length); 
     1154                } 
     1155        } 
     1156
  • wire/trunk/wire/files.c

    r4377 r4378  
    2929#include "config.h" 
    3030 
     31#include <sys/stat.h> 
    3132#include <stdio.h> 
    3233#include <stdlib.h> 
     34#include <dirent.h> 
     35#include <glob.h> 
    3336#include <readline/readline.h> 
    3437#include <wired/wired.h> 
     
    3841#include "main.h" 
    3942 
     43#include "windows.h" 
     44 
     45struct _wr_files_glob_dir { 
     46        wi_string_t                                             *path; 
     47        struct dirent                                   **entries; 
     48        uint32_t                                                count, offset; 
     49}; 
     50 
     51typedef struct _wr_files_glob_dir       wr_files_glob_dir_t; 
     52 
     53 
     54static wi_array_t *                                     wr_files_glob(wi_string_t *); 
     55static void *                                           wr_files_glob_opendir(const char *); 
     56static struct dirent *                          wr_files_glob_readdir(void *); 
     57static void                                                     wr_files_glob_closedir(void *); 
     58static int                                                      wr_files_glob_stat(const char *, struct stat *); 
     59 
    4060static void                                                     wr_file_dealloc(wi_runtime_instance_t *); 
    4161static wi_string_t *                            wr_file_description(wi_runtime_instance_t *); 
     
    4363wi_string_t *                                           wr_files_cwd; 
    4464wi_string_t *                                           wr_files_ld; 
    45 wi_list_t                                                     *wr_files; 
     65wi_array_t                                                    *wr_files; 
    4666 
    4767wr_ls_state_t                                           wr_ls_state; 
     
    6282        wr_file_runtime_id = wi_runtime_register_class(&wr_file_runtime_class); 
    6383 
    64         wr_files = wi_list_init(wi_list_alloc()); 
     84        wr_files = wi_array_init(wi_array_alloc()); 
    6585         
    6686        wr_files_cwd = wi_string_init_with_cstring(wi_string_alloc(), "/"); 
     
    7090 
    7191void wr_clear_files(void) { 
    72         wi_list_remove_all_data(wr_files); 
     92        wi_array_remove_all_data(wr_files); 
    7393         
    7494        wi_release(wr_files_ld); 
     
    81101 
    82102char * wr_readline_filename_generator(const char *text, int state) { 
    83         static wi_list_node_t   *node; 
    84103        static wi_string_t              *directory_path; 
     104        static uint32_t                 index; 
    85105        wi_string_t                             *path, *full_path, *name; 
    86106        wr_file_t                               *file; 
    87107        char                                    *cname; 
    88108        wi_boolean_t                    root; 
     109        uint32_t                                count; 
    89110         
    90111        cname = ((*rl_filename_dequoting_function) ((char *) text, 0)); 
     
    97118                directory_path  = wi_retain(wi_string_by_deleting_last_path_component(path)); 
    98119                full_path               = wr_files_full_path(directory_path); 
     120                index                   = 0; 
    99121 
    100122                wr_clear_files(); 
    101123                wr_send_command(WI_STR("LIST %@"), full_path); 
    102124                wr_runloop_run_for_socket(wr_socket, 3.0, 411); 
    103  
    104                 node = wi_list_first_node(wr_files); 
    105125        } 
    106126 
    107127        name = wi_string_last_path_component(path); 
    108128        root = wi_is_equal(name, WI_STR("/")); 
    109  
    110         while(node) { 
    111                file = wi_list_node_data(node); 
    112                 node = wi_list_node_next_node(node); 
     129        count = wi_array_count(wr_files); 
     130 
     131        while(index < count) { 
     132                file = WI_ARRAY(wr_files, index++); 
    113133 
    114134                if(file->type == WR_FILE_FILE && wr_ls_state == WR_LS_COMPLETING_DIRECTORY) 
     
    147167 
    148168wi_array_t * wr_files_full_paths(wi_array_t *paths) { 
    149         wi_array_t              *fullpaths
    150         uint32_t                i, count
     169        wi_array_t              *fullpaths, *globpaths
     170        uint32_t                i, count, j, globcount
    151171         
    152172        count = wi_array_count(paths); 
    153173        fullpaths = wi_array_init_with_capacity(wi_array_alloc(), count); 
    154174         
    155         for(i = 0; i < count; i++) 
    156                 wi_array_add_data(fullpaths, wr_files_full_path(WI_ARRAY(paths, i))); 
     175        for(i = 0; i < count; i++) { 
     176                globpaths = wr_files_glob(WI_ARRAY(paths, i)); 
     177                globcount = wi_array_count(globpaths); 
     178                 
     179                for(j = 0; j < globcount; j++) 
     180                        wi_array_add_data(fullpaths, wr_files_full_path(WI_ARRAY(globpaths, j))); 
     181        } 
    157182         
    158183        return wi_autorelease(fullpaths); 
     
    214239#pragma mark - 
    215240 
     241static wi_array_t * wr_files_glob(wi_string_t *pattern) { 
     242        wi_array_t              *array; 
     243        glob_t                  gl; 
     244        uint32_t                i; 
     245         
     246        gl.gl_opendir   = wr_files_glob_opendir; 
     247        gl.gl_readdir   = wr_files_glob_readdir; 
     248        gl.gl_closedir  = wr_files_glob_closedir; 
     249        gl.gl_lstat             = wr_files_glob_stat; 
     250        gl.gl_stat              = wr_files_glob_stat; 
     251         
     252        if(glob(wi_string_cstring(pattern), GLOB_ALTDIRFUNC, NULL, &gl) != 0) { 
     253                wr_printf_prefix(WI_STR("glob: %m")); 
     254                 
     255                return NULL; 
     256        } 
     257         
     258        array = wi_array_init_with_capacity(wi_array_alloc(), gl.gl_pathc); 
     259         
     260        for(i = 0; i < gl.gl_pathc; i++) 
     261                wi_array_add_data(array, wi_string_with_cstring(gl.gl_pathv[i])); 
     262         
     263        globfree(&gl); 
     264         
     265        return wi_autorelease(array); 
     266} 
     267 
     268 
     269 
     270static void * wr_files_glob_opendir(const char *path) { 
     271        wr_files_glob_dir_t             *dir; 
     272        wr_file_t                               *file; 
     273        uint32_t                                i; 
     274         
     275        dir = wi_malloc(sizeof(wr_files_glob_dir_t)); 
     276        dir->path = wi_retain(wr_files_full_path(wi_string_with_cstring(path))); 
     277         
     278        wr_ls_state = WR_LS_GLOBBING; 
     279        wr_clear_files(); 
     280        wr_send_command(WI_STR("LIST %@"), dir->path); 
     281        wr_runloop_run_for_socket(wr_socket, 3.0, 411); 
     282         
     283        dir->count = wi_array_count(wr_files); 
     284        dir->entries = wi_malloc(sizeof(struct dirent) * (dir->count + 1)); 
     285         
     286        for(i = 0; i < dir->count; i++) { 
     287                file = WI_ARRAY(wr_files, i); 
     288 
     289                dir->entries[i] = wi_malloc(sizeof(struct dirent)); 
     290                dir->entries[i]->d_ino = 0; 
     291                dir->entries[i]->d_reclen = 0; 
     292                dir->entries[i]->d_type = (file->type == WR_FILE_FILE) ? DT_REG : DT_DIR; 
     293                dir->entries[i]->d_namlen = wi_string_length(file->name); 
     294                 
     295                strlcpy(dir->entries[i]->d_name, wi_string_cstring(file->name), sizeof(dir->entries[i]->d_name)); 
     296        } 
     297 
     298        return dir; 
     299} 
     300 
     301 
     302 
     303static struct dirent * wr_files_glob_readdir(void *p) { 
     304        wr_files_glob_dir_t             *dir = p; 
     305 
     306        return dir->entries[dir->offset++]; 
     307} 
     308 
     309 
     310 
     311static void wr_files_glob_closedir(void *p) { 
     312        wr_files_glob_dir_t             *dir = p; 
     313        uint32_t                                i; 
     314         
     315        wi_release(dir->path); 
     316         
     317        for(i = 0; i < dir->count; i++) 
     318                wi_free(dir->entries[i]); 
     319         
     320        wi_free(dir->entries); 
     321        wi_free(dir); 
     322} 
     323 
     324 
     325 
     326static int wr_files_glob_stat(const char *path, struct stat *sp) { 
     327        memset(sp, 0, sizeof(struct stat)); 
     328         
     329        return 0; 
     330} 
     331 
     332 
     333 
     334#pragma mark - 
     335 
    216336wr_file_t * wr_file_alloc(void) { 
    217337        return wi_runtime_create_instance(wr_file_runtime_id, sizeof(wr_file_t)); 
  • wire/trunk/wire/files.h

    r4377 r4378  
    5555        WR_LS_LISTING, 
    5656        WR_LS_COMPLETING, 
    57         WR_LS_COMPLETING_DIRECTORY 
     57        WR_LS_COMPLETING_DIRECTORY, 
     58        WR_LS_GLOBBING 
    5859}; 
    5960typedef enum _wr_ls_state                       wr_ls_state_t; 
     
    8485extern wi_string_t                                      *wr_files_cwd; 
    8586extern wi_string_t                                      *wr_files_ld; 
    86 extern wi_list_t                                      *wr_files; 
     87extern wi_array_t                                     *wr_files; 
    8788 
    8889extern wr_ls_state_t                            wr_ls_state;