229 lines
5.6 KiB
C
229 lines
5.6 KiB
C
/* RCS $Id: state.c,v 1.3 2007-09-20 14:33:53 vg 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@dmake.wticorp.com
|
|
--
|
|
-- WWW
|
|
-- http://dmake.wticorp.com/
|
|
--
|
|
-- COPYRIGHT
|
|
-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
|
|
--
|
|
-- This program is NOT free software; you can redistribute it and/or
|
|
-- modify it under the terms of the Software License Agreement Provided
|
|
-- in the file <distribution-root>/readme/license.txt.
|
|
--
|
|
-- LOG
|
|
-- Use cvs log to obtain detailed change logs.
|
|
*/
|
|
|
|
#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()
|
|
{
|
|
char *buf;
|
|
char sizeb[20];
|
|
FILE *fp;
|
|
KSTATEPTR sp;
|
|
|
|
if( (fp = Search_file(".KEEP_STATE", &_st_file)) != NIL(FILE) )
|
|
{
|
|
if( _my_fgets( sizeb, 20, fp ) )
|
|
{
|
|
int size = atol(sizeb);
|
|
buf = MALLOC(size+2, char);
|
|
|
|
while( _my_fgets(buf, size, fp) )
|
|
{
|
|
TALLOC(sp, 1, KSTATE);
|
|
sp->st_name = DmStrDup(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()
|
|
{
|
|
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 );
|
|
/* long unsigned can be != uint32, silence the warning. */
|
|
fprintf( fp, "%lu\n", (unsigned long)sp->st_dkey );
|
|
fprintf( fp, "%lu\n", (unsigned long)sp->st_key );
|
|
}
|
|
}
|
|
|
|
Closefile();
|
|
}
|
|
else
|
|
Fatal("Cannot open STATE file %s", _st_file);
|
|
|
|
in_write = 0;
|
|
}
|
|
|
|
|
|
PUBLIC int
|
|
Check_state( cp, recipes, maxrcp )
|
|
CELLPTR cp;
|
|
STRINGPTR *recipes;
|
|
int maxrcp;
|
|
{
|
|
KSTATEPTR st;
|
|
STRINGPTR sp;
|
|
int i;
|
|
uint32 thkey;
|
|
uint32 hkey;
|
|
uint32 nkey;
|
|
uint32 dkey;
|
|
int update = FALSE;
|
|
|
|
if( !_st_file || (_st_file && !*_st_file) || Trace )
|
|
return(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 ) {
|
|
CELLPTR svct = Current_target;
|
|
char *cmnd;
|
|
t_attr silent = (Glob_attr & A_SILENT);
|
|
|
|
Current_target = cp;
|
|
Glob_attr |= A_SILENT;
|
|
cmnd = Expand(sp->st_string);
|
|
Glob_attr = (Glob_attr & ~A_SILENT)|silent;
|
|
Current_target = svct;
|
|
|
|
(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(buf, size, fp)
|
|
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';
|
|
if( (p=strrchr(buf,'\r')) != NIL(char) ) *p='\0';
|
|
return(1);
|
|
}
|