dmake/dmake/unix/gno/state.c

231 lines
5.5 KiB
C

/* RCS -- $Header: /u/dvadura/src/generic/dmake/src/RCS/state.c,v 1.2 1992/04/07 04:42:46 dvadura Exp $
-- SYNOPSIS -- .KEEP_STATE state file management
--
-- DESCRIPTION
-- Three routines to interface to the .KEEP_STATE state file.
--
-- Read_state() - reads the state file if any.
-- Write_state() - writes the state file.
--
-- Check_state(cp,how) - checks an entry returns 0 or 1
-- and updates the entry.
--
-- AUTHOR
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
--
-- COPYRIGHT
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- (version 1), as published by the Free Software Foundation, and
-- found in the file 'LICENSE' included with this distribution.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
--
-- LOG
-- $Log: state.c,v $
* Revision 1.2 1992/04/07 04:42:46 dvadura
* Removed a parameter to call of Closefile(), it doesn't need one.
*
* Revision 1.1 1992/01/24 03:27:05 dvadura
* dmake Version 3.8, Initial revision
*
*/
#include "extern.h"
typedef struct se {
char *st_name; /* name of cell */
uint32 st_nkey; /* name hash key */
int st_count; /* how count for how */
uint32 st_dkey; /* directory hash key */
uint32 st_key; /* hash key */
struct se *st_next;
} KSTATE, *KSTATEPTR;
static KSTATEPTR _st_head = NIL(KSTATE);
static KSTATEPTR _st_tail = NIL(KSTATE);
static int _st_upd = FALSE;
static char *_st_file = NIL(char);
static int _my_fgets ANSI((char *, int, FILE *));
PUBLIC void
Read_state(void)
{
char *buf;
char sizeb[20];
int size;
FILE *fp;
KSTATEPTR sp;
if( (fp = Search_file(".KEEP_STATE", &_st_file)) != NIL(FILE) ) {
if( _my_fgets( sizeb, 20, fp ) ) {
size = atol(sizeb);
buf = MALLOC(size+2, char);
while( _my_fgets(buf, size, fp) ) {
TALLOC(sp, 1, KSTATE);
sp->st_name = _strdup(buf);
(void) Hash(buf, &sp->st_nkey);
if( _my_fgets(buf, size, fp) ) sp->st_count = atoi(buf);
if( _my_fgets(buf, size, fp) ) sp->st_dkey = (uint32) atol(buf);
if( _my_fgets(buf, size, fp) )
sp->st_key = (uint32) atol(buf);
else {
FREE(sp);
break;
}
if( _st_head == NIL(KSTATE) )
_st_head = sp;
else
_st_tail->st_next = sp;
_st_tail = sp;
}
FREE(buf);
}
Closefile();
}
}
PUBLIC void
Write_state(void)
{
static int in_write = 0;
register KSTATEPTR sp;
FILE *fp;
if( !_st_upd || !_st_file || (_st_file && !*_st_file) ||
Trace || in_write ) return;
in_write++;
if( (fp = Openfile(_st_file, TRUE, TRUE)) != NIL(FILE) ) {
int maxlen = 0;
int tmplen;
for( sp = _st_head; sp; sp=sp->st_next )
if( (tmplen = strlen(sp->st_name)+2) > maxlen )
maxlen = tmplen;
/* A nice arbitrary minimum size */
if( maxlen < 20 ) maxlen = 20;
fprintf( fp, "%d\n", maxlen );
for( sp = _st_head; sp; sp=sp->st_next ) {
uint16 hv;
uint32 hk;
if( Search_table(Defs, sp->st_name, &hv, &hk) ) {
fprintf( fp, "%s\n", sp->st_name );
fprintf( fp, "%d\n", sp->st_count );
fprintf( fp, "%lu\n", sp->st_dkey );
fprintf( fp, "%lu\n", sp->st_key );
}
}
Closefile();
}
else
Fatal("Cannot open STATE file %s", _st_file);
in_write = 0;
}
PUBLIC int
Check_state(
CELLPTR cp,
STRINGPTR *recipes,
int maxrcp)
{
KSTATEPTR st;
STRINGPTR sp;
int i;
uint32 thkey;
uint32 hkey;
uint32 nkey;
uint32 dkey;
int update = FALSE;
if( strcmp(cp->CE_NAME,".REMOVE") == 0
|| (cp->ce_attr & (A_PHONY|A_NOSTATE)) )
return(FALSE);
(void) Hash( cp->CE_NAME, &nkey ); thkey = nkey + (uint32) cp->ce_count;
(void) Hash( Pwd, &dkey ); thkey += dkey;
Suppress_temp_file = TRUE;
for( i=0 ; i<maxrcp; i++ )
for(sp=recipes[i]; sp != NIL(STRING); sp=sp->st_next ) {
char *cmnd = Expand(sp->st_string);
(void) Hash(cmnd, &hkey); thkey += hkey;
FREE(cmnd);
}
Suppress_temp_file = FALSE;
for( st=_st_head; st != NIL(KSTATE); st=st->st_next ) {
if( st->st_nkey == nkey
&& st->st_dkey == dkey
&& st->st_count == cp->ce_count
&& !strcmp(cp->CE_NAME, st->st_name) )
break;
}
if( st == NIL(KSTATE) ) {
KSTATEPTR nst;
TALLOC(nst, 1, KSTATE);
nst->st_name = cp->CE_NAME;
nst->st_nkey = nkey;
nst->st_dkey = dkey;
nst->st_key = thkey;
nst->st_count = cp->ce_count;
if( _st_head == NIL(KSTATE) )
_st_head = nst;
else
_st_tail->st_next = nst;
_st_tail = nst;
_st_upd = TRUE;
}
else if( st->st_key != thkey ) {
st->st_key = thkey;
_st_upd = update = TRUE;
}
return(st != NIL(KSTATE) && update);
}
static int
_my_fgets(
char *buf,
int size,
FILE *fp)
{
char *p;
if( fgets(buf, size, fp) == NULL ) return(0);
if( (p=strrchr(buf,'\n')) != NIL(char) ) *p='\0';
return(1);
}