|
25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more... |
Home Projects Up Sitemap Search Blog Forum+Chat About Us Privacy Terms of Use Feedback FAQ Images Services Ads Donate Humor |
|
|
my.h - Borland C++ 4.0 header fileAll my programs #include "my.h". This is it. I've used this header file with MSDOS, Borland OWL for Windows, and the Borland EasyWin console interface for Windows. It contains some generally useful template functions. The date on the first line of the listing is the "version number". Starting with the 5-31-07 version, the #includes of external source files have been replaced with the code from the files that were being included, so it is no longer necessary to run around to other web pages collecting them. However, the old web pages containing the old code do still exist. If I have made any mistakes while collapsing code into this file, those pages might be useful for reference. Since the conversion, I've tested this briefly with MSDOS and Windows OWL targets without error. I no longer have any EasyWin target applications to use for testing. Most of my programs also require mylib.cpp.
|
|
/* my.h 5-31-07
Copyright (C)1994-2003, 2006-07 Steven Whitney.
Initially published by http://25yearsofprogramming.com.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Version 2 as published by the Free Software Foundation.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
------
Notes:
This is now only for C++; won't work for C.
I've used it with MSDOS, Borland OWL for Windows, and Borland's EasyWin Windows interface.
Because some of its sections are conditional, based on #defines defined by
standard Borland headers, this should be the last header file included in a project,
except for headers specific to the project, which can follow it.
This file contains some code that if enabled prevents precompiling the header.
When (or if) this is the case, put a #pragma hdrstop before the #include "my.h".
This file contains code for various platforms. To avoid conflicts, use conditionals when necessary:
#if !defined(_Windows)
#endif
many char* function parameters could probably be changed to string& or string.
Do it only as they are encountered, and where it would simplify a situation
where the char* string currently has to be built before the function call.
*/
#ifndef __MY_H
#define __MY_H
#include <values.h> // has MAXINT, MAXDOUBLE, etc.
#include <classlib\stdtempl.h> // defines min(), max(), range()
#include <classlib\time.h>
#include <cstring.h> // so that my library functions don't each need this line
#include <strstrea.h> // for the userinput() template function
#include <fstream.h> // these are so commonly used, might as well include them.
#include <iomanip.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <bios.h>
#include <ctype.h>
//////////////////////////////////////////////////////////////////////////////
typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef unsigned char uchar;
typedef signed char schar;
typedef int BOOL; // this is apparently only predefined in Windows.
// some alternative, but bad, ideas:
// enum BOOL { FALSE, TRUE }; // conflicts with Windows and can cause other problems
// enum bool { FALSE, TRUE }; // or a new type entirely, to enforce value checking
//////////////////////////////////////////////////////////////////////////////
// some macro definitions
//----------------------------------------------------------------------------
// zArray is an obsolete holdover from DeSmet C. Keep only until sure it's not still used somewhere.
// Keep it commented out so all instances of its use get flagged.
// #define zArray(a) setmem((a),(sizeof(a)),0)
#define ERR (-1)
#define ON (1)
#define OFF (0)
#define YES (1)
#define NO (0)
#define TRUE 1 // matches windows.h, which doesn't use parentheses
#define FALSE 0
#define MAXUINT (0xFFFF) // max unsigned, 65535 (should be (uint)(-1) but check its uses first)
#define MAXULONG (ulong)(-1) // largest possible ulong
//////////////////////////////////////////////////////////////////////////////
/* A Borland document suggests using a larger stack than the default 4K in large model.
Enabling this code prevents precompiled header, so this is just a reminder, in a
central location, of how to do it.
*/
//----------------------------------------------------------------------------
// #if defined(__MSDOS__) && defined(__LARGE__) && !defined(_Windows)
// extern unsigned _stklen = 64000U;
// #endif
//////////////////////////////////////////////////////////////////////////////
/* prototypes for my global library functions.
If a function has default parameters, specify them HERE because if you
call the function without the parameter, the compiler only has the
declaration here to refer to. It can't look ahead to the library module to
discover the default value there. Since it doesn't know there is a default
value, the missing parameter will generate an error.
Be sure to include my.h in all library function .cpp files so any
different or redeclared default values are caught.
*/
//----------------------------------------------------------------------------
void aborts(const string&); // abnormal termination, with message
const string& backupfile(const string& filename); // create a file, rename its old version to .bak
string bstring(const string& s); // output a string in brackets
int ci(); // console input
double cosine(double degrees); // cosine, with argument in degrees
uint countchr(const string& searchin, char lookforandcount); // count occurrences of a char in a string
string CRLFtoLF(const string& s); // change each CRLF to LF
string CRtoLF(const string& s); // change each CR to LF
int FontHeightInPixels(int pointsize); // Windows utility fn
double frand(); // random 0 to 1.0 (limit)
string& fromstring(string& var, const string& value); //overrides my template version, for for strings only
uint far getpixel(double dx, double dy); // get color value of a pixel with x,y as doubles
uint gettoken(const string& source, uint startpos, string& token); // extract token from text
uint gettoken(istream& is, string& token); // extract token from stream
uint getsentence(const string& source, uint startpos, string& sentence); // extract a sentence from text
uint getsentence(istream& is, string& sentence); // extract a sentence from stream
void gputs(int x, int y, int color, char *text); // prints string to screen in DOS BGI graphics
void graborts(const string&); // aborts() from within DOS BGI graphics app
int initgraf(); // set up BGI graphics
BOOL isallspace(char *s); // if string contains all whitespace
BOOL isterminator(const string& token); // if it's a sentence-terminating token
string LFtoCR(const string& s); // change each LF to CR
string LFtoCRLF(const string& s); // insert a CR before each LF
uint logerror(string error = "", string filename = "error.log", BOOL beep = TRUE); // log program error to a file
uint logtofile(const string& s, const string& filename); // send any string to a file
long lrandom(long top); // (long) random from 0 to top-1
int NormalRandom(double mean, double stddev); // normally distributed random number
int picload(const char *filename); // load a .PIC file
int picsave(const char *filename); // save a .PIC file
int presskey(ostream& os = cout); // says "Press any key to continue..."
string qstring(const string& s); // put a string in quotes
int round(double d); // round a double properly
uint far sgetpixel(int x, int y); // ignores out of bounds requests
double similarity(const string& first, const string& second); // measures similarity of two strings
double sine(double degrees); // sine, with argument in degrees
BOOL strand(char *str, char *tofind, char dontcare = '?'); // performs an AND on two strings
BOOL strand(const string& searchin, const string& pattern, char dontcare = '?');
string& titlecase(string& s); // renders string in Title Case
string TranslateControls(const string& s); // replaces control chars in a string with ASCII mnemonics, e.g. <NUL>.
string unqstring(const string& s); // remove quotes from around a string
BOOL yesno(string prompt = "Continue", ostream& os = cout); // asks user a yes/no question
//-------------------------
#if defined(__OWL_EDIT_H)
int append(TEdit* ed, const string& s); // OWL. Appends s to the text of the TEdit control.
#endif //(__OWL_EDIT_H)
//-------------------------
//////////////////////////////////////////////////////////////////////////////
// WHEREVER MATH.H IS USED
#if defined(__MATH_H)
#define M_PI_180 0.0174532925199432951 // pi / 180
#define M_180_PI 57.2957795130823231 // 180 / pi
#define ROOT12OF2 1.05946309435929526 //12th root of 2, for music apps.
// trigtabl.h 6-27-99 A sine/cosine lookup table for whole degrees, for speed.
struct Trigtable
{
Trigtable();
double cosines[360];
double sines[360];
};
#endif //(__MATH_H)
//////////////////////////////////////////////////////////////////////////////
/* 3-14-99 replacement for block from the Borland C++ 4.0 stdlib.h,
in which the method used for random() in FLAT model DOES NOT work properly.
see my lrandom() for explanation.
*/
//----------------------------------------------------------------------------
#if defined(__FLAT__)
// in ANSI C, random() doesn't even exist
#if !defined(__STDC__)
#if defined(__cplusplus)
// note that because of this definition, your implementation of lrandom()
// MUST NOT call random() directly or indirectly.
// lrandom() is a fn I wrote that returns a long random number.
inline int _RTLENTRY random(int __num) { return lrandom(__num); }
#else
#define random(num) (lrandom(num))
#endif
#endif
#endif
//////////////////////////////////////////////////////////////////////////////
// TOSHIBA PRINTER FUNCTIONS
//----------------------------------------------------------------------------
#define TOSHIBADRAFT "\033*0"
#define TOSHIBAELITE "\033*1"
#define TOSHIBACOURIER "\033*2"
#define TOSHIBACONDENSE "\033["
#define TOSHIBABOLDON "\033K2"
#define TOSHIBABOLDOFF "\033M"
//////////////////////////////////////////////////////////////////////////////
#if !defined(_Windows)
#include <conio.h>
#include <constrea.h> // constreams illegal even in EasyWin
//////////////////////////////////////////////////////////////////////////////
// a constream that upon construction does initialization that constream doesn't do.
// to reside here in my.h, all code must be inline.
//----------------------------------------------------------------------------
class SConstream : public constream
{
public:
SConstream(int left = 1, int top = 1, int right = 80, int bottom = 25) : constream()
{
constream::window(left,top,right,bottom); // set the window
constream::clrscr(); // clear the screen
(*this) << setclr(LIGHTGRAY); // default color
}
};
//----------------------------------------------------------------------------
// // end class SConstream
//////////////////////////////////////////////////////////////////////////////
#endif // !defined(_Windows)
//////////////////////////////////////////////////////////////////////////////
// DOS OR EASYWIN ONLY (It assumes Windows without OWL must be Easywin)
//----------------------------------------------------------------------------
#if !defined(__OWL_OWLCORE_H)
/* userinpu.h 6-25-97
Variable input routines: prompts user, accepts input.
If user enters CR, current value for the variable is unchanged.
If user enters a value, variable takes that value.
Luckily, this behavior is inherent in >> as used with cin (PG:213).
Don't call it input() because of possible conflicts, too general a name.
There are 2 versions because "only trivial type conversions are performed
with compiler-generated template functions" (PG:162).
Normally, you can pass a char array to a function requiring a string&, and
the compiler will do the conversion. In this case it won't, so you must
have the const char* version. The 2nd version is only useful where you
have a pre-constructed string that you want to pass, or you can cast the
prompt, as in: userinput(string("Enter something"),something);
which works but is cumbersome.
*/
//////////////////////////////////////////////////////////////////////////////
// OK for DOS or EASYWIN
//----------------------------------------------------------------------------
template<class T> void userinput(const char* prompt, T& defalt)
{
char temp[128] = { 0 };
cout << prompt << " <CR for " << defalt << ">: ";
cin.getline(temp,sizeof(temp)); // get new value, or a CR (empty)
if(strlen(temp))
istrstream(temp) >> defalt; // remember is >> string is buggy. see mystring.h
}
//----------------------------------------------------------------------------
template<class T> void userinput(const string& prompt, T& defalt)
{
userinput(prompt.c_str(),defalt);
}
//////////////////////////////////////////////////////////////////////////////
// DOS *ONLY*
//----------------------------------------------------------------------------
#if !defined(_Windows)
//----------------------------------------------------------------------------
template<class T> void userinput(const char* prompt, T& defalt, constream& os)
{
char temp[128] = { 0 };
os << prompt << " <CR for " << defalt << ">: ";
cin.getline(temp,sizeof(temp)); // get new value, or a CR (empty)
if(strlen(temp))
istrstream(temp) >> defalt; // remember is >> string is buggy. see mystring.h
}
//----------------------------------------------------------------------------
template<class T> void userinput(const string& prompt, T& defalt, constream& os)
{
userinput(prompt.c_str(),defalt,os);
}
#endif // Windows
//////////////////////////////////////////////////////////////////////////////
#endif //!defined(__OWL_OWLCORE_H)
//////////////////////////////////////////////////////////////////////////////
/* signum function, 12-3-96
In this version, the returned value has the same type as the argument.
For some uses (such as switch()), you should cast the returned value to int.
*/
//----------------------------------------------------------------------------
template<class T> T signum(const T& a)
{
return((a == (T)0) ? (T)0 : (a < (T)0) ? (T)(-1) : (T)1);
}
//////////////////////////////////////////////////////////////////////////////
// swap two variables. class T must have a default constructor and an = operator.
//----------------------------------------------------------------------------
template<class T> void swap(T& a, T& b)
{
T temp;
temp = a;
a = b;
b = temp;
}
//////////////////////////////////////////////////////////////////////////////
/* 6-30-99
wraparound. If a value falls outside the allowable range,
wrap it back into the range. Useful for screen wrap.
Only works properly for screen wrap for integral types (int, long).
See adapt.cpp for a specialized version for doubles.
Min and max are the lowest and highest values allowable, INCLUSIVE.
*/
//----------------------------------------------------------------------------
template<class T> T wrap(T val, T min, T max)
{
if(min > max) // prevent runaway disaster
swap(min,max);
if(min == max) // not much you can do about this
return(min); // just return a legal value
T adj = max - min + (T)1;
while(val < min) val += adj;
while(val > max) val -= adj;
return(val);
}
//////////////////////////////////////////////////////////////////////////////
/* number to string 12-25-96
Create a string containing the text representation of a number.
Eliminates need for itoa() and similar functions and makes it easier to build
compound strings from both text and numeric pieces.
Example: string s = string("Number = ") + tostring(10) + " " + tostring(i);
Note it must return a string object, not a string&.
Template makes it applicable to any type numeric parameter, and
oddly, even any non-numeric object with an ostream << operator.
That's why the os is dynamic, just in case.
*/
//----------------------------------------------------------------------------
template<class T> string tostring(const T& t)
{
ostrstream os;
os << t << ends;
string s(os.str());
delete[] os.str();
return(s);
}
//////////////////////////////////////////////////////////////////////////////
/* fromstring 4-18-00
complementary function to tostring().
Allows you to assign to a variable the value encoded in a string.
Similar to Basica I = VAL(A$), and similar to atoi(), atod(), etc.,
or istream >> variable, but for STRINGS.
Works for any type for which read-from operator >> is defined, since it uses it.
But mystring.cpp has a special overriding version for strings.
*/
//----------------------------------------------------------------------------
template<class T> T& fromstring(T& var, const string& value)
{
// refuse to change ANY references or pointers, including char*
// refuse to change strings. they have a separate version in mystring.cpp.
// (I haven't tested this after adding the string exclusion here.)
string n = typeid(var).name();
if(n.contains("*") || n.contains("&") || n.contains("string"))
return(var);
char* s = new char[value.length() + 1];
strcpy(s,value.c_str());
istrstream(s) >> var;
delete[] s;
return(var);
} // fromstring
//////////////////////////////////////////////////////////////////////////////
/* allocate and delete 2-dimensional arrays of any type object. 5-17-97
the result is (height) arrays, each (width) wide.
//----------------------------------------------------------------------------
needed because new int[a][b] is illegal. b must be a compile time constant.
if new fails, it will simply terminate the application, as xalloc always does.
adapted from PG:121. See also commented version in booksamp.cpp.
The unused T& argument is necessary so it knows what type a T is.
You can pass it any example of a "T" object.
//----------------------------------------------------------------------------
it is dimensioned backwards as [y][x] because x should vary fastest when traversing
in scan-line fashion. Seems like it wouldn't matter if it were [x][y],
but don't change, because it is already in use.
//----------------------------------------------------------------------------
When using with char arrays, don't try to load or write entire scan lines
at once, because each of the horizontal lines is not null-terminated.
*/
//----------------------------------------------------------------------------
template<class T> T** newarray2dim(const T&, int height, int width)
{
T** a = new T*[height];
for(int i = 0; i < height ; i++)
a[i] = new T[width];
return(a);
}
//----------------------------------------------------------------------------
template<class T> void deletearray2dim(T** a, int height)
{
for(int i = 0; i < height ; i++)
delete[] a[i];
delete[] a;
a = 0; // probably always want this, since it's an invalid pointer now, anyway
}
//////////////////////////////////////////////////////////////////////////////
/* csts() console status, for compatibility with DeSmet C.
It recognizes a function key as a keystroke, which kbhit() does not.
returns a (strangely encoded) non-zero value if keystroke waiting, zero if none.
If a keystroke is waiting, repeated csts() calls continue to return the SAME value
even if more keys are pressed. So if csts is nonzero, you should always
follow it with ci() to get whatever char is there.
Move to its own fn? if a key was pressed, get and return it, to flush.
*/
//----------------------------------------------------------------------------
#define csts() bioskey(_NKEYBRD_READY)
//////////////////////////////////////////////////////////////////////////////
// Common ASCII values (add as needed)
//----------------------------------------------------------------------------
#define NUL (0) // Nothing, CTL@, all bits 0
#define SOH (1) // Start Of Heading: XMODEM start of sector character
#define EOT (4) // End Of Transmission: XMODEM end of tranmission char
#define ACK (6) // ACKnowledge: XMODEM Acknowledge sector transmission
#define BS (8) // BackSpace
#define TAB (9) // =HT Horizontal Tab
#define LF (10) // Line Feed
#define CR (13) // Carriage Return
#define XON (17)
#define XOFF (19)
#define NAK (21) // Negative AcKnowledgment: XMODEM error in transmission detected
#define CAN (24) // CANcel
#define SUB (26) //
#define ESC (27) // ESCape
//////////////////////////////////////////////////////////////////////////////
/* IBM PC keycodes, as returned by my function ci(), to use for comparisons.
These posed no problem in Borland C++ 4.0, but some of the simple ones
like F1 caused conflicts and compile errors in C++ Builder 6 and MS VC++ 2005.
Few of my programs use them, and they can usually be commented out without
causing a problem. Its useful to have the list for reference, though.
*/
//----------------------------------------------------------------------------
// plain function keys
#define F1 (0x3b00)
#define F2 (0x3c00)
#define F3 (0x3d00)
#define F4 (0x3e00)
#define F5 (0x3f00)
#define F6 (0x4000)
#define F7 (0x4100)
#define F8 (0x4200)
#define F9 (0x4300)
#define F10 (0x4400)
#define F11 (0x8500)
#define F12 (0x8600)
// ci() returns identical values for corresponding keys
// on the middle and right keypads,
// but the hardware scan codes actually are different
// and could be used.
#define HOME (0x4700)
#define END (0x4f00)
#define PGUP (0x4900)
#define PGDN (0x5100)
#define INS (0x5200)
#define DEL (0x5300)
#define UP (0x4800)
#define DOWN (0x5000)
#define LEFT (0x4b00)
#define RIGHT (0x4d00)
#define FIVE (0x4c00)
// SHIFT + function keys
// shift + middle keypad have unique codes, not shown.
// shift + left keypad just produces numbers
#define SF1 (0x5400)
#define SF2 (0x5500)
#define SF3 (0x5600)
#define SF4 (0x5700)
#define SF5 (0x5800)
#define SF6 (0x5900)
#define SF7 (0x5a00)
#define SF8 (0x5b00)
#define SF9 (0x5c00)
#define SF10 (0x5d00)
#define SF11 (0x8700)
#define SF12 (0x8800)
// ALT + function keys
// alt + middle keypad have unique codes, not shown.
// alt + right keypad makes special chars numerically
#define AF1 (0x6800)
#define AF2 (0x6900)
#define AF3 (0x6a00)
#define AF4 (0x6b00)
#define AF5 (0x6c00)
#define AF6 (0x6d00)
#define AF7 (0x6e00)
#define AF8 (0x6f00)
#define AF9 (0x7000)
#define AF10 (0x7100)
#define AF11 (0x8b00)
#define AF12 (0x8c00)
// CTL + function keys
#define CF1 (0x5e00)
#define CF2 (0x5f00)
#define CF3 (0x6000)
#define CF4 (0x6100)
#define CF5 (0x6200)
#define CF6 (0x6300)
#define CF7 (0x6400)
#define CF8 (0x6500)
#define CF9 (0x6600)
#define CF10 (0x6700)
#define CF11 (0x8900)
#define CF12 (0x8a00)
// CTL + keypad keys
#define CHOME (0x7700)
#define CEND (0x7500)
#define CPGUP (0x8400)
#define CPGDN (0x7600)
#define CINS (0x9200)
#define CDEL (0x9300)
#define CUP (0x8d00)
#define CDOWN (0x9100)
#define CLEFT (0x7300)
#define CRIGHT (0x7400)
#define CFIVE (0x8f00)
// CTL + keys
#define CTLA (1)
#define CTLB (2)
#define CTLC (3)
#define CTLD (4)
#define CTLE (5)
#define CTLF (6)
#define CTLG (7)
#define CTLH (8)
#define CTLI (9)
#define CTLJ (10)
#define CTLK (11)
#define CTLL (12)
#define CTLM (13)
#define CTLN (14)
#define CTLO (15)
#define CTLP (16)
#define CTLQ (17)
#define CTLR (18)
#define CTLS (19)
#define CTLT (20)
#define CTLU (21)
#define CTLV (22)
#define CTLW (23)
#define CTLX (24)
#define CTLY (25)
#define CTLZ (26)
// ALT + keys
#define ALTA (0x1e00)
#define ALTB (0x3000)
#define ALTC (0x2e00)
#define ALTD (0x2000)
#define ALTE (0x1200)
#define ALTF (0x2100)
#define ALTG (0x2200)
#define ALTH (0x2300)
#define ALTI (0x1700)
#define ALTJ (0x2400)
#define ALTK (0x2500)
#define ALTL (0x2600)
#define ALTM (0x3200)
#define ALTN (0x3100)
#define ALTO (0x1800)
#define ALTP (0x1900)
#define ALTQ (0x1000)
#define ALTR (0x1300)
#define ALTS (0x1f00)
#define ALTT (0x1400)
#define ALTU (0x1600)
#define ALTV (0x2f00)
#define ALTW (0x1100)
#define ALTX (0x2d00)
#define ALTY (0x1500)
#define ALTZ (0x2c00)
#define ALT1 (0x7800)
#define ALT2 (0x7900)
#define ALT3 (0x7a00)
#define ALT4 (0x7b00)
#define ALT5 (0x7c00)
#define ALT6 (0x7d00)
#define ALT7 (0x7e00)
#define ALT8 (0x7f00)
#define ALT9 (0x8000)
#define ALT0 (0x8100)
// THESE ONLY HERE IN CASE I NEED THE VALUES SOMETIME
// must be spelled out: ALT\ (for example) generated errors
#define ALTMINUS (0x8200)
#define ALTEQUAL (0x8300)
#define ALTBACKSLASH (0x2b00)
#define ALTLBRACKET (0x1a00)
#define ALTRBRACKET (0x1b00)
#define ALTSEMICOLON (0x2700)
#define ALTAPOSTROPHE (0x2800)
#define ALTCOMMA (0x3300)
#define ALTPERIOD (0x3400)
#define ALTSLASH (0x3500)
#define ALTBAPOSTROPHE (0x2900)
//----------------------------------------------------------------------------
// function key status as returned by bioskey(2) or bioskey((0x12)
//----------------------------------------------------------------------------
#define RIGHT_SHIFT (0x01)
#define LEFT_SHIFT (0x02)
#define CTRL_SHIFT (0x04)
#define ALT_SHIFT (0x08)
#define SCROLL_LOCK (0x10)
#define NUM_LOCK (0x20)
#define CAPS_LOCK (0x40)
#define INSERT_KEY (0x80)
#endif // __MY_H DEFINED
|
|
|
|
|
|