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 *));
59 if( (fp
= Search_file(".KEEP_STATE", &_st_file
)) != NIL(FILE) ) {
60 if( _my_fgets( sizeb
, 20, fp
) ) {
62 buf
= MALLOC(size
+2, char);
64 while( _my_fgets(buf
, size
, fp
) ) {
65 TALLOC(sp
, 1, KSTATE
);
66 sp
->st_name
= DmStrDup(buf
);
67 (void) Hash(buf
, &sp
->st_nkey
);
69 if( _my_fgets(buf
, size
, fp
) ) sp
->st_count
= atoi(buf
);
70 if( _my_fgets(buf
, size
, fp
) ) sp
->st_dkey
= (uint32
) atol(buf
);
72 if( _my_fgets(buf
, size
, fp
) )
73 sp
->st_key
= (uint32
) atol(buf
);
79 if( _st_head
== NIL(KSTATE
) )
82 _st_tail
->st_next
= sp
;
98 static int in_write
= 0;
99 register KSTATEPTR sp
;
102 if( !_st_upd
|| !_st_file
|| (_st_file
&& !*_st_file
) ||
103 Trace
|| in_write
) return;
106 if( (fp
= Openfile(_st_file
, TRUE
, TRUE
)) != NIL(FILE) ) {
110 for( sp
= _st_head
; sp
; sp
=sp
->st_next
)
111 if( (tmplen
= strlen(sp
->st_name
)+2) > maxlen
)
114 /* A nice arbitrary minimum size */
115 if( maxlen
< 20 ) maxlen
= 20;
116 fprintf( fp
, "%d\n", maxlen
);
118 for( sp
= _st_head
; sp
; sp
=sp
->st_next
) {
122 if( Search_table(Defs
, sp
->st_name
, &hv
, &hk
) ) {
123 fprintf( fp
, "%s\n", sp
->st_name
);
124 fprintf( fp
, "%d\n", sp
->st_count
);
125 /* long unsigned can be != uint32, silence the warning. */
126 fprintf( fp
, "%lu\n", (unsigned long)sp
->st_dkey
);
127 fprintf( fp
, "%lu\n", (unsigned long)sp
->st_key
);
134 Fatal("Cannot open STATE file %s", _st_file
);
141 Check_state( cp
, recipes
, maxrcp
)
155 if( !_st_file
|| (_st_file
&& !*_st_file
) || Trace
)
158 if( strcmp(cp
->CE_NAME
,".REMOVE") == 0
159 || (cp
->ce_attr
& (A_PHONY
|A_NOSTATE
)) )
162 (void) Hash( cp
->CE_NAME
, &nkey
); thkey
= nkey
+ (uint32
) cp
->ce_count
;
163 (void) Hash( Pwd
, &dkey
); thkey
+= dkey
;
165 Suppress_temp_file
= TRUE
;
166 for( i
=0 ; i
<maxrcp
; i
++ )
167 for(sp
=recipes
[i
]; sp
!= NIL(STRING
); sp
=sp
->st_next
) {
168 CELLPTR svct
= Current_target
;
170 t_attr silent
= (Glob_attr
& A_SILENT
);
173 Glob_attr
|= A_SILENT
;
174 cmnd
= Expand(sp
->st_string
);
175 Glob_attr
= (Glob_attr
& ~A_SILENT
)|silent
;
176 Current_target
= svct
;
178 (void) Hash(cmnd
, &hkey
); thkey
+= hkey
;
181 Suppress_temp_file
= FALSE
;
183 for( st
=_st_head
; st
!= NIL(KSTATE
); st
=st
->st_next
) {
184 if( st
->st_nkey
== nkey
185 && st
->st_dkey
== dkey
186 && st
->st_count
== cp
->ce_count
187 && !strcmp(cp
->CE_NAME
, st
->st_name
) )
191 if( st
== NIL(KSTATE
) ) {
194 TALLOC(nst
, 1, KSTATE
);
195 nst
->st_name
= cp
->CE_NAME
;
199 nst
->st_count
= cp
->ce_count
;
201 if( _st_head
== NIL(KSTATE
) )
204 _st_tail
->st_next
= nst
;
209 else if( st
->st_key
!= thkey
) {
211 _st_upd
= update
= TRUE
;
214 return(st
!= NIL(KSTATE
) && update
);
219 _my_fgets(buf
, size
, fp
)
226 if( fgets(buf
, size
, fp
) == NULL
) return(0);
228 if( (p
=strrchr(buf
,'\n')) != NIL(char) ) *p
='\0';
229 if( (p
=strrchr(buf
,'\r')) != NIL(char) ) *p
='\0';