Source file: /~heha/hsn/borg.zip/COMMON.CPP

/************************************************************************
*		    common.cpp						*
* This includes the lptr class, and any other common functions that	*
* are needed.								*
* The lptr class is a class of 'long pointers' which contain a segment	*
* and an offset value.							*
* I have defined some arithmetic on these which make coding in Borg	*
* easier.								*
* Within Borg the seg/offset values should be well defined, ie unique.	*
* This means we do not have to test for seg1:offs1==seg2:offs2 where	*
* seg1!=seg2. Borg addresses should all be individual. [Of course this	*
* may make some coding of DOS exe's harder later on, but I dont believe *
* it will be a great burden.						*
************************************************************************/

#include <windows.h>
#include <string.h>

#include "common.h"
#include "dasm.h"
//#include "menuids.rh"
#include "resource.h"

/************************************************************************
* nlptr									*
* - this is a predefined null pointer					*
************************************************************************/
const lptr nlptr(0,0);

/************************************************************************
* lptr constructor with values						*
* - the standard constructor and destructor are defined in the header	*
*   as null functions. This constructor allows for declarations like	*
*   the nlptr declaration above						*
************************************************************************/
lptr::lptr(word seg,dword off)
{ segm=seg;
  offs=off;
}

/************************************************************************
* assign								*
* - this is an assign function for the lptr, to give it a specific	*
*   segment and offset combination.					*
************************************************************************/
void lptr::assign(word seg,dword off)
{ segm=seg;
  offs=off;
}

/************************************************************************
* between								*
* - returns true if loc >= lwb and loc <= upb				*
************************************************************************/
bool lptr::between(const lptr& lwb,const lptr& upb)
{ return ((*this>=lwb) && (*this<=upb));
}

/************************************************************************
* lptr == operator							*
************************************************************************/
bool lptr::operator==(const lptr& loc2)
{ return ((segm==loc2.segm)&&(offs==loc2.offs));
}

/************************************************************************
* lptr <= operator							*
* - this overload of <= is well defined given the constraints we have	*
*   placed on the lptr class. It allows simplification of code in many	*
*   of the lists and databases.						*
************************************************************************/
bool lptr::operator<=(const lptr& loc2)
{ if(segm!=loc2.segm)
    return (segm<=loc2.segm);
  return (offs<=loc2.offs);
}

/************************************************************************
* lptr >= operator							*
* - this overload of >= is well defined given the constraints we have	*
*   placed on the lptr class. It allows simplification of code in many	*
*   of the lists and databases.						*
************************************************************************/
bool lptr::operator>=(const lptr& loc2)
{ if(segm!=loc2.segm)
    return (segm>=loc2.segm);
  return (offs>=loc2.offs);
}

/************************************************************************
* lptr < operator							*
* - this overload of < is well defined given the constraints we have	*
*   placed on the lptr class. It allows simplification of code in many	*
*   of the lists and databases.						*
************************************************************************/
bool lptr::operator<(const lptr& loc2)
{ if(segm!=loc2.segm)
    return (segm<loc2.segm);
  return (offs<loc2.offs);
}

/************************************************************************
* lptr > operator							*
* - this overload of > is well defined given the constraints we have	*
*   placed on the lptr class. It allows simplification of code in many	*
*   of the lists and databases.						*
************************************************************************/
bool lptr::operator>(const lptr& loc2)
{ if(segm!=loc2.segm)
    return (segm>loc2.segm);
  return (offs>loc2.offs);
}

/************************************************************************
* lptr != operator							*
* - this overload of != is well defined given the constraints we have	*
*   placed on the lptr class. It allows simplification of code in many	*
*   of the lists and databases.						*
************************************************************************/
bool lptr::operator!=(const lptr& loc2)
{ return ((segm!=loc2.segm)||(offs!=loc2.offs));
}

/************************************************************************
* lptr + dword operator							*
* - this has been defined to allowed an expression like lptr r+1 to be	*
*   used. It simply adds the dword to the offset of the lptr, and does	*
*   not change the segment at all					*
************************************************************************/
lptr lptr::operator+(dword offs2)
{ lptr tmp;
  tmp.segm=segm;
  tmp.offs=offs+offs2;
  return tmp;
}

/************************************************************************
* lptr ++ operator							*
* - as for + dword we can define ++ similarly				*
* - note that in these functions offsets can wrap around but generally	*
*   this should not be a problem for us					*
************************************************************************/
// increment lptr.
lptr& lptr::operator++(int)
{ offs++;
  return *this;
}

/************************************************************************
* lptr += operator							*
* - An overload of +=, as for + and ++					*
************************************************************************/
lptr& lptr::operator+=(dword offs2)
{ offs+=offs2;
  return *this;
}

/************************************************************************
* lptr - (dword) operator						*
* - If we can add a dword then we take one away also....		*
************************************************************************/
lptr lptr::operator-(dword offs2)
{ lptr tmp;
  tmp.segm=segm;
  tmp.offs=offs-offs2;
  return tmp;
}

/************************************************************************
* lptr1 - lptr2 operator						*
* - I have overloaded - in two ways. The first, above, takes a dword	*
*   from an operator, by taking it from the lptrs offset. This overload *
*   allows the difference in two operators to be taken, and returns a	*
*   dword which is the difference in offsets. Now you should only	*
*   really be interested in this if the segments are the same. I found	*
*   it useful to make this definition because it greatly simplifies	*
*   code elsewhere. Note that with some complex expressions you need to *
*   force operator precedence, for example dword+(loc1-loc2)+dword2	*
*   type expressions need the brackets for force the - to be performed	*
*   first.								*
************************************************************************/
dword lptr::operator-(lptr& loc2)
{ return offs-loc2.offs;
}

/************************************************************************
* Basic Support Functions						*
************************************************************************/

/************************************************************************
* cleanstring								*
* - moved out of the disasm class build 211.				*
* - simply changes any strange characters in a string into an		*
*   underscore, used for generating automatic names from disassembled	*
*   strings.								*
************************************************************************/
void cleanstring(char *str) {
 unsigned i;
 for (i=0;i<(unsigned)lstrlen(str);i++) {
  if (!isalnum(str[i])) str[i]='_';
 }
}

/************************************************************************
* CenterWindow	replaced by resource					*
************************************************************************/

/************************************************************************
* demangle								*
* - this is a general string function. Name damangling is currently not *
*   very good, and I have some old Borland source code which could	*
*   improve this greatly......... just need to dig it out, rework it	*
*   for Borg, and put it in here now......				*
************************************************************************/
void demangle(char **nme)
{ unsigned char buff[256],buff2[256],*name;
  unsigned int namelen,i,j,k,atcount,bpoint;
  bool brac,pointer,rpointer;
  if(!options.demangle)
    return;
  atcount=0;
  i=0;
  j=0;
  bpoint=0;
  brac=false;
  name=(unsigned char *)(*nme);
  while(name[i])
  { if(name[i]=='@')
    { atcount++;
      if(atcount>1)
      { buff[j++]=':';
	buff[j++]=':';
      }
    }
    else if((name[i]=='$')&&(name[i+1]=='q')&&(!brac))
    { brac=true;
      bpoint=j;
      buff[j++]='(';
      i+=1;
    }
    else if((name[i]=='$')&&(name[i+1]=='x')&&(name[i+2]=='q')&&(!brac))
    { brac=true;
      bpoint=j;
      buff[j++]='(';
      i+=2;
    }
    else if(!strnicmp((char *)&name[i],"$bctr",5))
    { k=0;
      while((buff[k]!=':')&&(k<20))
      { buff[j++]=buff[k++];
      }
      i+=4;
    }
    else if(!strnicmp((char *)&name[i],"$bdtr",5))
    { k=0;
      buff[j++]='~';
      while((buff[k]!=':')&&(k<20))
      { buff[j++]=buff[k++];
      }
      i+=4;
    }
    else if(!strnicmp((char *)&name[i],"$bdla",5))
    { lstrcpy((char *)&buff[j],"delete");
      j+=6;
      i+=4;
    }
    else if(!strnicmp((char *)&name[i],"$bnwa",5))
    { lstrcpy((char *)&buff[j],"new");
      j+=3;
      i+=4;
    }
    else if(!strnicmp((char *)&name[i],"$bdele",6))
    { lstrcpy((char *)&buff[j],"delete");
      j+=6;
      i+=5;
    }
    else if(!strnicmp((char *)&name[i],"$bnew",5))
    { lstrcpy((char *)&buff[j],"new");
      j+=5;
      i+=4;
    }
    else
      buff[j++]=name[i];
    i++;
  }
  if(brac)
    buff[j++]=')';
  buff[j]=0;
  lstrcpy((char *)buff2,(char *)buff);
  if(brac)
  { j=bpoint;
    k=bpoint;
    i=0;
    pointer=false;
    rpointer=false;
    while(buff[j])
    { if((buff[j]=='p')&&(!i))
      { pointer=true;
	j++;
      }
      if((buff[j]=='r')&&(!i))
      { rpointer=true;
	j++;
      }
      else if((buff[j]=='i')&&(!i))
      { i=1;
	lstrcpy((char *)&buff2[k],"int");
	k+=3;
	j+=1;
      }
      else if((buff[j]=='c')&&(!i))
      { i=1;
	lstrcpy((char *)&buff2[k],"char");
	k+=4;
	j+=1;
      }
      else if((buff[j]=='v')&&(!i))
      { i=1;
	lstrcpy((char *)&buff2[k],"void");
	k+=4;
	j+=1;
      }
      else if((buff[j]=='l')&&(!i))
      { i=1;
	lstrcpy((char *)&buff2[k],"long");
	k+=4;
	j+=1;
      }
      else if((buff[j]=='u')&&(buff[j+1]=='i')&&(!i))
      { i=1;
	lstrcpy((char *)&buff2[k],"uint");
	k+=4;
	j+=2;
      }
      else if((buff[j]==':')&&(buff[j+1]==':')&&(i))
      { lstrcpy((char *)&buff2[k],"::");
	k+=2;
	j+=2;
      }
      else if((buff[j]=='t')&&((buff[j+1]>='0')&&(buff[j+1]<='9'))&&(!i))
      { buff2[k++]=buff[j++];
	buff2[k++]=buff[j++];
	i=1;
      }
      else if(((buff[j]>='0')&&(buff[j]<='9'))&&(!i))
      { i=buff[j]-'0';
	j++;
	if((buff[j]>='0')&&(buff[j]<='9'))
	{ i=i*10+buff[j]-'0';
	  j++;
	}
	i++;
      }
      else
	buff2[k++]=buff[j++];
      if(i)
      { i--;
	if(!i)
	{ if((pointer)&&(buff2[k-1]!=')'))
	    buff2[k++]='*';
	  if((rpointer)&&(buff2[k-1]!=')'))
	    buff2[k++]='&';
	  if((buff[j]!=')')&&(buff2[k-1]!=')'))
	    buff2[k++]=',';
	  pointer=false;
	  rpointer=false;
	}
      }
    }
    buff2[k]=0;
  }
  namelen=lstrlen((char *)buff2);
  //BugFix Build 15 nme-> *nme.
  delete *nme;
  name=new unsigned char[namelen+1];
  lstrcpy((char *)name,(char *)buff2);
  *nme=(char *)name;
}

/************************************************************************
* init_ofn								*
* - initialises the OPENFILENAME struct used in calls to common dialogs *
*   callers can then change options further as needed			*
************************************************************************/
void init_ofn(OPENFILENAME *ofn, char *szFileName, UINT FNSize, UINT FilterID) {
// FNSize = size in characters
 int cbString,i;
 char chReplace;
 static TCHAR szFilter[MAX_PATH];

 szFileName[0]=0;
 cbString=LoadString(hInst,FilterID,szFilter,elemof(szFilter));
 chReplace=szFilter[cbString-1];	// take last character
 for (i=0;i<cbString;i++) {
  if (szFilter[i]==chReplace) szFilter[i]=0;
 }
 ZeroMemory(ofn,sizeof(OPENFILENAME));
 ofn->lStructSize=sizeof(OPENFILENAME);
 ofn->hwndOwner=MainWnd;
 ofn->lpstrFilter=szFilter;
 ofn->nFilterIndex=1;
 ofn->lpstrFile=szFileName;
 ofn->nMaxFile=FNSize;
 ofn->lpstrTitle="Borg Disassembler - Select File";
 ofn->Flags=OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_LONGNAMES|OFN_EXPLORER;
}

/************************************************************************
* getfiletoload								*
* - obtains a filename for the file to be loaded			*
*   used for new files to load, and load database file			*
*   sets fname to the filename						*
************************************************************************/
BOOL getfiletoload(char *fname, UINT FNSize, UINT FilterID, UINT &Select) {
 OPENFILENAME ofn;

 init_ofn(&ofn,fname,FNSize,FilterID);
 ofn.Flags|=OFN_FILEMUSTEXIST;
 if (GetOpenFileName(&ofn)) {
  Select=ofn.nFilterIndex;
  return TRUE;
 }else return FALSE;
}

/************************************************************************
* getfiletosave								*
* - obtains a filename for the file to be saved				*
*   sets fname to the filename						*
************************************************************************/
BOOL getfiletosave(char *fname, UINT FNSize, UINT FilterID, UINT &Select) {
 OPENFILENAME ofn;

 init_ofn(&ofn,fname,FNSize,FilterID);
 if (GetSaveFileName(&ofn)) {
  Select=ofn.nFilterIndex;
  return TRUE;
 }else return FALSE;
}


Detected encoding: ASCII (7 bit)2