office-gobmx/dmake/state.c

231 lines
5.3 KiB
C
Raw Normal View History

/* RCS $Id: state.c,v 1.2 2006-04-20 12:02:17 hr Exp $
2000-09-22 09:33:37 -05:00
--
-- 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];
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 = 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 );
2000-09-22 09:33:37 -05:00
}
}
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';
return(1);
}