]>
git.saurik.com Git - wxWidgets.git/blob - src/xpm/dataxpm.c
2 * Copyright (C) 1989-94 GROUPE BULL
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 * Except as contained in this notice, the name of GROUPE BULL shall not be
22 * used in advertising or otherwise to promote the sale, use or other dealings
23 * in this Software without prior written authorization from GROUPE BULL.
26 /*****************************************************************************\
32 * Developed by Arnaud Le Hors *
33 \*****************************************************************************/
35 /* Official version number */
36 static char *RCS_Version
= "$XpmVersion: 3.4b $";
38 /* Internal version number */
39 static char *RCS_Id
= "$Id$";
43 #include "sys$library:stat.h"
44 #include "sys$library:ctype.h"
46 #include <sys/types.h>
53 LFUNC(ParseComment
, int, (xpmData
* mdata
));
56 ParseComment(xpmData
*mdata
)
58 if (mdata
->type
== XPMBUFFER
) {
60 register unsigned int n
= 0;
67 /* skip the string beginning comment */
74 } while (c
== *s2
&& *s2
!= '\0' && c
&& c
!= mdata
->Bos
);
77 /* this wasn't the beginning of a comment */
82 mdata
->Comment
[0] = *s
;
88 while (*s
!= *s2
&& c
&& c
!= mdata
->Bos
) {
93 mdata
->CommentLength
= n
;
99 } while (c
== *s2
&& *s2
!= '\0' && c
&& c
!= mdata
->Bos
);
101 /* this is the end of the comment */
108 FILE *file
= mdata
->stream
.file
;
110 register unsigned int n
= 0, a
;
117 /* skip the string beginning comment */
124 } while (c
== *s2
&& *s2
!= '\0'
125 && c
!= EOF
&& c
!= mdata
->Bos
);
128 /* this wasn't the beginning of a comment */
129 /* put characters back in the order that we got them */
130 for (a
= n
; a
> 0; a
--, s
--)
135 mdata
->Comment
[0] = *s
;
141 while (*s
!= *s2
&& c
!= EOF
&& c
!= mdata
->Bos
) {
146 mdata
->CommentLength
= n
;
152 } while (c
== *s2
&& *s2
!= '\0'
153 && c
!= EOF
&& c
!= mdata
->Bos
);
155 /* this is the end of the comment */
165 * skip to the end of the current string and the beginning of the next one
168 xpmNextString(xpmData
*mdata
)
171 mdata
->cptr
= (mdata
->stream
.data
)[++mdata
->line
];
172 else if (mdata
->type
== XPMBUFFER
) {
175 /* get to the end of the current string */
177 while ((c
= *mdata
->cptr
++) && c
!= mdata
->Eos
);
180 * then get to the beginning of the next string looking for possible
184 while ((c
= *mdata
->cptr
++) && c
!= mdata
->Bos
)
185 if (mdata
->Bcmt
&& c
== mdata
->Bcmt
[0])
187 } else if (mdata
->Bcmt
) { /* XPM2 natural */
188 while ((c
= *mdata
->cptr
++) == mdata
->Bcmt
[0])
194 FILE *file
= mdata
->stream
.file
;
196 /* get to the end of the current string */
198 while ((c
= getc(file
)) != mdata
->Eos
&& c
!= EOF
);
201 * then get to the beginning of the next string looking for possible
205 while ((c
= getc(file
)) != mdata
->Bos
&& c
!= EOF
)
206 if (mdata
->Bcmt
&& c
== mdata
->Bcmt
[0])
209 } else if (mdata
->Bcmt
) { /* XPM2 natural */
210 while ((c
= getc(file
)) == mdata
->Bcmt
[0])
220 * skip whitespace and compute the following unsigned int,
221 * returns 1 if one is found and 0 if not
224 xpmNextUI(xpmData
*mdata
, unsigned int *ui_return
)
229 l
= xpmNextWord(mdata
, buf
, BUFSIZ
);
230 return atoui(buf
, l
, ui_return
);
234 * skip whitespace and return the following word
237 xpmNextWord(xpmData
*mdata
, char *buf
, unsigned int buflen
)
239 register unsigned int n
= 0;
242 if (!mdata
->type
|| mdata
->type
== XPMBUFFER
) {
243 while (isspace(c
= *mdata
->cptr
) && c
!= mdata
->Eos
)
249 } while (!isspace(c
) && c
!= mdata
->Eos
&& n
< buflen
);
253 FILE *file
= mdata
->stream
.file
;
255 while ((c
= getc(file
)) != EOF
&& isspace(c
) && c
!= mdata
->Eos
);
256 while (!isspace(c
) && c
!= mdata
->Eos
&& c
!= EOF
&& n
< buflen
) {
267 * return end of string - WARNING: malloc!
270 xpmGetString(xpmData
*mdata
, char **sptr
, unsigned int *l
)
272 unsigned int i
, n
= 0;
274 char *p
, *q
, buf
[BUFSIZ
];
276 if (!mdata
->type
|| mdata
->type
== XPMBUFFER
) {
280 while (isspace(c
= *mdata
->cptr
) && c
!= mdata
->Eos
)
283 while ((c
= *mdata
->cptr
) && c
!= mdata
->Eos
)
285 n
= mdata
->cptr
- start
+ 1;
286 p
= (char *) XpmMalloc(n
);
288 return (XpmNoMemory
);
289 strncpy(p
, start
, n
);
290 if (mdata
->type
) /* XPMBUFFER */
294 FILE *file
= mdata
->stream
.file
;
296 while ((c
= getc(file
)) != EOF
&& isspace(c
) && c
!= mdata
->Eos
);
298 return (XpmFileInvalid
);
302 p
= (char *) XpmMalloc(1);
303 while (c
!= mdata
->Eos
&& c
!= EOF
) {
305 /* get to the end of the buffer */
306 /* malloc needed memory */
307 q
= (char *) XpmRealloc(p
, n
+ i
);
310 return (XpmNoMemory
);
314 /* and copy what we already have */
326 return (XpmFileInvalid
);
329 /* malloc needed memory */
330 q
= (char *) XpmRealloc(p
, n
+ i
+ 1);
333 return (XpmNoMemory
);
337 /* and copy the buffer */
353 * get the current comment line
356 xpmGetCmt(xpmData
*mdata
, char **cmt
)
360 else if (mdata
->CommentLength
) {
361 *cmt
= (char *) XpmMalloc(mdata
->CommentLength
+ 1);
362 strncpy(*cmt
, mdata
->Comment
, mdata
->CommentLength
);
363 (*cmt
)[mdata
->CommentLength
] = '\0';
364 mdata
->CommentLength
= 0;
371 * open the given file to be read as an xpmData which is returned.
374 xpmReadFile(char *filename
, xpmData
*mdata
)
377 char *compressfile
, buf
[BUFSIZ
];
383 mdata
->stream
.file
= (stdin
);
384 mdata
->type
= XPMFILE
;
387 if (((int) strlen(filename
) > 2) &&
388 !strcmp(".Z", filename
+ (strlen(filename
) - 2))) {
389 mdata
->type
= XPMPIPE
;
390 sprintf(buf
, "uncompress -c %s", filename
);
391 if (!(mdata
->stream
.file
= popen(buf
, "r")))
392 return (XpmOpenFailed
);
394 } else if (((int) strlen(filename
) > 3) &&
395 !strcmp(".gz", filename
+ (strlen(filename
) - 3))) {
396 mdata
->type
= XPMPIPE
;
397 sprintf(buf
, "gunzip -qc %s", filename
);
398 if (!(mdata
->stream
.file
= popen(buf
, "r")))
399 return (XpmOpenFailed
);
402 if (!(compressfile
= (char *) XpmMalloc(strlen(filename
) + 4)))
403 return (XpmNoMemory
);
405 strcpy(compressfile
, filename
);
406 strcat(compressfile
, ".Z");
407 if (!stat(compressfile
, &status
)) {
408 sprintf(buf
, "uncompress -c %s", compressfile
);
409 if (!(mdata
->stream
.file
= popen(buf
, "r"))) {
410 XpmFree(compressfile
);
411 return (XpmOpenFailed
);
413 mdata
->type
= XPMPIPE
;
415 strcpy(compressfile
, filename
);
416 strcat(compressfile
, ".gz");
417 if (!stat(compressfile
, &status
)) {
418 sprintf(buf
, "gunzip -c %s", compressfile
);
419 if (!(mdata
->stream
.file
= popen(buf
, "r"))) {
420 XpmFree(compressfile
);
421 return (XpmOpenFailed
);
423 mdata
->type
= XPMPIPE
;
426 if (!(mdata
->stream
.file
= fopen(filename
, "r"))) {
428 XpmFree(compressfile
);
430 return (XpmOpenFailed
);
432 mdata
->type
= XPMFILE
;
436 XpmFree(compressfile
);
440 mdata
->CommentLength
= 0;
445 * open the given file to be written as an xpmData which is returned
448 xpmWriteFile(char *filename
, xpmData
*mdata
)
456 mdata
->stream
.file
= (stdout
);
457 mdata
->type
= XPMFILE
;
460 if ((int) strlen(filename
) > 2
461 && !strcmp(".Z", filename
+ (strlen(filename
) - 2))) {
462 sprintf(buf
, "compress > %s", filename
);
463 if (!(mdata
->stream
.file
= popen(buf
, "w")))
464 return (XpmOpenFailed
);
466 mdata
->type
= XPMPIPE
;
467 } else if ((int) strlen(filename
) > 3
468 && !strcmp(".gz", filename
+ (strlen(filename
) - 3))) {
469 sprintf(buf
, "gzip -q > %s", filename
);
470 if (!(mdata
->stream
.file
= popen(buf
, "w")))
471 return (XpmOpenFailed
);
473 mdata
->type
= XPMPIPE
;
476 if (!(mdata
->stream
.file
= fopen(filename
, "w")))
477 return (XpmOpenFailed
);
479 mdata
->type
= XPMFILE
;
488 * open the given array to be read or written as an xpmData which is returned
491 xpmOpenArray(char **data
, xpmData
*mdata
)
493 mdata
->type
= XPMARRAY
;
494 mdata
->stream
.data
= data
;
497 mdata
->CommentLength
= 0;
498 mdata
->Bcmt
= mdata
->Ecmt
= NULL
;
499 mdata
->Bos
= mdata
->Eos
= '\0';
500 mdata
->format
= 0; /* this can only be Xpm 2 or 3 */
504 * open the given buffer to be read or written as an xpmData which is returned
507 xpmOpenBuffer(char *buffer
, xpmData
*mdata
)
509 mdata
->type
= XPMBUFFER
;
510 mdata
->cptr
= buffer
;
511 mdata
->CommentLength
= 0;
515 * close the file related to the xpmData if any
518 xpmDataClose(xpmData
*mdata
)
520 switch (mdata
->type
) {
525 if (mdata
->stream
.file
!= (stdout
) && mdata
->stream
.file
!= (stdin
))
526 fclose(mdata
->stream
.file
);
530 pclose(mdata
->stream
.file
);
537 xpmDataType xpmDataTypes
[] =
539 "", "!", "\n", '\0', '\n', "", "", "", "", /* Natural type */
540 "C", "/*", "*/", '"', '"', ",\n", "static char *", "[] = {\n", "};\n",
541 "Lisp", ";", "\n", '"', '"', "\n", "(setq ", " '(\n", "))\n",
545 NULL
, NULL
, NULL
, 0, 0, NULL
, NULL
, NULL
, NULL
553 xpmParseHeader(xpmData
*mdata
)
561 mdata
->Bcmt
= mdata
->Ecmt
= NULL
;
562 l
= xpmNextWord(mdata
, buf
, BUFSIZ
);
563 if (l
== 7 && !strncmp("#define", buf
, 7)) {
564 /* this maybe an XPM 1 file */
567 l
= xpmNextWord(mdata
, buf
, BUFSIZ
);
569 return (XpmFileInvalid
);
570 ptr
= strchr(buf
, '_');
571 if (!ptr
|| strncmp("_format", ptr
, l
- (ptr
- buf
)))
572 return XpmFileInvalid
;
573 /* this is definitely an XPM 1 file */
575 n
= 1; /* handle XPM1 as mainly XPM2 C */
579 * skip the first word, get the second one, and see if this is
582 l
= xpmNextWord(mdata
, buf
, BUFSIZ
);
583 if ((l
== 3 && !strncmp("XPM", buf
, 3)) ||
584 (l
== 4 && !strncmp("XPM2", buf
, 4))) {
586 n
= 1; /* handle XPM as XPM2 C */
588 /* get the type key word */
589 l
= xpmNextWord(mdata
, buf
, BUFSIZ
);
592 * get infos about this type
594 while (xpmDataTypes
[n
].type
595 && strncmp(xpmDataTypes
[n
].type
, buf
, l
))
600 /* nope this is not an XPM file */
601 return XpmFileInvalid
;
603 if (xpmDataTypes
[n
].type
) {
604 if (n
== 0) { /* natural type */
605 mdata
->Bcmt
= xpmDataTypes
[n
].Bcmt
;
606 mdata
->Ecmt
= xpmDataTypes
[n
].Ecmt
;
607 xpmNextString(mdata
); /* skip the end of the headerline */
608 mdata
->Bos
= xpmDataTypes
[n
].Bos
;
609 mdata
->Eos
= xpmDataTypes
[n
].Eos
;
611 mdata
->Bcmt
= xpmDataTypes
[n
].Bcmt
;
612 mdata
->Ecmt
= xpmDataTypes
[n
].Ecmt
;
613 if (!mdata
->format
) { /* XPM 2 or 3 */
614 mdata
->Bos
= xpmDataTypes
[n
].Bos
;
616 /* get to the beginning of the first string */
617 xpmNextString(mdata
);
618 mdata
->Eos
= xpmDataTypes
[n
].Eos
;
619 } else /* XPM 1 skip end of line */
620 xpmNextString(mdata
);
623 /* we don't know about that type of XPM file... */
624 return XpmFileInvalid
;