1 /* $Id: rcfile.c,v 1.4 2002/03/02 21:02:21 sverrehu Exp $ */
2 /**************************************************************************
3  *
4  *  FILE            rcfile.c
5  *  MODULE OF       Card game.
6  *
7  *  DESCRIPTION     Parse the startup file for this program.
8  *
9  *  WRITTEN BY      Sverre H. Huseby <shh@thathost.com>
10  *
11  **************************************************************************/
12 
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <string.h>
16 
17 #include <shhmsg.h>
18 #include <xalloc.h>
19 #include <shhcards.h>
20 
21 #include "parsefile.h"
22 #include "envvar.h"
23 #include "game.h"
24 #include "board.h"
25 #include "rcfile.h"
26 
27 /**************************************************************************
28  *                                                                        *
29  *                   P R I V A T E    F U N C T I O N S                   *
30  *                                                                        *
31  **************************************************************************/
32 
33 static int
rcParseError(const char * s)34 rcParseError(const char *s)
35 {
36     msgError("%s in `%s', line %d\n",
37 	     s, pfGetCurrentFile(), pfGetCurrentLine());
38     return -1;
39 }
40 
41 static int
rcCheckAssignment(int argc,char * argv[])42 rcCheckAssignment(int argc, char *argv[])
43 {
44     if (argc == 1 || strcmp(argv[1], "=") != 0)
45 	return rcParseError("missing `='");
46     else if (argc == 2 || !strlen(argv[2]))
47 	return rcParseError("missing argument to assignment");
48     else if (argc > 3)
49 	return rcParseError("too many arguments to assignment");
50     return 0;
51 }
52 
53 static int
rcCheckBooleanAssignment(int argc,char * argv[])54 rcCheckBooleanAssignment(int argc, char *argv[])
55 {
56     if (rcCheckAssignment(argc, argv) != 0 || pfGetBooleanValue(argv[2]) == -1)
57 	return -1;
58     return 0;
59 }
60 
61 static int
rcParseLine(int argc,char * argv[])62 rcParseLine(int argc, char *argv[])
63 {
64     int tmp;
65 
66     if (pfStrCaseCmp(argv[0], "NumberOfGamesPlayed") == 0) {
67 	if (rcCheckAssignment(argc, argv) == 0)
68 	    gameNumPlayed = atoi(argv[2]);
69     } else if (pfStrCaseCmp(argv[0], "NumberOfGamesSolved") == 0) {
70 	if (rcCheckAssignment(argc, argv) == 0)
71 	    gameNumSolved = atoi(argv[2]);
72     } else if (pfStrCaseCmp(argv[0], "TotalTimePlayed") == 0) {
73 	if (rcCheckAssignment(argc, argv) == 0)
74 	    gameTotalTime = atol(argv[2]);
75     } else if (pfStrCaseCmp(argv[0], "CardBackground") == 0) {
76 	if (rcCheckAssignment(argc, argv) == 0) {
77 	    tmp = atoi(argv[2]);
78 	    if (tmp >= 0 && tmp < CARD_NUM_BACKS)
79 		boardCardBackground = tmp;
80 	    else
81 		rcParseError("CardBackground out of range");
82 	}
83     } else if (pfStrCaseCmp(argv[0], "CardsToDraw") == 0) {
84 	if (rcCheckAssignment(argc, argv) == 0) {
85 	    tmp = atoi(argv[2]);
86 	    if (tmp == 1 || tmp == 3)
87 		gameNumCardsToDraw = tmp;
88 	    else
89 		rcParseError("illegal CardsToDraw");
90 	}
91     } else if (pfStrCaseCmp(argv[0], "IncludeInHighscoreFile") == 0) {
92 	if (rcCheckBooleanAssignment(argc, argv) == 0)
93 	    gameIncludeInHighscoreList = pfGetBooleanValue(argv[2]);
94     } else if (pfStrCaseCmp(argv[0], "Timing") == 0) {
95 	if (rcCheckBooleanAssignment(argc, argv) == 0)
96 	    gameDoTiming = pfGetBooleanValue(argv[2]);
97     } else {
98 	rcParseError("syntax error");
99     }
100     return 1; /* continue parsing */
101 }
102 
103 
104 /**************************************************************************
105  *                                                                        *
106  *                    P U B L I C    F U N C T I O N S                    *
107  *                                                                        *
108  **************************************************************************/
109 
110 void
rcRead(void)111 rcRead(void)
112 {
113     char *home, *filename;
114 
115     /* read rc-file in user's home directory */
116     if ((home = getenv("HOME")) != NULL) {
117 	filename = xmalloc(strlen(home) + strlen(RC_FILE) + 2);
118 	strcpy(filename, home);
119 	strcat(filename, "/");
120 	strcat(filename, RC_FILE);
121 	pfParseFile(filename, rcParseLine, 1);
122 	free(filename);
123     }
124 }
125 
126 void
rcWrite(void)127 rcWrite(void)
128 {
129     char *home, *filename;
130     FILE * f;
131 
132     /* read rc-file in user's home directory */
133     if ((home = getenv("HOME")) != NULL) {
134 	filename = xmalloc(strlen(home) + strlen(RC_FILE) + 2);
135 	strcpy(filename, home);
136 	strcat(filename, "/");
137 	strcat(filename, RC_FILE);
138 	if ((f = fopen(filename, "w")) != NULL) {
139 	    fprintf(f, "# Generated and updated automatically "
140 		       "by the Solitaire card game \"sol\".\n");
141 	    fprintf(f, "NumberOfGamesPlayed = %d\n", gameNumPlayed);
142 	    fprintf(f, "NumberOfGamesSolved = %d\n", gameNumSolved);
143 	    fprintf(f, "TotalTimePlayed = %ld\n", gameTotalTime);
144 	    fprintf(f, "CardBackground = %d\n", boardCardBackground);
145 	    fprintf(f, "CardsToDraw = %d\n", gameNumCardsToDraw);
146 	    fprintf(f, "IncludeInHighscoreFile = %s\n",
147 		       gameIncludeInHighscoreList ? "yes" : "no");
148 	    fprintf(f, "Timing = %s\n", gameDoTiming ? "yes" : "no");
149 	    fclose(f);
150 	}
151 	free(filename);
152     }
153 }
154