home *** CD-ROM | disk | FTP | other *** search
- /* $Header: Src:Dcc/BindNames/rcs/AssignNode.c,v 1.5 1995/06/21 17:24:04 cmh Exp cmh $
- *
- * BindNamesII: Handy assign/path maker.
- * Copyright (C) 1994-95 Magnus Holmgren <cmh@augs.se>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty 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.
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <dos/exall.h>
-
- #include <clib/alib_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/utility_protos.h>
-
- #ifdef __GNUC__
- #include <inline/dos.h>
- #include <inline/exec.h>
- #include <inline/utility.h>
- #endif
-
- #include <string.h>
- #include "assignnode.h"
-
- #define Prototype extern
-
- #include "proto.h"
- #include "macros.h"
-
- #define ANSI_WHITE_ON "\x9b" "2m"
- #define ANSI_WHITE_OFF "\x9b" "22m"
-
-
- /* Duplicate a string. Use FreeVec() to free the duplicate. */
- STRPTR
- StrDup( STRPTR string )
- {
- STRPTR newString;
-
- if( ( newString = AllocVec( strlen( string ) + 1, MEMF_ANY ) ) )
- {
- strcpy( newString, string );
- }
-
- return( newString );
- }
-
-
- /* Scans the specified list of AssignNodes after an AssignNode with
- * the specified name. Case is ignored.
- */
- Prototype struct AssignNode *FindAssignNode( struct MinList *, STRPTR );
- struct AssignNode *
- FindAssignNode( struct MinList *start, STRPTR name )
- {
- struct AssignNode *node, *next;
-
- FOREACHNODE( start, node, next )
- {
- if( !Stricmp( node->Name, name ) )
- {
- break;
- }
- }
-
- return( node->Node.mln_Succ ? node : NULL );
- }
-
-
- /* Simply free a PathNode. If NULL, do nothing. */
- Prototype VOID FreePathNode( struct PathNode * );
- VOID
- FreePathNode( struct PathNode *node )
- {
- if( node )
- {
- FreeVec( node->Name );
- FreeVec( node );
- }
- }
-
-
- /* Create a PathNode with the specified name and priority. */
- struct PathNode *
- AllocPathNode( STRPTR name, BYTE pri )
- {
- struct PathNode *node;
-
- if( ( node = AllocVec( sizeof( struct PathNode ), MEMF_CLEAR ) ) )
- {
- node->Node.ln_Pri = pri;
-
- if( !( node->Name = StrDup( name ) ) )
- {
- FreeVec( node );
- node = NULL;
- }
- }
-
- return( node );
- }
-
-
- /* Simply free an AssignNode. If NULL, do nothing. */
- Prototype VOID FreeAssignNode( struct AssignNode * );
- VOID
- FreeAssignNode( struct AssignNode *node )
- {
- if( node )
- {
- struct PathNode *pathNode, *next;
-
- FOREACHNODE( &node->Path, pathNode, next )
- {
- FreePathNode( pathNode );
- }
-
- FreeVec( node->Alias );
- FreeVec( node->Name );
- FreeVec( node );
- }
- }
-
-
- /* Create an AssignNode with the specified attributes. Scans the list for
- * nodes with the same name. If found, the path targets will be added to
- * the old node.
- */
- Prototype struct AssignNode *AllocAssignNode( struct MinList *, STRPTR, STRPTR *, BYTE, STRPTR, WORD, WORD );
- struct AssignNode *
- AllocAssignNode(
- struct MinList *list,
- STRPTR name,
- STRPTR *path,
- BYTE pri,
- STRPTR alias,
- WORD type,
- WORD flags )
- {
- struct AssignNode *assignNode;
-
- /* Try to locate previous node */
- assignNode = FindAssignNode( list, name );
-
- if( assignNode || ( assignNode = AllocVec( sizeof( struct AssignNode ), MEMF_CLEAR ) ) )
- {
- struct PathNode *pathNode;
- BOOL add = FALSE;
-
- /* Adding to a previous node? */
- if( !assignNode->Name )
- {
- /* Nope, init new list */
- NewList( ( struct List * ) &( assignNode->Path ) );
- add = TRUE;
-
- if( !( assignNode->Name = StrDup( name ) ) )
- {
- goto error; /* This kind of goto:s can be accepted sometimes.. :) */
- }
- }
-
- if( alias && !assignNode->Alias && !( assignNode->Alias = StrDup( alias ) ) )
- {
- goto error;
- }
-
- /* Add the targets */
- for( ; *path; ++path )
- {
- if( ( pathNode = AllocPathNode( *path, pri ) ) )
- {
- Enqueue( ( struct List * ) &( assignNode->Path ),
- ( struct Node * ) pathNode );
- }
- else
- {
- goto error;
- }
- }
-
- assignNode->AssignType = type;
- assignNode->Flags |= flags;
-
- if( add )
- {
- AddTail( ( struct List * ) list, ( struct Node * ) assignNode );
- }
- }
-
- return( assignNode );
-
- error: FreeAssignNode( assignNode );
- return( NULL );
- }
-
-
- /* Free all nodes on the list, assuming they are AssignNodes. */
- Prototype VOID FreeAssignList( struct MinList * );
- VOID
- FreeAssignList( struct MinList *list )
- {
- struct AssignNode *node, *next;
-
- FOREACHNODE( list, node, next )
- {
- FreeAssignNode( node );
- }
-
- NewList( ( struct List * ) list );
- }
-
-
- /* Print the assinglist, in an Assign-like manner.
- * Also prints any accumulated errors.
- */
- Prototype VOID PrintAssignList( struct MinList * );
- VOID
- PrintAssignList( struct MinList *list )
- {
- struct AssignNode *node, *nextAssign;
- struct PathNode *pathNode, *nextPath;
- BOOL first;
-
- FOREACHNODE( list, node, nextAssign )
- {
- STRPTR str;
-
- /* Print assign name */
- Printf( ( node->Flags & ANF_ADD ) ? "%-18s+ " : "%-20s", ( LONG ) node->Name );
- first = TRUE;
-
- /* Print the target(s) */
- FOREACHNODE( &node->Path, pathNode, nextPath )
- {
- switch( node->AssignType )
- {
- case ASN_DEFER:
- str = "<%s>\n";
- break;
-
- case ASN_PATH:
- str = "[%s]\n";
- break;
-
- default:
- str = first ? "%s\n" : "\t\t + %s\n";
- }
-
- Printf( str, ( LONG ) pathNode->Name );
- first = FALSE;
- }
-
- /* Handle the errors. */
- if( node->Flags & ( ANF_FAILED | ANF_LOOP | ANF_BAD | ANF_BADPARENT ) )
- {
- Printf( " " ANSI_WHITE_ON "Failed because: " );
-
- if( node->Flags & ANF_FAILED )
- {
- PrintFault( node->IoErr, NULL );
- }
- else if( node->Flags & ANF_LOOP )
- {
- Printf( "part of an assign loop" );
- }
- else if( node->Flags & ANF_BADPARENT )
- {
- Printf( "parent assign failed" );
- }
- else
- {
- Printf( "bad assign (multiple targets for DEFER or PATH)" );
- }
-
- Printf( ANSI_WHITE_OFF "\n" );
- }
- }
- }
-