Source file: /~heha/hs/[Download]borg.zip/GNAME.CPP

/************************************************************************
*	       gname.cpp						*
* generic name class							*
* the basic gname class consists of a name and a location, and these	*
* are the basic management functions for the class. The class is	*
* inherited by names, exports and imports which are all treated very	*
* slightly differently. These are essentially the common routines	*
* The gname class itself inherits the list class for management of the	*
* array of named locations.						*
************************************************************************/

#include <windows.h>

#include "gname.h"
#include "disasm.h"
#include "data.h"
#include "debug.h"

#ifdef NEW_GNAME
gnameitem::gnameitem() { name=NULL;}
gnameitem::~gnameitem() {
 if (name)
   delete name;
}
#endif
/************************************************************************
* gname constructor function						*
************************************************************************/
gname::gname() { }

/************************************************************************
* gname destructor function						*
* - empty. the deletion of the list is carried out by the list class	*
*   and by the deletion function					*
************************************************************************/
gname::~gname() { }

/************************************************************************
* gname compare function						*
* - the compare function for ordering the list of names			*
* - the names are kept in location order				*
************************************************************************/
int gname::compare(gnameitem *i,gnameitem *j) {
 if (i->addr==j->addr) return 0;
 if (i->addr>j->addr)  return 1;
 return -1;
}

/************************************************************************
* gname delete function							*
* - overrides the stnadard gnamefunc delete function			*
************************************************************************/
#ifndef NEW_GNAME
void gname::delfunc(gnameitem *i) { // delete name.
 delete i->name;
  // delete gnameitem.
 delete i;
}
#endif
/************************************************************************
* addname								*
* - this is to add a name to the list of names.				*
* - if the address is not covered in our list of segments then we	*
*   ignore the request							*
* - we check that it is ok to name the location before naming it. This	*
*   basically ensures that names cannot be added in the middle of a	*
*   disassembled instruction, etc. It should not affect imports/exports *
*   since these will be named prior to disassembly			*
* - the name is copied and a new string created for it, so the calling	*
*   function must delete any memory created to hold the name		*
* - if the same location is named twice then the first name is deleted	*
* - the name is added to the disassembly so that it appears in the	*
*   listing.								*
* - naming a location with "" results in any name being deleted		*
************************************************************************/
BOOL gname::addname(lptr loc,char *nm) {
 gnameitem *newname,*checkdup;
 dsegitem *l_ds;
  // check for non-existant address added v2.20
 l_ds=dta->findseg(loc);
 if (!l_ds) return FALSE;
 if (!dsm->oktoname(loc)) return FALSE; // check not in the middle of an instruction.
 if (findname(nm)) return FALSE;
 newname=new gnameitem;
 newname->name=new char[lstrlen(nm)+1];
 lstrcpy(newname->name,nm);
 demangle(&newname->name);
 newname->addr=loc;
 checkdup=find(newname);
  // just add it once.
 if (checkdup) {
  if (NamesBox) PostMessage(NamesBox,WM_DELETENAME,0,(LPARAM)checkdup);
  if (checkdup->addr==loc) {
   delete checkdup->name;
   checkdup->name=newname->name;
   delete newname;
   dsm->delcomment(loc,dsmnameloc);
   if (lstrlen(checkdup->name)) {
    dsm->discomment(loc,dsmnameloc,(byte *)checkdup->name);
   }else{
    delfrom(checkdup);
   }
   return TRUE;
  }
 }
 if (!lstrlen(newname->name)) { // bugfix by Mark Ogden
  delete newname->name;
  delete newname;
  return TRUE;
 }
 checkdup=addto(newname);
 if (NamesBox) PostMessage(NamesBox,WM_ADDNAME,0,(LPARAM)checkdup);
 dsm->discomment(loc,dsmnameloc,(byte *)newname->name);
  // NB - no need for this anymore. Need to ensure that
  // printing of names is done as :
  // if names.isname() ...
  // else if imports.isname()...
  // else if export.isexport()...
  // so names aren't printed twice, and import names,etc are retained always
  //if(dta.findseg(loc)!=NULL)name.addname(loc,nm);
 return TRUE;
}

BOOL gname::findname(LPCTSTR nm) {
// Search for string in the list
 gnameitem *i;
 resetiterator();
 while (i=nextiterator()) {
  if (!lstrcmpi(i->name,nm)) return TRUE;
 }
 return FALSE;
}

/************************************************************************
* isname								*
* - returns true if loc has a name					*
************************************************************************/
bool gname::isname(lptr loc)
{ gnameitem checkit,*findit;
  checkit.addr=loc;
  findit=find(&checkit);
  if(findit!=NULL)
    if(findit->addr==loc)
      return true;
  return false;
}

/************************************************************************
* isname								*
* - prints name to last buffer location in mainwindow buffering array	*
* - use with isname, for example:					*
*   if(name.isname(loc))name.printname(loc); etc			*
************************************************************************/
void gname::printname(lptr loc)
{ gnameitem checkit,*findit;
  checkit.addr=loc;
  findit=find(&checkit);
  if(findit!=NULL)
    cvd->LastPrintBuff("%s",findit->name);
}

/************************************************************************
* delname								*
* - used as a simple name deleter for a given location			*
* - also deletes the name from the disassembly listing			*
************************************************************************/
void gname::delname(lptr loc)
{ gnameitem dname,*checkdup;
  dname.addr=loc;
  checkdup=find(&dname);
  if(checkdup!=NULL)
    if(checkdup->addr==loc)
      delfrom(checkdup);
  dsm->delcomment(loc,dsmnameloc);
}

/************************************************************************
* getoffsfromname							*
* - this checks to see if a name is in the list, and if it is then it	*
*   returns the offset of its loc otherwise it returns 0. This function *
*   is used in generating the segment for imports in an NE file.	*
************************************************************************/
dword gname::getoffsfromname(char *nm)
{ gnameitem *t;
  resetiterator();
  t=nextiterator();
  while(t!=NULL)
  { if(!lstrcmp(t->name,nm))
      return t->addr.offs;
    t=nextiterator();
  }
  return 0;
}



Detected encoding: ASCII (7 bit)2