home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
vsiftp.vmssoftware.com
/
VSIPUBLIC@vsiftp.vmssoftware.com.tar
/
FREEWARE
/
FREEWARE40.ZIP
/
xpaint-247
/
readrc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-03
|
16KB
|
425 lines
/* +-------------------------------------------------------------------+ */
/* | Copyright 1993, David Koblas (koblas@netcom.com) | */
/* | Copyright 1995, 1996 Torsten Martinsen (bullestock@dk-online.dk) | */
/* | | */
/* | Permission to use, copy, modify, and to distribute this software | */
/* | and its documentation for any purpose is hereby granted without | */
/* | fee, provided that the above copyright notice appear in all | */
/* | copies and that both that copyright notice and this permission | */
/* | notice appear in supporting documentation. There is no | */
/* | representations about the suitability of this software for | */
/* | any purpose. this software is provided "as is" without express | */
/* | or implied warranty. | */
/* | | */
/* +-------------------------------------------------------------------+ */
/* $Id: readRC.c,v 1.4 1996/06/03 05:28:19 torsten Exp $ */
#include <stdio.h>
#include <pwd.h>
#include <ctype.h>
#include <X11/Intrinsic.h>
#include <X11/Xos.h>
#include <sys/stat.h>
#include "image.h"
#include "rc.h"
#include "misc.h"
#ifndef NOSTDHDRS
#include <stdlib.h>
#include <unistd.h>
#endif
#ifdef __STDC__
extern char *mktemp(char *);
#else
extern char *mktemp();
#endif /* __STDC__ */
#define RC_FILENAME ".XPaintrc"
static String defaultRC[] =
{
#ifndef VMS
#include "DefaultRC.txt.h"
#else
#include "DefaultRC_txt.h"
#endif
};
/*
** RC File Syntax
**
** brush [ BeginData\n ... \nEndData | filename ]
**
** pattern [ BeginData\n ... \nEndData | filename ]
**
** solid [ name | x-rgb-def | r g b ]
**
** \n# -- comment
*/
#define EQ(a,b) (strcasecmp(a,b) == 0)
static int tempIndex = -1;
static char *tempName[10];
static RCInfo *baseInfo = NULL;
static FILE *
openTemp(char **np)
{
char *n;
char xx[256];
#ifndef VMS
if ((n = getenv("TMPDIR")) == NULL)
n = "/tmp";
strcpy(xx, n);
strcat(xx, "/XPaintXXXXXXX");
#else
if ((n = getenv("TMPDIR")) == NULL)
n = "SYS$SRATCH:";
strcpy(xx, n);
strcat(xx, "XPaintXXXXXXX");
#endif /* VMS */
n = mktemp(xx);
tempName[++tempIndex] = XtNewString(n);
if (np != NULL)
*np = tempName[tempIndex];
return fopen(tempName[tempIndex], "w");
}
static void
removeTemp(void)
{
if (tempIndex < 0)
return;
if (tempName[tempIndex] != NULL) {
unlink(tempName[tempIndex]);
XtFree((XtPointer) tempName[tempIndex]);
}
tempName[tempIndex--] = NULL;
}
static void
addImage(RCInfo * info, Image * image, Boolean isBrush)
{
if (isBrush) {
info->brushes = (Image **)
XtRealloc((XtPointer) info->brushes,
(info->nbrushes + 1) * sizeof(Image *));
info->brushes[info->nbrushes++] = image;
} else {
info->images = (Image **)
XtRealloc((XtPointer) info->images,
(info->nimages + 1) * sizeof(Image *));
info->images[info->nimages++] = image;
}
}
static void
addSolid(RCInfo * info, char *color)
{
info->colors = (char **) XtRealloc((XtPointer) info->colors,
(info->ncolors + 1) * sizeof(char *));
info->colors[info->ncolors++] = XtNewString(color);
}
static RCInfo *
makeInfo(void)
{
RCInfo *info;
info = XtNew(RCInfo);
info->freed = False;
info->nimages = 0;
info->nbrushes = 0;
info->colorFlags = NULL;
info->colorPixels = NULL;
info->images = XtNew(Image *);
info->brushes = XtNew(Image *);
info->ncolors = 0;
info->colors = XtNew(char *);
baseInfo = info;
return info;
}
void
FreeRC(RCInfo * info)
{
int i;
if (info->colors != NULL) {
for (i = 0; i < info->ncolors; i++)
XtFree((XtPointer) info->colors[i]);
XtFree((XtPointer) info->colors);
}
if (info->colorFlags != NULL)
XtFree((XtPointer) info->colorFlags);
if (info->colorPixels != NULL)
XtFree((XtPointer) info->colorPixels);
for (i = 0; i < info->nimages; i++)
ImageDelete(info->images[i]);
if (info->images != NULL)
XtFree((XtPointer) info->images);
for (i = 0; i < info->nbrushes; i++)
ImageDelete(info->brushes[i]);
if (info->brushes != NULL)
XtFree((XtPointer) info->brushes);
XtFree((XtPointer) info);
if (info == baseInfo)
baseInfo = NULL;
}
/*
* Expand leading tilde in path name.
*/
static char *
expand(char *path)
{
static char out[512];
char name[80];
char *pp = path, *cp;
struct passwd *pw;
if (*path != '~')
return path;
path++;
cp = name;
while (*pp != '/' && *pp != '\0')
*cp++ = *pp++;
*cp = '\0';
#ifndef VMS
if (name[0] == '\0') {
pw = getpwuid(getuid());
} else {
pw = getpwnam(name);
}
#else
pw = NULL;
path = "SYS$LOGIN:";
return path;
#endif /* VMS */
if (pw == NULL)
return path;
strcpy(out, pw->pw_dir);
strcat(out, "/");
strcat(out, pp);
return out;
}
static Boolean
readRC(RCInfo ** info, char *file)
{
FILE *fd = fopen(file, "r");
char buf[512];
int lineno = 0;
int argc;
char *argv[128 + 2];
if (fd == NULL)
return False;
while (fgets(buf, sizeof(buf), fd) != NULL) {
lineno++;
if (buf[0] == '#' || buf[0] == '!')
continue;
StrToArgv(buf, &argc, argv);
if (argc == 0)
continue;
if (EQ(argv[0], "reset")) {
FreeRC(*info);
*info = makeInfo();
} else if (EQ(argv[0], "solid")) {
addSolid(*info, argv[1]);
} else if (EQ(argv[0], "pattern") || EQ(argv[0], "brush")) {
char *nm;
Image *image;
int isBrush = EQ(argv[0], "brush");
if (EQ(argv[1], "BeginData")) {
FILE *ofd;
ofd = openTemp(&nm);
while (fgets(buf, sizeof(buf), fd) != NULL) {
if (strncmp(buf, "EndData", 7) == 0)
break;
if (ofd != NULL)
fputs(buf, ofd);
}
if (ofd != NULL) {
fclose(ofd);
} else {
removeTemp();
continue;
}
} else {
nm = expand(argv[1]);
}
if ((image = ReadMagic(nm)) != NULL)
addImage(*info, image, isBrush);
removeTemp();
}
}
return True;
}
/*
** Simple RC reading strategy:
** load default
** append users ~/.XPaintrc
** append users ./.XPaintrc
**
*/
RCInfo *
ReadDefaultRC()
{
static Boolean inited = False;
static Boolean have[2] =
{False, False};
static time_t lastMtime;
static RCInfo *info = NULL;
static char homeRC[256];
FILE *fd;
int i;
char *tn;
#ifndef VMS
struct passwd *pw = getpwuid(getuid());
#else
struct passwd *pw;
#endif
struct stat statbufA, statbufB;
char *rcf;
Boolean defaultDone = False;
if (!inited) {
inited = True;
#ifndef VMS
if (pw != NULL && pw->pw_dir != NULL) {
strcpy(homeRC, pw->pw_dir);
strcat(homeRC, "/");
strcat(homeRC, RC_FILENAME);
} else {
homeRC[0] = '\0';
}
#else
strcat(homeRC, RC_FILENAME);
#endif /* VMS */
}
if ((rcf = GetDefaultRC()) != NULL) {
if (stat(rcf, &statbufA) < 0) /* missing file? */
goto readit;
if (info == NULL || statbufA.st_mtime > lastMtime) {
info = makeInfo();
readRC(&info, rcf);
lastMtime = statbufA.st_mtime;
defaultDone = True;
}
} else {
if (info != NULL) {
Boolean hA, hB;
hA = (stat(homeRC, &statbufA) >= 0);
hB = (stat(RC_FILENAME, &statbufB) >= 0);
if (hA != have[0] || hB != have[1])
goto readit;
if (hA && statbufA.st_mtime > lastMtime)
goto readit;
if (hB && statbufB.st_mtime > lastMtime)
goto readit;
/*
** No change
*/
return info;
}
readit:
if (info != NULL)
FreeRC(info);
info = makeInfo();
/*
** Set time information
*/
have[0] = (stat(homeRC, &statbufA) >= 0);
have[1] = (stat(RC_FILENAME, &statbufB) >= 0);
if (have[0] && have[1]) {
if (statbufA.st_mtime > statbufB.st_mtime)
lastMtime = statbufA.st_mtime;
else
lastMtime = statbufB.st_mtime;
} else if (have[0]) {
lastMtime = statbufA.st_mtime;
} else if (have[1]) {
lastMtime = statbufB.st_mtime;
}
/*
** Load the default RC
*/
if (!defaultDone && ((fd = openTemp(&tn)) != NULL)) {
for (i = 0; i < XtNumber(defaultRC); i++) {
fputs(defaultRC[i], fd);
putc('\n', fd);
}
fclose(fd);
readRC(&info, tn);
removeTemp();
}
/*
** Load ~/.XPaintrc
*/
if (homeRC[0] != '\0')
readRC(&info, homeRC);
/*
** Load ".XPaintrc"
*/
readRC(&info, RC_FILENAME);
}
if (info->ncolors == 0 && info->nimages == 0) {
addSolid(info, "black");
addSolid(info, "white");
addSolid(info, "red");
addSolid(info, "green");
addSolid(info, "blue");
addSolid(info, "cyan");
addSolid(info, "magenta");
addSolid(info, "yellow");
}
return info;
}
RCInfo *
ReadRC(char *file)
{
RCInfo *info = makeInfo();
if (!readRC(&info, file)) {
/*
** Error occured
*/
FreeRC(info);
return NULL;
}
return info;
}
(