/* Copyright 1990,91 GROUPE BULL -- See licence conditions in file COPYRIGHT */ /*****************************************************************************\ * data.c: * * * * XPM library * * IO utilities * * * * Developed by Arnaud Le Hors * \*****************************************************************************/ /* Official version number */ static char *RCS_Version = "$XpmVersion: 3.0 $"; /* Internal version number */ static char *RCS_Id = "$Id: xpm.shar,v 3.0 1991/10/04 10:38:20 lehors Exp $"; #include "xpmP.h" #ifdef VMS #include "sys$library:stat.h" #include "sys$library:ctype.h" #else #include #include #endif LFUNC(atoui, unsigned int, (char *p, unsigned int l, unsigned int *ui_return)); static unsigned int atoui(p, l, ui_return) register char *p; unsigned int l; unsigned int *ui_return; { register int n, i; n = 0; for (i = 0; i < l; i++) if (*p >= '0' && *p <= '9') n = n * 10 + *p++ - '0'; else break; if (i != 0 && i == l) { *ui_return = n; return 1; } else return 0; } /* * skip to the end of the current string and the beginning of the next one */ xpmNextString(mdata) xpmData *mdata; { int c; switch (mdata->type) { case XPMARRAY: mdata->cptr = (mdata->stream.data)[++mdata->line]; break; case XPMFILE: case XPMPIPE: if (mdata->Eos) while ((c = xpmGetC(mdata)) != mdata->Eos && c != EOF); if (mdata->Bos) /* if not natural XPM2 */ while ((c = xpmGetC(mdata)) != mdata->Bos && c != EOF); break; } } /* * skip whitespace and compute the following unsigned int, * returns 1 if one is found and 0 if not */ int xpmNextUI(mdata, ui_return) xpmData *mdata; unsigned int *ui_return; { char buf[BUFSIZ]; int l; l = xpmNextWord(mdata, buf); return atoui(buf, l, ui_return); } /* * return the current character, skipping comments */ xpmGetC(mdata) xpmData *mdata; { int c; register unsigned int n = 0, a; unsigned int notend; switch (mdata->type) { case XPMARRAY: return (*mdata->cptr++); case XPMFILE: case XPMPIPE: c = getc(mdata->stream.file); if (mdata->Bos && mdata->Eos && (c == mdata->Bos || c == mdata->Eos)) { /* if not natural XPM2 */ mdata->InsideString = !mdata->InsideString; return (c); } if (!mdata->InsideString && mdata->Bcmt && c == mdata->Bcmt[0]) { mdata->Comment[0] = c; /* * skip the string begining comment */ do { c = getc(mdata->stream.file); mdata->Comment[++n] = c; } while (c == mdata->Bcmt[n] && mdata->Bcmt[n] != '\0' && c != EOF); if (mdata->Bcmt[n] != '\0') { /* this wasn't the begining of a comment */ /* put characters back in the order that we got them */ for (a = n; a > 0; a--) xpmUngetC(mdata->Comment[a], mdata); return (mdata->Comment[0]); } /* * store comment */ mdata->Comment[0] = mdata->Comment[n]; notend = 1; n = 0; while (notend) { while (mdata->Comment[n] != mdata->Ecmt[0] && c != EOF) { c = getc(mdata->stream.file); mdata->Comment[++n] = c; } mdata->CommentLength = n; a = 0; do { c = getc(mdata->stream.file); n++; a++; mdata->Comment[n] = c; } while (c == mdata->Ecmt[a] && mdata->Ecmt[a] != '\0' && c != EOF); if (mdata->Ecmt[a] == '\0') { /* this is the end of the comment */ notend = 0; xpmUngetC(mdata->Comment[n], mdata); } } c = xpmGetC(mdata); } return (c); } } /* * push the given character back */ xpmUngetC(c, mdata) int c; xpmData *mdata; { switch (mdata->type) { case XPMARRAY: return (*--mdata->cptr = c); case XPMFILE: case XPMPIPE: if (mdata->Bos && (c == mdata->Bos || c == mdata->Eos)) /* if not natural XPM2 */ mdata->InsideString = !mdata->InsideString; return (ungetc(c, mdata->stream.file)); } } /* * skip whitespace and return the following word */ unsigned int xpmNextWord(mdata, buf) xpmData *mdata; char *buf; { register unsigned int n = 0; int c; switch (mdata->type) { case XPMARRAY: while (isspace(c = *mdata->cptr) && c != mdata->Eos) mdata->cptr++; do { c = *mdata->cptr++; buf[n++] = c; } while (!isspace(c) && c != mdata->Eos && c != '\0'); n--; mdata->cptr--; break; case XPMFILE: case XPMPIPE: while (isspace(c = xpmGetC(mdata)) && c != mdata->Eos); while (!isspace(c) && c != mdata->Eos && c != EOF) { buf[n++] = c; c = xpmGetC(mdata); } xpmUngetC(c, mdata); break; } return (n); } /* * get the current comment line */ xpmGetCmt(mdata, cmt) xpmData *mdata; char **cmt; { switch (mdata->type) { case XPMARRAY: *cmt = NULL; break; case XPMFILE: case XPMPIPE: if (mdata->CommentLength) { *cmt = (char *) malloc(mdata->CommentLength + 1); strncpy(*cmt, mdata->Comment, mdata->CommentLength); (*cmt)[mdata->CommentLength] = '\0'; mdata->CommentLength = 0; } else *cmt = NULL; break; } } /* * open the given file to be read as an xpmData which is returned. */ int xpmReadFile(filename, mdata) char *filename; xpmData *mdata; { char *compressfile, buf[BUFSIZ]; struct stat status; if (!filename) { mdata->stream.file = (stdin); mdata->type = XPMFILE; } else { #ifdef ZPIPE if ((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 (!(compressfile = (char *) malloc(strlen(filename) + 3))) 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"))) { free(compressfile); return (XpmOpenFailed); } mdata->type = XPMPIPE; } else { #endif if (!(mdata->stream.file = fopen(filename, "r"))) { #ifdef ZPIPE free(compressfile); #endif return (XpmOpenFailed); } mdata->type = XPMFILE; #ifdef ZPIPE } free(compressfile); } #endif } mdata->CommentLength = 0; mdata->InsideString = 0; return (XpmSuccess); } /* * open the given file to be written as an xpmData which is returned */ int xpmWriteFile(filename, mdata) char *filename; xpmData *mdata; { char buf[BUFSIZ]; if (!filename) { mdata->stream.file = (stdout); mdata->type = XPMFILE; } else { #ifdef ZPIPE if (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 { #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 */ int xpmOpenArray(data, mdata) 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->InsideString = 0; return (XpmSuccess); } /* * close the file related to the xpmData if any */ XpmDataClose(mdata) xpmData *mdata; { switch (mdata->type) { case XPMARRAY: break; case XPMFILE: if (mdata->stream.file != (stdout) && mdata->stream.file != (stdin)) fclose(mdata->stream.file); break; case XPMPIPE: pclose(mdata->stream.file); } }