Line data Source code
1 : /* RCS $Id: state.c,v 1.3 2007-09-20 14:33:53 vg Exp $
2 : --
3 : -- SYNOPSIS
4 : -- .KEEP_STATE state file management
5 : --
6 : -- DESCRIPTION
7 : -- Three routines to interface to the .KEEP_STATE state file.
8 : --
9 : -- Read_state() - reads the state file if any.
10 : -- Write_state() - writes the state file.
11 : --
12 : -- Check_state(cp,how) - checks an entry returns 0 or 1
13 : -- and updates the entry.
14 : --
15 : -- AUTHOR
16 : -- Dennis Vadura, dvadura@dmake.wticorp.com
17 : --
18 : -- WWW
19 : -- http://dmake.wticorp.com/
20 : --
21 : -- COPYRIGHT
22 : -- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
23 : --
24 : -- This program is NOT free software; you can redistribute it and/or
25 : -- modify it under the terms of the Software License Agreement Provided
26 : -- in the file <distribution-root>/readme/license.txt.
27 : --
28 : -- LOG
29 : -- Use cvs log to obtain detailed change logs.
30 : */
31 :
32 : #include "extern.h"
33 :
34 : typedef struct se {
35 : char *st_name; /* name of cell */
36 : uint32 st_nkey; /* name hash key */
37 : int st_count; /* how count for how */
38 : uint32 st_dkey; /* directory hash key */
39 : uint32 st_key; /* hash key */
40 : struct se *st_next;
41 : } KSTATE, *KSTATEPTR;
42 :
43 : static KSTATEPTR _st_head = NIL(KSTATE);
44 : static KSTATEPTR _st_tail = NIL(KSTATE);
45 : static int _st_upd = FALSE;
46 : static char *_st_file = NIL(char);
47 :
48 : static int _my_fgets ANSI((char *, int, FILE *));
49 :
50 : PUBLIC void
51 184 : Read_state()
52 : {
53 : char *buf;
54 : char sizeb[20];
55 : FILE *fp;
56 : KSTATEPTR sp;
57 :
58 184 : if( (fp = Search_file(".KEEP_STATE", &_st_file)) != NIL(FILE) )
59 : {
60 0 : if( _my_fgets( sizeb, 20, fp ) )
61 : {
62 0 : int size = atol(sizeb);
63 0 : buf = MALLOC(size+2, char);
64 :
65 0 : while( _my_fgets(buf, size, fp) )
66 : {
67 0 : TALLOC(sp, 1, KSTATE);
68 0 : sp->st_name = DmStrDup(buf);
69 0 : (void) Hash(buf, &sp->st_nkey);
70 0 : if( _my_fgets(buf, size, fp) )
71 0 : sp->st_count = atoi(buf);
72 0 : if( _my_fgets(buf, size, fp) )
73 0 : sp->st_dkey = (uint32) atol(buf);
74 0 : if( _my_fgets(buf, size, fp) )
75 0 : sp->st_key = (uint32) atol(buf);
76 : else {
77 0 : FREE(sp);
78 0 : break;
79 : }
80 0 : if( _st_head == NIL(KSTATE) )
81 0 : _st_head = sp;
82 : else
83 0 : _st_tail->st_next = sp;
84 0 : _st_tail = sp;
85 : }
86 0 : FREE(buf);
87 : }
88 0 : Closefile();
89 : }
90 184 : }
91 :
92 :
93 : PUBLIC void
94 188 : Write_state()
95 : {
96 : static int in_write = 0;
97 : register KSTATEPTR sp;
98 : FILE *fp;
99 :
100 188 : if( !_st_upd || !_st_file || (_st_file && !*_st_file) ||
101 188 : Trace || in_write ) return;
102 :
103 0 : in_write++;
104 0 : if( (fp = Openfile(_st_file, TRUE, TRUE)) != NIL(FILE) ) {
105 0 : int maxlen = 0;
106 : int tmplen;
107 :
108 0 : for( sp = _st_head; sp; sp=sp->st_next )
109 0 : if( (tmplen = strlen(sp->st_name)+2) > maxlen )
110 0 : maxlen = tmplen;
111 :
112 : /* A nice arbitrary minimum size */
113 0 : if( maxlen < 20 ) maxlen = 20;
114 0 : fprintf( fp, "%d\n", maxlen );
115 :
116 0 : for( sp = _st_head; sp; sp=sp->st_next ) {
117 : uint16 hv;
118 : uint32 hk;
119 :
120 0 : if( Search_table(Defs, sp->st_name, &hv, &hk) ) {
121 0 : fprintf( fp, "%s\n", sp->st_name );
122 0 : fprintf( fp, "%d\n", sp->st_count );
123 : /* long unsigned can be != uint32, silence the warning. */
124 0 : fprintf( fp, "%lu\n", (unsigned long)sp->st_dkey );
125 0 : fprintf( fp, "%lu\n", (unsigned long)sp->st_key );
126 : }
127 : }
128 :
129 0 : Closefile();
130 : }
131 : else
132 0 : Fatal("Cannot open STATE file %s", _st_file);
133 :
134 0 : in_write = 0;
135 : }
136 :
137 :
138 : PUBLIC int
139 40158 : Check_state( cp, recipes, maxrcp )
140 : CELLPTR cp;
141 : STRINGPTR *recipes;
142 : int maxrcp;
143 : {
144 : KSTATEPTR st;
145 : STRINGPTR sp;
146 : int i;
147 : uint32 thkey;
148 : uint32 hkey;
149 : uint32 nkey;
150 : uint32 dkey;
151 40158 : int update = FALSE;
152 :
153 40158 : if( !_st_file || (_st_file && !*_st_file) || Trace )
154 40158 : return(FALSE);
155 :
156 0 : if( strcmp(cp->CE_NAME,".REMOVE") == 0
157 0 : || (cp->ce_attr & (A_PHONY|A_NOSTATE)) )
158 0 : return(FALSE);
159 :
160 0 : (void) Hash( cp->CE_NAME, &nkey ); thkey = nkey + (uint32) cp->ce_count;
161 0 : (void) Hash( Pwd, &dkey ); thkey += dkey;
162 :
163 0 : Suppress_temp_file = TRUE;
164 0 : for( i=0 ; i<maxrcp; i++ )
165 0 : for(sp=recipes[i]; sp != NIL(STRING); sp=sp->st_next ) {
166 0 : CELLPTR svct = Current_target;
167 : char *cmnd;
168 0 : t_attr silent = (Glob_attr & A_SILENT);
169 :
170 0 : Current_target = cp;
171 0 : Glob_attr |= A_SILENT;
172 0 : cmnd = Expand(sp->st_string);
173 0 : Glob_attr = (Glob_attr & ~A_SILENT)|silent;
174 0 : Current_target = svct;
175 :
176 0 : (void) Hash(cmnd, &hkey); thkey += hkey;
177 0 : FREE(cmnd);
178 : }
179 0 : Suppress_temp_file = FALSE;
180 :
181 0 : for( st=_st_head; st != NIL(KSTATE); st=st->st_next ) {
182 0 : if( st->st_nkey == nkey
183 0 : && st->st_dkey == dkey
184 0 : && st->st_count == cp->ce_count
185 0 : && !strcmp(cp->CE_NAME, st->st_name) )
186 0 : break;
187 : }
188 :
189 0 : if( st == NIL(KSTATE) ) {
190 : KSTATEPTR nst;
191 :
192 0 : TALLOC(nst, 1, KSTATE);
193 0 : nst->st_name = cp->CE_NAME;
194 0 : nst->st_nkey = nkey;
195 0 : nst->st_dkey = dkey;
196 0 : nst->st_key = thkey;
197 0 : nst->st_count = cp->ce_count;
198 :
199 0 : if( _st_head == NIL(KSTATE) )
200 0 : _st_head = nst;
201 : else
202 0 : _st_tail->st_next = nst;
203 :
204 0 : _st_tail = nst;
205 0 : _st_upd = TRUE;
206 : }
207 0 : else if( st->st_key != thkey ) {
208 0 : st->st_key = thkey;
209 0 : _st_upd = update = TRUE;
210 : }
211 :
212 0 : return(st != NIL(KSTATE) && update);
213 : }
214 :
215 :
216 : static int
217 0 : _my_fgets(buf, size, fp)
218 : char *buf;
219 : int size;
220 : FILE *fp;
221 : {
222 : char *p;
223 :
224 0 : if( fgets(buf, size, fp) == NULL ) return(0);
225 :
226 0 : if( (p=strrchr(buf,'\n')) != NIL(char) ) *p='\0';
227 0 : if( (p=strrchr(buf,'\r')) != NIL(char) ) *p='\0';
228 0 : return(1);
229 : }
|