diff options
Diffstat (limited to 'doc/ref/general')
-rw-r--r-- | doc/ref/general/base64.texi | 22 | ||||
-rw-r--r-- | doc/ref/general/bst.texi | 37 | ||||
-rw-r--r-- | doc/ref/general/crypto.texi | 17 | ||||
-rw-r--r-- | doc/ref/general/datetime.texi | 670 | ||||
-rw-r--r-- | doc/ref/general/glob.texi | 37 | ||||
-rw-r--r-- | doc/ref/general/graphviz.texi | 10 | ||||
-rw-r--r-- | doc/ref/general/io.texi | 31 | ||||
-rw-r--r-- | doc/ref/general/srfi-41.texi | 100 | ||||
-rw-r--r-- | doc/ref/general/util-config.texi | 93 | ||||
-rw-r--r-- | doc/ref/general/util-exceptions.texi | 40 | ||||
-rw-r--r-- | doc/ref/general/util-path.texi | 62 | ||||
-rw-r--r-- | doc/ref/general/util.texi | 359 | ||||
-rw-r--r-- | doc/ref/general/uuid.texi | 17 | ||||
-rw-r--r-- | doc/ref/general/xdg-basedir.texi | 62 | ||||
-rw-r--r-- | doc/ref/general/zic.texi | 135 |
15 files changed, 1692 insertions, 0 deletions
diff --git a/doc/ref/general/base64.texi b/doc/ref/general/base64.texi new file mode 100644 index 00000000..ab6bba81 --- /dev/null +++ b/doc/ref/general/base64.texi @@ -0,0 +1,22 @@ +@node Base64 +@section Base64 + +@defun base64->bytevector bv +@defunx bytevector->base64 bv +Base procedure for all Base64 operations. +Takes and returns bytevectors. + +Throws @code{decoding-error} on invalid input. +@end defun + +@defun base64-string->bytevector string +@defunx bytevector->base64-string bv +Base64 side is strings, while data is bytevectors. +@end defun + + +@defun base64encode string [transcoder=(native-transcoder)] +@defunx base64decode string [transcoder=(native-transcoder)] +Highest level Base64 procedures. Both encoded and decoded data is +strings. +@end defun diff --git a/doc/ref/general/bst.texi b/doc/ref/general/bst.texi new file mode 100644 index 00000000..d2bba0ff --- /dev/null +++ b/doc/ref/general/bst.texi @@ -0,0 +1,37 @@ +@node Binary Search Tree +@section Binary Search Tree + +A simple ``read only'' binary search tree. + +@defun make-tree pred? lst +Constructs a new tree. @var{pred?} should be a procedure taking the +first element of @var{lst}, along with each element, and should return +a boolean value indicating if the specific element should go in the +left or right subtree. (left subtree is ``truthy'' values). + +This operation is done recursively. +@end defun + +@defun tree-node tree +Return the value of a tree node. +@end defun + +@defun left-subtree tree +Return all ``truthy'' children of tree node. +@end defun + +@defun right-subtree tree +Return all ``falsy children of tree node. +@end defun + +@defun length-of-longest-branch tree +Get the depth of a tree. +@end defun + +@defun tree-map proc tree +Apply proc onto the value of every node in tree, keeping the structure +of the tree. + +@b{Note:} this can cause the tree to no longer be a binary search +tree, but simply a ``formless'' binary tree. +@end defun diff --git a/doc/ref/general/crypto.texi b/doc/ref/general/crypto.texi new file mode 100644 index 00000000..b9e362d3 --- /dev/null +++ b/doc/ref/general/crypto.texi @@ -0,0 +1,17 @@ +@node Cryptographic and Hash Procedures +@section Cryptographic and Hash Procedures + +This module links libcrypto, exposing some hash procedures. + +@defun sha256 message +Calculate the sha256-sum of @var{message}. The message can either be a +bytevector or a string (in which case it will de encoded as UTF-8). + +Returns the checksum as a bytevector. +@end defun + +@defun checksum->string message-digest [port] +Generates a hex digest string from a checksum (generated by +@code{sha256}). The checksum is written to @var{port} if given, or +returned as a string otherwise. +@end defun diff --git a/doc/ref/general/datetime.texi b/doc/ref/general/datetime.texi new file mode 100644 index 00000000..037ac8d5 --- /dev/null +++ b/doc/ref/general/datetime.texi @@ -0,0 +1,670 @@ +@node Datetime +@section Datetime + +My datetime library, with focus on date manipulation in ways sensible +for humans. So that a date-time plus one day always keep the time of +day. +For example, 26 mars 2022 10:00 plus 1 day would give 27 mars 2022 +10:00, even though 25 hours have passed due to summer time starting +(in Sweden). + +Note that while some of these procedures mentions timezones, almost +nothing is actually done with it. + +@subsection Constants + +@defvar jan +@defvarx january +@defvarx feb +@defvarx february +@defvarx mar +@defvarx mars +@defvarx apr +@defvarx april +@defvarx may +@defvarx jun +@defvarx june +@defvarx jul +@defvarx july +@defvarx aug +@defvarx august +@defvarx sep +@defvarx september +@defvarx oct +@defvarx october +@defvarx nov +@defvarx november +@defvarx dec +@defvarx december +Numeric constants for all months. +@code{@var{jan} = 1}, @code{@var{dec} = 12}. +@end defvar + +@defvar sun +@defvarx sunday +@defvarx mon +@defvarx monday +@defvarx tue +@defvarx tuesday +@defvarx wed +@defvarx wednesday +@defvarx thu +@defvarx thursday +@defvarx fri +@defvarx friday +@defvarx sat +@defvarx saturday +@anchor{sunday} +Numeric constants for all weekdays. +@code{@var{sunday} = 0}, @code{@var{saturday} = 6}. +@end defvar + +@subsection Parameters and Configuration + +@deftp {parameter} week-start +@anchor{week-start} +Which weekday should be considered the first. Used for calculating +week numbers, the start dates of week, and is available for UI-code +and the like which wants it. +@end deftp + +@deftp {config} week-start +Configuration item, updates @xref{week-start}. +@end deftp + + +@subsection Datatypes + +@deftp {Immutable Record} <date> year month day +Object representing a date, without any timezone information. +Given the date 2040-03-23 (in ISO-8601 format), @var{year} = 2020, +@var{month} = 3 and @var{day} = 23. + +Values higher than those usually used are possible, but not recommended. + +@defun date? x +Is @var{x} a date object? +@end defun + +@defun date [#:year=0] [#:month=0] [#:day=0] +Create a new date object. +@end defun + +@defun year <date> +@defunx month <date> +@defunx day <date> +Fetch corresponding field from the date object. +@end defun +@end deftp + +@deftp {Immutable Record} <time> hour minute second +Object representing a timestamp in a given day, +without any timezone information. +Given the time 10:20:30, @var{hour} = 10, +@var{minute} = 20 and @var{second} = 30. + +Values larger than the ``regular'' are allowed, and useful since this +type is also used for time offsets. + +@defun time? x +Is @var{x} a time object? +@end defun + +@defun time [#:hour=0] [#:minute=0] [#:second=0] +Create a new time object. +@end defun + +@defun hour <time> +@defunx minute <time> +@defunx second <time> +Fetch corresponding field from the time object. +@end defun +@end deftp + + +@deftp {Immutable Record} <datetime> date time tz + +A collation of date and time, along with an optional timezone. +Set @code{tz = #f} if a timezone is not desired. + +@defun datetime? x +Is @var{x} a datetime object? +@end defun + +@defun datetime [#:date] [#:time] [#:tz] [#:year=0] [#:month=0] [#:day=0] [#:hour=0] [#:minute=0] [#:second=0] +Creates a new <datetime>. If @var{date} or @var{time} is given, those +are used. Otherwise, a date object is created from @var{year}, +@var{month} and @var{day}, and time is respectively created from +@var{hour}, @var{minute} and @var{second}. +@end defun + +@defun get-date +@defunx get-timezone +Note that @code{get-time} doesn't exists. +@end defun +@end deftp + + +@subsection Reader Extensions + +This module registers reader extensions on @code{#0}, @code{#1}, and +@code{#2}. These read either dates, times, or datetimes; using @code{string->date/-time}. + +@c @subsection CTIME + +@c These procedures are for interfacing with C's time procedures, see CTIME(3). + +@c The datetime<->tm procedures are internal, since they are slightly +@c unstable (see comments in code). +@c They are thereby not documented. +@c @defun datetime->tm datetime +@c Convert a @code{<datetime>} object to a @code{struct tm}, encoded in a +@c scheme vector. +@c @end defun +@c +@c @defun tm->datetime tm +@c Converts a @code{struct tm}, as returned from @code{datetime->tm} back +@c into a @code{<datetime>} object. +@c @end defun + +@subsection Procedures + +@defun datetime->unix-time datetime +Converts @var{datetime} to an integer representing its unix time. +@end defun + +@defun unix-time->datetime n +Converts a given unix timestamp to a datetime object. +Currently forces the timezone to be UTC. +@end defun + +@defun current-datetime +Return a datetime object of the current date and time. +Currently always returns it in UTC. +@end defun + +@defun current-date +Get the date component from a call to @code{current-datetime}. +@end defun + + +@defun get-datetime datetime +Takes a datetime in any timezone, and renormalize it to local time (as +defined by the environment variable TZ). This means that given UTC +10:00 new years day would return 11:00 new years day if ran in sweden. +@end defun + + +@defun as-date date/-time +@defunx as-time date/-time +Both procedures takes a <date>, <time>, or <datetime>, and return +respectively a <date> or <time> object. + +@code{as-date}, when given a time will return a zeroed date object. +Vice versa for @code{as-time}. +@end defun + +@defun as-datetime date/-time +Takes a <date>, <time>, or <datetime>, and returns a <datetime> object +with the same data, with the (possibly) missing date or time set to +all zeroes. +@end defun + + +@defun date-zero? date +@defunx time-zero? time +Checks if all components are zero. +@end defun + + +@defun leap-year? year +Given an integer @var{year}, return @code{#t} if it's a leap year, and +@code{#f} otherwise. +@end defun + +@defun days-in-month date +Returns how many days are in the month specified by the <date> @var{date}. +Note that the day component is ignored. +@end defun + +@defun days-in-year date +Returns how many days are in the year pointed to by @var{date}. +@end defun + +@defun start-of-month date +Returns a <date> object equal to date, but with the day component set +to 1. +@end defun + +@defun end-of-month date +Returns a <date> object equal to date, but with the day component set +to the last day of the month. + +@example +(end-of-month #2020-01-10) +⇒ #2020-01-31 +(end-of-month #2020-02-01) +⇒ #2020-02-29 +@end example +@end defun + + +@defun start-of-year date +Returns a <date> object equal to date, but with the day and month +component set to 1. +@end defun + +@defun date-stream date-increment start-day +Returns an @ref{(guile)SRFI-43} stream of <date> objects, starting at +@var{start-day} and stepping in increments of @var{date-increment}. +@end defun + +@defun day-stream start-day +Returns a stream of each day from @var{start-day}. +@end defun + +@defun month-stream start-day +Returns a stream of each months from @var{start-day}. +Day component stays the same. +@end defun + +@defun week-stream start-day +Returns a stream of each week from @var{start-day} +(increments of 7 days). +@end defun + +@defun time-min a b +@defunx time-max a b +@defunx date-min a b +@defunx date-max a b +@defunx datetime-min a b +@defunx datetime-max a b +Returns the smaller (or larger) of @var{a} or @var{b}. +@end defun + +@defun week-day date +Returns an integer representing the week day of @var{date}. +@ref{sunday} +@end defun + + +@defun week-1-start date [week-start=(week-start)] +Returns the date which week 1 starts on, according to the (at least) +Swedish rule of week counting. +@ref{week-start} +@end defun + + +@defun week-number date [week-start=(week-start)] +Returns the week number of @var{date}, according to the (at least) +Swedish rule of week counting. +@ref{week-start} +@end defun + +@defun date-starting-week week-number date [week-start=(week-start)] +Returns the first day of week @var{week-number}, @var{date} is used +for year information. +@ref{week-start} +@end defun + + +@defun week-day-name week-day [truncate-to] [#:key locale] +Returns the locale dependent name for the given week day. + +@var{week-day} is a number per @ref{sunday}. +@var{truncate-to} may be a number, which limits to the first @var{n} +letters of the resulting string. +@end defun + + +@defun timespan-overlaps? s1-begin s1-end s2-begin s2-end +Check if the interval @var{s1-begin} to @var{s1-end} overlaps with the +interval @var{s2-begin} to @var{s2-end}. +@end defun + +@defun find-first-week-day week-day date +Returns the first instance of the given week-day after @var{date}. + +@example +(find-first-week-day mon #2020-04-01) +⇒ #2020-04-06 +(find-first-week-day mon #2020-04-10) +⇒ #2020-04-13 +(find-first-week-day mon #2020-04-30) +⇒ #2020-05-04 +@end example +@end defun + +@defun all-wday-in-month week-day month-date +Returns instances of the given week-day in month between +month-date and end of month. +@example +(all-wday-in-month mon #2020-06-01) +⇒ (#2020-06-01 #2020-06-08 #2020-06-15 #2020-06-22 #2020-06-29) +(all-wday-in-month mon #2020-06-10) +⇒ (#2020-06-15 #2020-06-22 #2020-06-29) +@end example +@end defun + +@defun all-wday-in-year week-day year-date +Returns a list of all instances of @var{week-day} in @var{year-date}. +@end defun + +@defun in-date-range? start-date end-date → date → boolean +Returns a predicate procedure, which checks if a given date is between +@var{start-date} and @var{end-date}. +@end defun + +@defun weekday-list [week-start=(week-start)] +Returns a list of the seven week days, with @var{week-start} +as the beginning of the week. +@end defun + + +@defun start-of-week d [week-start=(week-start)] +@defunx end-of-week d [week-start=(week-start)] +Returns the date the week containing @var{d} started or ended. +@end defun + + +@defun month-days date [week-start=(week-start)] +Given a month and and which day the week starts on, +returns three lists, which are: +The days leading up to the current month, but share a week +The days in the current month +The days after the current month, but which shares a week. + +@example + mars 2020 +må ti on to fr lö sö + 1 + 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 +16 17 18 19 20 21 22 +23 24 25 26 27 28 29 +30 31 +@end example +@lisp +(month-days #2020-03-01 mon) +; ⇒ (2020-02-24 ... 2020-02-29) +; ⇒ (2020-03-01 ... 2020-03-31) +; ⇒ (2020-04-01 ... 2020-04-05) +@end lisp +Ignores day component of @var{date}. +@end defun + + +@defun days-in-interval start-date end-date +The amount of days in the given interval, including both endpoints. +@end defun + + +@defun year-day date +Day from start of the year, so 1 feb would be day 32. +Also known as Julian day. +@end defun + + +@defun time->decimal-hour time +Convert @var{time} to a decimal value, so 10:30 would become 10.5. +@end defun + +@defun datetime->decimal-hour dt [start-date] +Similar to @code{time->decimal-hour}, but also looks at the date component. + +@var{start-date} is required if either the month of year component of +@var{dt} is non-zero (since months and years have a variable number of hours). +@end defun + +@defun date-range start end [increment=(date day: 1)] +Returns a list of all dates from start to end. +Both inclusive +@end defun + +@defun locale-month +@defunx locale-month-short +These are direct re-exports from (ice-9 i18n) + +@xref{Accessing Locale Information,,,guile}. +@end defun + +@defun date= args ... +@defunx date=? args ... +@defunx date< args ... +@defunx date<? args ... +@defunx date> args ... +@defunx date>? args ... +@defunx date<= args ... +@defunx date<=? args ... +@defunx date>= args ... +@defunx date>=? args ... +Checks if all date arguments satisfy the predicate. +@end defun + +@defun time= args ... +@defunx time=? args ... +@defunx time< a b +@defunx time<? a b +@defunx time> a b +@defunx time>? a b +@defunx time<= a b +@defunx time<=? a b +@defunx time>= a b +@defunx time>=? a b +Checks if all time arguments satisfy the predicate. +@end defun + +@defun datetime= args ... +@defunx datetime=? args ... +@defunx datetime< a b +@defunx datetime<? a b +@defunx datetime> a b +@defunx datetime>? a b +@defunx datetime<= a b +@defunx datetime<=? a b +@defunx datetime>= a b +@defunx datetime>=? a b +Check if all datetime arguments satisfy the predicate. +The timezone field is ignored. +@end defun + +@defun date/-time< a b +@defunx date/-time<? a b +@defunx date/-time> a b +@defunx date/-time>? a b +@defunx date/-time<= a b +@defunx date/-time<=? a b +@defunx date/-time>= a b +@defunx date/-time>=? a b +Equivalent to the @code{datetime*} versions, but wraps its arguments +in @code{as-datetime}. +@end defun + +@subsection Arithmetic + +While only one date (and one time) type is available, it really should +be seen as two. Absolute dates, such as the fourth of november, +2022. The other type are intervals, such as 3 years, 4 months and 2 days. + +A ``type mismatch'' might therefore lead to some confounding results. +@example +(date- #2020-01-01 #2020-01-01) +⇒ #00-1-11-31 +(date-difference #2020-01-01 #2020-01-01) +⇒ #0000-00-00 +@end example + +@defun date+ base rest ... +@defunx date- base rest ... +Add or remove each difference from base. +@end defun + +@defun date-difference end start +Returns difference between the two dates, in years, months, and days. +In such a way that + +@lisp +(date= (date+ start (date-difference end start))) +@end lisp +@end defun + +@defun time+ base rest ... +@defunx time- base rest ... +Adds (or subtracts) each difference from the base, and returns two +values. The sum, and how many midnight's have passed. + +@lisp +(time+ #22:00:00 (time hour: 4)) +⇒ #02:00:00 +⇒ 1 +@end lisp +@end defun + +@defun datetime+ base change +@defunx datetime- base change +@end defun + +@defun datetime-difference end start +@end defun + +@subsection Parsing and Formatting + +@defun datetime->string datetime [fmt=''~Y-~m-~dT~H:~M:~S''] [#:allow-unknown?] + +Formats @var{datetime} into a string. +The function will throw an error when encountering an unknown format +specifier, unless @var{#:allow-unknown} is true. + +@table @samp +@item ~~ +A literal tilde (~). +@item ~H +Hour, left padded with zeroes to length 2. +@item ~k +Like @samp{~H}, but padded with spaces. +@item ~M +Minute, left padded with zeroes to length 2. +@item ~S +Seconds, left padded with zeroes to length 2. +@item ~Y +Year, left padded with zeroes to length 4; +@item ~m +Month number, left padded with zeroes to length 2. +@item ~d +Day in month, left padded with zeroes to length 2. +@item ~s +Epoch time, per UNIX. +@item ~e +Same as @samp{~d}, but padded with spaces. +@item ~1 +Shorthand for @samp{~Y-~m-~d}. +@item ~3 +Shorthand for @samp{~H:~M:~S}. +@item ~A +Locale week day name. +@item ~a +Locale week day name, truncated to 3 characters. +@item ~b +Locale month name, truncated. +@item ~B +Locale month name, in full. +@item ~Z +@samp{Z} if the timezone is @samp{UTC}. Nothing otherwise. +@end table +@end defun + +@defun date->string date [fmt=''~Y-~m-~d''] [#:allow-unknown?] +@defunx time->string date [fmt=''~H:~M:~S''] [#:allow-unknown?] +Simple wrappers around @code{datetime->string}, which works directly +on date or time objects. +@end defun + + +@defun string->datetime str [fmt=''~Y-~m-~dT~H:~M:~S~Z''] [locale=%global-locale] +Attempts to parse @var{str} as a datetime, according to the ruleset @var{fmt}. +An invalid or unparsable string will throw an error. + +Each token in @var{fmt} informs the parser what the next expected +token in @var{str} is. If a binding rule is parsed multiple times, +then the last one is used for the resulting object. For example, +@example +(string->datetime "10:20" "~H:~H") +⇒ (datetime hour: 20) +@end example + +spaces are literal, there is no way to match an arbitrary number of +whitespace characters + +@table @samp +@item ~~ +Next token is a literal tilde. + +@item ~Z +If next token is a literal @samp{Z} then the resulting timezone is set +to @samp{UTC}, otherwise does nothing. + +@item ~p +The next token is an AM/PM indicator, matched by the regex +@code{^([AaPp])[.]?[Mm][.]?}. A valid token will reinterpret the last +hour indicator as 12-hour time (instead of 24 hour time), regardless +if its before or after this token. + +@item ~b +@itemx ~B +@itemx ~h +Parses a month by name, just as @code{parse-month}. + +@item ~H +@itemx ~M +@itemx ~S +@itemx ~m +@itemx ~d +Parses up to two digits, but possibly less if a non-digit appears in +the string. Then stores the resulting value in either the hour, +minute, second, month, or day slot of the resulting object. + +This double function allows both dates without delimiters, such as +``0102'' to be correctly parsed, but also more free form formats, such +as ``1 jan''. + +@item ~Y +Equivalent to @samp{~H}, but reads up to 4 digits, and stores the +result in the year field. +@end table +@end defun + + +@defun parse-month str [locale=%global-locale] +Returns the first month whose name has @var{str} as its prefix. +The result will be on the interval [1, 12], or -1 if no month matched. +@end defun + + +@defun string->time str [fmt=''~H:~M:~S''] [locale=%global-locale] +@defunx string->date str [fmt=''~Y-~m-~d''] [locale=%global-locale] +Wrappers around @code{string->datetime}, but only returning the time +or date component. +@end defun + + +@defun string->date/-time string +Parses string as an ISO-8601 string. Checks for the existence of +@code{T}, @code{:}, or @code{-} to determine if it's a datetime, time +or date. +@end defun + +@defun parse-ics-date str +@defunx parse-ics-time str +@defunx parse-ics-datetime str [zone] +Parses dates per RFC5545. +@end defun + +@defun parse-iso-date str +@defunx parse-iso-time str +@defunx parse-iso-datetime str +Parses (the well known subset) of ISO-compatible dates. +@end defun + +@defun parse-freeform-date str +Currently an alias for parse-iso-datetime, but should preferably be extended. +@end defun diff --git a/doc/ref/general/glob.texi b/doc/ref/general/glob.texi new file mode 100644 index 00000000..400eb1f7 --- /dev/null +++ b/doc/ref/general/glob.texi @@ -0,0 +1,37 @@ +@node Glob +@section Glob + +@defun glob str +Globs (glob(7)) on @var{str}, returing a list of files, which will be +on the same form of the glob. E.g. @code{(glob "../*")} will return +strings all starting with ``../'' + +If no matches are found, a misc error is thrown. +@end defun + + + +@defvar GLOB_NOMAGIC +@defvarx GLOB_NOCHECK +@defvarx unix +@defvarx GLOB_NOSPACE +@defvarx GLOB_TILDE_CHECK +@defvarx GLOB_ALTDIRFUNC +@defvarx GLOB_NOSORT +@defvarx GLOB_NOMATCH +@defvarx GLOB_TILDE +@defvarx GLOB_ERR +@defvarx GLOB_MAGCHAR +@defvarx GLOB_BRACE +@defvarx GLOB_APPEND +@defvarx GLOB_NOSYS +@defvarx GLOB_DOOFFS +@defvarx GLOB_NOESCAPE +@defvarx GLOB_MARK +@defvarx GLOB_PERIOD +@defvarx linux +@defvarx GLOB_ABORTED +@defvarx _POSIX_VDISABLE +@defvarx GLOB_ONLYDIR +``Symbols'' imported from the C header ``glob.h''. See that documentation. +@end defvar diff --git a/doc/ref/general/graphviz.texi b/doc/ref/general/graphviz.texi new file mode 100644 index 00000000..72817ea8 --- /dev/null +++ b/doc/ref/general/graphviz.texi @@ -0,0 +1,10 @@ +@node Graphviz +@section Graphviz + +The graphviz library comes bundled with Guile bindings, but without a +corresponding .scm file exporting the symbols. The module @code{(guile)} does +exactly that. + +This ``header'' is borrowed from +@url{https://github.com/roelj/graphviz-guile/blob/master/graphviz.scm}, +under GPL 3.0. diff --git a/doc/ref/general/io.texi b/doc/ref/general/io.texi new file mode 100644 index 00000000..8c83ddcf --- /dev/null +++ b/doc/ref/general/io.texi @@ -0,0 +1,31 @@ +@node IO operations +@section IO + +Provided by module @code{(hnh util io)}. + +@defun open-input-port path +@defunx open-output-port path +Like @code{open-*-file}, but ``-'' gives @code{standard-@{input,output@}}. +@end defun + +@defun read-lines port +Return a list of all lines read from port. +@end defun + +@defun with-atomic-output-to-file filename thunk +Same functionality as the regular @var{with-output-to-file}, but +with the difference that either everything is written, or nothing +is written, and if anything is written it's all written atomicaly at +once (the original file will never contain an intermidiate state). +Does NOT handle race conditions between threads. + +propagates the return value of @var{thunk} upon successfully writing +the file, and @code{#f} otherwise. +@end defun + +@defun call-with-tmpfile proc [#:tmpl ``/tmp/file-XXXXXXX''] +@end defun + +@defun read-file path +Open file at path, and return its content as a string. +@end defun diff --git a/doc/ref/general/srfi-41.texi b/doc/ref/general/srfi-41.texi new file mode 100644 index 00000000..d8020ecc --- /dev/null +++ b/doc/ref/general/srfi-41.texi @@ -0,0 +1,100 @@ +@node SRFI 41 Utilities +@section SRFI 41 Utilities + +Extra utilities for handling streams. Provided by @code{(srfi srfi-41 +util)}. + +@defun stream-car+cdr stream +Returns the car and cdr of stream. +@end defun + +@defun interleave-streams < streams +Merges a number of totally ordered streams into a single +totally ordered stream. + +((≺, stream)) → (≺, stream) +@end defun + +@defun stream-insert < item stream +Insert item in the totally ordered stream (≺, stream). +@end defun + + +@defun filter-sorted-stream pred stream +@end defun + + +@defun filter-sorted-stream* pred keep-remaining? stream +@end defun + +@defun get-stream-interval start-pred end-pred stream +Get the substream from stream from the first match of start-pred, to +the first match of end-pred after start-pred. +@end defun + + +@defun stream-find pred stream +Find the first element in stream satisfying the predicate, or #f none +was found. +@end defun + + +@defun stream-remove pred stream +Stream-filter, but with predicate negated. +@end defun + + +@defun stream->values stream +Equivalent to list->values. Returns as many objects as the stream is long. +@end defun + + +@defun repeating-naturals from repeats +Natural numbers from @var{from} and up, but each repeated @var{repeat} +times. +@example +(stream->list 15 (repeating-naturals 1 3)) +⇒ (1 1 1 2 2 2 3 3 3 4 4 4 5 5 5) +@end example +@end defun + + +@defun stream-partition pred stream +@end defun + +@defun stream-split idx stream +@end defun + +@defun stream-paginate stream [page-size=10] +@end defun + + +@defun eager-stream-cons a b +stream cons, but eval arguments beforehand. +@end defun + +@defun stream-split-by pred strm +Chunks the content of @var{strm} into lists, breaking on @var{pred}. +If the end of the stream is reached, the remaining objects +are put into a final chunk. + +Can for example be used to split a stream of characters into a stream +of words. + +@lisp +(stream-split-by (lambda (c) (char=? c #\space)) + (-> "This is a short test" + string->list list->stream)) +⇒ #<stream (#\T #\h #\i #\s #\space) + (#\i #\s #\space) + (#\a #\space) + (#\s #\h #\o #\r #\t #\space) + (#\t #\e #\s #\t)> +@end lisp +@end defun + +@defun stream-timeslice-limit stream timeslice +Wrap a stream in time limits. Each element has at most @var{timeslice} +seconds to produce a value, otherwise the stream ends. Useful for finding the +``final'' element matching a predicate in an infinite stream. +@end defun diff --git a/doc/ref/general/util-config.texi b/doc/ref/general/util-config.texi new file mode 100644 index 00000000..2e197bcc --- /dev/null +++ b/doc/ref/general/util-config.texi @@ -0,0 +1,93 @@ +@node Configuration + +@section Configuration + +Provided by the module @code{(calp util config)}. + +Configuration items are similar to regular defines, but global to the +entire program, and assignable before they are declared. +Their primary purpose is to allow a user supplied @file{config.scm}, +without needing all appropriate modules already loaded. + +@defmac define-config name default kw-parameters ... +Declares a new configuration variable named @var{named}, with the +default value @var{default}. @var{kw-parameters} are given on Guile's +standard @code{hash: value} form. @pxref{get-property} for available parameters. +@end defmac + +@defun get-property config-name property-key +@anchor{get-property} +Returns a metadata-slot value for the given configuration setting. + +Each declared configuration item has (at least) the following metadata +slots: + +@table @samp +@item description +Short human-readable description of this configuration item. + +@item source-module +Module in which this item was declared. Automatically filled in by @code{define-config}. + +@item pre +Procedure which can pre-process or validate set values. Think about it +as if @code{(set-config! key value)} expands to +@code{(true-set-config! key (pre value))}, +with the bonus that if @code{pre value} returns @code{#f} then the +assignment fail. + +@item post +Procedure to run after the value is set. For example for updating a +local parameter. +@example +(define-public week-start (make-parameter sun)) +(define-config week-start sun + description: "First day of week" + pre: (ensure (lambda (x) (<= sun x sat))) + post: week-start) +@end example +@end table + +@findex set-property! +Note that @code{set-property!} doesn't exist, since properties are read-only. +@end defun + +@defun set-config! name value +Sets the @var{value} of the configuration variable @var{name}. +@end defun + +@defun get-config key [default] +Retrieve the configured value for @var{key}. Throws an error if key +isn't set, and @var{default} isn't given (to differentiate it from +@code{#f} being set. +@end defun + +@defun {(ensure predicate)} value +Helper procedure for @code{pre} hooks. Curried function which checks +if @var{value} satisfies @var{predicate}, and if so returns @var{value}. + +@example +(define-public ((ensure predicate) value) + (if (predicate value) + value #f)) +@end example +@end defun + +@defun get-configuration-documentation +Collects all variables we know about (both defined and non-defined +(but set)), and builds a markup-tree with information about them. +@c TODO document markup format, link it here +@end defun + +@defun format-procedure procedure +Procedure mainly used by @code{get-configuration-documentation}. Gives +a simple string representation of the given procedure. + +@example +(format-procedure format-procedure) +⇒ "format-procedure(proc)" + +(format-procedure (lambda* (key: (a 1)) (+ a 3))) +⇒ "λkey: a" +@end example +@end defun diff --git a/doc/ref/general/util-exceptions.texi b/doc/ref/general/util-exceptions.texi new file mode 100644 index 00000000..34ba33f9 --- /dev/null +++ b/doc/ref/general/util-exceptions.texi @@ -0,0 +1,40 @@ +@node Exception & Warning Utilities +@section Exception & Warning Utilities +@anchor{warning} + +Warnings are like exceptions, but only fatal when wanted. + +@code{(hnh util exceptions)} + +@defun warning fmt args ... +Emit a warning. + +If the parameter @var{warnings-are-errors} is true, then an exception +of type @code{'warning} will be raised, with @var{fmt} and @var{args} +as arguments. + +If that parameter is false, then the procedure in +@var{warning-handler} will instead be called. +@end defun + +@deftp {parameter} warning-handler +Parameter containing proceudre which will be called for non-throwing +warnings. This procedure is assumed by the program to log the warning +in some way, and continue program flow. But anything goes. + +The procedure is given a format specifier (as per Scheme's basic +@code{format}), along with the correct number of arguments. +@end deftp + +@deftp {parameter} warnings-are-errors +Boolean parameter, which if set causes warnings to be thrown as exceptions. +@end deftp + +@defun fatal fmt args ... +Display the message in fmt, populated with args, then raises the UNIX +signal SIGINT, which kills the program. +@end defun + +@defun filter-stack pred? stack +@c TODO document me +@end defun diff --git a/doc/ref/general/util-path.texi b/doc/ref/general/util-path.texi new file mode 100644 index 00000000..384915ef --- /dev/null +++ b/doc/ref/general/util-path.texi @@ -0,0 +1,62 @@ +@node Path Utilities +@section Path Utilities + +Provided by the module @code{(hnh util path)}. + + +@defun path-absolute? string +Alias of @code{absolute-file-name?} from Guile. +@end defun + +@defun path-append path paths ... +Joins all strings into a path, squeezing duplicated delimiters, but +ensuring that all delimiters that are needed are there. + +Note that delimiters embedded inside the string, which aren't first or +last in a substring (or are the only thing in a string) are +kept. Meaning that +@example +(path-append "/" "hello") ⇒ "/hello" +(path-append "/usr/local/bin" "cmd") ⇒ "/usr/local/bin/cmd" +@end example +@end defun + + +@defun path-join lst +@lisp +(apply path-append lst) +@end lisp +@end defun + + +@defun path-split path +Splits path into a list of components. +The first component will be @code{""} if path is absolute. +@end defun + + +@defun filename-extension filename +Returns the extension of the filename, or the empty string if none exists. +@end defun + +@defun realpath path +Equivalent of realpath(3). Absolute file names are returned as is, +while relative filenames gets expanded to absolute filenames. +@end defun + +@defun relative-to base path +Returns @var{path} as a relative path relative to @var{base}. + +base must be non-empty +@example +(relative-to "/some" "/some/path") +;; ⇒ "path" + +(relative-to "/some" "/other/path/") +;; ⇒ "../path" + +(relative-to "/a/b/c" "/a/b") +;; ⇒ "/a/b" +@end example + +@end defun diff --git a/doc/ref/general/util.texi b/doc/ref/general/util.texi new file mode 100644 index 00000000..bae19987 --- /dev/null +++ b/doc/ref/general/util.texi @@ -0,0 +1,359 @@ +@node Miscellaneous utilities +@section Miscellaneous utilities + +Provided by the module @code{(hnh util)}. + +@defmac define-syntax [stx] +Extends the default syntax from the default +@lisp +(define-syntax @r{<name>} (λ (stx) body ...)) +@end lisp +To also allow +@lisp +(define-syntax (@r{<name>} stx) body ...) +@end lisp +@end defmac + + +@defmac when pred body ... +@defmacx unless pred body ... +Extends @var{when} and @var{unless} to return @code{'()} on the +false-case (instead of being undefined). +@end defmac + + +@defmac aif condition consequent alternate +@defmacx awhen condition consequent ... +Equivalent to the standard @var{if} and @var{when}@footnote{Actually +our extra specialized @var{when}}, but binds the return of +@var{condition} in the variable @var{it}. +@end defmac + + +@defmac for key in collection body ... +@defmacx for (key ...) in collection body ... +Syntactic sugar over @code{map}. +@example +(for x in collection + body ...) +@end example +expands into +@example +(map (lambda (x) body ...) collection) +@end example + +If keys are a list, an match-lambda is used instead. +@xref{Pattern Matching,,,guile} + +@defun break args ... +Abandon the entire loop. Returing what was given to @code{break}. +@end defun + +@defun continue [arg] +Abandon the current iteration of the loop. If an argument is given, +it's used as the result in the resulting list, otherwise @code{#f} is +used. +@end defun + +@end defmac + + +@defmac print-and-return expr +Prints @var{expr}, and then returns it. +Only evaluates @var{expr} once. +@end defmac + + +@defun swap f +@math{swap (λ (x y) body ...) ⇔ λ (y x) body ...} +@end defun + +@defmac set! key value ... +@defmacx set! key = proc ... +@defmacx set! key = (op args ...) ... +Extends @var{set!} to allow multiple forms in one, also introduces the +cases: +@lisp +(set! x = f) ⇔ (set! x (f x)) +(set! x = (+ 1) ⇔ (set! x (+ x 1)) +@end lisp +@end defmac + +@defmac set/r! key value ... +See @var{set!}, but also returns the final value. +@end defmac + +@defmac label name proc +Equivalent to +@lisp +(letrec ((name proc)) + proc) +@end lisp +@end defmac + + +@defun sort* items comperator [get=identity] +@defunx sort*! items comperator [get=identity] +A sort more similar to Python's. Applies @var{get} to each item before +calling @var{comperator} on them. + +@var{sort*!} may modify the input list. +@end defun + + +@defun find-extreme items [<=<] [access=identity] +Returns 2 values, the most extreme value, as compared by @var{<} after +calling @var{access} on each element, along with the remaining values +in an undefined order. + +Should be faster than @var{car+cdr} ∘ @var{sort*}. +@end defun + +@defun find-min list [access=identity] +@defunx find-max list [access=identity] +See @var{find-extreme} +@end defun + +@defun filter-sorted proc list +@c TODO document me +@end defun + +@defun != args ... +@lisp +(define != (negate =)) +@end lisp +@end defun + +@defun take-to lst n +Equivalent to @var{take}, but return everything (instead of crash) if +n > (length lst). +@end defun + +@defun string-take-to str n +Same as @var{take-to}, but for strings +@end defun + + +@defun string-first +@defunx string-last +Returns the first and last character of a string respectivly +@end defun + + +@defun as-symb s +Returns @code{(string->symbol s)} if @var{s} is a string, @var{s} otherwise. +@end defun + +@defun enumerate lst +Returns a list of lists, where the @var{car} is the index in the list, +and the @var{cadr} is the corresponding element of the original list +@end defun + + +@defun unval proc [n=0] +Takes a procedure returning multiple values, and returns a function +which takes the same arguments as the original procedure, but only +returns one of the procedures. Which procedure can be sent as an +additional parameter. +@end defun + + +@defun flatten lst +Takes an arbitrarily nested list, and flattens it to a depth 1 list +@end defun + + +@defmac let-lazy forms body ... +Syntactically equivalent to a regular @var{let}, but wraps each variable +in @var{forms} in @var{delay}, while it finds each instance of that +variable in body and wraps in in @var{force}. +@end defmac + + +@defun map/dotted proc dotted-list +Like @var{map}, but also works for improper lists. +@end defun + + +@defun assq-merge a b +@c TODO +@end defun + +@defun kvlist->assq +Given a flat list where each odd element (counting from 1) is a +keyword, and each even element is any value, return these as a list of +pairs of symbols and values. + +@lisp +(kvlist->assq '(#:a 1 #:b "Hello")) +⇒ ((a . 1) + (b . "Hello")) +@end lisp +@end defun + +@defun assq-limit alist [number=1] +@c TODO document +@end defun + +@defun group-by proc lst +Calls @var{proc} on each element in @var{lst}, and return a +association list which @code{(proc e)} as its keys, and all elements +which mapped to that value. + +The values returned by @var{proc} are compared as per @code{equal?}. +@end defun + +@defun split-by lst element +Split a list into sub-lists on @var{element} +@lisp +(split-by '(0 1 2 3 4 2 5 6) 2) +⇒ ((0 1) (3 4) (5 6)) +@end lisp +@end defun + + +@defun span-upto count predicate list +Simar to span from srfi-1, but never takes more than +@var{count} items. Can however still take less. +@example +(span-upto 2 char-numeric? (string->list "123456")) +⇒ (#\1 #\2) +⇒ (#\3 #\4 #\5 #\6) +(span-upto 2 char-numeric? (string->list "H123456")) +⇒ () +⇒ (#\H #\1 #\2 #\3 #\4 #\5 #\6) +@end example +@end defun + + +@defun cross-product args ... +Returns the cross product between all given lists. Each pair will be a +list, whose indices matches the order of the inputs +@end defun + +@defun string-flatten tree +@c TODO document me +@end defun + +@defun intersperse item list +Inserts @var{item} between each element in @var{list}. +@end defun + + +@defun insert-ordered item collection [<=<] +Inserts @var{item} into @var{collection}, such that collection +remainins sorted if it was sorted beforehand. +@end defun + + +@defmac -> item forms ... +@defmacx ->> item forms ... +Applies each form onto item, from left to right. +A form can either by a symbol, which is the applied directly, or a +list, in which case @var{->} inserts item as the second argument +(after the operand), and @var{->>} inserts it last. +@end defmac + + +@defmac set (accessor object) value +@defmacx set (accessor object) = (operation args ...) +See @xref{SRFI-9 Records,,,guile} +@end defmac + +@defmac set-> object (accessor value) rest ... +@defmacx set-> object (accessor = (operator args)) rest ... +Wrapper around @var{set}, but applies transformations from left to +right, similar to @var{->}. +@end defmac + + +@defmac and=>> value procedures ... +Chained application of @code{and=>}, so applies each procedure from +left to right, stopping when one return @code{#f}. +@end defmac + +@defun downcase-symbol +Converts a symbol to lower case. +@end defun + + +@defun group list chunk-size +Splits @var{list} into sub-lists of size @var{chunk-size}. +Requires that @math{chunk-size|(length list)} +@end defun + + +@defun iterate proc until base +Repeatedly applies @var{proc} to @var{base}, until @var{until} is +satisfied. +@end defun + +@defun valued-map proc lists ... +Applies a procedure which returns multiple values to each element of a +list, and returns all values returned from all procedure calls. +@example +(define (± x) (values x (- x))) +(valued-map ± '(1 2)) +⇒ 1 +⇒ -1 +⇒ 2 +⇒ -2 +@end example +@end defun + + +@defun assoc-ref-all alist key +@defunx assq-ref-all alist key +@defunx assv-ref-all alist key +Equivalent to assoc-ref (and family), but works on association lists with +non-unique keys, returning all mathing records (instead of just the first). +@lisp +(assoc-ref-all '((a . 1) (b . 2) (a . 3)) 'a) +⇒ (1 3) +@end lisp +@end defun + + +@defun vector-last v +Returns the last element of @var{v}. +@end defun + +@defun ->string any +Converts @var{any} to a string, as per @var{display}. +@end defun + + +@defmac let-env bindings body ... +Similar to @var{let}, but sets environment variables for the code in +body. Restores the old values once we leave. + +A variable can also be removed from the environment, by setting its +value to @code{#f}. +@end defmac + +@defmac catch* thunk (symbol proc) ... +Macro allowing multiple exception types to be caught. Each (symbol +proc) pair expands to a regular @code{catch}, with the leftmost being +innermost. + +@var{Symbol} can also be on the form @code{(pre-unwind @var{symbol})}, +then @code{with-throw-handler} is used instead of @code{catch}. +@end defmac + +@defun uniq lst +@defunx univ lst +@defunx unique lst +@defunx uniqx comp lst +Squash repeated equivalent elements in a list into single instances, +similar to the POSIX command uniq(1). The three variants uses +@code{eq?}, @code{eqv?}, and @code{equal?} respectively. + +@code{uniqx} also takes @var{comp}, which is sholud be a binary +procedure returning if the elements are equal. +@end defun + +@defmac begin1 forms ... +Port of Common Lisp's @code{begin1} form. Like @code{begin} runs each +form in its body in order, but returns the first result instead of the +last. +@end defmac diff --git a/doc/ref/general/uuid.texi b/doc/ref/general/uuid.texi new file mode 100644 index 00000000..78674763 --- /dev/null +++ b/doc/ref/general/uuid.texi @@ -0,0 +1,17 @@ +@node UUIDs +@section UUID generation + +Provided by module @code{(hnh util uuid)}. + +@defun uuid-v4 +Generates a UUID-v4 string. +@end defun + +@defun uuid +Generates an implementation defined (but guaranteed valid) UUID. +@end defun + +@deftp {parameter} seed +Guile parameter containing the seed used when generating UUID's in +this module. Only set this when you want non-random randomness. +@end deftp diff --git a/doc/ref/general/xdg-basedir.texi b/doc/ref/general/xdg-basedir.texi new file mode 100644 index 00000000..2d3b2972 --- /dev/null +++ b/doc/ref/general/xdg-basedir.texi @@ -0,0 +1,62 @@ +@node XDG Base Directory +@section XDG Base Directory + +Implementation of the XDG Base Directory Specification +@url{https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html}, v0.8. + +It's recommended to include this module with a symbol prefix: + +@example +(use-modules ((xdg basedir) :prefix xdg-) + +(xdg-data-dirs) +⇒ ("/usr/local/share" "/usr/share") +@end example + +The users home directory is fetched from the environment variable @env{HOME}. + + +@defun data-home +@findex XDG_DATA_HOME +@env{XDG_DATA_HOME}, usually @file{~/.local/share}. +@end defun + +@defun config-home +@findex XDG_CONFIG_HOME +@env{XDG_CONFIG_HOME}, usually @file{~/.config}. +@end defun + +@defun state-home +@findex XDG_STATE_HOME +@env{XDG_STATE_HOME}, usually @file{~/.local/state}. +@end defun + +@defun data-dirs +@findex XDG_DATA_DIRS +@env{XDG_DATA_DIRS}, split into a list. + +Defaults to @code{("/usr/local/share" "/usr/share")}. +@end defun + +@defun config-dirs +@findex XDG_CONFIG_DIRS +@env{XDG_CONFIG_DIRS} as a list, usually @code{("/etc/xdg")}. + +Defaults to @file{/etc/xdg}. +@end defun + +@defun cache-home +@findex XDG_CACHE_HOME +@env{XDG_CACHE_HOME}, usually @file{~/.cache}. +@end defun + +@defun runtime-dir +@findex XDG_RUNTIME_DIR +If @env{XDG_RUNTIME_DIR} is set, than that is used. Otherwise a +warning message is printed to stderr and @file{/tmp} is returned. + +The standard also stipulates a few things about permissons for this +directory. These are currently not checked. + +Systemd usually sets this value to @file{/run/user/$(id -u)}. +@end defun diff --git a/doc/ref/general/zic.texi b/doc/ref/general/zic.texi new file mode 100644 index 00000000..5af36fd3 --- /dev/null +++ b/doc/ref/general/zic.texi @@ -0,0 +1,135 @@ +@node Timespec +@section Timespec + +Specifiers of times, including their offset from some origin, and what +kind they are. + +Refer to zic(8) and the AT field of rules. + +@defun make-timespec time sign type + +@defun timespec? x +@end defun + +@defun timspec-time timespec +Should be a time object. +@end defun + +@defun timspec-sign timespec +@code{'+} or @code{'-} +@end defun + +@defun timspec-type timespec +char +@end defun +@end defun + +@defun timespec-zero +The ``empty'' timespec. +@end defun + +@defun timespec-add specs ... +@end defun + +@defun parse-time-spec string [suffixes='(#\s #\w #\u #\g #\z)] +More or less follows the pattern @code{-?[0-9]@{2@}(:[0-9]@{2@})@{0,2@}[swugz]}. +@end defun + + +@node Zone Info Compiler +@section Zone Info Compiler + +@defun read-zoneinfo ports-or-filenames +Takes a (possibly mixed) list of ports and filenames, and calls +@code{parse-zic-file} on each of them. +@end defun + +@c @defun parse-zic-file port +@c @end defun + +@defun zoneinfo? +@end defun + +@defun get-zone zoneinfo name +Takes a zoneinfo object, and a name as a string (probably something +like ``Europe/Stockholm''), and returns a list of zone-entries. +@end defun + +@defun get-rule zoneinfo name +Gets a list of rule objects, sorted in chronological order. +@var{name} is a symbol. +@end defun + +@defun rule->dtstart rule +Returns the first time a given rule happens. +@end defun + +@defun rule->rrule rule +Converts a given zoneinfo rule into a recurrence rule, of all times +that change occurs. +@end defun + +@defun zone-format fmt-string arg +A special case of format, which handles the format strings containing +``%s'' and ``%z''. +@end defun + + + +@defun make-rule name from to in on at save letters + +See zic(8). + +@defun rule? +@end defun + +@defun rule-name +@end defun + +@defun rule-from +@end defun + +@defun rule-to +@end defun + +@c @defun rule-type +@c @end defun + +@defun rule-in +@end defun + +@defun rule-on +@end defun + +@defun rule-at +@end defun + +@defun rule-save +@end defun + +@defun rule-letters +@end defun + +@end defun + + +@defun make-zone-entry stdoff rule format until + +See zic(8). + +@defun zone-entry? +@end defun + +@defun zone-entry-stdoff +@end defun + +@defun zone-entry-rule +@end defun + +@defun zone-entry-format +@end defun + +@defun zone-entry-until +@end defun +@end defun + |