1// Port of touch -- change modification and access times of files for GNU.
2// 'touch' file modification program for Phasor.
3// Copyright (C) 2026 Daniel McGuire.
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
24// Global variables for options
25var g_no_create = false;
26var g_no_dereference = false;
27var g_update_atime = true;
28var g_update_mtime = true;
29var g_reference = null;
31var g_timestamp = null;
32var g_error_occurred = false;
34fn startsWith(input: string, prefix: string) {
35 if (len(input) < len(prefix)) return false;
36 return substr(input, 0, len(prefix)) == prefix;
39// Function to display help message
40fn show_help() -> void {
41 puts("Usage: touch [OPTION]... FILE");
42 puts("Update the access and modification times of FILE to the current time.");
43 puts("If FILE does not exist, it is created empty, unless -c is supplied.");
46 puts(" -a change only the access time");
47 puts(" -c, --no-create do not create any files");
48 puts(" -d, --date=STRING parse STRING and use as time");
49 puts(" -h, --no-dereference affect symbolic links directly");
50 puts(" -m change only the modification time");
51 puts(" -r, --reference=FILE use this file's times");
52 puts(" --help display this help and exit");
53 puts(" --version output version information and exit");
56// Function to display version information
57fn show_version() -> void {
58 puts("touch (Phasor coreutils) 0.1");
59 puts("License GPLv3+: GNU GPL version 3 or later");
60 puts("This is free software: you are free to change and redistribute it.");
61 puts("There is NO WARRANTY, to the extent permitted by law.");
64// Function to parse date string
65fn parse_date(date_str: string) -> int {
69// Function to get time from reference file
70fn get_reference_time(ref_file: string) -> int {
71 if (!fexists(ref_file)) {
72 puts("touch: cannot stat reference file");
73 g_error_occurred = true;
76 return fpropget(ref_file, "m", 0);
80fn touch_file(filename: string) -> void {
81 var current_time = time() / 1000;
82 var target_time = current_time;
85 target_time = get_reference_time(g_reference);
86 if (g_error_occurred) return;
88 target_time = parse_date(g_date);
89 } else if (g_timestamp) {
90 target_time = to_int(g_timestamp);
93 var exists = fexists(filename);
96 if (g_no_create) return;
98 puts("touch: cannot create file");
99 g_error_occurred = true;
104 if (g_update_atime && !fpropset(filename, "a", target_time)) {
105 puts("touch: cannot update access time");
106 g_error_occurred = true;
109 if (g_update_mtime && !fpropset(filename, "m", target_time)) {
110 puts("touch: cannot update modification time");
111 g_error_occurred = true;
116 var arg_count = sys_argc();
119 for (var i = 1; i < arg_count; i = i + 1) {
120 var arg = sys_argv(i);
122 if (arg == "--help") {
125 } else if (arg == "--version") {
128 } else if (arg == "--") {
131 } else if (arg == "--no-create" || arg == "-c") {
133 } else if (arg == "--no-dereference" || arg == "-h") {
134 g_no_dereference = true;
135 } else if (arg == "-a") {
136 g_update_atime = true;
137 g_update_mtime = false;
138 } else if (arg == "-m") {
139 g_update_atime = false;
140 g_update_mtime = true;
141 } else if (startsWith(arg, "-") && len(arg) > 1) {
142 for (var j = 1; j < len(arg); j = j + 1) {
143 var opt = substr(arg, j, 1);
145 g_update_atime = true;
146 g_update_mtime = false;
147 } else if (opt == "c") {
149 } else if (opt == "h") {
150 g_no_dereference = true;
151 } else if (opt == "m") {
152 g_update_atime = false;
153 g_update_mtime = true;
155 puts("touch: invalid option");
156 puts("Try 'touch --help' for more information.");
165 if (filename == null) {
166 puts("touch: missing file operand");
167 puts("Try 'touch --help' for more information.");
171 touch_file(filename);
173 if (g_error_occurred) {