Ajla 0.1.0
[ajla.git] / programs / acmd / common.ajla
blob6bb4ab7a713364bd081dfc7b35af4668995356fa
1 {*
2  * Copyright (C) 2024 Mikulas Patocka
3  *
4  * This file is part of Ajla.
5  *
6  * Ajla is free software: you can redistribute it and/or modify it under the
7  * terms of the GNU General Public License as published by the Free Software
8  * Foundation, either version 3 of the License, or (at your option) any later
9  * version.
10  *
11  * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * Ajla. If not, see <https://www.gnu.org/licenses/>.
17  *}
19 unit common;
21 uses io;
22 uses charset;
23 uses timezone;
25 record acmd_ro [
26         h : list(handle);
27         env : treemap(bytes, bytes);
28         home : maybe(bytes);
29         loc : locale;
30         tz : timezone;
33 const months~cache := [ `Jan`, `Feb`, `Mar`, `Apr`, `May`, `Jun`, `Jul`, `Aug`, `Sep`, `Oct`, `Nov`, `Dec` ];
34 const weekdays~cache := [ `Sun`, `Mon`, `Tue`, `Wed`, `Thu`, `Fri`, `Sat` ];
36 fn ex_str(t : type, e : t) : bytes;
38 fn glob(file pattern : string, case_sensitive : bool) : bool;
40 implementation
42 fn ex_str(t : type, e : t) : bytes
44         var p := exception_payload e;
45         if len_greater_than(p, 0) then
46                 return p;
47         return exception_string e;
50 fn glob_no_star(file pattern : string) : bool
52         if len(file) <> len(pattern) then
53                 return false;
54         for i := 0 to len(file) do [
55                 if pattern[i] = '?' then
56                         continue;
57                 if file[i] <> pattern[i] then
58                         return false;
59         ]
60         return true;
63 fn glob(file pattern : string, case_sensitive : bool) : bool
65         if not case_sensitive then [
66                 file := string_upcase(file);
67                 pattern := string_upcase(pattern);
68         ]
69         var star := list_search(pattern, '*');
70         if star = -1 then
71                 return glob_no_star(file, pattern);
72         if len(file) < star then
73                 return false;
74         if not glob_no_star(file[ .. star], pattern[ .. star]) then
75                 return false;
76         file := file[star .. ];
77         pattern := pattern[star + 1 .. ];
78 next_star:
79         var star2 := list_search(pattern, '*');
80         if star2 = -1 then [
81                 if len(file) < len(pattern) then
82                         return false;
83                 return glob_no_star(file[len(file) - len(pattern) .. ], pattern);
84         ]
85         var pattern_stars := pattern[ .. star2];
86         for i := 0 to len(file) - len(pattern_stars) do [
87                 if glob_no_star(file[i .. i + len(pattern_stars)], pattern_stars) then [
88                         file := file[i + len(pattern_stars) .. ];
89                         pattern := pattern[star2 + 1 .. ];
90                         goto next_star;
91                 ]
92         ]
93         return false;