| /* RCS $Id: struct.h,v 1.2 2006-06-29 11:24:50 ihi Exp $ |
| -- |
| -- SYNOPSIS |
| -- Structure definitions |
| -- |
| -- DESCRIPTION |
| -- dmake main data structure definitions. See each of the individual |
| -- struct declarations for more detailed information on the defined |
| -- fields and their use. |
| -- |
| -- 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. |
| */ |
| |
| #ifndef _STRUCT_INCLUDED_ |
| #define _STRUCT_INCLUDED_ |
| |
| typedef uint32 t_attr; |
| |
| /* The following struct is the cell used in the hash table. |
| * NOTE: It contains the actual hash value. This allows the hash table |
| * insertion to compare hash values and to do a string compare only |
| * for entries that have matching hash_key values. This elliminates |
| * 99.9999% of all extraneous string compare operations when searching |
| * a hash table chain for matching entries. */ |
| |
| typedef struct hcell { |
| struct hcell *ht_next; /* next entry in the hash table */ |
| struct hcell *ht_link; /* for temporary lists */ |
| char *ht_name; /* name of this cell */ |
| char *ht_value; /* cell value if any */ |
| uint32 ht_hash; /* actual hash_key of cell */ |
| int ht_flag; /* flags belonging to hash entry */ |
| |
| /* NOTE: some macros have corresponding variables defined |
| * that control program behaviour. For these macros a |
| * bit of ht_flag indicates the variable value will be set, and the |
| * type of the value that will be set. |
| * |
| * The struct below contains a mask for bit variables, and a |
| * pointer to the global STATIC location for that variable. |
| * String and char variables point to the same place as ht_value |
| * and must be updated when ht_value changes, bit variables must |
| * have their value recomputed. See Def_macro code for more |
| * details. |
| * |
| * NOTE: Macro variables and Targets are always distinct. Thus |
| * the value union contains pointers back at cells that own |
| * a particular name entry. A conflict in this can never |
| * arise, ie pointers at cells will never be used as |
| * values for a macro variable, since the cell and macro |
| * name spaces are completely distinct. */ |
| |
| struct { |
| int mv_mask; /* bit mask for bit variable */ |
| union { |
| char** mv_svar;/* ptr to string valued glob var */ |
| char* mv_cvar;/* ptr to char valued glob var */ |
| t_attr* mv_bvar;/* ptr to bit valued glob var */ |
| int* mv_ivar;/* ptr to int valued glob var */ |
| |
| struct { |
| struct tcell* ht_owner;/* ptr to CELL owning name */ |
| struct tcell* ht_root; /* root ptr for explode */ |
| } ht; |
| } val; |
| } var; /* variable's static equivalent */ |
| } HASH, *HASHPTR; |
| |
| #define MV_MASK var.mv_mask |
| #define MV_SVAR var.val.mv_svar |
| #define MV_CVAR var.val.mv_cvar |
| #define MV_BVAR var.val.mv_bvar |
| #define MV_IVAR var.val.mv_ivar |
| #define CP_OWNR var.val.ht.ht_owner |
| #define CP_ROOT var.val.ht.ht_root |
| |
| |
| |
| /* This struct holds the list of temporary files that have been created. |
| * It gets unlinked when Quit is called due to an execution error */ |
| typedef struct flst { |
| char *fl_name; /* file name */ |
| FILE *fl_file; /* the open file */ |
| struct flst *fl_next; /* pointer to next file */ |
| } FILELIST, *FILELISTPTR; |
| |
| |
| /* The next struct is used to link together prerequisite lists. It |
| * is also used to link multiple targets together. */ |
| typedef struct lcell { |
| struct tcell *cl_prq; /* link to a prerequisite */ |
| struct lcell *cl_next; /* next cell on dependency list */ |
| int cl_flag; /* flags for link cell */ |
| } LINK, *LINKPTR; |
| |
| |
| /* This is the structure of a target cell in the dag which represents the |
| * graph of dependencies. Each possible target is represented as a cell. |
| * |
| * Each cell contains a pointer to the hash table entry for this cell. |
| * The hash table entry records the name of the cell. */ |
| |
| typedef struct tcell { |
| struct hcell *ce_name; /* name of this cell */ |
| struct hcell *ce_pushed; /* local pushed macro definitions */ |
| |
| /* Def_cell sets ce_all.cl_prq to point back to itself. .UPDATEALL |
| * uses ce_all.cl_next to link the cells together. */ |
| struct lcell ce_all; |
| |
| /* If set it points to first element of the list linked by ce_all. */ |
| struct tcell *ce_set; |
| struct tcell *ce_setdir; /* SETDIR ROOT pointer for this cell*/ |
| struct tcell *ce_link; /* link for temporary list making */ |
| struct tcell *ce_parent; /* used by inner loop, not a static */ |
| |
| struct lcell *ce_prq; /* list of prerequisites for cell */ |
| struct lcell *ce_prqorg; /* list of original prerequisites */ |
| struct lcell *ce_indprq; /* indirect prerequisites for % cell*/ |
| |
| struct str *ce_recipe; /* recipe for making this cell */ |
| FILELISTPTR ce_files; /* list of temporary files for cell */ |
| struct str *ce_cond; /* conditional macro assignments */ |
| |
| char *ce_per; /* value of % in %-meta expansion */ |
| char *ce_fname; /* file name associated with target */ |
| char *ce_lib; /* archive name, if A_LIBRARYM */ |
| char *ce_dir; /* value for .SETDIR attribute */ |
| |
| int ce_count; /* value for :: recipe set */ |
| int ce_index; /* value of count for next :: child */ |
| int ce_flag; /* all kinds of goodies */ |
| t_attr ce_attr; /* attributes for this target */ |
| time_t ce_time; /* time stamp value of target if any*/ |
| } CELL, *CELLPTR; |
| |
| #define CE_NAME ce_name->ht_name |
| #define CE_RECIPE ce_recipe |
| #define CE_PRQ ce_prq |
| #define CeMeToo(C) &((C)->ce_all) |
| #define CeNotMe(C) (C)->ce_all.cl_next |
| |
| |
| /* This struct represents that used by Get_token to return and control |
| * access to a token list inside a particular string. This gives the |
| * ability to access non overlapping tokens simultaneously from |
| * multiple strings. */ |
| |
| typedef struct { |
| char *tk_str; /* the string to search for tokens */ |
| char tk_cchar; /* current char under *str */ |
| int tk_quote; /* if we are scanning a quoted str */ |
| } TKSTR, *TKSTRPTR; |
| |
| |
| |
| /* Below is the struct used to represent a string. It points at possibly |
| * another string, since the set of rules for making a target is a collection |
| * of strings. */ |
| |
| |
| typedef struct str { |
| char *st_string; /* the string value */ |
| struct str *st_next; /* pointer to the next string */ |
| t_attr st_attr; /* attr for rule operations */ |
| } STRING, *STRINGPTR; |
| |
| |
| |
| /* These structs are used in processing of the % rules, and in building |
| * the NFA machine that is used to match an arbitrary target string to |
| * one of the % rules that is represented by each DFA */ |
| |
| typedef int16 statecnt; /* limits the max number of dfa states */ |
| |
| |
| /* Each state of the DFA contains four pieces of information. */ |
| typedef struct st { |
| struct st *no_match; /* state to go to if no match */ |
| struct st *match; /* state to go to if we do match */ |
| char symbol; /* symbol on which we transit */ |
| char action; /* action to perform if match */ |
| } STATE, *STATEPTR; |
| |
| |
| /* Each DFA machine looks like this. It must have two pointers that represent |
| * the value of % in the matched string, and it contains a pointer into the |
| * current state, as well as the array of all states. */ |
| typedef struct { |
| char *pstart; /* start of % string match */ |
| char *pend; /* end of % string match */ |
| STATEPTR c_state; /* current DFA state */ |
| CELLPTR node; /* % target represented by this DFA */ |
| STATEPTR states; /* table of states for the DFA */ |
| } DFA, *DFAPTR; |
| |
| |
| /* An NFA is a collection of DFA's. For each DFA we must know it's current |
| * state and where the next NFA is. */ |
| typedef struct nfa_machine { |
| DFAPTR dfa; /* The DFA for this eps transition */ |
| char status; /* DFA state */ |
| struct nfa_machine *next; /* the next DFA in NFA */ |
| } NFA, *NFAPTR; |
| |
| |
| |
| /* The next struct is used to link together DFA nodes for inference. */ |
| |
| typedef struct dfal { |
| struct tcell *dl_meta; /* link to %-meta cell */ |
| struct dfal *dl_next; /* next cell on matched DFA list*/ |
| struct dfal *dl_prev; /* prev cell on matched DFA list*/ |
| struct dfal *dl_member; /* used during subset calc */ |
| char dl_delete; /* used during subset calc */ |
| char *dl_per; /* value of % for matched DFA */ |
| statecnt dl_state; /* matched state of the DFA */ |
| int dl_prep; /* repetion count for the cell */ |
| } DFALINK, *DFALINKPTR; |
| |
| |
| /* This struct is used to store the stack of DFA sets during inference */ |
| typedef struct dfst { |
| DFALINKPTR df_set; /* pointer to the set */ |
| struct dfst *df_next; /* next element in the stack */ |
| } DFASET, *DFASETPTR; |
| |
| |
| /* We need sets of items during inference, here is the item, we form sets |
| * by linking them together. */ |
| |
| typedef struct ic { |
| CELLPTR ic_meta; /* Edge we used to make this cell*/ |
| DFALINKPTR ic_dfa; /* Dfa that we matched against */ |
| CELLPTR ic_setdirroot; /* setdir root pointer for cell */ |
| DFASET ic_dfastack; /* set of dfas we're working with*/ |
| int ic_dmax; /* max depth of cycles in graph */ |
| char *ic_name; /* name of the cell to insert */ |
| char *ic_dir; /* dir to CD to prior to recurse */ |
| struct ic *ic_next; /* next pointer to link */ |
| struct ic *ic_link; /* link all ICELL'S together */ |
| struct ic *ic_parent; /* pointer to post-requisite */ |
| char ic_flag; /* flag, used for NOINFER only */ |
| char ic_exists; /* TRUE if prerequisite exists */ |
| } ICELL, *ICELLPTR; |
| |
| #endif |