]> git.saurik.com Git - wxWidgets.git/blobdiff - src/xpm/dataxpm.c
added wxListView class: this is going to be a wxListCtrl with human (inter)face
[wxWidgets.git] / src / xpm / dataxpm.c
index 247f8aaa09a772758c1d04da7213f9ecc640dfaa..917614e4be29e400eda483546d6d98d1830c2934 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 1989-94 GROUPE BULL
+ * Copyright (C) 1989-95 GROUPE BULL
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
 *  Developed by Arnaud Le Hors                                                *
 \*****************************************************************************/
 
 *  Developed by Arnaud Le Hors                                                *
 \*****************************************************************************/
 
+#ifndef CXPMPROG
 /* Official version number */
 /* Official version number */
-static char *RCS_Version = "$XpmVersion: 3.4b $";
+static char *RCS_Version = "$XpmVersion: 3.4k $";
 
 /* Internal version number */
 static char *RCS_Id = "$Id$";
 
 
 /* Internal version number */
 static char *RCS_Id = "$Id$";
 
-#include "xpm34p.h"
-#ifdef VMS
-#include "sys$library:stat.h"
-#include "sys$library:ctype.h"
-#else
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <ctype.h>
+#include "XpmI.h"
 #endif
 #endif
+#include <ctype.h>
 
 
-#include <string.h>
-
-LFUNC(ParseComment, int, (xpmData * mdata));
+#ifndef CXPMPROG
+#define Getc(data, file) getc(file)
+#define Ungetc(data, c, file) ungetc(c, file)
+#endif
 
 static int
 
 static int
-ParseComment(xpmData *mdata)
+ParseComment(data)
+    xpmData *data;
 {
 {
-    if (mdata->type == XPMBUFFER) {
+    if (data->type == XPMBUFFER) {
        register char c;
        register unsigned int n = 0;
        unsigned int notend;
        char *s, *s2;
 
        register char c;
        register unsigned int n = 0;
        unsigned int notend;
        char *s, *s2;
 
-       s = mdata->Comment;
-       *s = mdata->Bcmt[0];
+       s = data->Comment;
+       *s = data->Bcmt[0];
 
        /* skip the string beginning comment */
 
        /* skip the string beginning comment */
-       s2 = mdata->Bcmt;
+       s2 = data->Bcmt;
        do {
        do {
-           c = *mdata->cptr++;
+           c = *data->cptr++;
            *++s = c;
            n++;
            s2++;
            *++s = c;
            n++;
            s2++;
-       } while (c == *s2 && *s2 != '\0' && c && c != mdata->Bos);
+       } while (c == *s2 && *s2 != '\0' && c);
 
        if (*s2 != '\0') {
            /* this wasn't the beginning of a comment */
 
        if (*s2 != '\0') {
            /* this wasn't the beginning of a comment */
-           mdata->cptr -= n;
+           data->cptr -= n;
            return 0;
        }
        /* store comment */
            return 0;
        }
        /* store comment */
-       mdata->Comment[0] = *s;
-       s = mdata->Comment;
+       data->Comment[0] = *s;
+       s = data->Comment;
        notend = 1;
        n = 0;
        while (notend) {
        notend = 1;
        n = 0;
        while (notend) {
-           s2 = mdata->Ecmt;
-           while (*s != *s2 && c && c != mdata->Bos) {
-               c = *mdata->cptr++;
+           s2 = data->Ecmt;
+           while (*s != *s2 && c) {
+               c = *data->cptr++;
+               if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+                   s = data->Comment;
+                   n = 0;
+               }
                *++s = c;
                n++;
            }
                *++s = c;
                n++;
            }
-           mdata->CommentLength = n;
+           data->CommentLength = n;
            do {
            do {
-               c = *mdata->cptr++;
-               n++;
+               c = *data->cptr++;
+               if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+                   s = data->Comment;
+                   n = 0;
+               }
                *++s = c;
                *++s = c;
+               n++;
                s2++;
                s2++;
-           } while (c == *s2 && *s2 != '\0' && c && c != mdata->Bos);
+           } while (c == *s2 && *s2 != '\0' && c);
            if (*s2 == '\0') {
                /* this is the end of the comment */
                notend = 0;
            if (*s2 == '\0') {
                /* this is the end of the comment */
                notend = 0;
-               mdata->cptr--;
+               data->cptr--;
            }
        }
        return 0;
     } else {
            }
        }
        return 0;
     } else {
-       FILE *file = mdata->stream.file;
+       FILE *file = data->stream.file;
        register int c;
        register unsigned int n = 0, a;
        unsigned int notend;
        char *s, *s2;
 
        register int c;
        register unsigned int n = 0, a;
        unsigned int notend;
        char *s, *s2;
 
-       s = mdata->Comment;
-       *s = mdata->Bcmt[0];
+       s = data->Comment;
+       *s = data->Bcmt[0];
 
        /* skip the string beginning comment */
 
        /* skip the string beginning comment */
-       s2 = mdata->Bcmt;
+       s2 = data->Bcmt;
        do {
        do {
-           c = getc(file);
+           c = Getc(data, file);
            *++s = c;
            n++;
            s2++;
            *++s = c;
            n++;
            s2++;
-       } while (c == *s2 && *s2 != '\0'
-                && c != EOF && c != mdata->Bos);
+       } while (c == *s2 && *s2 != '\0' && c != EOF);
 
        if (*s2 != '\0') {
            /* this wasn't the beginning of a comment */
            /* put characters back in the order that we got them */
            for (a = n; a > 0; a--, s--)
 
        if (*s2 != '\0') {
            /* this wasn't the beginning of a comment */
            /* put characters back in the order that we got them */
            for (a = n; a > 0; a--, s--)
-               ungetc(*s, file);
+               Ungetc(data, *s, file);
            return 0;
        }
        /* store comment */
            return 0;
        }
        /* store comment */
-       mdata->Comment[0] = *s;
-       s = mdata->Comment;
+       data->Comment[0] = *s;
+       s = data->Comment;
        notend = 1;
        n = 0;
        while (notend) {
        notend = 1;
        n = 0;
        while (notend) {
-           s2 = mdata->Ecmt;
-           while (*s != *s2 && c != EOF && c != mdata->Bos) {
-               c = getc(file);
+           s2 = data->Ecmt;
+           while (*s != *s2 && c != EOF) {
+               c = Getc(data, file);
+               if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+                   s = data->Comment;
+                   n = 0;
+               }
                *++s = c;
                n++;
            }
                *++s = c;
                n++;
            }
-           mdata->CommentLength = n;
+           data->CommentLength = n;
            do {
            do {
-               c = getc(file);
-               n++;
+               c = Getc(data, file);
+               if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+                   s = data->Comment;
+                   n = 0;
+               }
                *++s = c;
                *++s = c;
+               n++;
                s2++;
                s2++;
-           } while (c == *s2 && *s2 != '\0'
-                    && c != EOF && c != mdata->Bos);
+           } while (c == *s2 && *s2 != '\0' && c != EOF);
            if (*s2 == '\0') {
                /* this is the end of the comment */
                notend = 0;
            if (*s2 == '\0') {
                /* this is the end of the comment */
                notend = 0;
-               ungetc(*s, file);
+               Ungetc(data, *s, file);
            }
        }
        return 0;
            }
        }
        return 0;
@@ -165,142 +176,146 @@ ParseComment(xpmData *mdata)
  * skip to the end of the current string and the beginning of the next one
  */
 int
  * skip to the end of the current string and the beginning of the next one
  */
 int
-xpmNextString(xpmData *mdata)
+xpmNextString(data)
+    xpmData *data;
 {
 {
-    if (!mdata->type)
-       mdata->cptr = (mdata->stream.data)[++mdata->line];
-    else if (mdata->type == XPMBUFFER) {
+    if (!data->type)
+       data->cptr = (data->stream.data)[++data->line];
+    else if (data->type == XPMBUFFER) {
        register char c;
 
        /* get to the end of the current string */
        register char c;
 
        /* get to the end of the current string */
-       if (mdata->Eos)
-           while ((c = *mdata->cptr++) && c != mdata->Eos);
+       if (data->Eos)
+           while ((c = *data->cptr++) && c != data->Eos);
 
        /*
         * then get to the beginning of the next string looking for possible
         * comment
         */
 
        /*
         * then get to the beginning of the next string looking for possible
         * comment
         */
-       if (mdata->Bos) {
-           while ((c = *mdata->cptr++) && c != mdata->Bos)
-               if (mdata->Bcmt && c == mdata->Bcmt[0])
-                   ParseComment(mdata);
-       } else if (mdata->Bcmt) {       /* XPM2 natural */
-           while ((c = *mdata->cptr++) == mdata->Bcmt[0])
-               ParseComment(mdata);
-           mdata->cptr--;
+       if (data->Bos) {
+           while ((c = *data->cptr++) && c != data->Bos)
+               if (data->Bcmt && c == data->Bcmt[0])
+                   ParseComment(data);
+       } else if (data->Bcmt) {        /* XPM2 natural */
+           while ((c = *data->cptr++) == data->Bcmt[0])
+               ParseComment(data);
+           data->cptr--;
        }
     } else {
        register int c;
        }
     } else {
        register int c;
-       FILE *file = mdata->stream.file;
+       FILE *file = data->stream.file;
 
        /* get to the end of the current string */
 
        /* get to the end of the current string */
-       if (mdata->Eos)
-           while ((c = getc(file)) != mdata->Eos && c != EOF);
+       if (data->Eos)
+           while ((c = Getc(data, file)) != data->Eos && c != EOF);
 
        /*
         * then get to the beginning of the next string looking for possible
         * comment
         */
 
        /*
         * then get to the beginning of the next string looking for possible
         * comment
         */
-       if (mdata->Bos) {
-           while ((c = getc(file)) != mdata->Bos && c != EOF)
-               if (mdata->Bcmt && c == mdata->Bcmt[0])
-                   ParseComment(mdata);
-
-       } else if (mdata->Bcmt) {       /* XPM2 natural */
-           while ((c = getc(file)) == mdata->Bcmt[0])
-               ParseComment(mdata);
-           ungetc(c, file);
+       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) {        /* XPM2 natural */
+           while ((c = Getc(data, file)) == data->Bcmt[0])
+               ParseComment(data);
+           Ungetc(data, c, file);
        }
     }
     return 0;
 }
 
 
        }
     }
     return 0;
 }
 
 
-/*
- * skip whitespace and compute the following unsigned int,
- * returns 1 if one is found and 0 if not
- */
-int
-xpmNextUI(xpmData *mdata, unsigned int *ui_return)
-{
-    char buf[BUFSIZ];
-    int l;
-
-    l = xpmNextWord(mdata, buf, BUFSIZ);
-    return atoui(buf, l, ui_return);
-}
-
 /*
  * skip whitespace and return the following word
  */
 unsigned int
 /*
  * skip whitespace and return the following word
  */
 unsigned int
-xpmNextWord(xpmData *mdata, char *buf, unsigned int buflen)
+xpmNextWord(data, buf, buflen)
+    xpmData *data;
+    char *buf;
+    unsigned int buflen;
 {
     register unsigned int n = 0;
     int c;
 
 {
     register unsigned int n = 0;
     int c;
 
-    if (!mdata->type || mdata->type == XPMBUFFER) {
-       while (isspace(c = *mdata->cptr) && c != mdata->Eos)
-           mdata->cptr++;
+    if (!data->type || data->type == XPMBUFFER) {
+       while (isspace(c = *data->cptr) && c != data->Eos)
+           data->cptr++;
        do {
        do {
-           c = *mdata->cptr++;
+           c = *data->cptr++;
            *buf++ = c;
            n++;
            *buf++ = c;
            n++;
-       } while (!isspace(c) && c != mdata->Eos && n < buflen);
+       } while (!isspace(c) && c != data->Eos && n < buflen);
        n--;
        n--;
-       mdata->cptr--;
+       data->cptr--;
     } else {
     } else {
-       FILE *file = mdata->stream.file;
+       FILE *file = data->stream.file;
 
 
-       while ((c = getc(file)) != EOF && isspace(c) && c != mdata->Eos);
-       while (!isspace(c) && c != mdata->Eos && c != EOF && n < buflen) {
+       while ((c = Getc(data, file)) != EOF && isspace(c) && c != data->Eos);
+       while (!isspace(c) && c != data->Eos && c != EOF && n < buflen) {
            *buf++ = c;
            n++;
            *buf++ = c;
            n++;
-           c = getc(file);
+           c = Getc(data, file);
        }
        }
-       ungetc(c, file);
+       Ungetc(data, c, file);
     }
     return (n);
 }
 
     }
     return (n);
 }
 
+/*
+ * skip whitespace and compute the following unsigned int,
+ * returns 1 if one is found and 0 if not
+ */
+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);
+}
+
 /*
  * return end of string - WARNING: malloc!
  */
 int
 /*
  * return end of string - WARNING: malloc!
  */
 int
-xpmGetString(xpmData *mdata, char **sptr, unsigned int *l)
+xpmGetString(data, sptr, l)
+    xpmData *data;
+    char **sptr;
+    unsigned int *l;
 {
     unsigned int i, n = 0;
     int c;
 {
     unsigned int i, n = 0;
     int c;
-    char *p, *q, buf[BUFSIZ];
-
-    if (!mdata->type || mdata->type == XPMBUFFER) {
-       if (mdata->cptr) {
-           char *start;
-
-           while (isspace(c = *mdata->cptr) && c != mdata->Eos)
-               mdata->cptr++;
-           start = mdata->cptr;
-           while ((c = *mdata->cptr) && c != mdata->Eos)
-               mdata->cptr++;
-           n = mdata->cptr - start + 1;
+    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);
            p = (char *) XpmMalloc(n);
            if (!p)
                return (XpmNoMemory);
            strncpy(p, start, n);
-           if (mdata->type)            /* XPMBUFFER */
+           if (data->type)             /* XPMBUFFER */
                p[n - 1] = '\0';
        }
     } else {
                p[n - 1] = '\0';
        }
     } else {
-       FILE *file = mdata->stream.file;
+       FILE *file = data->stream.file;
 
 
-       while ((c = getc(file)) != EOF && isspace(c) && c != mdata->Eos);
-       if (c == EOF)
+       if ((c = Getc(data, file)) == EOF)
            return (XpmFileInvalid);
            return (XpmFileInvalid);
-       p = NULL;
+
        i = 0;
        q = buf;
        p = (char *) XpmMalloc(1);
        i = 0;
        q = buf;
        p = (char *) XpmMalloc(1);
-       while (c != mdata->Eos && c != EOF) {
+       while (c != data->Eos && c != EOF) {
            if (i == BUFSIZ) {
                /* get to the end of the buffer */
                /* malloc needed memory */
            if (i == BUFSIZ) {
                /* get to the end of the buffer */
                /* malloc needed memory */
@@ -319,7 +334,7 @@ xpmGetString(xpmData *mdata, char **sptr, unsigned int *l)
            }
            *q++ = c;
            i++;
            }
            *q++ = c;
            i++;
-           c = getc(file);
+           c = Getc(data, file);
        }
        if (c == EOF) {
            XpmFree(p);
        }
        if (c == EOF) {
            XpmFree(p);
@@ -342,7 +357,7 @@ xpmGetString(xpmData *mdata, char **sptr, unsigned int *l)
            *p = '\0';
            n = 1;
        }
            *p = '\0';
            n = 1;
        }
-       ungetc(c, file);
+       Ungetc(data, c, file);
     }
     *sptr = p;
     *l = n;
     }
     *sptr = p;
     *l = n;
@@ -353,187 +368,22 @@ xpmGetString(xpmData *mdata, char **sptr, unsigned int *l)
  * get the current comment line
  */
 int
  * get the current comment line
  */
 int
-xpmGetCmt(xpmData *mdata, char **cmt)
+xpmGetCmt(data, cmt)
+    xpmData *data;
+    char **cmt;
 {
 {
-    if (!mdata->type)
+    if (!data->type)
        *cmt = NULL;
        *cmt = NULL;
-    else if (mdata->CommentLength) {
-       *cmt = (char *) XpmMalloc(mdata->CommentLength + 1);
-       strncpy(*cmt, mdata->Comment, mdata->CommentLength);
-       (*cmt)[mdata->CommentLength] = '\0';
-       mdata->CommentLength = 0;
+    else if (data->CommentLength) {
+       *cmt = (char *) XpmMalloc(data->CommentLength + 1);
+       strncpy(*cmt, data->Comment, data->CommentLength);
+       (*cmt)[data->CommentLength] = '\0';
+       data->CommentLength = 0;
     } else
        *cmt = NULL;
     return 0;
 }
 
     } else
        *cmt = NULL;
     return 0;
 }
 
-/*
- * open the given file to be read as an xpmData which is returned.
- */
-int
-xpmReadFile(char *filename, xpmData *mdata)
-{
-#ifdef ZPIPE
-    char *compressfile, buf[BUFSIZ];
-    struct stat status;
-
-#endif
-
-    if (!filename) {
-       mdata->stream.file = (stdin);
-       mdata->type = XPMFILE;
-    } else {
-#ifdef ZPIPE
-       if (((int) strlen(filename) > 2) &&
-           !strcmp(".Z", filename + (strlen(filename) - 2))) {
-           mdata->type = XPMPIPE;
-           sprintf(buf, "uncompress -c %s", filename);
-           if (!(mdata->stream.file = popen(buf, "r")))
-               return (XpmOpenFailed);
-
-       } else if (((int) strlen(filename) > 3) &&
-                  !strcmp(".gz", filename + (strlen(filename) - 3))) {
-           mdata->type = XPMPIPE;
-           sprintf(buf, "gunzip -qc %s", filename);
-           if (!(mdata->stream.file = popen(buf, "r")))
-               return (XpmOpenFailed);
-
-       } else {
-           if (!(compressfile = (char *) XpmMalloc(strlen(filename) + 4)))
-               return (XpmNoMemory);
-
-           strcpy(compressfile, filename);
-           strcat(compressfile, ".Z");
-           if (!stat(compressfile, &status)) {
-               sprintf(buf, "uncompress -c %s", compressfile);
-               if (!(mdata->stream.file = popen(buf, "r"))) {
-                   XpmFree(compressfile);
-                   return (XpmOpenFailed);
-               }
-               mdata->type = XPMPIPE;
-           } else {
-               strcpy(compressfile, filename);
-               strcat(compressfile, ".gz");
-               if (!stat(compressfile, &status)) {
-                   sprintf(buf, "gunzip -c %s", compressfile);
-                   if (!(mdata->stream.file = popen(buf, "r"))) {
-                       XpmFree(compressfile);
-                       return (XpmOpenFailed);
-                   }
-                   mdata->type = XPMPIPE;
-               } else {
-#endif
-                   if (!(mdata->stream.file = fopen(filename, "r"))) {
-#ifdef ZPIPE
-                       XpmFree(compressfile);
-#endif
-                       return (XpmOpenFailed);
-                   }
-                   mdata->type = XPMFILE;
-#ifdef ZPIPE
-               }
-           }
-           XpmFree(compressfile);
-       }
-#endif
-    }
-    mdata->CommentLength = 0;
-    return (XpmSuccess);
-}
-
-/*
- * open the given file to be written as an xpmData which is returned
- */
-int
-xpmWriteFile(char *filename, xpmData *mdata)
-{
-#ifdef ZPIPE
-    char buf[BUFSIZ];
-
-#endif
-
-    if (!filename) {
-       mdata->stream.file = (stdout);
-       mdata->type = XPMFILE;
-    } else {
-#ifdef ZPIPE
-       if ((int) strlen(filename) > 2
-           && !strcmp(".Z", filename + (strlen(filename) - 2))) {
-           sprintf(buf, "compress > %s", filename);
-           if (!(mdata->stream.file = popen(buf, "w")))
-               return (XpmOpenFailed);
-
-           mdata->type = XPMPIPE;
-       } else if ((int) strlen(filename) > 3
-                  && !strcmp(".gz", filename + (strlen(filename) - 3))) {
-           sprintf(buf, "gzip -q > %s", filename);
-           if (!(mdata->stream.file = popen(buf, "w")))
-               return (XpmOpenFailed);
-
-           mdata->type = XPMPIPE;
-       } else {
-#endif
-           if (!(mdata->stream.file = fopen(filename, "w")))
-               return (XpmOpenFailed);
-
-           mdata->type = XPMFILE;
-#ifdef ZPIPE
-       }
-#endif
-    }
-    return (XpmSuccess);
-}
-
-/*
- * open the given array to be read or written as an xpmData which is returned
- */
-void
-xpmOpenArray(char **data, xpmData *mdata)
-{
-    mdata->type = XPMARRAY;
-    mdata->stream.data = data;
-    mdata->cptr = *data;
-    mdata->line = 0;
-    mdata->CommentLength = 0;
-    mdata->Bcmt = mdata->Ecmt = NULL;
-    mdata->Bos = mdata->Eos = '\0';
-    mdata->format = 0;                 /* this can only be Xpm 2 or 3 */
-}
-
-/*
- * open the given buffer to be read or written as an xpmData which is returned
- */
-void
-xpmOpenBuffer(char *buffer, xpmData *mdata)
-{
-    mdata->type = XPMBUFFER;
-    mdata->cptr = buffer;
-    mdata->CommentLength = 0;
-}
-
-/*
- * close the file related to the xpmData if any
- */
-int
-xpmDataClose(xpmData *mdata)
-{
-    switch (mdata->type) {
-    case XPMARRAY:
-    case XPMBUFFER:
-       break;
-    case XPMFILE:
-       if (mdata->stream.file != (stdout) && mdata->stream.file != (stdin))
-           fclose(mdata->stream.file);
-       break;
-#ifdef ZPIPE
-    case XPMPIPE:
-       pclose(mdata->stream.file);
-       break;
-#endif
-    }
-    return 0;
-}
-
 xpmDataType xpmDataTypes[] =
 {
     "", "!", "\n", '\0', '\n', "", "", "", "", /* Natural type */
 xpmDataType xpmDataTypes[] =
 {
     "", "!", "\n", '\0', '\n', "", "", "", "", /* Natural type */
@@ -550,28 +400,30 @@ xpmDataType xpmDataTypes[] =
  * parse xpm header
  */
 int
  * parse xpm header
  */
 int
-xpmParseHeader(xpmData *mdata)
+xpmParseHeader(data)
+    xpmData *data;
 {
     char buf[BUFSIZ];
     int l, n = 0;
 
 {
     char buf[BUFSIZ];
     int l, n = 0;
 
-    if (mdata->type) {
-       mdata->Bos = '\0';
-       mdata->Eos = '\n';
-       mdata->Bcmt = mdata->Ecmt = NULL;
-       l = xpmNextWord(mdata, buf, BUFSIZ);
+    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)) {
            /* this maybe an XPM 1 file */
            char *ptr;
 
        if (l == 7 && !strncmp("#define", buf, 7)) {
            /* this maybe an XPM 1 file */
            char *ptr;
 
-           l = xpmNextWord(mdata, buf, BUFSIZ);
+           l = xpmNextWord(data, buf, BUFSIZ);
            if (!l)
                return (XpmFileInvalid);
            if (!l)
                return (XpmFileInvalid);
-           ptr = strchr(buf, '_');
+           buf[l] = '\0';
+           ptr = rindex(buf, '_');
            if (!ptr || strncmp("_format", ptr, l - (ptr - buf)))
                return XpmFileInvalid;
            /* this is definitely an XPM 1 file */
            if (!ptr || strncmp("_format", ptr, l - (ptr - buf)))
                return XpmFileInvalid;
            /* this is definitely an XPM 1 file */
-           mdata->format = 1;
+           data->format = 1;
            n = 1;                      /* handle XPM1 as mainly XPM2 C */
        } else {
 
            n = 1;                      /* handle XPM1 as mainly XPM2 C */
        } else {
 
@@ -579,14 +431,14 @@ xpmParseHeader(xpmData *mdata)
             * skip the first word, get the second one, and see if this is
             * XPM 2 or 3
             */
             * skip the first word, get the second one, and see if this is
             * XPM 2 or 3
             */
-           l = xpmNextWord(mdata, buf, BUFSIZ);
+           l = xpmNextWord(data, buf, BUFSIZ);
            if ((l == 3 && !strncmp("XPM", buf, 3)) ||
                (l == 4 && !strncmp("XPM2", buf, 4))) {
                if (l == 3)
                    n = 1;              /* handle XPM as XPM2 C */
                else {
                    /* get the type key word */
            if ((l == 3 && !strncmp("XPM", buf, 3)) ||
                (l == 4 && !strncmp("XPM2", buf, 4))) {
                if (l == 3)
                    n = 1;              /* handle XPM as XPM2 C */
                else {
                    /* get the type key word */
-                   l = xpmNextWord(mdata, buf, BUFSIZ);
+                   l = xpmNextWord(data, buf, BUFSIZ);
 
                    /*
                     * get infos about this type
 
                    /*
                     * get infos about this type
@@ -595,29 +447,29 @@ xpmParseHeader(xpmData *mdata)
                           && strncmp(xpmDataTypes[n].type, buf, l))
                        n++;
                }
                           && strncmp(xpmDataTypes[n].type, buf, l))
                        n++;
                }
-               mdata->format = 0;
+               data->format = 0;
            } else
                /* nope this is not an XPM file */
                return XpmFileInvalid;
        }
        if (xpmDataTypes[n].type) {
            if (n == 0) {               /* natural type */
            } else
                /* nope this is not an XPM file */
                return XpmFileInvalid;
        }
        if (xpmDataTypes[n].type) {
            if (n == 0) {               /* natural type */
-               mdata->Bcmt = xpmDataTypes[n].Bcmt;
-               mdata->Ecmt = xpmDataTypes[n].Ecmt;
-               xpmNextString(mdata);   /* skip the end of the headerline */
-               mdata->Bos = xpmDataTypes[n].Bos;
-               mdata->Eos = xpmDataTypes[n].Eos;
+               data->Bcmt = xpmDataTypes[n].Bcmt;
+               data->Ecmt = xpmDataTypes[n].Ecmt;
+               xpmNextString(data);    /* skip the end of the headerline */
+               data->Bos = xpmDataTypes[n].Bos;
+               data->Eos = xpmDataTypes[n].Eos;
            } else {
            } else {
-               mdata->Bcmt = xpmDataTypes[n].Bcmt;
-               mdata->Ecmt = xpmDataTypes[n].Ecmt;
-               if (!mdata->format) {   /* XPM 2 or 3 */
-                   mdata->Bos = xpmDataTypes[n].Bos;
-                   mdata->Eos = '\0';
+               data->Bcmt = xpmDataTypes[n].Bcmt;
+               data->Ecmt = xpmDataTypes[n].Ecmt;
+               if (!data->format) {    /* XPM 2 or 3 */
+                   data->Bos = xpmDataTypes[n].Bos;
+                   data->Eos = '\0';
                    /* get to the beginning of the first string */
                    /* get to the beginning of the first string */
-                   xpmNextString(mdata);
-                   mdata->Eos = xpmDataTypes[n].Eos;
+                   xpmNextString(data);
+                   data->Eos = xpmDataTypes[n].Eos;
                } else                  /* XPM 1 skip end of line */
                } else                  /* XPM 1 skip end of line */
-                   xpmNextString(mdata);
+                   xpmNextString(data);
            }
        } else
            /* we don't know about that type of XPM file... */
            }
        } else
            /* we don't know about that type of XPM file... */