Académique Documents
Professionnel Documents
Culture Documents
Lei Unciano
in partial fulfillment of the requirements
of the subject Project Management
Theory of computation
According to Peter J. Denning, the fundamental question underlying computer science
is, "What can be (efficiently) automated?" [11] The study of the theory of computation is
focused on answering fundamental questions about what can be computed and what
amount of resources are required to perform those computations. In an effort to answer
the first question, computability theory examines which computational problems are
solvable on various theoretical models of computation. The second question is
addressed by computational complexity theory, which studies the time and space costs
associated with different approaches to solving a computational problem.
Artificial Intelligence
This branch of computer science aims to create synthetic systems which solve
computational problems, reason and/or communicate like animals and humans do. This
theoretical and applied subfield requires a very rigorous and integrated expertise in
multiple subject areas such as applied mathematics, logic, semiotics, electrical
engineering, philosophy of mind, neurophysiology, and social intelligence which can be
used to advance the field of intelligence research or be applied to other subject areas
which require computational understanding and modelling such as in finance or the
physical sciences. It all started with the grandfather of computer science and artificial
intelligence, Alan Turing, who proposed the Turing Test for the purpose of answering
the ultimate question... "Can computers think ?".
Turbo C
From Wikipedia, the free encyclopedia
Turbo C was an Integrated Development Environment and compiler for the C
programming language from Borland. It was first introduced in 1987 and was noted for
its integrated development environment, small size, extremely fast compile speed,
comprehensive manuals and low price.
In May 1990, Borland replaced Turbo C with Turbo C++. In 2006, Borland reintroduced
the Turbo moniker.
Version 1.0, on May 13, 1987 - It offered the first integrated edit-compile-run
development environment for C on IBM PCs. The software was, like many
Borland products of the time, bought from another company and branded with
the "Turbo" name, in this case Wizard C by Bob Jervis[1] [2] (The flagship Borland
product at that time, Turbo Pascal, which at this time did not have pull-down
menus, would be given a facelift with version 4 released late in 1987 to make it
look more like Turbo C.) It ran in 384KB of memory. It allowed inline assembly
with full access to C symbolic names and structures, supported all memory
models, and offered optimizations for speed, size, constant folding, and jump
elimination.
Version 1.5, in January 1988 - This was an incremental improvement over
version 1.0. It included more sample programs, improved manuals and other bug
fixes. It was shipped on five 360 KB diskettes of uncompressed files, and came
with sample C programs, including a stripped down spreadsheet called mcalc.
This version introduced the <conio.h> header file (which provided fast, PC-
specific console I/O routines). (Note: The copyright date in the startup screen is
1987, but the files in the system distribution were created in January 1988.)
Version 2.0, in 1989 - The American release was in late 1988, and featured the
first "blue screen" version, which would be typical of all future Borland releases
for MS-DOS. The American release did not have Turbo Assembler or a separate
debugger. (These were being sold separately as the product Turbo Assembler.)
See this ad for details: Turbo C, Asm, and Debugger were sold together as a
professional suite of tools. This seems to describe another release: Featured
Turbo Debugger, Turbo Assembler, and an extensive graphics library. This
version of Turbo C was also released for the Atari ST, but distributed in Germany
only.
Note on later releases: The name "Turbo C" was used after version 2.0, because with
the release of Turbo C++ 1.0 with 1990, the two products were folded into a single
product. That first C++ compiler was developed under contract by a company in San
Diego and was one of the first true compilers for C++ (until then, most C++ work was
done with pre-compilers that generated C code). The next version was named Borland
C++ to emphasize its flagship status and completely rewritten in-house, with Peter
Kukol as the lead engineer. The Turbo C++ name was briefly dropped, eventually
reappearing as Turbo C++ 3.0. There was never a 2.0 of the Turbo C++ product series.
Introduction
No explanation of the exact functionality of the various TurboC library elements is
offered here, except for noting differences between Borland's version and my version.
As Pablo Vidal points out on his UConio web page, if you don't know how to use these
functions already, then you won't need the TurboC library, since you shouldn't be using
it for new program development anyway. Consult Borland's Turbo C Reference Guide
as needed.
But if you are porting or supporting a Turbo C program that somebody else has created,
and don't have access to Borland's printed materials yourself, I'd offer the following
advice: Download the free Turbo C development environment that Borland has kindly
provided on their "museum" website. (Requires you to register, but registering is
free.) The IDE has context-sensitive help, and you can find out what most functions do
by typing the name of the thing (such as clrscr) into the source-code editor and then
hitting ctrl-F1. Of course, this requires you to have some means of running an MS-DOS
program.
Alternately, the online help for Borland's C++Builder program actually provides much
fuller documentation of Turbo C library functions (even though it doesn't support a lot of
them), and while C++Builder itself is not free, Borland allows you to download the
Win32-based helpfile for free from their website . After you download it, the particular
helpfile you want is the one which Borland calls the DOS Reference. Sadly, there's no
guarantee that this documentation corresponds exactly to the functionality provided in
Turbo C.
Using TurboC
Compile the Turbo C source you're trying to port, using GNU gcc. Add command-line
switches to link to TurboC, to ncurses, to Xlib , and to pthreads:
gcc [-O0] ... your switches ... -lTurboC -lm -lncurses -L/usr/X11R6/lib -lX11 -lpthread
or
gcc -DDoNotFixIntegers ... your switches ... -lTurboCu -lm -lncurses -L/usr/X11R6/lib
-lX11 -lpthread
In FreeBSD, you'll have to say "-lc_r" rather than "-lpthread". Note that the actual
directories containing header files and libraries of the X-window system may vary, so
you may need to alter the "-L" switch or add a "-I" switch to access the appropriate X
files.
The command-line switch "-DDoNotFixIntegers" is optionally used to turn off TurboC's
integer datatype conversion macros and (as you may notice) uses a slightly different
version of the library. In the past, some GNU "functions" actually implemented as
macros have failed to compile with optimization level higher than -O0, when integer
datatype conversion is turned on. That's why one of the examples includes -O0 and the
other does not. However, this precaution is probably no longer necessary, and you
needn't use -O0 unless experiencing problems.
You can see samples of both types of compilation in the provided Makefile. If there are
complaints from the compiler, refer to the trouble-shooting section below.
The switch "-lm" is required by only a couple of functions, but there's no harm in using it
for everything. The switch "-lncurses" is needed only if you are using the Turbo C
functions prototyped in conio.h, while the switches "-L/usr/X11R6/lib -lX11 -lpthread" are
needed only if using the functions prototyped in graphics.h. You'll want to remove these
switches if they're not used, to enhance your ability to compile the ported program on
more platforms. For example, neither ncurses nor Xlib are typically present in a Mac
OS X system (though they can be installed with some effort), and compilation of your
ported program will therefore typically fail if these compiler switches are included.
Although I'm not entirely sure why you'd want to do it, and though I haven't tried it
myself, I think you can probably disable the graphics.h functions in the TurboC library,
and replace them with those in the GRX 2D graphics library. In the TurboC library
Makefile, remove the compiler switch "-DWITH_X" before compiling the TurboC library.
Then install GRX and follow the instructions in GRX's readme.bgi file. I'd be happy to
hear from anyone with feedback (pro/con/howto) on this topic, and will post those
comments if they seem to be of general interest.
Licensing
Since TurboC is provided under the LGPL , you are free to license your own program
however you like. In other words, your program does not have to be GPL'd. Of course,
it would be nice to do so, and you might want to consider GPL'ing your code. You'll still
want to read the LGPL to make sure that you conform to its (rather minimal)
requirements.
If your code is linked to ncurses or X, as described in the previous section, you'll also
have to conform to their licenses, namely the MIT license and the X-Consortium license
respectively. These licenses are highly non-restrictive, and require merely that you
include their copyright notices. Both licenses can be viewed at the Free Software
Foundation's website.
Special-function keys
In Turbo C, special keyboard character such as F1 or Ctrl-PgUp are indicated by a two-
byte sequence with the getch function: If the first byte returned is 0, then the next byte
indicates which special-function key has been pressed. The values for this second byte
have been summarized in the fnkeys.h file, which also provides symbolic names for all
of them.
Unfortunately, many function-key sequences available using getch in MS-DOS are not
available at all using the ncurses library. (For example, F1 is available, but Ctrl-PgUp is
not.) Others may or may not be available, depending on various factors.
Consequently, while the TurboC library has mimicked this functionality as best it can --
or rather, as best I can -- you may still be in the position of having to change some of
the special-function keys used by your program.
Here's a list of all special keys that I believe are handled by Turbo C's getch function,
along with my observations of how they are handled by the TurboC library's getch
function. Your mileage may vary.
Symbol
Special Under KDE Under a text-mode
provided in Under xterm
Key Konsole login
fnkeys.h
Digits on No! Treated as
n/a (0-9, of
numeric Ok Ok arrows,
course)
keypad PgUp/PgDn.
Ctrl-A
Ok, except there is
through C_A-C_Z Ok Ok
no Ctrl-Z.
Ctrl-Z
Ok, except that Alt-
Alt-A
O has a slight
through A_A-A_Z Ok Ok
delay before
Alt-Z
registering.
F1
through N_F1-N-F10 Ok Ok Ok
F10
Ok, except: Shift- Ok, except: Shift-
Shift-F1 Ok, except Shift-
F5 terminates F5 terminates
though S_F1-S_F10 F5 terminates
program, and F9- program, and F9-
Shift-F10 program
F10 don't work. F10 don't work.
Alt-F1
No! (These are No! (These are No! (Switches
through A_F1-A_F10
KDE hotkeys.) KDE hotkeys.) between consoles.)
Alt-F10
Ctrl-F1
No! (These are No! (These are
through C_F1-C_F10 No!
KDE hotkeys.) KDE hotkeys.)
Ctrl-F10
Alt-0
through A_0-A9 Ok Ok Ok
Alt-9
N_UP, N_DOWN, Ok on standalone
Arrows N_LEFT, Ok arrow keys, but not Ok
N_RIGHT on numeric keypad.
Ok on standalone
PgUp, N_PGUP,
Ok arrow keys, but not Ok
PgDn N_PGDN
on numeric keypad.
Ok on standalone
Home, N_HOME,
No! arrow keys, but not No!
End N_END
on numeric keypad.
Ok on standalone
Ins, Del N_INS, N_DEL Ok arrow keys, but not Ok
on numeric keypad.
Pad-
N_PADPLUS, No, treated as No, treated as
minus, Ok
N_PADMINUS regular +/-. regular +/-.
Pad-plus
Ok on standalone
Ctrl-right, C_LEFT, arrow keys, but No, treated as No, treated as
Ctrl-left C_RIGHT not on numeric regular right/left. regular right/left.
keypad.
No, treated as No, treated as
Ctrl-PgUp, C_PGUP,
No! regular regular
Ctrl-PgDn C_PGDN
PgUp/PgDn. PgUp/PgDn.
Ok on standalone
Ctrl-
C_HOME, arrow keys, but No, treated as
Home, No!
C_END not on numeric regular home/end.
Ctrl-End
keypad.
Ok on main
Alt-minus, A_MINUS, keyboard, but not
Ok Ok
Alt-equals A_EQUALS on the numeric
keypad.
Ok, though there
Ok, though there is Ok, though there is
is a short delay
a short delay a short delay
Esc N_ESC before the
before the before the
keystroke
keystroke registers. keystroke registers.
registers.
I'd be happy to hear from anyone with a clear idea on how make this work more
consistently, perhaps by using termcap/terminfo, of which I'm completely ignorant.
When I say that we attempt to map the characters as closely as possible, I mean that
given a character with a certain numerical code, we attempt to display a character that
looks as much as possible like the IBM PC character with that same numerical code.
On the other hand, we have no way to translate string characters appearing in your
source code. What do I mean by this? Well, consider the character 'é'. This happens
to correspond to character 0x82 in the IBM PC character set. Suppose you have
source code like this:
Graphics mode
Note: The material in this section and the next describes both features that exist and
features that are planned for the future. Consult the change log for more info about the
support provided in specific code versions.
In true Turbo C, graphics-mode screens (as opposed to text-mode screens) are handled
by something called the Borland Graphics Interface, or BGI for short. The BGI is an API
containing 80+ functions. Note that the graphics functions provided with the TurboC
library are somewhat less portable than the remainder of the library, in that the X-
window system is required. If you need graphics functions that can operate without X,
I'd suggest reading the next section.
Some of the more important points of departure from true Turbo C are these:
External files. True Turbo C relies on the existence of certain plug-in files,
specifically the BGI "drivers" (such as EGAVGA.BGI, HERC.BGI, etc.) and the
fonts (such as TRIP.CHR, SANS.CHR, etc.). The TurboC library has no such
dependence, though it may eventually be possible to load new fonts at runtime.
Functions related to manipulation of these files are provided, so that you don't
have to take the effort of writing them out of your code, but often they are empty
stubs.
Missing functions. Implementation of the floodfill function is not presently
planned.
Screen hiding. Since true Turbo C ran under MS-DOS, a non-windowed non-
graphical environment, the way it had to operate was to take over the entire
display screen, and to place the hardware graphics controller itself either in "text
mode" or in "graphics mode". In other words, if the graphics controller was in text
mode then only textual functions (like those in stdio.h or conio.h) could be used,
whereas in graphics mode only graphical functions (graphic.h) could be used.
Material written to the screen in text mode disappeared when graphics mode was
started, and vice-versa. With the TurboC library, because a windowed
environment is used, both text-mode windows and graphics-mode windows can
appear simultaneously. In other words, when graphics mode is started, a new
graphics-mode window is created, but no effort is made to hide the old text-mode
window.
Palettes. Since true Turbo C dealt with actual modes of the hardware graphics
controller, palettes were built into the graphics controller itself, and changes to
palettes (for example, reassignment of a palette color, like the background color)
were instantly reflected on-screen. With the TurboC library, changes to the
paletted (and specifically, to the background color) are reflected only in future
screen-writes, and don't affect anything already written to the screen.
Text. The bitmapped font is supported. For various reasons, sadly -- having
spent a considerable amount of work on it -- I find that it's not convenient to
support Borland's "stroked font" (CHR) format. (These reasons include the
following: Borland's license does not allow using the Borland-supplied fonts with
the TurboC library; nobody has made any free CHR fonts available on the
Internet; and, while there are TrueType-to-CHR programs available, they cost
more than I'm willing to pay -- i.e., more than zero.) Therefore, the functionality
otherwise normally provided by the stroked fonts will eventually be supplied
indirectly by means of *nix system fonts. Currently, this has not yet been
implemented. Or, you may draw text directly using Xlib functions, as described a
few lines below. You may also find the TcUnicodeMappings array useful when
using Xlib.
The getimage and putimage functions . This is described in detail above. Briefly,
these functions are used to fetch a rectangular area of the display into an image
buffer, or to write the image back to the screen. The formats of the image buffers
were undocumented by Borland, but actually corresponded to the memory maps
used by the specific graphics controllers and graphics modes. These formats are
not duplicated by the TurboC library.
Flexibility. You don't need to confine yourself to the BGI functions. You can also
use X-window library functions. For example, *nix system fonts -- which BGI
obviously doesn't support -- can be used in a TurboC-ported program via Xlib
functions like XLoadFont , XDrawString, etc. All you have to know -- other than
basic X operations -- is that the TurboC library exposes the following X objects
for your use:
Display *TcDisplay; // The X-window "display".
Window TcWindow; // The X-window "window".
gint TcScreen; // The X-window "screen".
GC TcGc; // The X-window "graphics context".
It's necessary to modify the graphics context (TcGc) for any serious drawing. If
you don't restore it to its original settings, the TurboC library will become
seriously confused. Therefore, it's best to copy the graphics context (with X-
window function XCreateGC followed by XCopyGC), and work only with your
copy of the graphics context rather than with the original. Also, to avoid
threading conflicts, always wrap your X operations as follows:
XLockDisplay (TcDisplay);
// ... your X code goes here ...
// For Example, draw a text string at x=10, y=20:
XDrawString (TcDisplay, TcScreen, TcGc,
10, 20, "I am text", 9);
XSync (TcDisplay);
XUnlockDisplay (TcDisplay);
Endian conversions
Since all Turbo C functions have been run only on Intel 'x86 processors, it is not
uncommon in Turbo C code to find that the programmer has simply assumed that the
CPU is little-endian -- i.e., that the LSB of multi-byte integers precedes the MSB. In
porting such code to GNU gcc, one has to recognize that it may not necessarily be run
on a little-endian processor. For example, I do a lot of work on an iMac, which is based
on a big-endian PowerPC processor. This is not important in most cases, but does
affect various operations such as the matching of bytes within union objects and,
especially, reading/writing files.
To make it easier to deal with this problem, I've provided a number of functions not
originally present in Turbo C that can be used to convert endian types where required.
Unfortunately, it's still up to you to figure out that there's a problem and to add these
function calls to the program.
There are two separate groups of functions, those which convert the endian type of an
integer value already stored in memory, and those which convert data on-the-fly whilst
reading/writing a file. All of the functions require the TurboC.h header file.
Function prototype Description
Performs an in-place conversion of a
16-bit integer value stored in memory
from little-endian format to the natural
CPU endian format, or vice-versa .
Using this function twice in succession
void FixLittle16 (uint16_t *);
gets back whatever you started with.
There's no harm using this function if
the CPU happens to be little-endian,
since the value is passed through
unchanged in that case.
void FixLittle32 (uint32_t *); Same as FixLittle16, but 32-bit instead.
Same as FixLittle16, but big-endian
void FixBig16 (uint16_t *);
instead.
Same as FixLittle16, but 32-bit big-
void FixBig32 (uint32_t *);
endian instead.
Reads a 16-bit little-endian integer from
a file, and delivers it in the natural
int ReadLittle16 (FILE *fp, uint16_t *Value);
endian-format of the CPU. Returns 0
on success, non-zero on failure.
Same as ReadLittle16, but big-endian
int ReadBig16 (FILE *fp, uint16_t *Value);
instead.
Same as ReadLittle16, but 32-bit
int ReadLittle32 (FILE *fp, uint32_t *Value);
instead.
Same as ReadLittle16, but 32-bit big-
int ReadBig32 (FILE *fp, uint32_t *Value);
endian instead.
Takes a 16-bit integer value in the
natural endian format of the CPU, and
int WriteLittle16 (FILE *fp, uint16_t Value); writes it to a file as a 16-bit little-endian
integer. Returns 0 on success and
non-zero on failure.
Same as WriteLittle16, but big-endian
int WriteBig16 (FILE *fp, uint16_t Value);
instead.
Same as WriteLittle16, but 32-bit
int WriteLittle32 (FILE *fp, uint32_t Value);
instead.
Same as WriteLittle16, but 32-bit big-
int WriteBig32 (FILE *fp, uint32_t Value);
endian instead.
Examples
Hello, world! Consider the following Turbo C program:
#include <conio.h>
#include <time.h>
void
main (void)
{
time_t t, newt;
int i = 0, x, y;
time (&t);
clrscr ();
cprintf ("Hit any key to continue: ");
x = wherex ();
y = wherey ();
// Wait for a keypress, flashing the message
// "I'm waiting!" on and off once per second.
// After any key is hit, display "Hello, world!"
while (!kbhit ())
{
time (&newt);
if (t != newt)
{
t = newt;
i++;
if (0 == (i & 1))
cprintf ("I\'m waiting!");
clreol ();
gotoxy (x, y);
}
}
getch ();
cprintf ("\r\nHello, world!\r\n");
}
This program almost compiles with GNU gcc (and the TurboC library), and almost
works as-is, except for a couple of points:
You will want to add the following statement at the very end of the program:
textmode (EXITMODE);
The "Hello, world!" message won't actually be seen, because the
textmode(EXITMODE)you have to end with will instantly restore whatever was on
the screen prior to running the program. So, you might want to add another
getch() printing the "Hello, world!" message.
GNU gcc expects main to be of type int rather than void, and of course you can't
actually use int because of the automatic conversion of integer datatypes. So
use gint instead.
Having done these things, you'll find that you can compile the program and run it without
any errors:
gcc -o Hello Hello.c -lTurboC -lncurses
xterm +sb -e Hello
Compiling without warnings is actually a little unusual, because there are quite a few
things that can cause non-fatal warning messages. See the trouble-shooting section for
more detail.
Trouble-shooting
Well, as you've seen, there are many factors that come into play porting from Turbo C to
gcc/TurboC. Some of these are describe above, but there are others that haven't even
been hinted at. For the sake of completeness, here's a somewhat-complete list of the
difficulties I've personally encountered:
Summary or illumination of trouble-shooting items covered earlier
Whenever possible, run the ported program under xterm, with the command-line
switches "+sb -tn linux".
Functions needed by Turbo C may not have been provided in the TurboC library
function list. Solution: Write them and send them to me.
Integer datatypes may not have been converted properly. Solution: Handle as
described earlier.
Some functions, such as strupr, strlwr, and fcloseall are not handled by any of
the Turbo C header files. Solution: #include <TurboC.h> .
The TurboC library cannot physically resize the console unless the ported
program is being run under xterm. Solution: Manually resize the console,
rewrite the code to adjust automatically to size changes, or send me a fix.
The ported program does not release control of the console on exit. Solution:
Add a call to textmode(EXITMODE) before exiting the program.
Functions don't behave as expected. Quite a few functions are common to Turbo
C and to gcc, but act somewhat differently. An example is printf. In gcc this
supports the carriage-return character ('\r'), but in true Turbo C does not. I've
chosen not to correct this. Other functions, like getch , ungetch, and mkdir, are
different enough that I've had to correct for their differences. Typically this is
done by means of macros, so that these functions have their gcc interpretations
above the point in the source file where their associated header files are
included, and have their Turbo C interpretations below that point. Solution:
Learn to recognize it, I guess. The gcc functions are always available, even after
macro assignment, by means of a new name, such as getchNcurses.
Not all special-function keys on the keyboard are supported. Solution: Rewrite
the code to eliminate the keys that aren't supported, or send me a fix .
Not all graphics characters are supported in console i/o mode (cprintf/putch/etc.),
and none of them are supported in regular text mode (printf/putchar /etc.).
Solution: Rewrite the code to eliminate those characters, or send me a fix.
char is signed but is supposed to be unsigned (or vice versa). Solution: Both
Turbo C and gcc have options/switches for setting whether characters are
signed or unsigned by default. Make sure you set the switch in gcc the same
way as the option in Turbo C.
Main function is of the wrong type. The gcc compiler expects main to be of type
int, whereas in Turbo C these are often (always?) of type void. Solution:
Change it.
You may experience some compiler errors if integer datatype conversion is
turned on but a compiler optimization level higher than -O0 is used when
compiling your code. Solution: reduce the optimization level to -O0 and report
the problem. This applies only to compiling your own code, and not to building
the TurboC library.
Allocating the image buffers for the getimage function: The proper sequence of
operations, as defined by Borland's docs, is this:
// Good code, approved by Borland and by the TurboC library.
void MyFunction (void)
{
void *bitmap;
bitmap = farmalloc (imagesize (left, top, right, bottom));
getimage (left, top, right, bottom, bitmap);
... do stuff, such as call the putimage function ...
farfree (bitmap);
return;
}
If instead your program does stuff like the following, it will probably work, but
you'll have a memory leak in which the memory allocated for the image buffers
won't be fully deallocated:
// Bad code, by any standards.
void MyFunction (void)
{
char bitmap[4 + X_SIZE * Y_SIZE * COLOR_DEPTH];
getimage (left, top, left + X_SIZE - 1, top + Y_SIZE - 1, bitmap);
... do stuff, such as call the putimage function ...
return;
}
The problem is that getimage has to transparently allocate memory of which
you're not aware -- specifically, X-window system Pixmap structures. In the
olden days, programmers (such as myself) were tempted to write this kind of bad
code because they believed that they understood the format of the graphical data
in the image buffers -- even though Borland did not specify or even hint at its
nature. This assumption is now revealed as being false.
Manipulation of the image buffers used by the getimage and putimage
functions: Borland does not specify the format of the data in the image-buffer
structures used by the getimage and putimage functions. (See the item above.)
All that is specified is that this:
struct {
unsigned short width;
unsigned short height;
... some undocumented stuff representing graphical data ...
};
For practical reasons, it is likely that some (perhaps many) programmers -- such
as myself -- hacked the format of the graphical-data area, and chose to
manipulate the area directly. Programs based on this principle will not work,
because the format of this area -- at least in the X-window based implementation
of graphics.h functions -- is not the same in the TurboC library as it was in
Borland's Turbo C. (Note: it is possible to rewrite the code for getimage and
putimage so that the old Borland formats are preserved. The formats were
dependent on the graphics controller and the graphics mode. Anyone who cares
to hack all of these and to rewrite the code accordingly is very welcome to do so.
Please send me the fixes. As of Borland C++ v5.0, the graphics.h file listed 43
graphics controllers and 29 graphics modes by name. The comments in the next
trouble-shooting item below may be of assistance to you, if you try to undertake
this task.) However, it is possible to manipulate the graphical data in the TurboC
library image buffers, because I will tell you the format. You need to use X-
window drawing functions such as XDrawLine, as applied to X-windowPixmap
structures. The format of the image buffer, for the X-window implementation of
the TurboC library, is as follows:
struct TcImageBuffer
{
gushort Width;
gushort Height;
Pixmap Handle;
};
Saving getimage image buffers to disk, or loading putimage image buffers from
disk: If you read the discussion above, it will be obvious to you that this is next-
to-useless, since the image buffers themselves no longer contain graphical data.
What needs to be save or loaded is the Pixmap structures themselves, whereas
the image buffers contain only the handles of the Pixmap structures. I believe
that it is possible to get around this problem by rewriting the getimage /putimage
functions in terms of the X-window functions XGetImage and XPutImage rather
than Pixmap structures. If you want to do this and send me the patches, tell me
about it.
Trouble-shooting items not covered earlier
Various standard C library "functions" may actually be implemented as macros
on some target platforms, and as true functions on others. A common example
is strcpy. When such macros contain casts (such as "(unsigned int)") that are
questionable as described above under handling of integer datatypes, code
containing them will fail to compile. It's difficult for me to catch all of these, since
they may be perfectly fine on my test machines. For clues as to how to work
around such problems, look at the implementation of strcpy in TurboC.h.
Sometimes, changing the compiler optimization level to "-O0" fixes the problem.
Or, just don't use the automatic datatype conversion.
Header files are messed up. The TurboC header files all include TurboC.h,
which by default redefines short, int, unsigned , and long. Solution: Any
standard system headers, must be included before any TurboC header, or else
the reassignments of the integer datatypes will destroy them. Actually, TurboC.h
itself includes a variety of standard system headers -- like stdlib.h, stdio.h,
string.h, ctype.h, and so on -- and this problem won't arise for those headers.
But your typical *nix system has a cadjillion header files, and TurboC.h can't
include them all.
Filenames don't work in fopen. MS-DOS expected filenames like
C:\MYDIR\MY.FIL, whereas *nix expects names like /MYDIR/MY.FIL. Also, *nix
is case-sensitive, whereas MS-DOS is not. So if you have any hardcoded
filenames that violate these rules, you'll have to fix them. I suppose I could have
fixed fopen to get around some of these problems, but I have not done so.
scanf/gets/getchar doesn't work. In Turbo C, to a certain extent you can get
away with mixing and matching getchar & getch or cgets & gets. This doesn't
work with the TurboC library because once the conio text console is active you
can't use scanf/gets/getchar until closing the conio console. Solution: Rewrite
the code to eliminate gets/getchar in favor of cgets/getch (or vice versa). But
note this: In my experience, a large motivator for using conio was often simply
that Turbo C's print/puts functions did not correctly support '\r'. gcc 'sprintf/puts
functions do correctly support '\r', so you might not even need conio.
The compiler gives weird errors for printf/scanf/(etc.) commands. The gcc
compiler is intelligent enough to find many discrepancies between format strings
and value lists in printf statements. For example, it can recognize that this is an
error:
long n; // a long
printf ("%d\n", n); // an int
But it's not smart enough to necessarily recognize that the following isn't an error:
uint32_t n; // a long
printf ("%ld\n", n); // a long
That's okay, though, because gcc produces only warning message rather than
fatal errors for these problems. Besides, you'll want to check all of your i/o
statements carefully anyway, since stuff like the following is correct in Turbo C
but not in gcc/TurboC:
int n; // 16-bits
printf ("%d\n", n); // 16-bit in Turbo C but 32-bit in gcc.
printf/scanf/(etc.) don't work, but there's no compiler error. See the item above.
File i/o is messed up. File i/o is not messed up, but since different datatypes are
supported in Turbo C than in gcc/TurboC, the data formats you're reading/writing
may be different. This can happen in numerous ways:
o Integer datatypes are the wrong size.
o Integer datatypes are the wrong endian type.
o printf/scanf/(etc.) may use the wrong format strings (see above).
o Floating-point formats differ. Sorry, but I've no clue about this.
o Structures are packed differently. For example, a structure like this in
Turbo C
struct MyStruct {
char c;
short s;
int i;
long n;
};
might have to be rewritten as follows in gcc/TurboC if you expect to use it
for direct i/o to a file:
struct MyStruct {
int8_t c __attribute__ ((packed));
int16_t s __attribute__ ((packed));
int16_t i __attribute__ ((packed));
int32_t n __attribute__ ((packed));
};
I can't guarantee that this always works, but I've ported a reasonably
substantial text-indexing system from MS-DOS (16-bit, little-endian) to
LinuxPPC (32-bit, big-endian) that made heavy use of directly
inputting/outputting structures to files, and the file formats were
preserved. That seems to me to be a good sign.
Interrupt service routines. Sorry, I don't even want to think about this.
Inline assembler code. It can be done, but I don't know how, and the syntax will
be different. I personally don't care about this problem, because I'm interested
only in completely portable code. Sorry!
Making DOS or BIOS system calls. Obviously, you can't.
Turbo C pragmas. These will get warning messages from the compiler, but will
be otherwise ignored. But they're confusing, so unless you expect to go back to
MS-DOS someday, I'd suggest removing them manually. :-)