// Copyright (C) 1999-2003 Core Technologies. // // This file is part of tpasm. // // tpasm is free software; you can redistribute it and/or modify // it under the terms of the tpasm LICENSE AGREEMENT. // // tpasm 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 // tpasm LICENSE AGREEMENT for more details. // // You should have received a copy of the tpasm LICENSE AGREEMENT // along with tpasm; see the file "LICENSE.TXT". // File handling #include "include.h" #define PATH_SEP '/' // path separation character (change this for your OS if needed) struct PATH_HEADER { PATH_HEADER *nextPath; char pathName[1]; // variable length path name }; static PATH_HEADER *topPath, *bottomPath; void CloseTextOutputFile(FILE *theFile) // close the text output file { fclose(theFile); } FILE *OpenTextOutputFile(char *theName) // Open a file for writing text output into // If there is a problem, complain and return NULL { FILE *theFile; if(!(theFile=fopen(theName,"w"))) { ReportComplaint(true,"Could not open file '%s'\nOS Reports: %s\n",theName,strerror(errno)); } return(theFile); } void CloseBinaryOutputFile(FILE *theFile) // Close the binary output file { fclose(theFile); } FILE *OpenBinaryOutputFile(char *theName) // Open a file for writing binary output into // If there is a problem, complain and return NULL { FILE *theFile; if(!(theFile=fopen(theName,"wb"))) { ReportComplaint(true,"Could not open file '%s'\nOS Reports: %s\n",theName,strerror(errno)); } return(theFile); } static SYMTABLENODE *CreateFileNameSymbol(char *theName) // Create (or locate) an entry in the global file name symbol table for theName // NOTE: this table is used to keep track of all files accessed during assembly (across // all passes). // If there is a problem, return NULL { SYMTABLENODE *theNode; theNode=STFindNode(fileNameSymbols,theName); if(!theNode) // if node could not be located, try to create one { theNode=STAddEntryAtEnd(fileNameSymbols,theName,NULL); } return(theNode); } void CloseSourceFile(FILE *theFile) // Close the source file (leave symbol table entry around because // things created when parsing the file are still referencing it) { fclose(theFile); } FILE *OpenSourceFile(char *theName,bool huntForIt,SYMTABLENODE **fileNameSymbol) // Open a source/include file // If there is a problem, complain and return NULL // if huntForIt is true, then look through the include paths trying to locate // it. // If a file is successfully opened, a pointer to it is returned, along with // a pointer to a symbol table entry for its name { FILE *theFile; char newPath[MAXFILEPATH]; int nameLength; PATH_HEADER *thePath; strcpy(newPath,theName); if(!(theFile=fopen(newPath,"r+b"))) // try to open the passed file (open for writing so we fail if it is a directory) { if(huntForIt) // if we failed, see if we need to hunt for it { nameLength=strlen(theName); thePath=topPath; while(thePath&&!theFile) { if(nameLength+strlen(thePath->pathName)pathName,theName); theFile=fopen(newPath,"rb"); } thePath=thePath->nextPath; } } } if(theFile) { if(((*fileNameSymbol)=CreateFileNameSymbol(newPath))) { return(theFile); } else { AssemblyComplaint(NULL,true,"Failed to create file name symbol table entry\n"); } fclose(theFile); } else { AssemblyComplaint(NULL,true,"Could not open source file '%s': %s\n",theName,strerror(errno)); } return(NULL); } bool AddIncludePath(char *thePathName) // Add thePath to the list of paths to be searched for include files // If there is a problem, return false { int length; PATH_HEADER *thePath; bool addPathSep; length=strlen(thePathName); addPathSep=false; if(length&&thePathName[length-1]!=PATH_SEP) // see if we need to add a path separator to the end of the path { addPathSep=true; length++; // make room for it } if((thePath=(PATH_HEADER *)NewPtr(sizeof(PATH_HEADER)+length))) { strcpy(&thePath->pathName[0],thePathName); // copy over the path name if(addPathSep) // see if need to add seperator { thePath->pathName[length-1]=PATH_SEP; thePath->pathName[length]='\0'; } // link this to the list at the end (so they are searched in the order given) thePath->nextPath=NULL; if(bottomPath) { bottomPath->nextPath=thePath; bottomPath=thePath; } else { topPath=bottomPath=thePath; } } return(thePath!=NULL); } void UnInitFiles() // undo what InitFiles did { PATH_HEADER *nextPath; while(topPath) { nextPath=topPath->nextPath; DisposePtr(topPath); topPath=nextPath; } STDisposeSymbolTable(fileNameSymbols); // get rid of the file names symbol table } bool InitFiles() // Initialize file handling { if((fileNameSymbols=STNewSymbolTable())) { topPath=bottomPath=NULL; return(true); } return(false); }