X-Git-Url: https://git.ladys.computer/Shushe/blobdiff_plain/c3f0f4eafee4cb3bf51d438efab5d649b9079677..b620a662b669862cd7bf01aa06c8ad3de2f1a7f4:/GNUmakefile?ds=inline
diff --git a/GNUmakefile b/GNUmakefile
index b7e1112..73c8057 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -36,7 +36,6 @@ override define makefileinfo
║│ • rm │║
║│ • sed │║
║│ • sleep │║
-║│ • stat │║
║│ • test │║
║│ • touch │║
║│ • tr │║
@@ -117,7 +116,6 @@ PRINTF := printf
RM := rm
SED := sed
SLEEP := sleep
-STAT := stat
TEST := test
TOUCH := touch
TR := tr
@@ -257,10 +255,17 @@ override silent := $(if $(VERBOSE),,@)
# (callable) Get the modified time of the provided file.
#
-# This is messy; there is no portable way of using `stat´.
+# Only the date·time information available via `ls -l´ is supported; that is, only minute precision for files newer than six months, and only day precision for files which are older.
+# This is, unfortunately, the best that can be done in pure Posix as of now.
+#
+# There is an easier implementation which provides the full date·time by archiving an empty file and then reading it back out of the archive :—
+#
+# $(shell LC_TIME=POSIX TZ=UTC0 $(TOUCH) -m -r $(callquote,$1) $(BUILDDIR)/.mtime && $(PAX) -w -x ustar $(BUILDDIR)/.mtime | $(PAX) -v -o 'listopt=%(mtime=%Y-%m-%dT%H:%M:%SZ)T')
+#
+# However, it depends on the `listopt´ option in `pax´, which (despite being specified in Posix) no implementations actually support.
#
# ☡ This variable creates a subshell every time it is computed.
-override modtime = $(shell if $(STAT) --version 2> /dev/null | $(GREP) -q GNU; then $(DATE) -u -d "@$$(TZ= $(STAT) -c '%Y' $(call quote,$1))" '+%Y-%m-%dT%H:%M:%SZ'; else TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$1); fi)
+override modtime = $(shell { $(DATE) -u '+%Y-%m'; LC_TIME=POSIX TZ=UTC0 ls -q -A -l $(call quote,$1) | $(SED) 's/\([^ ]* \{1,\}\)\{5\}\(\([^ ]* \{1,\}\)\{3\}\).*/\2/;s/ \([0123456789]\) / 0\1 /;s/Jan/01/;s/Feb/02/;s/Mar/03/;s/Apr/04/;s/May/05/;s/Jun/06/;s/Jul/07/;s/Aug/08/;s/Sep/09/;s/Oct/10/;s/Nov/11/;s/Dec/12/;s/\([0123456789]\{2\}\) *\([0123456789]\{2\}\) *\([0123456789]\{4\}\)/\3-\1-\2T00:00:00Z/;s/\([0123456789]\{2\}\) *\([0123456789]\{2\}\) *\([0123456789:]\{5\}\)/XXXX-\1-\2T\3:00Z/'; } | $(TR) -d ' ' | $(AWK) -F '-' 'NR==1{year=$$1;month=$$2}$$1=="XXXX"&&$$2<=month{print year"-"$$2"-"$$3}$$1=="XXXX"&&$$2>month{print year-1"-"$$2"-"$$3}NR>1&&$$1!="XXXX"')
# ─ ¶ Recipe Variable Definitions ─────────────────────────────────────
@@ -288,7 +293,7 @@ override associatedfiles = $(LS) -1 $(call quote,$1) | $(SED) '/.*"{.*}".*/!d;s/
override removeassociatedfiles = ASSOCIATED="$$($(call associatedfiles,$(dir $1),$(notdir $1)) | $(TR) '\n' ' ')"; if $(TEST) -n "$$ASSOCIATED"; then cd $(call quote,$(dir $1)) && $(PRINTF) '%s\n' "$$ASSOCIATED" | $(SED) 's/ \{2,\}/ /g;s/^ //;s/ $$//' | $(TR) ' ' '\n' | $(xargsmultiquote) | $(XARGS) -E '' $(RM); fi
# (callable) Process the provided transformation result and output the result to the provided location, given the provided relative path.
-override processresultto = if $(call xpath,/*[local-name()="raw-text" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(call extracttext,$1) > $(call quote,$2); $(call removeassociatedfiles,$2); elif $(call xpath,/*[local-name()="base64-binary" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then { $(PRINTF) '%s\n' 'begin-base64 644 -'; $(call extracttext,$1) | $(TR) -d '\t\n\f\r '; $(PRINTF) '%s\n' '===='; } | $(UUDECODE) -o /dev/stdout > $(call quote,$2); $(call removeassociatedfiles,$2); elif $(call xpath,/*[local-name()="archive" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(MAKE) -f $(call quote,$(abspath $(THISDIR)/GNUmakefile)) $(call quote,$2) NAME=$(call quote,$3) SRC=$(call quote,$1) BUILDDIR=$(call quote,$(BUILDDIR)/archive/$3) DESTDIR=$(call quote,$(patsubst %/,%,$(dir $2))) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:archive'; $(call removeassociatedfiles,$2); elif $(call xpath,//*[local-name()="page" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(MAKE) -f $(call quote,$(abspath $(THISDIR)/GNUmakefile)) $(call quote,$2) NAME=$(call quote,$3) SRC=$(call quote,$1) BUILDDIR=$(call quote,$(BUILDDIR)/paged/$3) DESTDIR=$(call quote,$(patsubst %/,%,$(dir $2))) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:paged'; else $(XMLLINT) --nsclean $(call quote,$1) > $(call quote,$2); $(call removeassociatedfiles,$2); fi
+override processresultto = if $(call xpath,/*[local-name()="raw-text" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(call extracttext,$1) > $(call quote,$2); $(call removeassociatedfiles,$2); elif $(call xpath,/*[local-name()="base64-binary" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then { $(PRINTF) '%s\n' 'begin-base64 644 -'; $(call extracttext,$1) | $(TR) -d '\t\n\f\r '; $(PRINTF) '\n%s\n' '===='; } | $(UUDECODE) -o /dev/stdout > $(call quote,$2); $(call removeassociatedfiles,$2); elif $(call xpath,/*[local-name()="archive" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(MAKE) -f $(call quote,$(abspath $(THISDIR)/GNUmakefile)) $(call quote,$2) NAME=$(call quote,$3) SRC=$(call quote,$1) BUILDDIR=$(call quote,$(BUILDDIR)/archive/$3) DESTDIR=$(call quote,$(patsubst %/,%,$(dir $2))) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:archive'; $(call removeassociatedfiles,$2); elif $(call xpath,//*[local-name()="page" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(MAKE) -f $(call quote,$(abspath $(THISDIR)/GNUmakefile)) $(call quote,$2) NAME=$(call quote,$3) SRC=$(call quote,$1) BUILDDIR=$(call quote,$(BUILDDIR)/paged/$3) DESTDIR=$(call quote,$(patsubst %/,%,$(dir $2))) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:paged'; else $(XMLLINT) --nsclean $(call quote,$1) > $(call quote,$2); $(call removeassociatedfiles,$2); fi
# ━ § BEGIN DEFAULT MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -309,7 +314,7 @@ override diffprereqs = $(if $(subst $(shell $(CAT) $(call quote,$(BUILDDIR)/last
override sedesc = $(subst /,[/],$(subst $$,\$$,$(subst *,\*,$(subst .,\.,$(subst [,\[,$(subst ^,\^,$(subst \,\\,$1)))))))
# The command to use for percent‐decoding.
-override perdeccmd := $(SED) 's/|/%7C/g;s/[\]/%5C/g;s/%[0-9A-Fa-f]\{2\}/|&|/g' | $(TR) '|' '\n' | $(SED) '/^%[0-9A-Fa-f]\{2\}$$/!s/%/|%25|/' | $(TR) '|' '\n' | $(AWK) '$$0!~/%/{printf "%s",$$0}/%/{d="0123456789ABCDEF";v=substr(toupper($$0),2,2);printf "\\%04o",(index(d,substr(v,1,1))-1)*16+index(d,substr(v,2,1))-1}' | $(xargsquote) | $(XARGS) -E '' $(PRINTF) '%b'
+override perdeccmd := $(SED) 's/|/%7C/g;s/[\]/%5C/g;s/%[0123456789ABCDEFabcdef]\{2\}/|&|/g' | $(TR) '|' '\n' | $(SED) '/^%[0123456789ABCDEFabcdef]\{2\}$$/!s/%/|%25|/' | $(TR) '|' '\n' | $(AWK) '$$0!~/%/{printf "%s",$$0}/%/{d="0123456789ABCDEF";v=substr(toupper($$0),2,2);printf "\\%04o",(index(d,substr(v,1,1))-1)*16+index(d,substr(v,2,1))-1}' | $(xargsquote) | $(XARGS) -E '' $(PRINTF) '%b'
# (callable) Percent‐decode the given strings.
#
@@ -324,7 +329,7 @@ override perdec = $(shell $(PRINTF) '%s\0450A' $(foreach encoded,$1,$(call quote
# It is assumed that the given strings do not contain newlines.
#
# ☡ This variable creates a subshell every time it is computed.
-override perenc = $(shell $(PRINTF) '%s\n' $(foreach unencoded,$1,$(call quote,$(unencoded))) | $(OD) -t x1 | $(SED) 's/^[0-9]*//;s/0[Aa]/%&/g;s/2[146-9A-Ea-e]/%&/g;s/3[0-9AaBbDd]/%&/g;s/40/%&/g;s/[46][1-9A-Fa-f]/%&/g;s/[57][0-9Aa]/%&/g;s/5[Ff]/%&/g;s/7[Ee]/%&/g;s/[ ][0-9A-Fa-f]\{2\}/%25&/g' | $(TR) -d ' \n' | $(TR) 'abcdef' 'ABCDEF' | $(perdeccmd))
+override perenc = $(shell $(PRINTF) '%s\n' $(foreach unencoded,$1,$(call quote,$(unencoded))) | $(OD) -t x1 | $(SED) 's/^[0123456789]*//;s/0[Aa]/%&/g;s/2[146789ABCDEabcde]/%&/g;s/3[0123456789AaBbDd]/%&/g;s/40/%&/g;s/[46][123456789ABCDEFabcdef]/%&/g;s/[57][0123456789Aa]/%&/g;s/5[Ff]/%&/g;s/7[Ee]/%&/g;s/[ ][0123456789ABCDEFabcdef]\{2\}/%25&/g' | $(TR) -d ' \n' | $(TR) 'abcdef' 'ABCDEF' | $(perdeccmd))
# (callable) Percent‐encode each component in the given paths.
#
@@ -472,14 +477,14 @@ endif
override id = $(XMLLINT) --xpath '/*/*[local-name()="id" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"]/text()[1]' $(call quote,$1) 2> /dev/null || $(PRINTF) '%s\n' $(call quote,about:shushe?$(or $2,unknown)=$(call pathenc,$(basename $(notdir $1))))
# (callable) Sanitize and wrap the provided plaintext file in X·M·L, printing to `stdout´.
-override wrapplaintext = { $(PRINTF) '%s\n%s' '' ''; }
+override wrapplaintext = { $(PRINTF) '%s\n%s' '' ''; }
# (callable) Check if the provided X·M·L file is X·M·L 1.1, and if so, coerce to X·M·L 1.0 as best as possible, printing the result (or the original file contents) to `stdout´.
#
# The X·M·L declaration will be dropped and character escapes for C0 control codes will be replaced with a literal `U+0091 PRIVATE USE ONE´, which is invalid in X·M·L 1.1, but valid X·M·L 1.0 (making the replacement obvious).
#
# This isn’t a perfect substitution (it makes some assumptions about the format of the underlying X·M·L), but it should be workable for most sensible, welformed files.
-override serializexml = $(SED) "$$($(PRINTF) '%b' '/]*?>//\n s/&\0043x0*[1-8BCEFbcef];/\0302\0221/g\n s/&\0043x0*1[0-9A-Fa-f];/\0302\0221/g\n s/&\00430*[1-8];/\0302\0221/g\n s/&\00430*1[124-9];/\0302\0221/g\n s/&\00430*2[0-9];/\0302\0221/g\n s/&\00430*3[01];/\0302\0221/g\n}')" < $(call quote,$1) | $(SED) "$$($(PRINTF) '%b' ':a\n/^\\n*$$/{ $$d\n N\n ba\n}')"
+override serializexml = $(SED) "$$($(PRINTF) '%b' '/]*?>//\n s/&\0043x0*[12345678BCEFbcef];/\0302\0221/g\n s/&\0043x0*1[0123456789ABCDEFabcdef];/\0302\0221/g\n s/&\00430*[12345678];/\0302\0221/g\n s/&\00430*1[12456789];/\0302\0221/g\n s/&\00430*2[0123456789];/\0302\0221/g\n s/&\00430*3[01];/\0302\0221/g\n}')" < $(call quote,$1) | $(SED) "$$($(PRINTF) '%b' ':a\n/^\\n*$$/{ $$d\n N\n ba\n}')"
# ─ ¶ Phony Targets ───────────────────────────────────────────────────
@@ -502,7 +507,7 @@ install : $(call installed,$(recursivefiles) $(installablefiles)) ;
# List all source files and includes and their computed types.
list :
- @$(PRINTF) '%b' $(call quote,$(foreach file,$(sort $(sourcefiles)) $(sort $(sourceincludes)),\0033[1m$(file)\0033[22m|$(call typeoffile,$(file))|[\0033[3m$(if $(filter $(file),$(xmlfiles)),xml,$(if $(filter $(file),$(plaintextfiles)),text,asset))$(if $(filter $(file),$(sourceincludes)),|include,)\0033[23m]$(if $(call dependencies,$(file))$(call recursives,$(file)), $(strip $(foreach recursive,$(call recursives,$(file)),\0033[93;41m•|Recursive|Dependency|\0033[39;49m|$(recursive)) $(foreach dependency,$(call dependencies,$(file)),\0033[2m•|Dependency|\0033[22m|$(dependency))))$(if $(filter $(file),$(sourcefiles)), →|<\0033[4m/$(call destination,$(file))\0033[24m>,) )) | $(TR) ' |' '\n '
+ @$(PRINTF) '%b' $(call quote,$(foreach file,$(sort $(sourcefiles)) $(sort $(sourceincludes)),\0033[1m$(file)\0033[22m|$(call typeoffile,$(file))|[\0033[3m$(if $(filter $(file),$(xmlfiles)),xml,$(if $(filter $(file),$(plaintextfiles)),text,asset))$(if $(filter $(file),$(sourceincludes)),|include,)\0033[23m] Modified:|$(call modtime,$(file))$(if $(call dependencies,$(file))$(call recursives,$(file)), $(strip $(foreach recursive,$(call recursives,$(file)),\0033[93;41m•|Recursive|Dependency|\0033[39;49m|$(recursive)) $(foreach dependency,$(call dependencies,$(file)),\0033[2m•|Dependency|\0033[22m|$(dependency))))$(if $(filter $(file),$(sourcefiles)), →|<\0033[4m/$(call destination,$(file))\0033[24m>,) )) | $(TR) ' |' '\n '
# Lists out the destinations of all resulting files (relative to `DESTDIR´).
listout :
@@ -640,17 +645,20 @@ $(call compiled,$(compilablefiles)) : $(BUILDDIR)/results/% : $$(call parsed,$$(
$(call built,$(compilablefiles)) : $(BUILDDIR)/public/% : $(BUILDDIR)/results/%
@$(PRINTF) '%s\n' $(call quote,Building $*>…)
$(silent)$(call ensuredirectory,$(dir $@))
+ $(silent)$(RM) -f -R $(call quote,$@)
$(silent)$(call processresultto,$<,$@,$*)
$(call built,$(filter $(assetfiles),$(sourcefiles))) : $(BUILDDIR)/public/% : $$(call unbuilt,$$@)
@$(PRINTF) '%s\n' $(call quote,Building $*>…)
$(silent)$(call ensuredirectory,$(dir $@))
+ $(silent)$(RM) -f -R $(call quote,$@)
$(silent)$(CP) $(call quote,$<) $(call quote,$@)
# Install compiled files (or error in the case of recursive ones).
$(call installed,$(recursivefiles) $(installablefiles)) : $(DESTDIR)/% : $(BUILDDIR)/public/%
@$(PRINTF) '%s\n' $(call quote,Installing $*>…)
$(silent)$(call ensuredirectory,$(dir $@))
- $(silent)if $(TEST) -d $(call quote,$<); then $(RM) -f -R $(call quote,$@); $(CP) -R $(call quote,$<) $(call quote,$@); else $(CP) $(call quote,$<) $(call quote,$@); fi
+ $(silent)$(RM) -f -R $(call quote,$@)
+ $(silent)$(CP) -R $(call quote,$<) $(call quote,$@)
$(silent)for associated in $$($(call associatedfiles,$(dir $<),$(notdir $<))); do $(PRINTF) '%s\n' "$$associated" | $(SED) 's/^\(.*\)"{\(.*\)}"\(.*\)$$/\1\2\3/' | $(xargsquote) | $(XARGS) -E '' $(PRINTF) '%s%s\n' $(call quote,$(dir $@)) | $(xargsquote) | $(XARGS) -E '' $(CP) $(call quote,$(dir $<))"$$associated"; done
# ━ § BEGIN ARCHIVE MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -697,6 +705,7 @@ $(foreach file,$(archivefiles),$(BUILDDIR)/extracted/$(file)) : $(BUILDDIR)/inde
$(foreach file,$(archivefiles),$(BUILDDIR)/files/$(file)) : $(BUILDDIR)/files/% : $(BUILDDIR)/extracted/%
@$(PRINTF) '%s\n' $(call quote,Building $(NAME)/$*>…)
$(silent)$(call ensuredirectory,$(dir $@))
+ $(silent)$(RM) -f -R $(call quote,$@)
$(silent)$(call processresultto,$<,$@,$*)
# Archive all components in the file to the destination.
@@ -705,7 +714,8 @@ $(foreach file,$(archivefiles),$(BUILDDIR)/files/$(file)) : $(BUILDDIR)/files/%
$(DESTDIR)/% : $(SRC) $(foreach file,$(archivefiles),$(BUILDDIR)/files/$(file))
@$(PRINTF) '%s\n' $(call quote,Archiving $(NAME)>…)
$(silent)$(call ensuredirectory,$(dir $@))
- $(silent)cd $(call quote,$(BUILDDIR)/files); if $(call xpath,/*/@*[local-name()="expanded" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$(abspath $<)); then $(RM) -f -R $(call quote,$(abspath $@)); $(MKDIR) -p $(call quote,$(abspath $@)); $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -r -w $(call quote,$(abspath $@)); else $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -w -x ustar > $(call quote,$(abspath $@)); fi
+ $(silent)$(RM) -f -R $(call quote,$@)
+ $(silent)cd $(call quote,$(BUILDDIR)/files); if $(call xpath,/*/@*[local-name()="expanded" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$(abspath $<)); then $(MKDIR) -p $(call quote,$(abspath $@)); $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -r -w $(call quote,$(abspath $@)); else $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -w -x ustar > $(call quote,$(abspath $@)); fi
# ━ § BEGIN PAGED MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━