{* * Copyright (C) 2024 Mikulas Patocka * * This file is part of Ajla. * * Ajla is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * Ajla. If not, see . *} unit common; uses io; uses charset; uses timezone; record acmd_ro [ h : list(handle); env : treemap(bytes, bytes); home : maybe(bytes); loc : locale; tz : timezone; ] const months~cache := [ `Jan`, `Feb`, `Mar`, `Apr`, `May`, `Jun`, `Jul`, `Aug`, `Sep`, `Oct`, `Nov`, `Dec` ]; const weekdays~cache := [ `Sun`, `Mon`, `Tue`, `Wed`, `Thu`, `Fri`, `Sat` ]; fn ex_str(t : type, e : t) : bytes; fn glob(file pattern : string, case_sensitive : bool) : bool; implementation fn ex_str(t : type, e : t) : bytes [ var p := exception_payload e; if len_greater_than(p, 0) then return p; return exception_string e; ] fn glob_no_star(file pattern : string) : bool [ if len(file) <> len(pattern) then return false; for i := 0 to len(file) do [ if pattern[i] = '?' then continue; if file[i] <> pattern[i] then return false; ] return true; ] fn glob(file pattern : string, case_sensitive : bool) : bool [ if not case_sensitive then [ file := string_upcase(file); pattern := string_upcase(pattern); ] var star := list_search(pattern, '*'); if star = -1 then return glob_no_star(file, pattern); if len(file) < star then return false; if not glob_no_star(file[ .. star], pattern[ .. star]) then return false; file := file[star .. ]; pattern := pattern[star + 1 .. ]; next_star: var star2 := list_search(pattern, '*'); if star2 = -1 then [ if len(file) < len(pattern) then return false; return glob_no_star(file[len(file) - len(pattern) .. ], pattern); ] var pattern_stars := pattern[ .. star2]; for i := 0 to len(file) - len(pattern_stars) do [ if glob_no_star(file[i .. i + len(pattern_stars)], pattern_stars) then [ file := file[i + len(pattern_stars) .. ]; pattern := pattern[star2 + 1 .. ]; goto next_star; ] ] return false; ]