1% Copyright (C) 2012-2017,2018 John E. Davis 2% 3% This file is part of the S-Lang Library and may be distributed under the 4% terms of the GNU General Public License. See the file COPYING for 5% more information. 6%--------------------------------------------------------------------------- 7private define needs_globbing (path) 8{ 9 return (path != str_delete_chars (path, "*?[")); 10} 11 12private define do_the_glob (dir, pat) 13{ 14 variable files; 15 16 if (dir == "") 17 files = listdir ("."); 18 else 19 files = listdir (dir); 20 21 if (files == NULL) 22 return String_Type[0]; 23 24 files = [files, ".", ".."]; 25 26 if ((pat[0] == '?') || (pat[0] == '*')) 27 { 28 files = files [where (strncmp (files, ".", 1))]; 29 } 30 31 if (length (files) == 0) 32 return files; 33 34 pat = glob_to_regexp (pat); 35 36 variable i = where (array_map (Int_Type, &string_match, files, pat, 1)); 37 if (length (i) == 0) 38 return String_Type[0]; 39 40 files = files[i]; 41 if (dir == "") 42 return files; 43 44 return array_map (String_Type, &path_concat, dir, files); 45} 46 47private define is_dir (dirs) 48{ 49 variable n = length(dirs); 50 variable ok = Char_Type[n]; 51 _for (0, n-1, 1) 52 { 53 variable i = (); 54 variable st = stat_file (dirs[i]); 55 if (st == NULL) 56 continue; 57 ok[i] = stat_is ("dir", st.st_mode); 58 } 59 return ok; 60} 61 62define glob (); % recursion 63define glob () 64{ 65 variable patterns = __pop_args (_NARGS); 66 if (length (patterns) == 0) 67 throw UsageError, "files = glob (patterns...)"; 68 69 patterns = [__push_args (patterns)]; 70 71 variable list = String_Type[0]; 72 foreach (patterns) 73 { 74 variable pat = (); 75 76 !if (needs_globbing (pat)) 77 { 78 if (NULL != stat_file (pat)) 79 list = [list, pat]; 80 81 continue; 82 } 83 84 variable base = path_basename (pat); 85 variable dir = ""; 86 if (base != pat) 87 dir = path_dirname (pat); 88 89 if (needs_globbing (dir)) 90 { 91 variable dirs = glob (dir); 92 !if (strlen (base)) 93 { 94 list = [list, dirs[where(is_dir (dirs))]]; 95 continue; 96 } 97 98 foreach dir (glob (dir)) 99 list = [list, do_the_glob (dir, base)]; 100 101 continue; 102 } 103 104 list = [list, do_the_glob (dir, base)]; 105 } 106 return list; 107} 108 109#ifntrue 110define slsh_main () 111{ 112 variable files = glob (__argv[[1:]]); 113 foreach (files) 114 { 115 variable f = (); 116 fprintf (stdout, "%s\n", f); 117 } 118} 119#endif 120 121$1 = path_concat (path_dirname (__FILE__), "help/glob.hlp"); 122if (NULL != stat_file ($1)) 123 add_doc_file ($1); 124 125provide ("glob"); 126