Line data Source code
1 : % Copyright (C) 2012-2021,2022 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 : %---------------------------------------------------------------------------
7 : private define needs_globbing (path)
8 : {
9 18 : return (path != str_delete_chars (path, "*?["));
10 : }
11 :
12 : private define do_the_glob (dir, pat)
13 : {
14 : variable files;
15 :
16 7 : if (dir == "")
17 1 : files = listdir (".");
18 : else
19 6 : files = listdir (dir);
20 :
21 7 : if (files == NULL)
22 0 : return String_Type[0];
23 :
24 7 : files = [files, ".", ".."];
25 :
26 7 : if ((pat[0] == '?') || (pat[0] == '*'))
27 : {
28 4 : files = files [where (strncmp (files, ".", 1))];
29 : }
30 :
31 7 : if (length (files) == 0)
32 0 : return files;
33 :
34 7 : pat = glob_to_regexp (pat);
35 :
36 7 : variable i = where (array_map (Int_Type, &string_match, files, pat, 1));
37 7 : if (length (i) == 0)
38 0 : return String_Type[0];
39 :
40 7 : files = files[i];
41 7 : if (dir == "")
42 1 : return files;
43 :
44 6 : return array_map (String_Type, &path_concat, dir, files);
45 : }
46 :
47 : private define is_dir (dirs)
48 : {
49 1 : variable n = length(dirs);
50 1 : variable ok = Char_Type[n];
51 1 : _for (0, n-1, 1)
52 : {
53 1 : variable i = ();
54 1 : variable st = stat_file (dirs[i]);
55 1 : if (st == NULL)
56 0 : continue;
57 1 : ok[i] = stat_is ("dir", st.st_mode);
58 : }
59 1 : return ok;
60 : }
61 :
62 : define glob (); % recursion
63 : define glob ()
64 : {
65 9 : variable patterns = __pop_args (_NARGS);
66 9 : if (length (patterns) == 0)
67 0 : throw UsageError, "files = glob (patterns...)";
68 :
69 9 : patterns = [__push_args (patterns)];
70 :
71 9 : variable list = String_Type[0];
72 9 : foreach (patterns)
73 : {
74 10 : variable pat = ();
75 :
76 10 : !if (needs_globbing (pat))
77 : {
78 2 : if (NULL != stat_file (pat))
79 1 : list = [list, pat];
80 :
81 2 : continue;
82 : }
83 :
84 8 : variable base = path_basename (pat);
85 8 : variable dir = "";
86 8 : if (base != pat)
87 7 : dir = path_dirname (pat);
88 :
89 8 : if (needs_globbing (dir))
90 : {
91 2 : variable dirs = glob (dir);
92 2 : !if (strlen (base))
93 : {
94 1 : list = [list, dirs[where(is_dir (dirs))]];
95 1 : continue;
96 : }
97 :
98 1 : foreach dir (glob (dir))
99 1 : list = [list, do_the_glob (dir, base)];
100 :
101 1 : continue;
102 : }
103 :
104 6 : list = [list, do_the_glob (dir, base)];
105 : }
106 9 : return list;
107 : }
108 :
109 : #ifntrue
110 : define 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 2 : $1 = path_concat (path_dirname (__FILE__), "help/glob.hlp");
122 2 : if (NULL != stat_file ($1))
123 2 : add_doc_file ($1);
124 :
125 2 : provide ("glob");
|