Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/calendar/events.c
Show All 29 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#ifdef WITH_ICONV | |||||
#include <iconv.h> | |||||
#include <errno.h> | |||||
#include <langinfo.h> | |||||
static iconv_t conv = (iconv_t)-1; | |||||
static char *currentEncoding = NULL; | |||||
#endif | |||||
#include "pathnames.h" | #include "pathnames.h" | ||||
#include "calendar.h" | #include "calendar.h" | ||||
#ifdef WITH_ICONV | |||||
void | |||||
set_new_encoding(void) | |||||
{ | |||||
const char *newenc; | |||||
newenc = nl_langinfo(CODESET); | |||||
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; | |||||
outlen = inleft; | |||||
if ((output = malloc(outlen + 1)) == NULL) | |||||
errx(1, "convert: cannot allocate memory"); | |||||
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); | |||||
err(1, "convert"); | |||||
} | |||||
converted = outbuf - output; | |||||
outlen += inleft * 2; | |||||
if ((tmp = realloc(output, outlen + 1)) == NULL) { | |||||
free(output); | |||||
errx(1, "convert: cannot allocate memory"); | |||||
} | |||||
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 * | struct event * | ||||
event_add(int year, int month, int day, char *date, int var, char *txt, | event_add(int year, int month, int day, char *date, int var, char *txt, | ||||
char *extra) | char *extra) | ||||
{ | { | ||||
struct event *e; | struct event *e; | ||||
/* | /* | ||||
* Creating a new event: | * Creating a new event: | ||||
* - Create a new event | * - Create a new event | ||||
* - Copy the machine readable day and month | * - Copy the machine readable day and month | ||||
* - Copy the human readable and language specific date | * - Copy the human readable and language specific date | ||||
* - Copy the text of the event | * - Copy the text of the event | ||||
*/ | */ | ||||
e = (struct event *)calloc(1, sizeof(struct event)); | e = (struct event *)calloc(1, sizeof(struct event)); | ||||
if (e == NULL) | if (e == NULL) | ||||
errx(1, "event_add: cannot allocate memory"); | errx(1, "event_add: cannot allocate memory"); | ||||
e->month = month; | e->month = month; | ||||
e->day = day; | e->day = day; | ||||
e->var = var; | e->var = var; | ||||
e->date = strdup(date); | e->date = convert(date); | ||||
if (e->date == NULL) | if (e->date == NULL) | ||||
errx(1, "event_add: cannot allocate memory"); | errx(1, "event_add: cannot allocate memory"); | ||||
e->text = strdup(txt); | e->text = convert(txt); | ||||
if (e->text == NULL) | if (e->text == NULL) | ||||
errx(1, "event_add: cannot allocate memory"); | errx(1, "event_add: cannot allocate memory"); | ||||
e->extra = NULL; | e->extra = NULL; | ||||
if (extra != NULL && extra[0] != '\0') | if (extra != NULL && extra[0] != '\0') | ||||
e->extra = strdup(extra); | e->extra = convert(extra); | ||||
addtodate(e, year, month, day); | addtodate(e, year, month, day); | ||||
return (e); | return (e); | ||||
} | } | ||||
void | void | ||||
event_continue(struct event *e, char *txt) | event_continue(struct event *e, char *txt) | ||||
{ | { | ||||
char *text; | char *oldtext, *text; | ||||
/* | text = convert(txt); | ||||
* Adding text to the event: | oldtext = e->text; | ||||
* - Save a copy of the old text (unknown length, so strdup()) | if (oldtext == NULL) | ||||
* - 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) | |||||
errx(1, "event_continue: cannot allocate memory"); | errx(1, "event_continue: cannot allocate memory"); | ||||
free(e->text); | asprintf(&e->text, "%s\n%s", oldtext, text); | ||||
asprintf(&e->text, "%s\n%s", text, txt); | |||||
if (e->text == NULL) | if (e->text == NULL) | ||||
errx(1, "event_continue: cannot allocate memory"); | errx(1, "event_continue: cannot allocate memory"); | ||||
free(oldtext); | |||||
free(text); | free(text); | ||||
return; | return; | ||||
} | } | ||||
void | void | ||||
event_print_all(FILE *fp) | event_print_all(FILE *fp) | ||||
{ | { | ||||
Show All 24 Lines |