diff options
Diffstat (limited to 'dmake/state.c')
-rw-r--r-- | dmake/state.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/dmake/state.c b/dmake/state.c new file mode 100644 index 000000000000..7b5a2fe79ab8 --- /dev/null +++ b/dmake/state.c @@ -0,0 +1,229 @@ +/* RCS $Id: state.c,v 1.1.1.1 2000-09-22 15:33:25 hr 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]; + 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 ); + 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( 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); +} |