commit: 2f9d3d84b8a2a1a9d3f038ae0f33def0bb0af3c4
parent 2b7c2e96b970a727f4d3a5956dc6175a54af1c80
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sat,  3 Jun 2023 12:11:09 +0200
cmd/touch: Split iso_parse to lib/iso_parse.c
Diffstat:
5 files changed, 85 insertions(+), 65 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -8,6 +8,7 @@
 !/cmd/*.ha
 !/cmd/*.1
 *.t.err
+*.o
 
 # Kyua
 /html/
diff --git a/Makefile b/Makefile
@@ -49,7 +49,7 @@ cmd-install:
 coverage:
 	$(GCOV) -b $(EXE)
 
-C_SOURCES = cmd/*.c
+C_SOURCES = cmd/*.c lib/*.h lib/*.c
 format: $(C_SOURCES)
 	clang-format -style=file -assume-filename=.clang-format -i $(C_SOURCES)
 
@@ -72,3 +72,7 @@ cmd/strings: cmd/strings.c Makefile
 cmd/sleep: cmd/sleep.c Makefile
 	rm -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno}
 	$(CC) -std=c99 $(CFLAGS) $(LIBBSD_CFLAGS) -o $@ cmd/sleep.c $(LIBBSD_LIBS) $(LDFLAGS)
+
+cmd/touch: cmd/touch.c lib/iso_parse.c Makefile
+	rm -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno}
+	$(CC) -std=c99 $(CFLAGS) -o $@ cmd/touch.c lib/iso_parse.c $(LDFLAGS)
diff --git a/cmd/touch.c b/cmd/touch.c
@@ -2,75 +2,16 @@
 // SPDX-FileCopyrightText: 2023 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
 
-#define _DEFAULT_SOURCE   // tm_gmtoff/tm_zone
-#define _XOPEN_SOURCE 700 // strptime (NetBSD)
-#define _POSIX_C_SOURCE 200809L // O_NOFOLLOW, st_atim/st_mtim
+#define _POSIX_C_SOURCE 200809L // O_NOFOLLOW
+
+#include "../lib/iso_parse.h" /* iso_parse */
 
 #include <errno.h>    /* errno */
 #include <fcntl.h>    /* open */
 #include <stdbool.h>  /* bool */
-#include <stdio.h>    /* perror, sscanf */
-#include <stdlib.h>   /* exit */
-#include <string.h>   /* memset */
+#include <stdio.h>    /* perror */
 #include <sys/stat.h> /* futimens, stat, utimensat */
-#include <time.h>     /* strptime, tm */
-#include <unistd.h>   /* access */
-
-// Calls exit() on failure
-struct timespec
-iso_parse(char *arg)
-{
-	// YYYY-MM-DD[T ]hh:mm:SS([,\.]frac)?Z?
-	// Dammit Unixes why no nanoseconds in `struct tm` nor `strptime`
-	struct timespec time = {.tv_sec = 0, .tv_nsec = 0};
-
-	// For Alpine's abuild compatibility
-	if(arg[0] == '@')
-	{
-		arg++;
-		if(sscanf(arg, "%ld", &time.tv_sec) < 1) exit(EXIT_FAILURE);
-		return time;
-	}
-
-	struct tm tm;
-	memset(&tm, 0, sizeof(tm));
-
-	// No %F in POSIX
-	char *s = strptime(arg, "%Y-%m-%d", &tm);
-
-	if(s[0] != 'T' && s[0] != ' ') exit(EXIT_FAILURE);
-	s++;
-
-	s = strptime(s, "%H:%M:%S", &tm);
-
-	if(s[0] == ',' || s[0] == '.')
-	{
-		float fraction = 0.0;
-		int parsed     = 0;
-
-		if(s[0] == ',') s[0] = '.';
-
-		if(sscanf(s, "%f%n", &fraction, &parsed) < 1) exit(EXIT_FAILURE);
-
-		time.tv_nsec = fraction * 1000000000;
-		s += parsed;
-	}
-
-	if(s[0] == 'Z')
-	{
-		tm.tm_gmtoff = 0;
-		tm.tm_zone   = "UTC";
-	}
-
-	time.tv_sec = mktime(&tm);
-	if(time.tv_sec == (time_t)-1)
-	{
-		perror("touch: mktime");
-		exit(EXIT_FAILURE);
-	}
-
-	return time;
-}
+#include <unistd.h>   /* getopt, opt*, close */
 
 int
 main(int argc, char *argv[])
diff --git a/lib/iso_parse.c b/lib/iso_parse.c
@@ -0,0 +1,68 @@
+// Collection of Unix tools, comparable to coreutils
+// SPDX-FileCopyrightText: 2023 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
+// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
+
+#define _DEFAULT_SOURCE         // tm_gmtoff/tm_zone
+#define _XOPEN_SOURCE 700       // strptime (NetBSD)
+#define _POSIX_C_SOURCE 200809L // st_atim/st_mtim
+
+#include <stdio.h>  /* perror, sscanf */
+#include <stdlib.h> /* exit */
+#include <string.h> /* memset */
+#include <time.h>   /* strptime, tm */
+
+// Calls exit() on failure
+struct timespec
+iso_parse(char *arg)
+{
+	// YYYY-MM-DD[T ]hh:mm:SS([,\.]frac)?Z?
+	// Dammit Unixes why no nanoseconds in `struct tm` nor `strptime`
+	struct timespec time = {.tv_sec = 0, .tv_nsec = 0};
+
+	// For Alpine's abuild compatibility
+	if(arg[0] == '@')
+	{
+		arg++;
+		if(sscanf(arg, "%ld", &time.tv_sec) < 1) exit(EXIT_FAILURE);
+		return time;
+	}
+
+	struct tm tm;
+	memset(&tm, 0, sizeof(tm));
+
+	// No %F in POSIX
+	char *s = strptime(arg, "%Y-%m-%d", &tm);
+
+	if(s[0] != 'T' && s[0] != ' ') exit(EXIT_FAILURE);
+	s++;
+
+	s = strptime(s, "%H:%M:%S", &tm);
+
+	if(s[0] == ',' || s[0] == '.')
+	{
+		float fraction = 0.0;
+		int parsed     = 0;
+
+		if(s[0] == ',') s[0] = '.';
+
+		if(sscanf(s, "%f%n", &fraction, &parsed) < 1) exit(EXIT_FAILURE);
+
+		time.tv_nsec = fraction * 1000000000;
+		s += parsed;
+	}
+
+	if(s[0] == 'Z')
+	{
+		tm.tm_gmtoff = 0;
+		tm.tm_zone   = "UTC";
+	}
+
+	time.tv_sec = mktime(&tm);
+	if(time.tv_sec == (time_t)-1)
+	{
+		perror("mktime");
+		exit(EXIT_FAILURE);
+	}
+
+	return time;
+}
diff --git a/lib/iso_parse.h b/lib/iso_parse.h
@@ -0,0 +1,6 @@
+// Collection of Unix tools, comparable to coreutils
+// SPDX-FileCopyrightText: 2023 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
+// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
+
+#include <time.h> /* struct timespec */
+extern struct timespec iso_parse(char *);