home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xpaint-247 / readrc.c < prev    next >
C/C++ Source or Header  |  1997-01-03  |  16KB  |  425 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1993, David Koblas (koblas@netcom.com)                  | */
  3. /* | Copyright 1995, 1996 Torsten Martinsen (bullestock@dk-online.dk)  | */
  4. /* |                                                                   | */
  5. /* | Permission to use, copy, modify, and to distribute this software  | */
  6. /* | and its documentation for any purpose is hereby granted without   | */
  7. /* | fee, provided that the above copyright notice appear in all       | */
  8. /* | copies and that both that copyright notice and this permission    | */
  9. /* | notice appear in supporting documentation.  There is no           | */
  10. /* | representations about the suitability of this software for        | */
  11. /* | any purpose.  this software is provided "as is" without express   | */
  12. /* | or implied warranty.                                              | */
  13. /* |                                                                   | */
  14. /* +-------------------------------------------------------------------+ */
  15.  
  16. /* $Id: readRC.c,v 1.4 1996/06/03 05:28:19 torsten Exp $ */
  17.  
  18. #include <stdio.h>
  19. #include <pwd.h>
  20. #include <ctype.h>
  21. #include <X11/Intrinsic.h>
  22. #include <X11/Xos.h>
  23. #include <sys/stat.h>
  24. #include "image.h"
  25. #include "rc.h"
  26. #include "misc.h"
  27.  
  28. #ifndef NOSTDHDRS
  29. #include <stdlib.h>
  30. #include <unistd.h>
  31. #endif
  32.  
  33. #ifdef __STDC__
  34. extern char *mktemp(char *);
  35. #else
  36. extern char *mktemp();
  37. #endif /* __STDC__ */
  38.  
  39. #define RC_FILENAME    ".XPaintrc"
  40.  
  41. static String defaultRC[] =
  42. {
  43. #ifndef VMS
  44. #include "DefaultRC.txt.h"
  45. #else
  46. #include "DefaultRC_txt.h"
  47. #endif
  48. };
  49.  
  50. /*
  51. **   RC File Syntax
  52. **
  53. **     brush   [ BeginData\n ... \nEndData | filename ]
  54. **
  55. **     pattern [ BeginData\n ... \nEndData | filename ]
  56. **
  57. **     solid   [ name | x-rgb-def | r g b ]
  58. **     
  59. **     \n# -- comment
  60.  */
  61.  
  62. #define EQ(a,b)        (strcasecmp(a,b) == 0)
  63.  
  64. static int tempIndex = -1;
  65. static char *tempName[10];
  66. static RCInfo *baseInfo = NULL;
  67.  
  68. static FILE *
  69. openTemp(char **np)
  70. {
  71.     char *n;
  72.     char xx[256];
  73.  
  74. #ifndef VMS
  75.     if ((n = getenv("TMPDIR")) == NULL)
  76.     n = "/tmp";
  77.  
  78.     strcpy(xx, n);
  79.     strcat(xx, "/XPaintXXXXXXX");
  80. #else
  81.     if ((n = getenv("TMPDIR")) == NULL)
  82.     n = "SYS$SRATCH:";
  83.  
  84.     strcpy(xx, n);
  85.     strcat(xx, "XPaintXXXXXXX");
  86. #endif /* VMS */
  87.  
  88.     n = mktemp(xx);
  89.     tempName[++tempIndex] = XtNewString(n);
  90.     if (np != NULL)
  91.     *np = tempName[tempIndex];
  92.     return fopen(tempName[tempIndex], "w");
  93. }
  94.  
  95. static void 
  96. removeTemp(void)
  97. {
  98.     if (tempIndex < 0)
  99.     return;
  100.     if (tempName[tempIndex] != NULL) {
  101.     unlink(tempName[tempIndex]);
  102.     XtFree((XtPointer) tempName[tempIndex]);
  103.     }
  104.     tempName[tempIndex--] = NULL;
  105. }
  106.  
  107. static void 
  108. addImage(RCInfo * info, Image * image, Boolean isBrush)
  109. {
  110.     if (isBrush) {
  111.     info->brushes = (Image **)
  112.         XtRealloc((XtPointer) info->brushes,
  113.               (info->nbrushes + 1) * sizeof(Image *));
  114.     info->brushes[info->nbrushes++] = image;
  115.     } else {
  116.     info->images = (Image **)
  117.         XtRealloc((XtPointer) info->images,
  118.               (info->nimages + 1) * sizeof(Image *));
  119.     info->images[info->nimages++] = image;
  120.     }
  121. }
  122.  
  123. static void 
  124. addSolid(RCInfo * info, char *color)
  125. {
  126.     info->colors = (char **) XtRealloc((XtPointer) info->colors,
  127.                        (info->ncolors + 1) * sizeof(char *));
  128.     info->colors[info->ncolors++] = XtNewString(color);
  129. }
  130.  
  131. static RCInfo *
  132. makeInfo(void)
  133. {
  134.     RCInfo *info;
  135.  
  136.     info = XtNew(RCInfo);
  137.     info->freed = False;
  138.     info->nimages = 0;
  139.     info->nbrushes = 0;
  140.     info->colorFlags = NULL;
  141.     info->colorPixels = NULL;
  142.     info->images = XtNew(Image *);
  143.     info->brushes = XtNew(Image *);
  144.     info->ncolors = 0;
  145.     info->colors = XtNew(char *);
  146.  
  147.     baseInfo = info;
  148.  
  149.     return info;
  150. }
  151.  
  152. void 
  153. FreeRC(RCInfo * info)
  154. {
  155.     int i;
  156.  
  157.     if (info->colors != NULL) {
  158.     for (i = 0; i < info->ncolors; i++)
  159.         XtFree((XtPointer) info->colors[i]);
  160.     XtFree((XtPointer) info->colors);
  161.     }
  162.     if (info->colorFlags != NULL)
  163.     XtFree((XtPointer) info->colorFlags);
  164.     if (info->colorPixels != NULL)
  165.     XtFree((XtPointer) info->colorPixels);
  166.  
  167.     for (i = 0; i < info->nimages; i++)
  168.     ImageDelete(info->images[i]);
  169.     if (info->images != NULL)
  170.     XtFree((XtPointer) info->images);
  171.  
  172.     for (i = 0; i < info->nbrushes; i++)
  173.     ImageDelete(info->brushes[i]);
  174.     if (info->brushes != NULL)
  175.     XtFree((XtPointer) info->brushes);
  176.  
  177.     XtFree((XtPointer) info);
  178.  
  179.     if (info == baseInfo)
  180.     baseInfo = NULL;
  181. }
  182.  
  183. /*
  184.  * Expand leading tilde in path name.
  185.  */
  186. static char *
  187. expand(char *path)
  188. {
  189.     static char out[512];
  190.     char name[80];
  191.     char *pp = path, *cp;
  192.     struct passwd *pw;
  193.  
  194.     if (*path != '~')
  195.     return path;
  196.     path++;
  197.     cp = name;
  198.     while (*pp != '/' && *pp != '\0')
  199.     *cp++ = *pp++;
  200.     *cp = '\0';
  201. #ifndef VMS
  202.     if (name[0] == '\0') {
  203.     pw = getpwuid(getuid());
  204.     } else {
  205.     pw = getpwnam(name);
  206.     }
  207. #else
  208.        pw = NULL;
  209.        path = "SYS$LOGIN:";
  210.        return path;
  211. #endif /* VMS */
  212.     if (pw == NULL)
  213.     return path;
  214.     strcpy(out, pw->pw_dir);
  215.     strcat(out, "/");
  216.     strcat(out, pp);
  217.  
  218.     return out;
  219. }
  220.  
  221. static Boolean
  222. readRC(RCInfo ** info, char *file)
  223. {
  224.     FILE *fd = fopen(file, "r");
  225.     char buf[512];
  226.     int lineno = 0;
  227.     int argc;
  228.     char *argv[128 + 2];
  229.  
  230.     if (fd == NULL)
  231.     return False;
  232.  
  233.     while (fgets(buf, sizeof(buf), fd) != NULL) {
  234.     lineno++;
  235.     if (buf[0] == '#' || buf[0] == '!')
  236.         continue;
  237.     StrToArgv(buf, &argc, argv);
  238.     if (argc == 0)
  239.         continue;
  240.     if (EQ(argv[0], "reset")) {
  241.         FreeRC(*info);
  242.         *info = makeInfo();
  243.     } else if (EQ(argv[0], "solid")) {
  244.         addSolid(*info, argv[1]);
  245.     } else if (EQ(argv[0], "pattern") || EQ(argv[0], "brush")) {
  246.         char *nm;
  247.         Image *image;
  248.         int isBrush = EQ(argv[0], "brush");
  249.  
  250.         if (EQ(argv[1], "BeginData")) {
  251.         FILE *ofd;
  252.  
  253.         ofd = openTemp(&nm);
  254.         while (fgets(buf, sizeof(buf), fd) != NULL) {
  255.             if (strncmp(buf, "EndData", 7) == 0)
  256.             break;
  257.             if (ofd != NULL)
  258.             fputs(buf, ofd);
  259.         }
  260.         if (ofd != NULL) {
  261.             fclose(ofd);
  262.         } else {
  263.             removeTemp();
  264.             continue;
  265.         }
  266.         } else {
  267.         nm = expand(argv[1]);
  268.         }
  269.  
  270.         if ((image = ReadMagic(nm)) != NULL)
  271.         addImage(*info, image, isBrush);
  272.  
  273.         removeTemp();
  274.     }
  275.     }
  276.  
  277.     return True;
  278. }
  279.  
  280. /*
  281. **  Simple RC reading strategy:
  282. **    load default
  283. **    append users ~/.XPaintrc
  284. **    append users ./.XPaintrc
  285. **
  286.  */
  287. RCInfo *
  288. ReadDefaultRC()
  289. {
  290.     static Boolean inited = False;
  291.     static Boolean have[2] =
  292.     {False, False};
  293.     static time_t lastMtime;
  294.     static RCInfo *info = NULL;
  295.     static char homeRC[256];
  296.     FILE *fd;
  297.     int i;
  298.     char *tn;
  299. #ifndef VMS
  300.     struct passwd *pw = getpwuid(getuid());
  301. #else
  302.         struct passwd   *pw;
  303. #endif
  304.     struct stat statbufA, statbufB;
  305.     char *rcf;
  306.     Boolean defaultDone = False;
  307.  
  308.     if (!inited) {
  309.     inited = True;
  310. #ifndef VMS
  311.     if (pw != NULL && pw->pw_dir != NULL) {
  312.         strcpy(homeRC, pw->pw_dir);
  313.         strcat(homeRC, "/");
  314.         strcat(homeRC, RC_FILENAME);
  315.     } else {
  316.         homeRC[0] = '\0';
  317.     }
  318. #else
  319.                 strcat(homeRC, RC_FILENAME);
  320. #endif /* VMS */
  321.     }
  322.     if ((rcf = GetDefaultRC()) != NULL) {
  323.     if (stat(rcf, &statbufA) < 0)    /* missing file? */
  324.         goto readit;
  325.  
  326.     if (info == NULL || statbufA.st_mtime > lastMtime) {
  327.         info = makeInfo();
  328.         readRC(&info, rcf);
  329.         lastMtime = statbufA.st_mtime;
  330.         defaultDone = True;
  331.     }
  332.     } else {
  333.     if (info != NULL) {
  334.         Boolean hA, hB;
  335.  
  336.         hA = (stat(homeRC, &statbufA) >= 0);
  337.         hB = (stat(RC_FILENAME, &statbufB) >= 0);
  338.  
  339.         if (hA != have[0] || hB != have[1])
  340.         goto readit;
  341.  
  342.         if (hA && statbufA.st_mtime > lastMtime)
  343.         goto readit;
  344.         if (hB && statbufB.st_mtime > lastMtime)
  345.         goto readit;
  346.  
  347.         /*
  348.         **  No change
  349.          */
  350.         return info;
  351.     }
  352.       readit:
  353.     if (info != NULL)
  354.         FreeRC(info);
  355.     info = makeInfo();
  356.  
  357.     /*
  358.     **  Set time information
  359.      */
  360.     have[0] = (stat(homeRC, &statbufA) >= 0);
  361.     have[1] = (stat(RC_FILENAME, &statbufB) >= 0);
  362.  
  363.     if (have[0] && have[1]) {
  364.         if (statbufA.st_mtime > statbufB.st_mtime)
  365.         lastMtime = statbufA.st_mtime;
  366.         else
  367.         lastMtime = statbufB.st_mtime;
  368.     } else if (have[0]) {
  369.         lastMtime = statbufA.st_mtime;
  370.     } else if (have[1]) {
  371.         lastMtime = statbufB.st_mtime;
  372.     }
  373.     /*
  374.     **  Load the default RC
  375.      */
  376.     if (!defaultDone && ((fd = openTemp(&tn)) != NULL)) {
  377.         for (i = 0; i < XtNumber(defaultRC); i++) {
  378.         fputs(defaultRC[i], fd);
  379.         putc('\n', fd);
  380.         }
  381.         fclose(fd);
  382.  
  383.         readRC(&info, tn);
  384.         removeTemp();
  385.     }
  386.     /*
  387.     **  Load ~/.XPaintrc
  388.      */
  389.     if (homeRC[0] != '\0')
  390.         readRC(&info, homeRC);
  391.  
  392.     /*
  393.     **  Load ".XPaintrc"
  394.      */
  395.     readRC(&info, RC_FILENAME);
  396.     }
  397.  
  398.     if (info->ncolors == 0 && info->nimages == 0) {
  399.     addSolid(info, "black");
  400.     addSolid(info, "white");
  401.     addSolid(info, "red");
  402.     addSolid(info, "green");
  403.     addSolid(info, "blue");
  404.     addSolid(info, "cyan");
  405.     addSolid(info, "magenta");
  406.     addSolid(info, "yellow");
  407.     }
  408.     return info;
  409. }
  410.  
  411. RCInfo *
  412. ReadRC(char *file)
  413. {
  414.     RCInfo *info = makeInfo();
  415.  
  416.     if (!readRC(&info, file)) {
  417.     /*
  418.     **  Error occured
  419.      */
  420.     FreeRC(info);
  421.     return NULL;
  422.     }
  423.     return info;
  424. }
  425. (