Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109451771
D19221.id54008.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D19221.id54008.diff
View Options
Index: usr.bin/calendar/Makefile
===================================================================
--- usr.bin/calendar/Makefile
+++ usr.bin/calendar/Makefile
@@ -13,6 +13,10 @@
DE_LINKS= de_DE.ISO8859-15
FR_LINKS= fr_FR.ISO8859-15
+.if ${MK_ICONV} == "yes"
+CFLAGS+= -DWITH_ICONV
+.endif
+
FILESGROUPS+= CALS
CALS= calendars/calendar.all \
calendars/calendar.australia \
Index: usr.bin/calendar/calendar.h
===================================================================
--- usr.bin/calendar/calendar.h
+++ usr.bin/calendar/calendar.h
@@ -59,6 +59,9 @@
extern struct fixs nmarequinox, nsepequinox, njunsolstice, ndecsolstice;
extern double UTCOffset;
extern int EastLongitude;
+#ifdef WITH_ICONV
+extern const char *outputEncoding;
+#endif
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
@@ -197,3 +200,7 @@
void equinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays);
void fequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays);
int calculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths);
+
+#ifdef WITH_ICONV
+void set_new_encoding(void);
+#endif
Index: usr.bin/calendar/calendar.c
===================================================================
--- usr.bin/calendar/calendar.c
+++ usr.bin/calendar/calendar.c
@@ -66,6 +66,9 @@
static time_t f_time = 0;
double UTCOffset = UTCOFFSET_NOTSET;
int EastLongitude = LONGITUDE_NOTSET;
+#ifdef WITH_ICONV
+const char *outputEncoding;
+#endif
static void usage(void) __dead2;
@@ -80,6 +83,21 @@
struct tm tp1, tp2;
(void)setlocale(LC_ALL, "");
+#ifdef WITH_ICONV
+ /* save the information about the encoding used in the terminal */
+ const char *enc;
+
+ enc = setlocale(LC_CTYPE, NULL);
+ enc = strchr(enc, '.');
+ if (enc == NULL)
+ enc = "ASCII";
+ else
+ enc++;
+ outputEncoding = strdup(enc);
+ if (outputEncoding == NULL)
+ errx(1, "cannot allocate memory");
+
+#endif
while ((ch = getopt(argc, argv, "-A:aB:D:dF:f:l:t:U:W:?")) != -1)
switch (ch) {
Index: usr.bin/calendar/events.c
===================================================================
--- usr.bin/calendar/events.c
+++ usr.bin/calendar/events.c
@@ -35,10 +35,128 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef WITH_ICONV
+#include <iconv.h>
+#include <errno.h>
+#include <locale.h>
+static iconv_t conv = (iconv_t)-1;
+static char *currentEncoding = NULL;
+
+#endif
+
#include "pathnames.h"
#include "calendar.h"
+#ifdef WITH_ICONV
+void
+set_new_encoding(void)
+{
+ const char *newenc;
+
+ newenc = setlocale(LC_CTYPE, NULL);
+ newenc = strchr(newenc, '.');
+ if (newenc == NULL)
+ newenc = "ASCII";
+ else
+ newenc++;
+ if (currentEncoding == NULL) {
+ currentEncoding = strdup(newenc);
+ if (currentEncoding == NULL)
+ errx(1, "set_new_encoding: cannot allocate memory");
+ return;
+ }
+ if (strcmp(currentEncoding, newenc) == 0)
+ return;
+ free(currentEncoding);
+ currentEncoding = strdup(newenc);
+ if (currentEncoding == NULL)
+ errx(1, "set_new_encoding: cannot allocate memory");
+ if (conv != (iconv_t) -1) {
+ iconv_close(conv);
+ conv = (iconv_t) -1;
+ }
+}
+#endif
+
+static char *
+convert(char *input) {
+ char *output;
+#ifdef WITH_ICONV
+ size_t inleft, outleft, converted = 0;
+ char *outbuf, *tmp;
+ char *inbuf;
+ size_t outlen;
+
+ if (currentEncoding == NULL) {
+ output = strdup(input);
+ if (output == NULL)
+ errx(1, "convert: cannot allocate memory");
+ return (output);
+ }
+ if (conv == (iconv_t)-1) {
+ conv = iconv_open(outputEncoding, currentEncoding);
+ if (conv == (iconv_t)-1) {
+ if (errno == EINVAL)
+ errx(1, "Conversion is not supported");
+ else
+ err(1, "Initialization failure");
+ }
+ }
+
+ inleft = strlen(input);
+ inbuf = input;
+
+ /* we'll start off allocating an output buffer which is the same size
+ * as our input buffer. */
+ outlen = inleft;
+
+ if (!(output = malloc(outlen + 1))) {
+ return NULL;
+ }
+
+ for (;;) {
+ errno = 0;
+ outbuf = output + converted;
+ outleft = outlen - converted;
+
+ converted = iconv(conv, (char **) &inbuf, &inleft, &outbuf, &outleft);
+ if (converted != (size_t) -1 || errno == EINVAL) {
+ /* finished or invalid multibyte, so truncate and ignore */
+ break;
+ }
+
+ if (errno != E2BIG) {
+ free(output);
+ return (NULL);
+ }
+
+ converted = outbuf - output;
+ outlen += inleft * 2;
+
+ if ((tmp = realloc(output, outlen + 1)) == NULL) {
+ free(output);
+ return (NULL);
+ }
+
+ output = tmp;
+ outbuf = output + converted;
+ }
+
+ /* flush the iconv conversion */
+ iconv(conv, NULL, NULL, &outbuf, &outleft);
+
+ /* null terminate the string */
+ *outbuf = '\0';
+#else
+ output = strdup(input);
+ if (output == NULL)
+ errx(1, "convert: cannot allocate memory");
+#endif
+
+ return (output);
+}
+
struct event *
event_add(int year, int month, int day, char *date, int var, char *txt,
char *extra)
@@ -58,15 +176,15 @@
e->month = month;
e->day = day;
e->var = var;
- e->date = strdup(date);
+ e->date = convert(date);
if (e->date == NULL)
errx(1, "event_add: cannot allocate memory");
- e->text = strdup(txt);
+ e->text = convert(txt);
if (e->text == NULL)
errx(1, "event_add: cannot allocate memory");
e->extra = NULL;
if (extra != NULL && extra[0] != '\0')
- e->extra = strdup(extra);
+ e->extra = convert(extra);
addtodate(e, year, month, day);
return (e);
}
@@ -74,23 +192,18 @@
void
event_continue(struct event *e, char *txt)
{
- char *text;
+ char *oldtext, *text;
- /*
- * Adding text to the event:
- * - Save a copy of the old text (unknown length, so strdup())
- * - Allocate enough space for old text + \n + new text + 0
- * - Store the old text + \n + new text
- * - Destroy the saved copy.
- */
- text = strdup(e->text);
- if (text == NULL)
+ text = convert(txt);
+ oldtext = strdup(e->text);
+ if (oldtext == NULL)
errx(1, "event_continue: cannot allocate memory");
free(e->text);
- asprintf(&e->text, "%s\n%s", text, txt);
+ asprintf(&e->text, "%s\n%s", oldtext, text);
if (e->text == NULL)
errx(1, "event_continue: cannot allocate memory");
+ free(oldtext);
free(text);
return;
Index: usr.bin/calendar/io.c
===================================================================
--- usr.bin/calendar/io.c
+++ usr.bin/calendar/io.c
@@ -294,6 +294,9 @@
if (strncmp(buf, "LANG=", 5) == 0) {
(void)setlocale(LC_ALL, buf + 5);
d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
+#ifdef WITH_ICONV
+ set_new_encoding();
+#endif
setnnames();
continue;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 6, 6:06 AM (10 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16488311
Default Alt Text
D19221.id54008.diff (6 KB)
Attached To
Mode
D19221: Use iconv to ensure the output of calendar respects the output encoding
Attached
Detach File
Event Timeline
Log In to Comment