Porting Database
13 messages in this thread
Doug, I have two questions. While attempting to port Mix's Database
toolchest to the AMIGA per the article in AC's Tech vol3#2, I found that
the prototype for open used by SAS/C6.2 uses the variable argument
convention which was conflicting with the prototypes in the Mix source.
The documentation doesn't mention anything regarding the variable argument
list either on-line or in the manual. What gives?
Second I am currently using #if … #endif using the __SASC and _AMIGA
variables to reconfigure around this. Is this a good way? Is there a
better way?
There are a couple of ways that you could do this. The variable arguments
for the prototype for open allows an optional protection word for creat
type calls. Only when you specify O_CREAT as an open mode is this
variable referenced. The #if is probably your best way to deal with it.
Note that if mix is attempting to declare a prototype for open and then
call it, you are better off just not having that prototype in the mix
header files. Basically, anything that is part of the compiler library
should be declared by the compiler include files and not redeclared by the
program using it.
John is correct (of course) – you should always use the compiler's version
of a prototype if possible. As to why it's different, our version of
open() corresponds to the version used on most recent UNIX systems.
The problem is that open() uses two parameters MOST OF THE TIME, and
a third parameter if the open mode is O_CREAT (Also as John says.)
UNIX code tends to only pass 2 parameters except when O_CREAT is
specified. This makes open() a varargs function, according to the
ANSI standard.
–Doug
James, I have been also trying to port MIX btree to amiga. My major
problem is that I am just a beginner in C. I have made all changes as
per AC's Tech vol3#2, but I get the feeling that the MIX source I
have (latest version as of 1 month ago) is slightly different than
the source referenced in AC's Tech's article. The first problem I am
having is a complier casting error in the module source "opendb.c" It
flags the following line as an error: i = *((unsigned char
*)keya)++; keyb++;
This error was called illegal lvalue error.
What is needed here. Please spell out exact changes as I really don't
understand C well enough yet.
Also could you provide exact code change for the Open prototypes error?
Thanks in advance
Ron Stein (Toronto,Ontario)
We'd need to know more about the type of 'keya' and 'keyb' and 'i'
before we can help…
John, 'keya' and 'keyb' are passed as an argument and defined:
char *keya; and char *keyb;
the variable 'i' is defined as: int i;
Hope this helps
Thanks,Ron Stein (Toronto,Ontario CANADA)
I'm not sure I can see the problem, it may be elsewhere. The 'i = *((unsigned
char *) keya) ++;' means "cast pointer keya to be a pointer to an unsigned char
(instead of the char * it was) and then retrieve the byte value from where it
pointed, treat it as an unsigned char integer, convert to int, assign to i,
then increment the pointer keya." Maybe the cast of keya is the problem, it
doesn't like the fact that you've changed it to an unsigned char and then
expected to increment it. There's a logical flaw in this program, which I'd
suggest you'd clean up later. You need to determine if 'char *keya' should be
'unsigned char' or just plain 'char'. From this code fragment, it looks like
the program expects to store unsigned integers in the range 0..255 in those
bytes where 'keya' might point. Therefore, I'd suggest changing it to
'unsigned char *keya' and removing the other casts.
John, I'am quite unclear has to how to change this snytax: ie. change all
occurences of '*((unsigned char *) keya) ++;' to:
'*(keya) ++;' ???????
I'am afaid that is done have a good enough grasp of this casting syntax yet
and also the
'*((unsigned char *) keya)' is used all over this source code!! I
have managed to compress the source file to 6227 bytes as a 'lha' file, but I
don't know how yet the proper syntax of this forum to send you this file. This
might clear up what's going on?
I think you need to learn how to fix this yourself much more than you need to
learn how to send this to me to fix. 🙂
My point is: if you have *((unsigned char *) keya) all over this source code,
then 'keya' shouldn't be 'char *', it should be 'unsigned char *keya'. Or
better yet, 'typedef unsigned char keyType;' and then 'keyType *keya;'. You
are dealing with source code that sells for, what, $20? You might get what you
pay for. (Although I bought Mix because it was so cheap, too.)
The ANSI C standard sets down certain requirements for what can be
assigned to and what can't. Things that can be assigned to are
called "lvalues", or "left values". "left values" can appear on the
left-hand side of an assignment operator.
In your example, the ++ operator is the assignment operator
involved. Of course, foo++ is really (foo=foo+1) to the compiler, so
it must consider ++ an assignment operator.
One explicit restriction in ANSI C that K&R C left ambiguous was "The
result of a cast is not an lvalue." I believe it's in the ANSI
standard in almost exactly those words. Many pre-ANSI compilers
allowed this, and a lot of pre-ANSI code does it, but it's illegal
all the same.
So what your code is doing is first casting keya to (unsigned char
*), then trying to use ++ on it. This will not work. You need to
split out the ++ and the cast into seperate operations.
Ron, sorry I didn't get back to you sooner! Looks like the problem
has been quashed. I haven't yet compiled the isam portion of the
database source. After getting the CBT source compiled I am
attempting to learn/use GadToolBox to create a test program to enable
testing and debugging. Then the next version of GadToolBox came out
and just reading the docs… Let me know if anything else
interesting comes up.