unistr *unistr_new(void);
void unistr_free(unistr *str);
-int unistr_cmp(unistr *str1, unistr *str2);
-unistr *unistr_dup(unistr *str);
+int unistr_cmp(const unistr *str1, const unistr *str2);
+unistr *unistr_dup(const unistr *str);
void unistr_append_char(unistr *str, unistr_char uc);
-void unistr_append_usascii(unistr *str, char *binary, size_t bin_len);
-void unistr_append_utf8(unistr *str, char *binary, size_t bin_len);
-void unistr_append_iso88591(unistr *str, char *binary, size_t bin_len);
-void unistr_dump(unistr *str);
-char *unistr_to_utf8(unistr *str);
-char *unistr_header_to_utf8(char *str);
-char *unistr_utf8_to_header(char *str);
-char *unistr_escaped_to_utf8(char *str);
+void unistr_append_usascii(unistr *str, const char *binary, size_t bin_len);
+void unistr_append_utf8(unistr *str, const char *binary, size_t bin_len);
+void unistr_append_iso88591(unistr *str, const char *binary, size_t bin_len);
+void unistr_dump(const unistr *str);
+char *unistr_to_utf8(const unistr *str);
+char *unistr_header_to_utf8(const char *str);
+char *unistr_utf8_to_header(const char *str);
+char *unistr_escaped_to_utf8(const char *str);
#endif
static void begin_new_source_file(text *txt, char **line_p, char **pos_p,
- const char *filename) {
+ const char *filename, int transparent) {
char *line = *line_p;
char *pos = *pos_p;
- char *tmp;
+ char *tmp, *esc;
source *src;
int fd;
size_t len;
src->suffix = NULL;
src->fd = fd;
src->fmt = NULL;
- src->transparent = 0;
+ src->transparent = transparent;
src->limit = -1;
txt->src = src;
tmp = mygetline(fd);
**pos_p = '\0';
return;
}
+ if (!transparent) {
+ esc = unistr_escaped_to_utf8(tmp);
+ myfree(tmp);
+ tmp = esc;
+ }
line = concatstr(2, line, tmp);
*pos_p = line + (*pos_p - *line_p);
myfree(*line_p);
static void begin_new_formatted_source(text *txt, char **line_p, char **pos_p,
- char *suffix, formatted *fmt) {
+ char *suffix, formatted *fmt, int transparent) {
char *line = *line_p;
char *pos = *pos_p;
const char *str;
}
src->fd = -1;
src->fmt = fmt;
- src->transparent = 0;
+ src->transparent = transparent;
src->limit = -1;
txt->src = src;
str = (*fmt->get)(fmt->state);
*pos_p = *line_p;
return;
}
+ if (!transparent) str = unistr_escaped_to_utf8(str);
line = concatstr(2, line, str);
/* The suffix will be added back in get_processed_text_line() */
*pos_p = line + strlen(line);
token = filename_token(token + 8);
if (token != NULL) {
filename = concatstr(3, listdir, "/control/", token);
- begin_new_source_file(txt, line_p, pos_p, filename);
+ begin_new_source_file(txt, line_p, pos_p, filename, 0);
myfree(filename);
return 0;
}
token = filename_token(token + 5);
if (token != NULL) {
filename = concatstr(3, listdir, "/text/", token);
- begin_new_source_file(txt, line_p, pos_p, filename);
+ begin_new_source_file(txt, line_p, pos_p, filename, 0);
myfree(filename);
return 0;
}
}
if (limit != 0) {
begin_new_source_file(txt, line_p, pos_p,
- txt->mailname);
- txt->src->transparent = 1;
+ txt->mailname, 1);
if (limit == -1) txt->src->limit = -1;
else txt->src->limit = limit - 1;
return 0;
while (fmt != NULL) {
if (strcmp(token, fmt->token) == 0) {
begin_new_formatted_source(txt, line_p, pos_p,
- endpos + 1, fmt);
+ endpos + 1, fmt, 0);
return 0;
}
fmt = fmt->next;
}
if (txt->src->limit != 0) {
if (txt->src->fd != -1) {
- txt->src->upcoming =
- mygetline(txt->src->fd);
+ tmp = mygetline(txt->src->fd);
} else if (txt->src->fmt != NULL) {
item = (*txt->src->fmt->get)(
- txt->src->fmt->state);
- if (item==NULL) txt->src->upcoming=NULL;
- else txt->src->upcoming=mystrdup(item);
+ txt->src->fmt->state);
+ if (item==NULL) tmp = NULL;
+ else tmp = mystrdup(item);
} else {
- txt->src->upcoming = NULL;
+ tmp = NULL;
}
if (txt->src->limit > 0) txt->src->limit--;
+ if (tmp == NULL) {
+ txt->src->upcoming = NULL;
+ } else if (txt->src->transparent) {
+ txt->src->upcoming = tmp;
+ } else {
+ txt->src->upcoming =
+ unistr_escaped_to_utf8(tmp);
+ myfree(tmp);
+ }
} else {
txt->src->upcoming = NULL;
}
return NULL;
}
- tmp = unistr_escaped_to_utf8(line);
- myfree(line);
- line = tmp;
-
if (prev != NULL) {
/* Wrapping */
len = strlen(prev);
spc = pos - line;
spcnext = spc + 1;
}
- } else if (*pos == '\\' && *(pos + 1) == ' ') {
- if (txt->skip == NULL) {
- spc = pos - line - 1;
- spcnext = spc + 1;
- }
- *pos = '\0';
- tmp = concatstr(2, line, pos + 2);
- pos = tmp + (pos - line);
- myfree(line);
- line = tmp;
- continue;
} else if (*pos == '\t') {
/* Avoid breaking due to peeking */
} else if (txt->src->transparent) {
/* Do nothing if the file is to be included
* transparently */
if (peeking && txt->skip == NULL) break;
+ } else if (*pos == '\\' && txt->skip == NULL) {
+ if (peeking) break;
+ if (*(pos + 1) == ' ') {
+ spc = len - 1;
+ tmp = pos + 2;
+ } else {
+ /* Includes backslash */
+ tmp = pos + 1;
+ }
+ *pos = '\0';
+ tmp = concatstr(2, line, tmp);
+ pos = tmp + len;
+ myfree(line);
+ line = tmp;
+ skipwhite = 0;
+ continue;
} else if (*pos == '$' && txt->skip == NULL) {
if (peeking) break;
substitute_one(&line, &pos, listaddr,
}
-int unistr_cmp(unistr *str1, unistr *str2)
+int unistr_cmp(const unistr *str1, const unistr *str2)
{
unsigned int i;
}
-unistr *unistr_dup(unistr *str)
+unistr *unistr_dup(const unistr *str)
{
unistr *ret;
unsigned int i;
}
-void unistr_append_usascii(unistr *str, char *binary, size_t bin_len)
+void unistr_append_usascii(unistr *str, const char *binary, size_t bin_len)
{
unsigned int i;
}
-void unistr_append_utf8(unistr *str, char *binary, size_t bin_len)
+void unistr_append_utf8(unistr *str, const char *binary, size_t bin_len)
{
unsigned int i, j;
unistr_char ch;
}
-void unistr_append_iso88591(unistr *str, char *binary, size_t bin_len)
+void unistr_append_iso88591(unistr *str, const char *binary, size_t bin_len)
{
unsigned int i;
}
-void unistr_dump(unistr *str)
+void unistr_dump(const unistr *str)
{
unsigned int i;
}
-char *unistr_to_utf8(unistr *str)
+char *unistr_to_utf8(const unistr *str)
{
unsigned int i;
size_t len = 0;
/* IN: "=?iso-8859-1?Q?hyggem=F8de?= torsdag"
* OUT: "hyggem\xC3\xB8de torsdag"
*/
-char *unistr_header_to_utf8(char *str)
+char *unistr_header_to_utf8(const char *str)
{
char *my_str;
char *word;
/* IN: "hyggem\xC3\xB8de torsdag"
* OUT: "=?utf-8?Q?hyggem=C3=B8de_torsdag?="
*/
-char *unistr_utf8_to_header(char *str)
+char *unistr_utf8_to_header(const char *str)
{
unistr *us;
char *ret;
- char *p;
+ const char *p;
int clean;
char buf[4];
/* IN: "hyggem\\u00F8de torsdag"
* OUT: "hyggem\xC3\xB8de torsdag"
*/
-char *unistr_escaped_to_utf8(char *str)
+char *unistr_escaped_to_utf8(const char *str)
{
unistr_char ch;
unistr *us;
char *ret;
char u[5];
int len;
+ int skip = 0;
us = unistr_new();
while (*str) {
if (*str == '\\') {
str++;
- if (*str == '\\') {
- str++;
- unistr_append_char(us, '\\');
- continue;
- } else if (*str == 'u') {
+ if (*str == 'u' && !skip) {
str++;
if (!isxdigit(str[0]) ||
!isxdigit(str[1]) ||
unistr_append_char(us, ch);
continue;
} else {
- unistr_append_char(us, '?');
+ unistr_append_char(us, '\\');
+ /* Avoid processing the second backslash of a
+ * double-backslash; but if this was a such a
+ * one, go back to normal */
+ skip = !skip;
continue;
}
} else {