mirror of
https://frontier.innolan.net/rainlance/amiga-tz.git
synced 2026-05-07 07:58:06 +00:00
Add optional meta-information to version-3 format.
* Makefile (ZFLAGS): Add a comment about how to enable meta-info. * tzfile.5: Describe meta-information. * zic.8: Document new options -n and -o, which cause zic to generate meta-info. * zic.c: Include <stddef.h>, for ptrdiff_t. (genoption, genoptions, genname): New static vars. (usage): Summarize new options. (addgenoption, writevalue): New function. (main, writezone): Add support for new options.
This commit is contained in:
3
Makefile
3
Makefile
@@ -250,6 +250,9 @@ LDFLAGS= $(LFLAGS)
|
||||
zic= ./zic
|
||||
ZIC= $(zic) $(ZFLAGS)
|
||||
|
||||
# Uncomment this to put name and version info into zic output files.
|
||||
#ZFLAGS= -n -o version='$(VERSION)'
|
||||
|
||||
# The name of a Posix-compliant `awk' on your system.
|
||||
AWK= awk
|
||||
|
||||
|
||||
13
tzfile.5
13
tzfile.5
@@ -154,6 +154,19 @@ First, the hours part of its transition times may be signed and range from
|
||||
from 0 through 24. Second, DST is in effect all year if it starts
|
||||
January 1 at 00:00 and ends December 31 at 24:00 plus the difference
|
||||
between daylight saving and standard time.
|
||||
.PP
|
||||
Also, for version-3-format time zone files, the version-2 header and
|
||||
data are optionally followed by a section containing auxiliary
|
||||
meta-information that is not needed to process time stamps. This
|
||||
section, if present, consists of the four magic bytes "=TZ\en"
|
||||
followed by zero or more newline-terminated byte strings, each
|
||||
containing a name-value pair separated by "=". Names consist of ASCII
|
||||
letters, digits and underscores, and start with a letter; duplicate
|
||||
names are not allowed. Two common names are "name", the Zone name for
|
||||
the data, and "version", the version number. Values consist of any
|
||||
bytes except NUL, newline, and backslash; however, newline and
|
||||
backslash can represented via the two-byte strings "\en" and "\e\e"
|
||||
respectively.
|
||||
.SH SEE ALSO
|
||||
newctime(3), newtzset(3)
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
|
||||
14
zic.8
14
zic.8
@@ -15,6 +15,11 @@ zic \- time zone compiler
|
||||
.B \-l
|
||||
.I localtime
|
||||
] [
|
||||
.B \-n
|
||||
] [
|
||||
.B \-o
|
||||
.IB name = value
|
||||
] [
|
||||
.B \-p
|
||||
.I posixrules
|
||||
] [
|
||||
@@ -62,6 +67,15 @@ will act as if the input contained a link line of the form
|
||||
.ti +.5i
|
||||
Link \fItimezone\fP localtime
|
||||
.TP
|
||||
.B "\-n"
|
||||
Store each zone's name into its generated file, as meta-information
|
||||
with the name "name" and value the zone's name.
|
||||
.TP
|
||||
.BI "\-o " name = value
|
||||
Store the given name-value pair into the generated file, as
|
||||
meta-information. This option can be repeated, once for each distinct
|
||||
name.
|
||||
.TP
|
||||
.BI "\-p " timezone
|
||||
Use the given time zone's rules when handling POSIX-format
|
||||
time zone environment variables.
|
||||
|
||||
73
zic.c
73
zic.c
@@ -9,6 +9,7 @@
|
||||
#include "tzfile.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define ZIC_VERSION '3'
|
||||
|
||||
@@ -140,6 +141,9 @@ static int yearistype(int year, const char * type);
|
||||
static int charcnt;
|
||||
static int errors;
|
||||
static const char * filename;
|
||||
static const char ** genoption;
|
||||
static int genoptions;
|
||||
static int genname;
|
||||
static int leapcnt;
|
||||
static int leapseen;
|
||||
static zic_t leapminyear;
|
||||
@@ -432,7 +436,8 @@ static _Noreturn void
|
||||
usage(FILE *stream, int status)
|
||||
{
|
||||
(void) fprintf(stream, _("%s: usage is %s \
|
||||
[ --version ] [ --help ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
|
||||
[ --version ] [ --help ] [ -v ] [ -l localtime ]\\\n\
|
||||
\t[ -n ] [ -o name=value ]... [ -p posixrules ] \\\n\
|
||||
\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\
|
||||
\n\
|
||||
Report bugs to %s.\n"),
|
||||
@@ -446,6 +451,31 @@ static const char * directory;
|
||||
static const char * leapsec;
|
||||
static const char * yitcommand;
|
||||
|
||||
static int
|
||||
addgenoption(char const *option)
|
||||
{
|
||||
register char const *o = option;
|
||||
register ptrdiff_t namelen;
|
||||
register int i;
|
||||
if (! (isascii (*o) && isalpha(*o)))
|
||||
return 0;
|
||||
while (*++o != '=')
|
||||
if (! (isascii (*o) && (isalnum(*o) || *o == '_')))
|
||||
return 0;
|
||||
namelen = o - option;
|
||||
if (INT_MAX < namelen)
|
||||
return 0; /* fprintf won't work. */
|
||||
if (namelen == sizeof "name" - 1
|
||||
&& memcmp(option, "name", namelen) == 0)
|
||||
return 0;
|
||||
for (i = 0; i < genoptions; i++)
|
||||
if (strncmp(genoption[i], option, namelen + 1) == 0)
|
||||
return 0;
|
||||
genoption = erealloc(genoption, (genoptions + 1) * sizeof *genoption);
|
||||
genoption[genoptions++] = option;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -476,7 +506,7 @@ main(int argc, char **argv)
|
||||
} else if (strcmp(argv[i], "--help") == 0) {
|
||||
usage(stdout, EXIT_SUCCESS);
|
||||
}
|
||||
while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF && c != -1)
|
||||
while ((c = getopt(argc, argv, "d:l:p:L:no:vsy:")) != EOF && c != -1)
|
||||
switch (c) {
|
||||
default:
|
||||
usage(stderr, EXIT_FAILURE);
|
||||
@@ -500,6 +530,17 @@ _("%s: More than one -l option specified\n"),
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
genname = TRUE;
|
||||
break;
|
||||
case 'o':
|
||||
if (!addgenoption(optarg)) {
|
||||
fprintf(stderr,
|
||||
_("%s: %s: invalid -o option\n"),
|
||||
progname, optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
if (psxrules == NULL)
|
||||
psxrules = optarg;
|
||||
@@ -1385,6 +1426,22 @@ is32(const zic_t x)
|
||||
return INT32_MIN <= x && x <= INT32_MAX;
|
||||
}
|
||||
|
||||
static void
|
||||
writevalue(FILE *fp, char const *v)
|
||||
{
|
||||
fputc('=', fp);
|
||||
|
||||
for (; *v; v++)
|
||||
if (*v == '\n')
|
||||
fprintf(fp, "\\n");
|
||||
else if (*v == '\\')
|
||||
fprintf(fp, "\\\\");
|
||||
else
|
||||
fputc(*v, fp);
|
||||
|
||||
fputc('\n', fp);
|
||||
}
|
||||
|
||||
static void
|
||||
writezone(const char *const name, const char *const string)
|
||||
{
|
||||
@@ -1708,6 +1765,18 @@ writezone(const char *const name, const char *const string)
|
||||
(void) putc(ttisgmts[i], fp);
|
||||
}
|
||||
(void) fprintf(fp, "\n%s\n", string);
|
||||
if (genname || genoptions)
|
||||
fprintf(fp, "=TZ\n");
|
||||
if (genname) {
|
||||
fprintf(fp, "name");
|
||||
writevalue(fp, name);
|
||||
}
|
||||
for (i = 0; i < genoptions; i++) {
|
||||
register char const *v = genoption[i];
|
||||
register int namelen = strchr(v, '=') - v;
|
||||
fprintf(fp, "%.*s", namelen, v);
|
||||
writevalue(fp, v + namelen + 1);
|
||||
}
|
||||
if (ferror(fp) || fclose(fp)) {
|
||||
(void) fprintf(stderr, _("%s: Error writing %s\n"),
|
||||
progname, fullname);
|
||||
|
||||
Reference in New Issue
Block a user