update dev300-m58
[ooovba.git] / dmake / state.c
blob92a5af4f7ebe8a1726f6663b922a11d5c2fcb9ac
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.
12 -- Check_state(cp,how) - checks an entry returns 0 or 1
13 -- and updates the entry.
15 -- AUTHOR
16 -- Dennis Vadura, dvadura@dmake.wticorp.com
18 -- WWW
19 -- http://dmake.wticorp.com/
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.
28 -- LOG
29 -- Use cvs log to obtain detailed change logs.
32 #include "extern.h"
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;
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 *));
50 PUBLIC void
51 Read_state()
53 char *buf;
54 char sizeb[20];
55 int size;
56 FILE *fp;
57 KSTATEPTR sp;
59 if( (fp = Search_file(".KEEP_STATE", &_st_file)) != NIL(FILE) ) {
60 if( _my_fgets( sizeb, 20, fp ) ) {
61 size = atol(sizeb);
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);
74 else {
75 FREE(sp);
76 break;
79 if( _st_head == NIL(KSTATE) )
80 _st_head = sp;
81 else
82 _st_tail->st_next = sp;
84 _st_tail = sp;
87 FREE(buf);
90 Closefile();
95 PUBLIC void
96 Write_state()
98 static int in_write = 0;
99 register KSTATEPTR sp;
100 FILE *fp;
102 if( !_st_upd || !_st_file || (_st_file && !*_st_file) ||
103 Trace || in_write ) return;
105 in_write++;
106 if( (fp = Openfile(_st_file, TRUE, TRUE)) != NIL(FILE) ) {
107 int maxlen = 0;
108 int tmplen;
110 for( sp = _st_head; sp; sp=sp->st_next )
111 if( (tmplen = strlen(sp->st_name)+2) > maxlen )
112 maxlen = tmplen;
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 ) {
119 uint16 hv;
120 uint32 hk;
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 );
131 Closefile();
133 else
134 Fatal("Cannot open STATE file %s", _st_file);
136 in_write = 0;
140 PUBLIC int
141 Check_state( cp, recipes, maxrcp )
142 CELLPTR cp;
143 STRINGPTR *recipes;
144 int maxrcp;
146 KSTATEPTR st;
147 STRINGPTR sp;
148 int i;
149 uint32 thkey;
150 uint32 hkey;
151 uint32 nkey;
152 uint32 dkey;
153 int update = FALSE;
155 if( !_st_file || (_st_file && !*_st_file) || Trace )
156 return(FALSE);
158 if( strcmp(cp->CE_NAME,".REMOVE") == 0
159 || (cp->ce_attr & (A_PHONY|A_NOSTATE)) )
160 return(FALSE);
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;
169 char *cmnd;
170 t_attr silent = (Glob_attr & A_SILENT);
172 Current_target = cp;
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;
179 FREE(cmnd);
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) )
188 break;
191 if( st == NIL(KSTATE) ) {
192 KSTATEPTR nst;
194 TALLOC(nst, 1, KSTATE);
195 nst->st_name = cp->CE_NAME;
196 nst->st_nkey = nkey;
197 nst->st_dkey = dkey;
198 nst->st_key = thkey;
199 nst->st_count = cp->ce_count;
201 if( _st_head == NIL(KSTATE) )
202 _st_head = nst;
203 else
204 _st_tail->st_next = nst;
206 _st_tail = nst;
207 _st_upd = TRUE;
209 else if( st->st_key != thkey ) {
210 st->st_key = thkey;
211 _st_upd = update = TRUE;
214 return(st != NIL(KSTATE) && update);
218 static int
219 _my_fgets(buf, size, fp)
220 char *buf;
221 int size;
222 FILE *fp;
224 char *p;
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';
230 return(1);