cleaned awk scripts, str escape bugfix, proper use of local variables

This commit is contained in:
2025-06-16 11:04:32 +02:00
parent ee02a7647b
commit 83beaa3ad5
12 changed files with 401 additions and 262 deletions

View File

@@ -1,46 +1,72 @@
## src/awk/parse.awk
## Parse iCalendar file and print its key aspects:
## ```
## <start> <end> <fpath> <collection> <summary>
## ```.
##
## @assign collection_labels: See configuration of the current program.
# Functions
# parse
# Time-zone aware parsing of the date/date-time entry at the current record.
#
# @local variables: dt
# @return: date or date-time string that can be used in date (1)
function parse( dt) {
# Get timezone information
dt = "";
for (i=2; i<NF-1; i+=2) {
if ($i == "TZID") {
dt = "TZ=\"" $(i+1) "\" ";
break;
dt = "TZ=\"" $(i+1) "\" "
break
}
}
# Get date/datetime
# Get date/date-time
return length($NF) == 8 ?
dt $NF :
dt gensub(/^([0-9]{8})T([0-9]{2})([0-9]{2})([0-9]{2})(Z)?$/, "\\1 \\2:\\3:\\4\\5", "g", $NF);
dt gensub(/^([0-9]{8})T([0-9]{2})([0-9]{2})([0-9]{2})(Z)?$/, "\\1 \\2:\\3:\\4\\5", "g", $NF)
}
function parse_duration( dt, dta, i, n, a, seps) {
n = split($NF, a, /[PTWHMSD]/, seps);
delete dta;
# parse_duration
# Map iCalendar duration specification into the format to be used in date (1).
#
# @local variables: dt, dta, i, n, a, seps
# @input duration: iCalendar duration string
# @return: relative-date/date-time specification to be used in date (1)
function parse_duration(duration, dt, dta, i, n, a, seps) {
n = split(duration, a, /[PTWHMSD]/, seps)
for (i=2; i<=n; i++) {
if(seps[i] == "W") dta["weeks"] = a[i];
if(seps[i] == "H") dta["hours"] = a[i];
if(seps[i] == "M") dta["minutes"] = a[i];
if(seps[i] == "S") dta["seconds"] = a[i];
if(seps[i] == "D") dta["days"] = a[i];
if(seps[i] == "W") dta["weeks"] = a[i]
if(seps[i] == "H") dta["hours"] = a[i]
if(seps[i] == "M") dta["minutes"] = a[i]
if(seps[i] == "S") dta["seconds"] = a[i]
if(seps[i] == "D") dta["days"] = a[i]
}
dt = a[1] ? a[1] : "+";
for (i in dta) {
dt = dt " " dta[i] " " i;
}
return dt;
dt = a[1] ? a[1] : "+"
for (i in dta)
dt = dt " " dta[i] " " i
return dt
}
function print_data(start, dur, end, summary, cmd, collection) {
summary = substr(summary, index(summary, ":") + 1);
gsub("\\\\n", " ", summary); # one-liner
gsub("\\\\N", " ", summary); # one-liner
gsub("\\\\,", ",", summary);
gsub("\\\\;", ";", summary);
gsub("\\\\\\\\", "\\", summary);
depth = split(FILENAME, path, "/");
# print_data
# Print string of parsed data.
#
# @local variables: cmd, collection, depth, path
# @input start: Start time of event
# @input dur: Boolean that indicates that `end` specifies a duration
# @input end: End time of event, or event duration (see `dur`)
# @input summary: Content of SUMMARY field of the event
function print_data(start, dur, end, summary, cmd, collection, depth, path) {
summary = substr(summary, index(summary, ":") + 1)
gsub("\\\\n", " ", summary) # one-liner
gsub("\\\\N", " ", summary) # one-liner
gsub("\\\\,", ",", summary)
gsub("\\\\;", ";", summary)
gsub("\\\\\\\\", "\\", summary)
depth = split(FILENAME, path, "/")
fpath = path[depth-1] "/" path[depth]
collection = depth > 1 ? path[depth-1] : "";
collection = collection in collection2label ? collection2label[collection] : collection;
collection = depth > 1 ? path[depth-1] : ""
collection = collection in collection2label ? collection2label[collection] : collection
collection = collection2label[path[depth-1]]
end = dur ? start " " end : end
cmd = "date -d '" start "' +\"%s\""
@@ -52,20 +78,21 @@ function print_data(start, dur, end, summary, cmd, collection) {
print start, end, fpath, collection, summary
}
BEGIN {
FS="[:;=]";
split(collection_labels, mapping, ";");
# AWK program
BEGIN {
FS="[:;=]"
split(collection_labels, mapping, ";")
for (map in mapping)
{
split(mapping[map], m, "=");
collection2label[m[1]] = m[2];
split(mapping[map], m, "=")
collection2label[m[1]] = m[2]
}
}
/^END:VEVENT/ && inside { print_data(start, dur, end, summary, cmd, collection); exit }
/^DTSTART/ && inside { start = parse( dt) }
/^DTEND/ && inside { end = parse( dt) }
/^DURATION/ && inside { end = parse_duration( dt, dta, i, n, a, seps); dur = 1 }
/^[^ ]/ && rs { rs = 0 }
/^ / && rs { summary = summary substr($0, 2); }
/^SUMMARY/ && inside { rs = 1; summary = $0; }
/^BEGIN:VEVENT/ { inside = 1 }
/^END:VEVENT/ && inside { print_data(start, dur, end, summary); exit }
/^DTSTART/ && inside { start = parse() }
/^DTEND/ && inside { end = parse() }
/^DURATION/ && inside { end = parse_duration($NF); dur = 1 }
/^[^ ]/ && rs { rs = 0 }
/^ / && rs { summary = summary substr($0, 2) }
/^SUMMARY/ && inside { rs = 1; summary = $0 }
/^BEGIN:VEVENT/ { inside = 1 }