Commit f7ff70f6 authored by Tatsuya Kinoshita's avatar Tatsuya Kinoshita

Merge branch 'bug/win64gc'

Conflicts:
	istream.c
	main.c
parents 19416773 ec81194f
......@@ -210,6 +210,10 @@ typedef RETSIGTYPE MySignalHandler;
#define SUPPORT_WIN9X_CONSOLE_MBCS 1
#endif
#if defined(__CYGWIN__) && defined(__x86_64__)
#define DONT_CALL_GC_AFTER_FORK
#endif
#if defined(__DJGPP__)
#define DEFAULT_TERM "dosansi"
#else
......
......@@ -677,6 +677,7 @@ readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu)
#endif
init_stream(&f, SCM_LOCAL, newStrStream(src));
loadHTMLstream(&f, newBuf, NULL, TRUE);
UFclose(&f);
for (l = newBuf->lastLine; l && l->real_linenumber;
l = l->prev)
l->real_linenumber = 0;
......@@ -7238,16 +7239,17 @@ loadHTMLString(Str page)
MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;
Buffer *newBuf;
init_stream(&f, SCM_LOCAL, newStrStream(page));
newBuf = newBuffer(INIT_BUFFER_WIDTH);
if (SETJMP(AbortLoading) != 0) {
TRAP_OFF;
discardBuffer(newBuf);
UFclose(&f);
return NULL;
}
TRAP_ON;
init_stream(&f, SCM_LOCAL, newStrStream(page));
#ifdef USE_M17N
newBuf->document_charset = InnerCharset;
#endif
......@@ -7257,6 +7259,7 @@ loadHTMLString(Str page)
#endif
TRAP_OFF;
UFclose(&f);
newBuf->topLine = newBuf->firstLine;
newBuf->lastLine = newBuf->currentLine;
newBuf->currentLine = newBuf->firstLine;
......@@ -7486,15 +7489,13 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf)
!stat(cache->file, &st))
goto image_buffer;
TRAP_ON;
if (IStype(uf->stream) != IST_ENCODED)
uf->stream = newEncodedStream(uf->stream, uf->encoding);
TRAP_ON;
if (save2tmp(*uf, cache->file) < 0) {
UFclose(uf);
TRAP_OFF;
return NULL;
}
UFclose(uf);
TRAP_OFF;
cache->loaded = IMG_FLAG_LOADED;
......@@ -7514,6 +7515,7 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf)
init_stream(&f, SCM_LOCAL, newStrStream(tmp));
loadHTMLstream(&f, newBuf, src, TRUE);
UFclose(&f);
if (src)
fclose(src);
......@@ -7909,6 +7911,8 @@ save2tmp(URLFile uf, char *tmpf)
clen_t linelen = 0, trbyte = 0;
MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;
static JMP_BUF env_bak;
volatile int retval = 0;
char *volatile buf = NULL;
ff = fopen(tmpf, "wb");
if (ff == NULL) {
......@@ -7945,25 +7949,25 @@ save2tmp(URLFile uf, char *tmpf)
else
#endif /* USE_NNTP */
{
Str buf = Strnew_size(SAVE_BUF_SIZE);
while (UFread(&uf, buf, SAVE_BUF_SIZE)) {
if (Strfputs(buf, ff) != buf->length) {
bcopy(env_bak, AbortLoading, sizeof(JMP_BUF));
TRAP_OFF;
fclose(ff);
current_content_length = 0;
return -2;
int count;
buf = NewWithoutGC_N(char, SAVE_BUF_SIZE);
while ((count = ISread_n(uf.stream, buf, SAVE_BUF_SIZE)) > 0) {
if (fwrite(buf, 1, count, ff) != count) {
retval = -2;
goto _end;
}
linelen += buf->length;
linelen += count;
showProgress(&linelen, &trbyte);
}
}
_end:
bcopy(env_bak, AbortLoading, sizeof(JMP_BUF));
TRAP_OFF;
xfree(buf);
fclose(ff);
current_content_length = 0;
return 0;
return retval;
}
Buffer *
......@@ -8074,7 +8078,8 @@ _MoveFile(char *path1, char *path2)
FILE *f2;
int is_pipe;
clen_t linelen = 0, trbyte = 0;
Str buf;
char *buf = NULL;
int count;
f1 = openIS(path1);
if (f1 == NULL)
......@@ -8092,12 +8097,13 @@ _MoveFile(char *path1, char *path2)
return -1;
}
current_content_length = 0;
buf = Strnew_size(SAVE_BUF_SIZE);
while (ISread(f1, buf, SAVE_BUF_SIZE)) {
Strfputs(buf, f2);
linelen += buf->length;
buf = NewWithoutGC_N(char, SAVE_BUF_SIZE);
while ((count = ISread_n(f1, buf, SAVE_BUF_SIZE)) > 0) {
fwrite(buf, 1, count, f2);
linelen += count;
showProgress(&linelen, &trbyte);
}
xfree(buf);
ISclose(f1);
if (is_pipe)
pclose(f2);
......@@ -8456,21 +8462,23 @@ uncompress_stream(URLFile *uf, char **src)
}
if (pid2 == 0) {
/* child2 */
Str buf = Strnew_size(SAVE_BUF_SIZE);
char *buf = NewWithoutGC_N(char, SAVE_BUF_SIZE);
int count;
FILE *f = NULL;
setup_child(TRUE, 2, UFfileno(uf));
if (tmpf)
f = fopen(tmpf, "wb");
while (UFread(uf, buf, SAVE_BUF_SIZE)) {
if (Strfputs(buf, stdout) < 0)
while ((count = ISread_n(uf->stream, buf, SAVE_BUF_SIZE)) > 0) {
if (fwrite(buf, 1, count, stdout) != count)
break;
if (f && fwrite(buf, 1, count, f) != count)
break;
if (f)
Strfputs(buf, f);
}
UFclose(uf);
if (f)
fclose(f);
xfree(buf);
exit(0);
}
/* child1 */
......
......@@ -76,6 +76,7 @@ typedef int wc_ces; /* XXX: not used */
#include "textlist.h"
#include "funcname1.h"
#include "terms.h"
#include "istream.h"
#ifndef HAVE_BCOPY
void bcopy(const void *, void *, int);
......@@ -288,8 +289,6 @@ extern int REV_LB[];
#define inputFilenameHist(p,d,h) inputLineHist(p,d,IN_FILENAME,h)
#define inputChar(p) inputLine(p,"",IN_CHAR)
#define free(x) GC_free(x) /* let GC do it. */
#ifdef __EMX__
#define HAVE_STRCASECMP
#define strcasecmp stricmp
......@@ -895,6 +894,9 @@ global char *index_file init(NULL);
global char *CurrentDir;
global int CurrentPid;
#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE)
global char *MyProgramName init("w3m");
#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */
/*
* global Buffer *Currentbuf;
* global Buffer *Firstbuf;
......
/* $Id: html.h,v 1.31 2010/08/14 01:29:40 htrb Exp $ */
#ifndef _HTML_H
#define _HTML_H
#include "config.h"
#ifdef USE_SSL
#include <openssl/bio.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#endif /* USE_SSL */
#include "istream.h"
#define StrUFgets(f) StrISgets((f)->stream)
#define StrmyUFgets(f) StrmyISgets((f)->stream)
#define UFgetc(f) ISgetc((f)->stream)
#define UFundogetc(f) ISundogetc((f)->stream)
#define UFread(f,buf,len) ISread((f)->stream,buf,len)
#define UFclose(f) (void)(ISclose((f)->stream) == 0 && ((f)->stream = NULL))
#define UFfileno(f) ISfileno((f)->stream)
......@@ -62,11 +60,12 @@ typedef struct _ParsedURL {
int is_nocache;
} ParsedURL;
union input_stream;
typedef struct {
unsigned char scheme;
char is_cgi;
char encoding;
InputStream stream;
union input_stream *stream;
char *ext;
int compression;
int content_encoding;
......
......@@ -90,17 +90,18 @@ termImage()
static int
openImgdisplay()
{
char *cmd;
if (!strchr(Imgdisplay, '/'))
cmd = Strnew_m_charp(w3m_auxbin_dir(), "/", Imgdisplay, NULL)->ptr;
else
cmd = Imgdisplay;
Imgdisplay_pid = open_pipe_rw(&Imgdisplay_rf, &Imgdisplay_wf);
if (Imgdisplay_pid < 0)
goto err0;
if (Imgdisplay_pid == 0) {
/* child */
char *cmd;
setup_child(FALSE, 2, -1);
if (!strchr(Imgdisplay, '/'))
cmd = Strnew_m_charp(w3m_auxbin_dir(), "/", Imgdisplay, NULL)->ptr;
else
cmd = Imgdisplay;
myExec(cmd);
/* XXX: ifdef __EMX__, use start /f ? */
}
......@@ -333,6 +334,9 @@ loadImage(Buffer *buf, int flag)
struct stat st;
int i, draw = FALSE;
/* int wait_st; */
#ifdef DONT_CALL_GC_AFTER_FORK
char *loadargs[7];
#endif
if (maxLoadImage > MAX_LOAD_IMAGE)
maxLoadImage = MAX_LOAD_IMAGE;
......@@ -433,6 +437,24 @@ loadImage(Buffer *buf, int flag)
image_cache[i] = cache;
flush_tty();
#ifdef DONT_CALL_GC_AFTER_FORK
loadargs[0] = MyProgramName;
loadargs[1] = "-$$getimage";
loadargs[2] = conv_to_system(cache->url);
loadargs[3] = conv_to_system(parsedURL2Str(cache->current)->ptr);
loadargs[4] = cache->file;
loadargs[5] = cache->touch;
loadargs[6] = NULL;
if ((cache->pid = fork()) == 0) {
setup_child(FALSE, 0, -1);
execvp(MyProgramName, loadargs);
exit(1);
}
else if (cache->pid < 0) {
cache->pid = 0;
return;
}
#else /* !DONT_CALL_GC_AFTER_FORK */
if ((cache->pid = fork()) == 0) {
Buffer *b;
/*
......@@ -458,6 +480,7 @@ loadImage(Buffer *buf, int flag)
cache->pid = 0;
return;
}
#endif /* !DONT_CALL_GC_AFTER_FORK */
}
}
......
......@@ -721,6 +721,111 @@ shell_quote(char *str)
return str;
}
void *
xrealloc(void *ptr, size_t size)
{
void *newptr = realloc(ptr, size);
if (newptr == NULL) {
fprintf(stderr, "Out of memory\n");
exit(-1);
}
return newptr;
}
/* Define this as a separate function in case the free() has
* an incompatible prototype. */
void
xfree(void *ptr)
{
free(ptr);
}
void *
w3m_GC_realloc_atomic(void *ptr, size_t size)
{
return ptr ? GC_REALLOC(ptr, size) : GC_MALLOC_ATOMIC(size);
}
void
w3m_GC_free(void *ptr)
{
GC_FREE(ptr);
}
void
growbuf_init(struct growbuf *gb)
{
gb->ptr = NULL;
gb->length = 0;
gb->area_size = 0;
gb->realloc_proc = &w3m_GC_realloc_atomic;
gb->free_proc = &w3m_GC_free;
}
void
growbuf_init_without_GC(struct growbuf *gb)
{
gb->ptr = NULL;
gb->length = 0;
gb->area_size = 0;
gb->realloc_proc = &xrealloc;
gb->free_proc = &xfree;
}
void
growbuf_clear(struct growbuf *gb)
{
(*gb->free_proc) (gb->ptr);
gb->ptr = NULL;
gb->length = 0;
gb->area_size = 0;
}
Str
growbuf_to_Str(struct growbuf *gb)
{
Str s;
if (gb->free_proc == &w3m_GC_free) {
growbuf_reserve(gb, gb->length + 1);
gb->ptr[gb->length] = '\0';
s = New(struct _Str);
s->ptr = gb->ptr;
s->length = gb->length;
s->area_size = gb->area_size;
} else {
s = Strnew_charp_n(gb->ptr, gb->length);
(*gb->free_proc) (gb->ptr);
}
gb->ptr = NULL;
gb->length = 0;
gb->area_size = 0;
return s;
}
void
growbuf_reserve(struct growbuf *gb, int leastarea)
{
int newarea;
if (gb->area_size < leastarea) {
newarea = gb->area_size * 3 / 2;
if (newarea < leastarea)
newarea = leastarea;
newarea += 16;
gb->ptr = (*gb->realloc_proc) (gb->ptr, newarea);
gb->area_size = newarea;
}
}
void
growbuf_append(struct growbuf *gb, const char *src, int len)
{
growbuf_reserve(gb, gb->length + len);
memcpy(&gb->ptr[gb->length], src, len);
gb->length += len;
}
static char *
w3m_dir(const char *name, char *dft)
{
......
......@@ -12,6 +12,14 @@
#define FALSE 0
#endif /* FALSE */
struct growbuf {
char *ptr;
int length;
int area_size;
void *(*realloc_proc) (void *, size_t);
void (*free_proc) (void *);
};
#define RAW_MODE 0
#define PAGER_MODE 1
#define HTML_MODE 2
......@@ -65,6 +73,18 @@ extern Str Str_url_unquote(Str x, int is_form, int safe);
extern Str Str_form_quote(Str x);
#define Str_form_unquote(x) Str_url_unquote((x), TRUE, FALSE)
extern char *shell_quote(char *str);
#define xmalloc(s) xrealloc(NULL, s)
extern void *xrealloc(void *ptr, size_t size);
extern void xfree(void *ptr);
extern void *w3m_GC_realloc_atomic(void *ptr, size_t size);
extern void w3m_GC_free(void *ptr);
extern void growbuf_init(struct growbuf *gb);
extern void growbuf_init_without_GC(struct growbuf *gb);
extern void growbuf_clear(struct growbuf *gb);
extern Str growbuf_to_Str(struct growbuf *gb);
extern void growbuf_reserve(struct growbuf *gb, int leastarea);
extern void growbuf_append(struct growbuf *gb, const char *src, int len);
#define GROWBUF_ADD_CHAR(gb,ch) ((((gb)->length>=(gb)->area_size)?growbuf_reserve(gb,(gb)->length+1):(void)0),(void)((gb)->ptr[(gb)->length++] = (ch)))
extern char *w3m_auxbin_dir();
extern char *w3m_lib_dir();
......@@ -77,5 +97,8 @@ extern char *w3m_help_dir();
#define New_N(type,n) ((type*)GC_MALLOC((n)*sizeof(type)))
#define NewAtom_N(type,n) ((type*)GC_MALLOC_ATOMIC((n)*sizeof(type)))
#define New_Reuse(type,ptr,n) ((type*)GC_REALLOC((ptr),(n)*sizeof(type)))
#define NewWithoutGC(type) ((type*)xmalloc(sizeof(type)))
#define NewWithoutGC_N(type,n) ((type*)xmalloc((n)*sizeof(type)))
#define NewWithoutGC_Reuse(type,ptr,n) ((type*)xrealloc(ptr,(n)*sizeof(type)))
#endif /* INDEP_H */
This diff is collapsed.
......@@ -2,13 +2,13 @@
#ifndef IO_STREAM_H
#define IO_STREAM_H
#include "indep.h"
#include <stdio.h>
#ifdef USE_SSL
#include <openssl/bio.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#endif
#include "Str.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
......@@ -36,7 +36,7 @@ union input_stream;
struct ens_handle {
union input_stream *is;
Str s;
struct growbuf gb;
int pos;
char encoding;
};
......@@ -119,9 +119,14 @@ extern InputStream newEncodedStream(InputStream is, char encoding);
extern int ISclose(InputStream stream);
extern int ISgetc(InputStream stream);
extern int ISundogetc(InputStream stream);
extern Str StrISgets(InputStream stream);
extern Str StrmyISgets(InputStream stream);
extern Str StrISgets2(InputStream stream, char crnl);
#define StrISgets(stream) StrISgets2(stream, FALSE)
#define StrmyISgets(stream) StrISgets2(stream, TRUE)
void ISgets_to_growbuf(InputStream stream, struct growbuf *gb, char crnl);
#ifdef unused
extern int ISread(InputStream stream, Str buf, int count);
#endif
int ISread_n(InputStream stream, char *dst, int bufsize);
extern int ISfileno(InputStream stream);
extern int ISeos(InputStream stream);
#ifdef USE_SSL
......
......@@ -359,6 +359,10 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
int status;
pid_t pid;
char *file = uri, *name = uri, *path_info = NULL, *tmpf = NULL;
#ifdef HAVE_CHDIR
char *cgi_dir;
#endif
char *cgi_basename;
#ifdef __MINGW32_VERSION
return NULL;
......@@ -373,7 +377,14 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
if (!fw)
return NULL;
}
if (qstr)
uri = Strnew_m_charp(uri, "?", qstr, NULL)->ptr;
#ifdef HAVE_CHDIR
cgi_dir = mydirname(file);
#endif
cgi_basename = mybasename(file);
pid = open_pipe_rw(&fr, NULL);
/* Don't invoke gc after here, or the program might crash in some platforms */
if (pid < 0)
return NULL;
else if (pid) {
......@@ -383,8 +394,6 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
}
setup_child(TRUE, 2, fw ? fileno(fw) : -1);
if (qstr)
uri = Strnew_m_charp(uri, "?", qstr, NULL)->ptr;
set_cgi_environ(name, file, uri);
if (path_info)
set_environ("PATH_INFO", path_info);
......@@ -415,11 +424,11 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
}
#ifdef HAVE_CHDIR /* ifndef __EMX__ ? */
chdir(mydirname(file));
chdir(cgi_dir);
#endif
execl(file, mybasename(file), NULL);
execl(file, cgi_basename, NULL);
fprintf(stderr, "execl(\"%s\", \"%s\", NULL): %s\n",
file, mybasename(file), strerror(errno));
file, cgi_basename, strerror(errno));
exit(1);
return NULL;
#endif
......
......@@ -11,6 +11,9 @@
#include <sys/wait.h>
#endif
#include <time.h>
#if defined(__CYGWIN__) && defined(USE_BINMODE_STREAM)
#include <io.h>
#endif
#include "terms.h"
#include "myctype.h"
#include "regex.h"
......@@ -407,6 +410,10 @@ main(int argc, char **argv, char **envp)
wc_ces CodePage;
#endif
#endif
#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE)
char **getimage_args = NULL;
#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */
GC_INIT();
#if defined(ENABLE_NLS) || (defined(USE_M17N) && defined(HAVE_LANGINFO_CODESET))
setlocale(LC_ALL, "");
......@@ -428,6 +435,10 @@ main(int argc, char **argv, char **envp)
CurrentDir = currentdir();
CurrentPid = (int)getpid();
#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE)
if (argv[0] && *argv[0])
MyProgramName = argv[0];
#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */
BookmarkFile = NULL;
config_file = NULL;
......@@ -751,6 +762,15 @@ main(int argc, char **argv, char **envp)
else if (!strcmp("-reqlog",argv[i])) {
w3m_reqlog=rcFile("request.log");
}
#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE)
else if (!strcmp("-$$getimage", argv[i])) {
++i;
getimage_args = argv + i;
i += 4;
if (i > argc)
usage();
}
#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */
else {
usage();
}
......@@ -839,6 +859,30 @@ main(int argc, char **argv, char **envp)
if (w3m_backend)
backend();
#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE)
if (getimage_args) {
char *image_url = conv_from_system(getimage_args[0]);
char *base_url = conv_from_system(getimage_args[1]);
ParsedURL base_pu;
parseURL2(base_url, &base_pu, NULL);
image_source = getimage_args[2];
newbuf = loadGeneralFile(image_url, &base_pu, NULL, 0, NULL);
if (!newbuf || !newbuf->real_type ||
strncasecmp(newbuf->real_type, "image/", 6))
unlink(getimage_args[2]);
#if defined(HAVE_SYMLINK) && defined(HAVE_LSTAT)
symlink(getimage_args[2], getimage_args[3]);
#else
{
FILE *f = fopen(getimage_args[3], "w");
if (f)
fclose(f);
}
#endif
w3m_exit(0);
}
#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */
if (w3m_dump)
mySignal(SIGINT, SIG_IGN);
......
......@@ -63,13 +63,23 @@ ha2d(char x, char y)
Str
decodeB(char **ww)
{
struct growbuf gb;
growbuf_init(&gb);
decodeB_to_growbuf(&gb, ww);
return growbuf_to_Str(&gb);
}
void
decodeB_to_growbuf(struct growbuf *gb, char **ww)
{
unsigned char c[4];
char *wp = *ww;
char d[3];
int i, n_pad;
Str ap = Strnew_size(strlen(wp));
growbuf_reserve(gb, strlen(wp) + 1);
n_pad = 0;
while (1) {
for (i = 0; i < 4; i++) {
......@@ -93,39 +103,50 @@ decodeB(char **ww)
for (i = 0; i < 4; i++) {
c[i] = c2e(c[i]);
if (c[i] == BAD_BASE64) {
*ww = wp;
return ap;
goto last;
}
}
d[0] = ((c[0] << 2) | (c[1] >> 4));
d[1] = ((c[1] << 4) | (c[2] >> 2));
d[2] = ((c[2] << 6) | c[3]);
for (i = 0; i < 3 - n_pad; i++) {
Strcat_char(ap, d[i]);
GROWBUF_ADD_CHAR(gb, d[i]);
}
if (n_pad || *wp == '\0' || *wp == '?')
break;
}
last:
growbuf_reserve(gb, gb->length + 1);
gb->ptr[gb->length] = '\0';
*ww = wp;
return ap;
return;
}
Str
decodeU(char **ww)
{
struct growbuf gb;
growbuf_init(&gb);
decodeU_to_growbuf(&gb, ww);
return growbuf_to_Str(&gb);
}
void
decodeU_to_growbuf(struct growbuf *gb, char **ww)
{
unsigned char c1, c2;
char *w = *ww;
int n, i;
Str a;
if (*w <= 0x20 || *w >= 0x60)
return Strnew_size(0);
return;
n = *w - 0x20;
a = Strnew_size(n);
growbuf_reserve(gb, n + 1);
for (w++, i = 2; *w != '\0' && n; n--) {
c1 = (w[0] - 0x20) % 0x40;
c2 = (w[1] - 0x20) % 0x40;
Strcat_char(a, (c1 << i) | (c2 >> (6 - i)));
gb->ptr[gb->length++] = (c1 << i) | (c2 >> (6 - i));
if (i == 6) {
w += 2;
i = 2;
......@@ -135,7 +156,8 @@ decodeU(char **ww)
i += 2;
}
}
return a;
gb->ptr[gb->length] = '\0';
return;
}
/* RFC2047 (4.2. The "Q" encoding) */
......@@ -164,10 +186,20 @@ decodeQ(char **ww)
/* RFC2045 (6.7. Quoted-Printable Content-Transfer-Encoding) */
Str
decodeQP(char **ww)
{
struct growbuf gb;
growbuf_init(&gb);
decodeQP_to_growbuf(&gb, ww);
return growbuf_to_Str(&gb);
}
void
decodeQP_to_growbuf(struct growbuf *gb, char **ww)
{
char *w = *ww;
Str a = Strnew_size(strlen(w));
growbuf_reserve(gb, strlen(w) + 1);
for (; *w != '\0'; w++) {
if (*w == '=') {
w++;
......@@ -180,15 +212,16 @@ decodeQP(char **ww)
else {
if (*w == '\0' || *(w + 1) == '\0')
break;
Strcat_char(a, ha2d(*w, *(w + 1)));
gb->ptr[gb->length++] = ha2d(*w, *(w + 1));
w++;
}
}
else
Strcat_char(a, *w);
gb->ptr[gb->length++] = *w;
}
gb->ptr[gb->length] = '\0';
*ww = w;
return a;
return;
}
#ifdef USE_M17N
......
......@@ -607,9 +607,12 @@ extern char *getAnchorText(Buffer *buf, AnchorList *al, Anchor *a);
extern Buffer *link_list_panel(Buffer *buf);