1 /* RCS $Id: state.c,v 1.3 2007-09-20 14:33:53 vg Exp $
4 -- .KEEP_STATE state file management
7 -- Three routines to interface to the .KEEP_STATE state file.
9 -- Read_state() - reads the state file if any.
10 -- Write_state() - writes the state file.
12 -- Check_state(cp,how) - checks an entry returns 0 or 1
13 -- and updates the entry.
16 -- Dennis Vadura, dvadura@dmake.wticorp.com
19 -- http://dmake.wticorp.com/
22 -- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
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.
29 -- Use cvs log to obtain detailed change logs.
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 */
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);
48 static int _my_fgets
ANSI((char *, int, FILE *));
58 if( (fp
= Search_file(".KEEP_STATE", &_st_file
)) != NIL(FILE) )
60 if( _my_fgets( sizeb
, 20, fp
) )
62 int size
= atol(sizeb
);
63 buf
= MALLOC(size
+2, char);
65 while( _my_fgets(buf
, size
, fp
) )
67 TALLOC(sp
, 1, KSTATE
);
68 sp
->st_name
= DmStrDup(buf
);
69 (void) Hash(buf
, &sp
->st_nkey
);
70 if( _my_fgets(buf
, size
, fp
) )
71 sp
->st_count
= atoi(buf
);
72 if( _my_fgets(buf
, size
, fp
) )
73 sp
->st_dkey
= (uint32
) atol(buf
);
74 if( _my_fgets(buf
, size
, fp
) )
75 sp
->st_key
= (uint32
) atol(buf
);
80 if( _st_head
== NIL(KSTATE
) )
83 _st_tail
->st_next
= sp
;
96 static int in_write
= 0;
97 register KSTATEPTR sp
;
100 if( !_st_upd
|| !_st_file
|| (_st_file
&& !*_st_file
) ||
101 Trace
|| in_write
) return;
104 if( (fp
= Openfile(_st_file
, TRUE
, TRUE
)) != NIL(FILE) ) {
108 for( sp
= _st_head
; sp
; sp
=sp
->st_next
)
109 if( (tmplen
= strlen(sp
->st_name
)+2) > maxlen
)
112 /* A nice arbitrary minimum size */
113 if( maxlen
< 20 ) maxlen
= 20;
114 fprintf( fp
, "%d\n", maxlen
);
116 for( sp
= _st_head
; sp
; sp
=sp
->st_next
) {
120 if( Search_table(Defs
, sp
->st_name
, &hv
, &hk
) ) {
121 fprintf( fp
, "%s\n", sp
->st_name
);
122 fprintf( fp
, "%d\n", sp
->st_count
);
123 /* long unsigned can be != uint32, silence the warning. */
124 fprintf( fp
, "%lu\n", (unsigned long)sp
->st_dkey
);
125 fprintf( fp
, "%lu\n", (unsigned long)sp
->st_key
);
132 Fatal("Cannot open STATE file %s", _st_file
);
139 Check_state( cp
, recipes
, maxrcp
)
153 if( !_st_file
|| (_st_file
&& !*_st_file
) || Trace
)
156 if( strcmp(cp
->CE_NAME
,".REMOVE") == 0
157 || (cp
->ce_attr
& (A_PHONY
|A_NOSTATE
)) )
160 (void) Hash( cp
->CE_NAME
, &nkey
); thkey
= nkey
+ (uint32
) cp
->ce_count
;
161 (void) Hash( Pwd
, &dkey
); thkey
+= dkey
;
163 Suppress_temp_file
= TRUE
;
164 for( i
=0 ; i
<maxrcp
; i
++ )
165 for(sp
=recipes
[i
]; sp
!= NIL(STRING
); sp
=sp
->st_next
) {
166 CELLPTR svct
= Current_target
;
168 t_attr silent
= (Glob_attr
& A_SILENT
);
171 Glob_attr
|= A_SILENT
;
172 cmnd
= Expand(sp
->st_string
);
173 Glob_attr
= (Glob_attr
& ~A_SILENT
)|silent
;
174 Current_target
= svct
;
176 (void) Hash(cmnd
, &hkey
); thkey
+= hkey
;
179 Suppress_temp_file
= FALSE
;
181 for( st
=_st_head
; st
!= NIL(KSTATE
); st
=st
->st_next
) {
182 if( st
->st_nkey
== nkey
183 && st
->st_dkey
== dkey
184 && st
->st_count
== cp
->ce_count
185 && !strcmp(cp
->CE_NAME
, st
->st_name
) )
189 if( st
== NIL(KSTATE
) ) {
192 TALLOC(nst
, 1, KSTATE
);
193 nst
->st_name
= cp
->CE_NAME
;
197 nst
->st_count
= cp
->ce_count
;
199 if( _st_head
== NIL(KSTATE
) )
202 _st_tail
->st_next
= nst
;
207 else if( st
->st_key
!= thkey
) {
209 _st_upd
= update
= TRUE
;
212 return(st
!= NIL(KSTATE
) && update
);
217 _my_fgets(buf
, size
, fp
)
224 if( fgets(buf
, size
, fp
) == NULL
) return(0);
226 if( (p
=strrchr(buf
,'\n')) != NIL(char) ) *p
='\0';
227 if( (p
=strrchr(buf
,'\r')) != NIL(char) ) *p
='\0';