[Fribidi-discuss] (Justified?) compilation warning (fwd)
Shachar Shemesh
fribidi-discuss at sun.consumer.org.il
Wed Oct 23 01:31:02 EST 2002
This email is a bit long, sorry.
Behdad Esfahbod wrote:
>I don't like the idea too much. IMHO the FriBidiChar type should
>remain 4 bytes. We should have different encoding types.
>
>
I don't understand the "Different encoding types" part.
As for FriBidiChar - as far as the application is concerned, it is 4
bytes, unless the application explicitly asks for a different size (by
setting a preprocessor macro). This is the way Windows implement the
different encoding functions. I will explain the windows way because I
have some experience with it from both ends. Both as a user using this
API to create programs, and as a developer (Wine) that has to develop
using this infrastructure. I truely believe this is the way to go.
In windows there are three character types and one meta-type:
char - 1 byte
WCHAR - 2 bytes (utf-16)
mbcs - 1 or 2 bytes (unsigned char - meant to be used for CJK Multi Byte
Character Strings).
TCHAR - the current character base type.
If a macro called "UNICODE" is defined - this is WCHAR. If "MBCS" -
mbcs, otherwise - char.
When calling a function that depends on the character width (almost all
of them), two variants are defined in the DLLs. One with the A extension
(for ANSI) and another with a W extension (for Wide). A set of #ifdefs
and #defines in the windows headers map the basic function name (for
example - CreateWindow) to either CreateWindowA or CreateWindowW.
At some point I wanted to write a program that will be compiled for both
an Ansi and a Unicode variant. This was simply done by setting the
equivalent of "CFLAGS" for "-DUNICODE" or not in two flavours. The
program itself was written almost exclusively with function names of
"CreateWindow". The only exception was a certain parameter passing
filename in char * syntax. Instead of converting it, I just called
"CreateFileA" instead of "CreateFile", thus calling the Ansi variation
even if the program is a "unicode" variation.
Then again, at some point I asked for a feature (Font dialog - the
encoding selection) that made no sense in the Unicode variation. At that
point I had to place an #ifdef UNICODE, as the ALGORITHM was was
different among the flavours.
When working on the other side of the API, as a Wine developer, both A
and W variants need to be implemented. In Windows as in Wine, the way to
do that is usually by converting the Ansi strings to Unicode and calling
the W variant. This, I believe, would be the wrong way to go for
Fribidi, hense my, admitably a bit unusual, suggestion.
>>Makefile - don't you know what that is?
>>There are two special tricks performed in this makefile.
>>The first is for compiling fribidi_utf.c three times, selecting a
>>different default each time. The three .o files are then merged into a
>>single library.
>>
>>
>Nice trick, it's a bit unreadible at first, but I like it. But I
>really don't know how to merge it with fribidi's current
>codebase.
>
>
The only problem I see is with the various auto* tools. I have to admit
this is the first time I see anything beyond autoconf used, even for
projects far larger than fribidi, and I'm begining to understand why.
The other tools seem to impose limitations on directory structure at the
very least. I have not given up on implementing this strange trick yet,
but if that fails, how crucial is it to use them all?
Mean while, in a different email, Behdad also wrote:
>In the patch you sent, the answers were (as far as my understanding goes):
>> A. Automatically, according to the first argument's type (assuming it's
>> the right type)
>
>
>
>I like the idea of selection according to the first argument's
>type, but seems that I should forget it.
>
>
I don't. This spells out compilation problems left and right. If this
was a C++ interface, and we could do that without losing static type
checking, I'd perhaps reconsider.
>>> B. Either no reference was made, or suggested reimplementation for each
>>> size (different sources).
>>
>>
>
>Same source, In what I'm thinking of, the main functions are the
>same, and the wrappers do the casts. Some small functions may
>need three implementations though.
>
>
And you are suffering performance penalties, because you are moving four
bytes units using one byte functions. This means that you are apriori
limited by the design to inefficient engine. The alternative is to
reimplement some functions. This will suffer from duplicate code.
Had we been writing in C++, the implementation I would suggest would
involve templating the entire engine. This achieve's your goal of
autoselecting based on variable type, and solves the duplicate code
problem. While this would have been a reasonable solution HAD C++ been
used, for C I think I suggest a reasonable alternative.
No duplicate code - instead of duplicating the code, we are simply
recompiling the same code as many times as necessary. We actually have
better control over variations in algorithm as you cannot place #ifdefs
inside templates (you could, theoretically, use "if", but that's a
different discussion).
No auto selecting the function based on type, true, but that's actually
a C limitation rather than a design limitation. Using C++ you could just
as easily define three overloaded functions and call log2vis8, log2vis16
and log2vis32 from each function. Get this, however. NO CAST!!! You
don't have to cast anything to anything, and you get full static typing.
If you want, you can give me CVS access, and I'll create a branch and
try to implement what I'm talking about there. I'm a bit afraid of doing
too long a development on my personal machine's only, as I just suffered
a HD crash that wiped my entire installation, and the only reason I have
a backup of the demo I showed on the list is because I have the list
archives.
As usual, opinions etc. are welcome.
Shachar
P.S.
How DO you pronounce "Behdad"?
More information about the FriBidi
mailing list