#ifndef CXPMPROG
#if 0
static char *RCS_Version = "$XpmVersion: 3.4k $";
static char *RCS_Id = "Id: xpm.shar,v 3.71 1998/03/19 19:47:14 lehors Exp $";
#endif
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "XpmI.h"
#endif
#include <ctype.h>
#ifndef CXPMPROG
#define Getc(data, file) getc(file)
#define Ungetc(data, c, file) ungetc(c, file)
#endif
static int
ParseComment(xpmData *data)
{
if (data->type == XPMBUFFER) {
register char c;
register unsigned int n = 0;
unsigned int notend;
char *s, *s2;
s = data->Comment;
*s = data->Bcmt[0];
s2 = data->Bcmt;
do {
c = *data->cptr++;
*++s = c;
n++;
s2++;
} while (c == *s2 && *s2 != '\0' && c);
if (*s2 != '\0') {
data->cptr -= n;
return 0;
}
data->Comment[0] = *s;
s = data->Comment;
notend = 1;
n = 0;
while (notend) {
s2 = data->Ecmt;
while (*s != *s2 && c) {
c = *data->cptr++;
if (n == XPMMAXCMTLEN - 1) {
s = data->Comment;
n = 0;
}
*++s = c;
n++;
}
data->CommentLength = n;
do {
c = *data->cptr++;
if (n == XPMMAXCMTLEN - 1) {
s = data->Comment;
n = 0;
}
*++s = c;
n++;
s2++;
} while (c == *s2 && *s2 != '\0' && c);
if (*s2 == '\0') {
notend = 0;
data->cptr--;
}
}
return 0;
} else {
FILE *file = data->stream.file;
register int c;
register unsigned int n = 0, a;
unsigned int notend;
char *s, *s2;
s = data->Comment;
*s = data->Bcmt[0];
s2 = data->Bcmt;
do {
c = Getc(data, file);
*++s = c;
n++;
s2++;
} while (c == *s2 && *s2 != '\0' && c != EOF);
if (*s2 != '\0') {
for (a = n; a > 0; a--, s--)
Ungetc(data, *s, file);
return 0;
}
data->Comment[0] = *s;
s = data->Comment;
notend = 1;
n = 0;
while (notend) {
s2 = data->Ecmt;
while (*s != *s2 && c != EOF) {
c = Getc(data, file);
if (n == XPMMAXCMTLEN - 1) {
s = data->Comment;
n = 0;
}
*++s = c;
n++;
}
data->CommentLength = n;
do {
c = Getc(data, file);
if (n == XPMMAXCMTLEN - 1) {
s = data->Comment;
n = 0;
}
*++s = c;
n++;
s2++;
} while (c == *s2 && *s2 != '\0' && c != EOF);
if (*s2 == '\0') {
notend = 0;
Ungetc(data, *s, file);
}
}
return 0;
}
}
int
xpmNextString(data)
xpmData *data;
{
if (!data->type)
data->cptr = (data->stream.data)[++data->line];
else if (data->type == XPMBUFFER) {
register char c;
if (data->Eos)
while ((c = *data->cptr++) && c != data->Eos);
if (data->Bos) {
while ((c = *data->cptr++) && c != data->Bos)
if (data->Bcmt && c == data->Bcmt[0])
ParseComment(data);
} else if (data->Bcmt) {
while ((c = *data->cptr++) == data->Bcmt[0])
ParseComment(data);
data->cptr--;
}
} else {
register int c;
FILE *file = data->stream.file;
if (data->Eos)
while ((c = Getc(data, file)) != data->Eos && c != EOF);
if (data->Bos) {
while ((c = Getc(data, file)) != data->Bos && c != EOF)
if (data->Bcmt && c == data->Bcmt[0])
ParseComment(data);
} else if (data->Bcmt) {
while ((c = Getc(data, file)) == data->Bcmt[0])
ParseComment(data);
Ungetc(data, c, file);
}
}
return 0;
}
unsigned int
xpmNextWord(data, buf, buflen)
xpmData *data;
char *buf;
unsigned int buflen;
{
register unsigned int n = 0;
int c;
if (!data->type || data->type == XPMBUFFER) {
while (isspace(c = *data->cptr) && c != data->Eos)
data->cptr++;
do {
c = *data->cptr++;
*buf++ = c;
n++;
} while (!isspace(c) && c != data->Eos && n < buflen);
n--;
data->cptr--;
} else {
FILE *file = data->stream.file;
while ((c = Getc(data, file)) != EOF && isspace(c) && c != data->Eos);
while (!isspace(c) && c != data->Eos && c != EOF && n < buflen) {
*buf++ = c;
n++;
c = Getc(data, file);
}
Ungetc(data, c, file);
}
return (n);
}
int
xpmNextUI(data, ui_return)
xpmData *data;
unsigned int *ui_return;
{
char buf[BUFSIZ];
int l;
l = xpmNextWord(data, buf, BUFSIZ);
return xpmatoui(buf, l, ui_return);
}
int
xpmGetString(data, sptr, l)
xpmData *data;
char **sptr;
unsigned int *l;
{
unsigned int i, n = 0;
int c;
char *p = NULL, *q, buf[BUFSIZ];
if (!data->type || data->type == XPMBUFFER) {
if (data->cptr) {
char *start = data->cptr;
while ((c = *data->cptr) && c != data->Eos)
data->cptr++;
n = data->cptr - start + 1;
p = (char *) XpmMalloc(n);
if (!p)
return (XpmNoMemory);
strncpy(p, start, n);
if (data->type)
p[n - 1] = '\0';
}
} else {
FILE *file = data->stream.file;
if ((c = Getc(data, file)) == EOF)
return (XpmFileInvalid);
i = 0;
q = buf;
p = (char *) XpmMalloc(1);
while (c != data->Eos && c != EOF) {
if (i == BUFSIZ) {
q = (char *) XpmRealloc(p, n + i);
if (!q) {
XpmFree(p);
return (XpmNoMemory);
}
p = q;
q += n;
strncpy(q, buf, i);
n += i;
i = 0;
q = buf;
}
*q++ = c;
i++;
c = Getc(data, file);
}
if (c == EOF) {
XpmFree(p);
return (XpmFileInvalid);
}
if (n + i != 0) {
q = (char *) XpmRealloc(p, n + i + 1);
if (!q) {
XpmFree(p);
return (XpmNoMemory);
}
p = q;
q += n;
strncpy(q, buf, i);
n += i;
p[n++] = '\0';
} else {
*p = '\0';
n = 1;
}
Ungetc(data, c, file);
}
*sptr = p;
*l = n;
return (XpmSuccess);
}
int
xpmGetCmt(data, cmt)
xpmData *data;
char **cmt;
{
if (!data->type)
*cmt = NULL;
else if (data->CommentLength != 0 && data->CommentLength < UINT_MAX - 1) {
if( (*cmt = (char *) XpmMalloc(data->CommentLength + 1)) == NULL)
return XpmNoMemory;
strncpy(*cmt, data->Comment, data->CommentLength);
(*cmt)[data->CommentLength] = '\0';
data->CommentLength = 0;
} else
*cmt = NULL;
return 0;
}
xpmDataType xpmDataTypes[] =
{
{"", "!", "\n", '\0', '\n', "", "", "", ""},
{"C", "/*", "*/", '"', '"', ",\n", "static char *", "[] = {\n", "};\n"},
{"Lisp", ";", "\n", '"', '"', "\n", "(setq ", " '(\n", "))\n"},
{NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL}
};
int
xpmParseHeader(data)
xpmData *data;
{
char buf[BUFSIZ+1] = {0};
int l, n = 0;
if (data->type) {
data->Bos = '\0';
data->Eos = '\n';
data->Bcmt = data->Ecmt = NULL;
l = xpmNextWord(data, buf, BUFSIZ);
if (l == 7 && !strncmp("#define", buf, 7)) {
char *ptr;
l = xpmNextWord(data, buf, BUFSIZ);
if (!l)
return (XpmFileInvalid);
buf[l] = '\0';
ptr = strrchr(buf, '_');
if (!ptr || strncmp("_format", ptr, l - (ptr - buf)))
return XpmFileInvalid;
data->format = 1;
n = 1;
} else {
l = xpmNextWord(data, buf, BUFSIZ);
if ((l == 3 && !strncmp("XPM", buf, 3)) ||
(l == 4 && !strncmp("XPM2", buf, 4))) {
if (l == 3)
n = 1;
else {
l = xpmNextWord(data, buf, BUFSIZ);
while (xpmDataTypes[n].type
&& strncmp(xpmDataTypes[n].type, buf, l))
n++;
}
data->format = 0;
} else
return XpmFileInvalid;
}
if (xpmDataTypes[n].type) {
if (n == 0) {
data->Bcmt = xpmDataTypes[n].Bcmt;
data->Ecmt = xpmDataTypes[n].Ecmt;
xpmNextString(data);
data->Bos = xpmDataTypes[n].Bos;
data->Eos = xpmDataTypes[n].Eos;
} else {
data->Bcmt = xpmDataTypes[n].Bcmt;
data->Ecmt = xpmDataTypes[n].Ecmt;
if (!data->format) {
data->Bos = xpmDataTypes[n].Bos;
data->Eos = '\0';
xpmNextString(data);
data->Eos = xpmDataTypes[n].Eos;
} else
xpmNextString(data);
}
} else
return XpmFileInvalid;
}
return XpmSuccess;
}