home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xpaint-244 / src / readrc.c_prev < prev    next >
Text File  |  1996-07-28  |  9KB  |  412 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.     if ((n = getenv("TMPDIR")) == NULL)
  75.     n = "/tmp";
  76.  
  77.     strcpy(xx, n);
  78.     strcat(xx, "/XPaintXXXXXXX");
  79.     n = mktemp(xx);
  80.     tempName[++tempIndex] = XtNewString(n);
  81.     if (np != NULL)
  82.     *np = tempName[tempIndex];
  83.     return fopen(tempName[tempIndex], "w");
  84. }
  85.  
  86. static void 
  87. removeTemp(void)
  88. {
  89.     if (tempIndex < 0)
  90.     return;
  91.     if (tempName[tempIndex] != NULL) {
  92.     unlink(tempName[tempIndex]);
  93.     XtFree((XtPointer) tempName[tempIndex]);
  94.     }
  95.     tempName[tempIndex--] = NULL;
  96. }
  97.  
  98. static void 
  99. addImage(RCInfo * info, Image * image, Boolean isBrush)
  100. {
  101.     if (isBrush) {
  102.     info->brushes = (Image **)
  103.         XtRealloc((XtPointer) info->brushes,
  104.               (info->nbrushes + 1) * sizeof(Image *));
  105.     info->brushes[info->nbrushes++] = image;
  106.     } else {
  107.     info->images = (Image **)
  108.         XtRealloc((XtPointer) info->images,
  109.               (info->nimages + 1) * sizeof(Image *));
  110.     info->images[info->nimages++] = image;
  111.     }
  112. }
  113.  
  114. static void 
  115. addSolid(RCInfo * info, char *color)
  116. {
  117.     info->colors = (char **) XtRealloc((XtPointer) info->colors,
  118.                        (info->ncolors + 1) * sizeof(char *));
  119.     info->colors[info->ncolors++] = XtNewString(color);
  120. }
  121.  
  122. static RCInfo *
  123. makeInfo(void)
  124. {
  125.     RCInfo *info;
  126.  
  127.     info = XtNew(RCInfo);
  128.     info->freed = False;
  129.     info->nimages = 0;
  130.     info->nbrushes = 0;
  131.     info->colorFlags = NULL;
  132.     info->colorPixels = NULL;
  133.     info->images = XtNew(Image *);
  134.     info->brushes = XtNew(Image *);
  135.     info->ncolors = 0;
  136.     info->colors = XtNew(char *);
  137.  
  138.     baseInfo = info;
  139.  
  140.     return info;
  141. }
  142.  
  143. void 
  144. FreeRC(RCInfo * info)
  145. {
  146.     int i;
  147.  
  148.     if (info->colors != NULL) {
  149.     for (i = 0; i < info->ncolors; i++)
  150.         XtFree((XtPointer) info->colors[i]);
  151.     XtFree((XtPointer) info->colors);
  152.     }
  153.     if (info->colorFlags != NULL)
  154.     XtFree((XtPointer) info->colorFlags);
  155.     if (info->colorPixels != NULL)
  156.     XtFree((XtPointer) info->colorPixels);
  157.  
  158.     for (i = 0; i < info->nimages; i++)
  159.     ImageDelete(info->images[i]);
  160.     if (info->images != NULL)
  161.     XtFree((XtPointer) info->images);
  162.  
  163.     for (i = 0; i < info->nbrushes; i++)
  164.     ImageDelete(info->brushes[i]);
  165.     if (info->brushes != NULL)
  166.     XtFree((XtPointer) info->brushes);
  167.  
  168.     XtFree((XtPointer) info);
  169.  
  170.     if (info == baseInfo)
  171.     baseInfo = NULL;
  172. }
  173.  
  174. /*
  175.  * Expand leading tilde in path name.
  176.  */
  177. static char *
  178. expand(char *path)
  179. {
  180.     static char out[512];
  181.     char name[80];
  182.     char *pp = path, *cp;
  183.     struct passwd *pw;
  184.  
  185.     if (*path != '~')
  186.     return path;
  187.     path++;
  188.     cp = name;
  189.     while (*pp != '/' && *pp != '\0')
  190.     *cp++ = *pp++;
  191.     *cp = '\0';
  192. #ifndef VMS
  193.     if (name[0] == '\0') {
  194.     pw = getpwuid(getuid());
  195.     } else {
  196.     pw = getpwnam(name);
  197.     }
  198. #else
  199.        pw = NULL;
  200.        path = "SYS$LOGIN:";
  201.        return path;
  202. #endif /* VMS */
  203.     if (pw == NULL)
  204.     return path;
  205.     strcpy(out, pw->pw_dir);
  206.     strcat(out, "/");
  207.     strcat(out, pp);
  208.  
  209.     return out;
  210. }
  211.  
  212. static Boolean
  213. readRC(RCInfo ** info, char *file)
  214. {
  215.     FILE *fd = fopen(file, "r");
  216.     char buf[512];
  217.     int lineno = 0;
  218.     int argc;
  219.     char *argv[128 + 2];
  220.  
  221.     if (fd == NULL)
  222.     return False;
  223.  
  224.     while (fgets(buf, sizeof(buf), fd) != NULL) {
  225.     lineno++;
  226.     if (buf[0] == '#' || buf[0] == '!')
  227.         continue;
  228.     StrToArgv(buf, &argc, argv);
  229.     if (argc == 0)
  230.         continue;
  231.     if (EQ(argv[0], "reset")) {
  232.         FreeRC(*info);
  233.         *info = makeInfo();
  234.     } else if (EQ(argv[0], "solid")) {
  235.         addSolid(*info, argv[1]);
  236.     } else if (EQ(argv[0], "pattern") || EQ(argv[0], "brush")) {
  237.         char *nm;
  238.         Image *image;
  239.         int isBrush = EQ(argv[0], "brush");
  240.  
  241.         if (EQ(argv[1], "BeginData")) {
  242.         FILE *ofd;
  243.  
  244.         ofd = openTemp(&nm);
  245.         while (fgets(buf, sizeof(buf), fd) != NULL) {
  246.             if (strncmp(buf, "EndData", 7) == 0)
  247.             break;
  248.             if (ofd != NULL)
  249.             fputs(buf, ofd);
  250.         }
  251.         if (ofd != NULL) {
  252.             fclose(ofd);
  253.         } else {
  254.             removeTemp();
  255.             continue;
  256.         }
  257.         } else {
  258.         nm = expand(argv[1]);
  259.         }
  260.  
  261.         if ((image = ReadMagic(nm)) != NULL)
  262.         addImage(*info, image, isBrush);
  263.  
  264.         removeTemp();
  265.     }
  266.     }
  267.  
  268.     return True;
  269. }
  270.  
  271. /*
  272. **  Simple RC reading strategy:
  273. **    load default
  274. **    append users ~/.XPaintrc
  275. **    append users ./.XPaintrc
  276. **
  277.  */
  278. RCInfo *
  279. ReadDefaultRC()
  280. {
  281.     static Boolean inited = False;
  282.     static Boolean have[2] =
  283.     {False, False};
  284.     static time_t lastMtime;
  285.     static RCInfo *info = NULL;
  286.     static char homeRC[256];
  287.     FILE *fd;
  288.     int i;
  289.     char *tn;
  290. #ifndef VMS
  291.     struct passwd *pw = getpwuid(getuid());
  292. #else
  293.         struct passwd   *pw;
  294. #endif
  295.     struct stat statbufA, statbufB;
  296.     char *rcf;
  297.     Boolean defaultDone = False;
  298.  
  299.     if (!inited) {
  300.     inited = True;
  301.     if (pw != NULL && pw->pw_dir != NULL) {
  302.         strcpy(homeRC, pw->pw_dir);
  303.         strcat(homeRC, "/");
  304.         strcat(homeRC, RC_FILENAME);
  305.     } else {
  306.         homeRC[0] = '\0';
  307.     }
  308.     }
  309.     if ((rcf = GetDefaultRC()) != NULL) {
  310.     if (stat(rcf, &statbufA) < 0)    /* missing file? */
  311.         goto readit;
  312.  
  313.     if (info == NULL || statbufA.st_mtime > lastMtime) {
  314.         info = makeInfo();
  315.         readRC(&info, rcf);
  316.         lastMtime = statbufA.st_mtime;
  317.         defaultDone = True;
  318.     }
  319.     } else {
  320.     if (info != NULL) {
  321.         Boolean hA, hB;
  322.  
  323.         hA = (stat(homeRC, &statbufA) >= 0);
  324.         hB = (stat(RC_FILENAME, &statbufB) >= 0);
  325.  
  326.         if (hA != have[0] || hB != have[1])
  327.         goto readit;
  328.  
  329.         if (hA && statbufA.st_mtime > lastMtime)
  330.         goto readit;
  331.         if (hB && statbufB.st_mtime > lastMtime)
  332.         goto readit;
  333.  
  334.         /*
  335.         **  No change
  336.          */
  337.         return info;
  338.     }
  339.       readit:
  340.     if (info != NULL)
  341.         FreeRC(info);
  342.     info = makeInfo();
  343.  
  344.     /*
  345.     **  Set time information
  346.      */
  347.     have[0] = (stat(homeRC, &statbufA) >= 0);
  348.     have[1] = (stat(RC_FILENAME, &statbufB) >= 0);
  349.  
  350.     if (have[0] && have[1]) {
  351.         if (statbufA.st_mtime > statbufB.st_mtime)
  352.         lastMtime = statbufA.st_mtime;
  353.         else
  354.         lastMtime = statbufB.st_mtime;
  355.     } else if (have[0]) {
  356.         lastMtime = statbufA.st_mtime;
  357.     } else if (have[1]) {
  358.         lastMtime = statbufB.st_mtime;
  359.     }
  360.     /*
  361.     **  Load the default RC
  362.      */
  363.     if (!defaultDone && ((fd = openTemp(&tn)) != NULL)) {
  364.         for (i = 0; i < XtNumber(defaultRC); i++) {
  365.         fputs(defaultRC[i], fd);
  366.         putc('\n', fd);
  367.         }
  368.         fclose(fd);
  369.  
  370.         readRC(&info, tn);
  371.         removeTemp();
  372.     }
  373.     /*
  374.     **  Load ~/.XPaintrc
  375.      */
  376.     if (homeRC[0] != '\0')
  377.         readRC(&info, homeRC);
  378.  
  379.     /*
  380.     **  Load ".XPaintrc"
  381.      */
  382.     readRC(&info, RC_FILENAME);
  383.     }
  384.  
  385.     if (info->ncolors == 0 && info->nimages == 0) {
  386.     addSolid(info, "black");
  387.     addSolid(info, "white");
  388.     addSolid(info, "red");
  389.     addSolid(info, "green");
  390.     addSolid(info, "blue");
  391.     addSolid(info, "cyan");
  392.     addSolid(info, "magenta");
  393.     addSolid(info, "yellow");
  394.     }
  395.     return info;
  396. }
  397.  
  398. RCInfo *
  399. ReadRC(char *file)
  400. {
  401.     RCInfo *info = makeInfo();
  402.  
  403.     if (!readRC(&info, file)) {
  404.     /*
  405.     **  Error occured
  406.      */
  407.     FreeRC(info);
  408.     return NULL;
  409.     }
  410.     return info;
  411. }
  412.