Thursday, November 29, 2007

Supported Turbo C entities

Of course, there are a lot of functions in Turbo C that are not only supported in GNU gcc, but that are even supported identically, such as fopen , fclose, fread, printf, time, etc. On the other hand, a generic function like putchar may operate similarly only over a certain range. For example, putchar(0xA5) is unlikely to display characters that appear to be identical in Borland Turbo C on an IBM PC and in GNU gcc in Linux. I'm sorry about that, in a theoretical way, but life is too short for me to expend a lot of energy fixing it.

Anyway, the table below isn't a complete list of all the Turbo C entities you can use, but simply those that the TurboC library treats specially. Also, I'm sure there are Turbo C functions that need special treatment which I've simply not encountered yet in my porting activities, and so aren't included here.

Turbo C Entity Entity Type Supported Notes
__libTurboC__ constant n/a Provided by the TurboC library, but not normally present in actual Turbo C. Can be used with conditionaly compilation to insure that any changes you make to your code in porting to libTurboC are discarded if the program is recompiled later in actual Turbo C. :-)
alloc.h header file Yes This is supported in the sense that a file of this name is provided. However, not all of the functions are necessarily supported.
arc function Yes
bar function Yes
bar3d function Yes
bios.h header file Yes This is supported in the sense that a file of this name is provided. However, not all of the functions are necessarily supported.
biosprint function Yes Thanks to Igor Bujna! At the moment, this one relies on Linux specifically (not FreeBSD or other Unices).
BypassResizeXterm variable n/a This is not present in real Turbo C. Normally, the TurboC library will attempt to physically resize the text console when you call textmode . However, this does not work unless you are running xterm. If you set BypassResizeXterm to a non-zero value before calling -- say, on the basis of some environment variable setting -- then the attempt to resize the window is bypassed. However, the window must still be resized by some other mechanism or else the program may segfault. textmode
cgets function Yes
circle function Yes
cleardevice function Yes
clearviewport function Yes
clock function Yes This is already a standard *nix function, but the existing *nix function is not suitable for Turbo C. Instead the existing function is rename clockUnix and a new clock (clockTurbo) function is created. The CLK_TCK constant may also pre-exist in *nix, but it may (or may not) be assigned a different value than needed for clock . If TurboC.h or any other header files from the TurboC library are included, CLK_TCK will automatically be reassigned (within that source file) to an appropriate value. However, it may not be the same value for CLK_TCK used in true Turbo C (variously, 18 or 1000). For example, in my experiments it is equal to 100, but there's no guarantee that it won't be 1000000 on some system. This means that the output of clock must always be assigned to a variable of type clock_t , because it may overflow an intunsigned. clock and CLK_TCK are supposed to be prototyped in time.h -- and are -- but won't have the behavior expected in TurboC unless a TurboC library header file is included also. In other words, if time.h is included but no TurboC header file is included, clock will behave incorrectly but there will be no errors or warnings. Finally, clock is supposed to measure the time since program startup, but in TurboC it actually measures the time since clock itself was first called by the program. or
closegraph function Yes
clreol function Yes
clrscr function Yes
COLS variable n/a This is not present in true Turbo C. It is an ncurses variable that tells the current number of text columns in the display console.
conio.h header file Yes Most conio.h functions are supported. Currently, only cscanf is omitted. Support is through ncurses.
ConioResizeCallback function n/a This is not present in true Turbo C. It is a function which the TurboC library calls when it has detected that the user has resized the console. By default, it does nothing, but you can override this behavior by providing your own version of this function (which will be preferentially chosen at linktime over the version already within the TurboC library). You can do anything you like with this function, but one possible use is to refresh all of the text data on the screen. Use the LINES and COLS variables to determine the current screen height and width.
cprintf function Yes
cputs function Yes
cscanf function No It may seem naively that this function is a simple combination of cgets with sscanf. However, on closer inspection it really isn't. I don't presently see how to implement it without messing with the guts of the scanf function family (which I have no desire to do).

Workaround: For the present time, I'd suggest writing cscanf out of your code in favor of cgets and sscanf . Actually, I've seen Borland docs that recommend this also.

struct date data type Yes Thanks to Igor Bujna.
delay function Yes (Igor Bujna provided this function but I haven't used it, because his version relies on ncurses. Thanks but sorry, Igor!) The function parameter has arbitrarily been changed from 16-bit to 32-bit.
delline function Yes
detectgraph function Yes
dir.h header file Yes This is supported in the sense that a file of this name is provided. However, not all of the functions are necessarily supported.
directvideo
_directvideo
variable Yes I provide variables of this name, which you can manipulated as desired, but they don't affect any conio functionality. (It seems to me that variables of both names have been provided in different versions of Turbo C, but they behave the same.)
dos.h header file Yes This is supported in the sense that a file of this name is provided. However, not all of the functions are necessarily supported.
dostounix function Yes Contributed by Igor Bujna.
drawpoly function Yes
ellipse function Yes
far type modifier Yes Requires TurboC.h. There's no need for "far pointers" with a 32-bit compiler, so this is simply an empty macro.
farcalloc function Yes This is the same as calloc.
farcoreleft function Yes This is supposed to determine how much space remains on the heap. There's no way to do this, since the heap size is not limited in any practical sense. Hence, it is a macro that simply always has the value 512K.
farfree function Yes This is the same as free.
farmalloc function Yes This is the same as malloc.
fcloseall function Linux: Yes
FreeBSD: No
Other: TBD
Requires TurboC.h. This is not a function for which I provide any code. It's simply a standard library function.
struct ffblk data type Yes
fillellipse function Yes
fillpoly function Yes
findfirst function Yes While substantially a functional replacement for the Turbo C function of the same name, it is also subtly different in a number of ways:
  • Most importantly, please read about the findlast function.
  • Long filenames (not just 8.3) are supported.
  • Regular expressions are used for the filename patterns. This means that expressions like "*.c" and "foobar.?" will work mostly -- but not entirely -- as expected. For example, the pattern "*" in Linux corresponds more closely to the pattern "*.*" in DOS than does "*.*" in Linux. (In Linux, "*.*" implies that the filename really contains a dot, and so it wouldn't match a filename like "foobar".)
  • Since *nix filenames are case-sensitive, patterns like "*.c" and "*.C" are not interchangeable.
  • Among the flags, only FA_DIRECFA_DIREC flag. FA_ARCH and FA_LABEL flags are not supported at all. I've arbitrarily defined FA_RDONLY to correspond to files for which the user-write-permission bit is not set, and FA_SYSTEM to correspond to files for which the user-read-permission bit is not set. FA_HIDDEN is defined to correspond to files whith names beginning in '.'. However, this does not work on all systems. (It works in Linux, but not presently in BSD.) corresponds directly to the DOS
findlast function n/a This is not a function provided by true Turbo C, but is provided to correct a problem in the libTurboC emulation. The "normal" use of findfirst/findnext, as defined by me, is that the entire file list is read, and then terminates when findnext cannot locate any more files. If the functions are not used in this way -- in other words, if findnext never locates the last file -- then libTurboC has no way to know that it should free the memory which has been allocated. With each "abnormal" use of findfirst/findnext this memory will accumulate. The symptom is that eventuallyfindfirst/findnext will not be able to locate files even though they exist. This problem can be fixed by explicitly adding a call to findlast after the last use of findnext, but before deallocating its struct ffblk . The prototype is:
void findlast (struct ffblk *);
findnext function Yes See the notes for findfirst.
floodfill function TBD I may prove to be too darned lazy for this. However, there's a GRX function that does this. If anyone wants to adapt it ...
fnkeys.h header file n/a This is a file I've provided, but there is not any equivalent Turbo C header file. This header simply provides symbolic names for all of the special-function keys recognized by MS-DOS. Unfortunately, these are not all supported by ncurses. See the discussion below.
getarccoords function Yes Requires the "-lm" compiler switch.
getaspectratio function Yes There is a function of this name, but at this point it acts as though the pixels are always square.
getbkcolor function Yes
getch function Yes There is an ncurses function of the same name, but somewhat different functionality. In any source file using conio.h, the conio version of getch#include "conio.h", while the ncurses version of getchgetchNcurses . applies below the applies above it. The ncurses functionality continues to be available, however, as a new function

Please note that getch will work in textmode or in graphics mode, but will not presently work otherwise. Conversely, getchar will work only when not in textmode . (getchar will work in graphics mode if textmode has not been previously called, but will not echo to graphics screen).

getche function Yes
getcolor function Yes
getdate function Yes Contributed by Igor Bujna. In some newer system libraries, there actually is a function called getdate, which works differently and conflicts with this function. That function, if it exists, will be accessible in TurboC programs as getdateSystem.
getdefaultpalette function Yes The true Turbo C function returns a pointer to a struct palettetype , whereas the TurboC library function returns a pointer to const struct palettetype.
getdrivername function Yes This functions returns a const char *, whereas the true Turbo C function returns char *.
getfillpattern function Yes
getfillsettings function Yes
getftime function Yes I initially believed that this function did not work, because the linker could not find the fstat function on which it is based. Later, this problem mysteriously disappeared. I mention this just FYI.
getgraphmode function Yes
getimage function Yes Borland's documentation does not specify the format of the buffer into which the image is placed, beyond fact that the first two words contain the width and height, in pixels. If you use this function with those restrictions in mind, you'll be okay.

On the other hand ... I think it's very likely that programs containing this function might exploit knowledge of the graphics controller in the PC, and thus may (improperly if cleverly) directly manipulate date within the output graphics buffer. Realize that no effort has been made to duplicate these undocumented buffer formats. If your program depends on the size or format of the graphical area of the output buffer, I guarantee that it will not work!

As a corollary, be sure to allocate image buffers dynamically using imagesize, per Borland's docs, with malloc or calloc. I suspect that many existing programs statically allocate the buffers, on the incorrect notion that the buffer format is known.

Finally, you should not expect to be able to save the image buffer as a file and to reload it later.

getlinesettings function Yes
getmaxcolor function Yes
getmaxmode function Yes See the comments for getmoderange.
getmaxx function Yes
getmaxy function Yes
getmodename function Yes Since the TurboC library does not limit the graphics modes to those of a particular "graphics driver" as Borland Turbo C does, and since there are many more graphics modes, it is not practical to make the name strings identical to those reported in an actual Turbo C program.
getmoderange function Yes Since the TurboC library rejects the concept of a "graphics driver", everyeveryVGAHI, VGALO, etc.), the symbolic constants don't have the same numeric values as in true Turbo C, and many more modes are available than are assigned symbolic constants. (To understand this, refer to the graph.h file.) The upshot of all this is that getmoderange returns a huge range of allowable modes, in comparison to true Turbo C. At this writing, the range is from 0 to approximately 1439, whereas true Turbo C topped out at about 5; this maximum mode presently provides a 1280x1024 screen with 256 colors and 4 pages. Whether this presents a problem remains to be seen. graphics mode is allowed for driver. Furthermore, while various graphics modes are available under the same symbolic constant names as in true Turbo C (such as
getpass function Yes
getpixel function Yes In true Turbo C, we are guaranteed that the on-screen color corresponds to an actual color in our palette. In the TurboC library, this isn't true. The closest-match paletted color is returned. If there is more than one match, the first one encountered is returned.
getpalette function Yes
getpalettesize function Yes
gettext function Yes The format of the text buffer created is the same as in true Turbo C. The same bytes are produced, and they are stored in the same order.

11/02/03 and later: There is a function called gettext in the internationalization library (libintl). To avoid a conflict, the internationalization library's function will be accessible instead by the name gettextIntl.
gettextinfo function Yes
gettextsettings function Yes
gettime function Yes There are two versions of this, one by me, and one by Igor Bujna (called). I'm not aware of the pros and cons of the two. gettime_d
getviewsettings function Yes
getx function Yes
gety function Yes
gotoxy function Yes
graphics.h header file Yes At present, most graphics.h functionality is supported in one form or another except text output, which is next on the to-do list.

Use of graphics requires the X-window system.

graphdefaults function Yes
grapherrormsg function Yes
_graphfreemem function Yes This function is not used in any way by the TurboC library -- or hopefully, by the user code -- but has nevertheless been provided.
_graphgetmem function Yes See the comments for _graphfreemem.
graphresult function Yes
highvideo function Yes
huge type modifier Yes Requires TurboC.h. There's no need for "huge pointers" with a 32-bit compiler, so this is simply an empty macro.
imagesize function Yes Important: see the warnings for the getimage function above.
initgraph function Yes Causes a separate graphics window to open. (The parent text-based window remains visible.) The location of this graphics window (i.e., locally or remotely) is dependent on the value of the DISPLAY environment variable. Typically (but not always) this variable is set automatically for you by the system, and so you usually don't have to worry about it. The graphdriver and pathtodriver input-parameters of initgraph are (almost) completely ignored, though the constants used as names for the various drivers are available for your use (DETECT, CGA, MCGA, EGA, etc.). As far as the graphmode input-parameter is concerned, every mode applicable to any graphics driver is accepted. All graphics modes through Borland C++ 5.0 are supported: CGAC0, CGAC1, CGAC2, CGAC3, CGAHI, MCGAC0, MCGAC1, MCGAC2, MCGAC3, MCGAMED, MCGAHI, EGALO, EGAHI, EGA64LO, EGA64HI, EGAMONOHI, HERCMONOHI, ATT400C0, ATT400C1, ATT400C2, ATT400C3, ATT400MED, ATT400HI, VGALO, VGAMED, VGAHI, PC3270HI, IBM8514HI, IBM8514LO.
insline function Yes
installuserdriver function Yes (sort of) Graphics drivers as such are not used by the TurboC library (which allows every defined graphics mode to be used by every "driver" anyway). This function, therefore, does nothing. It always returns a value of IBM8514.
installuserfont function TBD
io.h header file Yes This is supported in the sense that a file of this name is provided. However, not all of the functions are necessarily supported.
kbhit function Yes
line function Yes
linerel function Yes
LINES variable n/a This is not present in true Turbo C. It is an ncurses variable that tells the current number of text rows in the display console.
lineto function Yes
lowvideo function Yes
mkdir function Yes A function of the same name is provided by GNU gcc, but behaves somewhat differently in the Linux environment. The version provided by TurboC corrects that behavior.
moverel function Yes
movetext function Yes
moveto function Yes
normvideo function Yes
outtext function Yes See the comments for outtextxy.
outtextxy function Yes See the comments for settextstyle.

Borland seems to perform clipping on text by not displaying any characters that aren't wholly within the viewport. The TurboC library performs clipping on text by not displaying any pixels of the characters that are outside of the viewport. In other words, the TurboC library may display partial characters in some cases, whereas true Turbo C will not do so.

pieslice function Yes
putch function Yes
putimage function Yes Important: see the warnings for the getimage function above.
putpixel function Yes
puttext function Yes See the notes for gettext.
random function Yes Requires TurboC.h.
randomize function Yes Requires TurboC.h.
rectangle function Yes
registerbgidriver function Yes (sort of) This function serves no purpose in the TurboC library, since there is no need to load separate graphics "drivers". Hence, this function actually does nothing. It always returns a value of IBM8514, which probably doesn't correspond to what you might have wanted. Therefore, it is probably best to write this function out of your code.
registerbgifont function TBD
restorecrtmode function Yes Note that Borland's documentation does not specify whether the resulting text-mode screen is cleared or not. With the TurboC library, it will not be cleared.
sector function Yes Requires the "-lm" compiler switch.
setactivepage function Yes
setallpalette function Yes
setaspectratio function Yes There's a function of this name, but it does nothing, on the assumption that the pixels are always square.
setbkcolor function Yes See the comment for setpalette below.
setcolor function Yes
_setcursortype function Yes This function was not present in Turbo C 2.0, but appeared in some later versions. The cursor type, as in Turbo C, is one of the following: _NOCURSOR, _NORMALCURSOR, _SOLIDCURSOR. However, ncurses does not provide these choices as such; it provides only "invisible", "visible", and "very visible", with the differences between these being dependent on the target platform. For example, on my iMac Linux box, both _NORMALCURSOR and _SOLIDCURSOR appear as indistinguishable block cursors. In other words, your mileage may vary.
setfillpattern function Yes
setfillstyle function Yes
setftime function No The closest *nix function corresponding to this that I can find is utimes, which unfortunately requires knowing the filename. On the other hand, setftimehandle of an open file. There's no clean way I know to determine a filename given a file handle. I don't see any clean way to implement this without intercepting all open and fopen calls. requires the

Workaround: Rewrite your code to use utimes rather than setftime.

Note: Actually, there is a way of writing such a function without trapping fopen, but it's so unclean that I'd hesitate to do it. I'd be happy to receive someone else's code for it, though. Given the file handle, the fstat function can reveal the file's "inode". There's no way to do a reverse lookup and determine a filename given an inode, but a search of the entire file-system (using the findrelatively efficient by first searching just the current directory, and then searching the home directory only on failure, and then searching the entire file-system only on failure. (Unfortunately, the inode numbers are not necessarily unique. They are only unique within a given file-system, and if multiple file-systems are mounted, they could each have files with the same inode.) Finally, after find has determined the filename, the utimes functions could be used. Ick! function from the command line, with the appropriate switches) can give a list of the filenames of all files with a given inode. The search can be made

setgraphbufsize function Yes ... and no Yes there is a function of this name. No, it doesn't do anything, though it does return the correct values. I don't allow you to alter the size of any memory buffers used internally by the TurboC library.
setgraphmode function Yes
setlinestyle function Yes
setpalette function Yes In true Turbo C, changes to the palette may instantly be seen on the graphics display, because true hardware modes within the graphics controller are affected. With the TurboC library, only future drawing operations are affected, but pixels which have already been drawn are unaffected.
setrgbpalette function Yes See the comment for setpalette above.
settextjustify function Yes Borland Turbo C 2.x seemingly has a bug in which if the text style is HORIZ_DIR, then LEFT_TEXT is treated as RIGHT_TEXT . This bug has not been duplicated in the TurboC library.
settextstyle function Yes ... and no So far (20020608), only the bitmapped font (DEFAULT_FONT) has been implemented.

Eventually, all stroked fonts defined in Borland C++ 5.0 will be supported, supposing that I can find appropriate open-source fonts with which to implement them: TRIPLEX_FONT, SMALL_FONT , SANS_SERIF_FONT, GOTHIC_FONT, SCRIPT_FONT, SIMPLEX_FONT, TRIPLEX_SCR_FONT, COMPLEX_FONT, EUROPEAN_FONT, BOLD_FONT

setusercharsize function TBD
setviewport function Yes
setvisualpage function Yes
setwritemode function Yes Supports not only the modes COPY_PUTXOR_PUT specified by Borland, but also the modes OR_PUT, AND_PUT, and NOT_PUT (which in true Turbo C were used only for the putimage function). and
sopen function Yes This function (implemented as a macro) was contributed by Igor Bujna. Never having used it myself, I don't know how closely it matches the Turbo C function. However, O_TEXT is defined identically to O_BINARY, so it clearly doesn't distinguish between text and binary modes.
_stklen global variable Yes Requires TurboC.h. In Turbo C, this was used to define the size of the stack. This is pointless in gcc, so a variable of this name is provided, but assigning it a value does nothing.
strcmpi function Yes Requires TurboC.h. This is simply a macro that renames the function as strcasecmp.
stricmp function Yes Requires TurboC.h. This is simply a macro that renames the function as strcasecmp.
strlwr function Yes Requires TurboC.h.
strncmpi function Yes Requires TurboC.h. This is simply a macro that renames the function as strncasecmp.
strupr function Yes Requires TurboC.h.
const int TcUnicodeMappings[256] global variable n/a This is a resource not available in true Turbo C, but is helpful if you choose to use Xlib functions rather than graphics.h functions to display text on a graphics-mode screen. Except for the usual ASCII printable characters (0x20-0x7E), the character set in normal *nix fonts is not the same as the normal character set in MS-DOS. However, you can fake up this character set if a Unicode font (one with font descriptions ending in 10646-1) is used. The array simply provides a decent Unicode equivalent for MS-DOS characters. Every character is represented, but not every character is necessarily present in every Unicode font. The so-called GNU Unifont supports every character we reference. Note that lots of characters were missing from the original Borland-supplied stroked fonts anyhow.
textattr function Yes (See notes for textcolor.)
textbackground function Yes (See notes for textcolor.)
textcolor function Yes For color control, Borland's color constants are used, and are assigned the same numerical values as in Turbo C: BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE, BLINK. Whether or not you actually get blinking when using BLINK seems to depend on the console being used. For me, it seems to blink with KDE's konsole but not with xterm. Anyhow, your mileage may vary.
textheight function Yes
struct text_info data type Yes
textmode function Yes All of the Turbo C 2.0 text modes are supported, and I've included many added later, up to those defined in Borland C++ 5.5. The same constants, with the same numerical values are used as in Turbo C. (BW40, C40, BW80, C80, MONO, C4350, ....)

If you don't explicitly call textmode textmode(C80). Unfortunately, even though the initial call to textmode is optional, there is a non-optional call to textmode at the endEXITMODE not found in Turbo C is provided to allow ncurses to gracefully shutdown. You must call textmode(EXITMODE) prior to exiting your program, or else you risk losing control of the console from within which you're running the program. before beginning to use the various console-i/o operations, there is an implicit call of the program, not needed by the original Turbo C program but needed by the TurboC library. A mode called

TurboC does not actually distinguish between B&W and Color modes; all modes are color modes.

The rationale for sizing of the text console differs somewhat between Turbo C and ncurses, in a way that makes it difficult to reconcile them with perfect accuracy. You'll want to read the section titled "Screen resizing" for an explanation.

textwidth function Yes
struct time data type Yes
TurboC.h header file n/a There is no Turbo C header file of this name, but this is sort of a catch-all header I've created to cover everything not directly covered in conio.h and the other actual Turbo C header files. For example, it contains the integer datatype conversion macros and the prototypes for the strupr and strlwrgcc that way because string.h already exists). This file is automatically included if any of the other header files (conio.h, io.h, dir.h, etc.) are included. functions (which are handled in Turbo C by the string.h header file, but can't be handled in
ungetch function Yes There is an ncurses function of the same name, but somewhat different functionality. In any source file using conio.h, the conio version of ungetch#include "conio.h", while the ncurses version of ungetchungetchNcurses . applies below the applies above it. The ncurses functionality continues to be available, however, as a new function
unixtodos functions Yes Contributed by Igor Bujna.
wherex function Yes
wherey function Yes
window function Yes
_wscroll variable Yes This global variable variable was not present in Turbo C 2.0, but is present in some later versions.

No comments: