From: Andreas L. <no...@sb...> - 2001-05-27 11:31:59
|
On 27 May 2001 11:27:16 +0200, Eric Bezault wrote: > Andreas Leitner wrote: > > > > ad 7) > > External C dependencies make life really really hard... I have my > > examples all setup very general. Due to the factory class they check > > what back end parsers are compiled in and you can choose your favoriteat > > runtime via a command line argument. This brings in some trouble at > > build time though: I want to provide a simple way for the user to choose > > at build time what backends he wants to have compiled in. This is > > important because not everybody wants to go through the hassel and > > install expat on his system. Also a possible compile_to_jvm is not > > possible with expat dependencies in the build configuration. Now how can > > I do that? With Makefiles of course, but they do not work on Windows ): > > > > Do you have any idea on how I can solve that issue? > > I thought that having expat/no_expat would solve the problem. > One has just to choose one or the other in the Ace file at > build-time. Did I miss something? Additionally to the optional clusters you have optional C libraries. You need to link to libraries specify include directories, give cecil files etc. All this must be done _only_ if a user wants to compile the correspoding implementation in. That's why I came up with XACE. It's structure allows to specify all those things in subclusters. The tool merges the dependencies of the total ACE file and generates the usual build files. And simple EXPRESSIONS (like those in GEPP - EXPAT||EIFFEL) allow for selecting and deselecting various clusters. Only that I don't need "#ifdefs", but can use attributes in XML to do the job. > BTW, I was surprised by your directory structure: > > impl/expat/expat/ep_event_parser_factory.e > impl/expat/expat/... > impl/expat/no_expat/ep_event_parser_factory.e > > I thought you would have done something like that: > > impl/expat/factory/ep_event_parser_factory.e > impl/expat/... > impl/no_expat/factory/ep_event_parser_factory.e > > I'm not saying that one is better than the other, but it > seems more natural to me to choose whether I want to > compile with expat or not at the impl level. Then you > could have a loadpath.se, ise.ace, etc. in the directories: > > impl/expat > impl/no_expat > > and include one or the other in your application loadpath > or Ace file depending on whether you want to include > expat or not. Yes, that is on my list. I must give this some more thought though. Initially I wanted to put all factory classes into the factory cluster, but that's not a good choice, because Then factory would include both event and tree specific classes. That means that if you decide to include cluster factory you need to include both tree and event as well. So I probably go for s.th. like this: Event impls have: expat/event/ep_event_parser_factory.e no_expat/event/ep_event_parser_factory.e and Tree impls have: eiffel/tree/ef_tree_parser_factory.e no_eiffel/tree/ef_tree_parser_factory.e > > ad 8) > > In order to get actual data from expat I need to convert all kinds of C > > strings (fixed length, zero terminated, ...) into Eiffel Strings (or > > UCSTRINGs) C_STRING_HELPER is what I built to do that, but it is > > compiler dependent of course. I think this is a good candidate for GOBO > > itself (outside of the proper eXML clusters) - maybe with a few > > modifications. > > Yes, it is clear that many libraries currently have their > own string handling clusters, and one of the advantage of > merging everything into Gobo is that we will be able to > do some refactoring with all these classes, and possibly > share them between libraries. > > You were suggesting putting these classes into the 'utility' > library. Wouldn't all these string handling classes deserve > a library on their own? Something like $GOBO/library/string? > Then we could have: > > library/string/c_string > /formatter > /input > /output > /... > > The cluster c_string would be where to put your class since > it is dependent on C (even though they don't have external > routines) and applications compiled on .Net or JVM would not > include this cluster. > > In the version of C_STRING_HELPER_NP for ISE Eiffel you > wrote: > > make_pointer_from_string (s: STRING): POINTER is > -- returns the pointer to the data of a specific string > -- does this work with a moving gc?? > > make_pointer_from_string_buffer (data: SPECIAL [CHARACTER]): POINTER > is > -- returns the pointer to the data of a specific string > -- does this work with a moving gc?? > > the answer is no: it is not safe when using a moving GC and > you might get weird behaviors. The only safe way to pass > pointers to Eiffel objects to C code is to use directly the > $ construct in the arguments of the external routines. So > I would suggest that you put all your external routines in > a class *_EXTERNALS along with routines without POINTERs > as arguments or results, and that you put this class in > clusters spec/[ise|se|ve|hact] (you can possibly use 'gepp'). > For example if you have an external C routine such as: > > char *foo (char *str) {} > > I would suggest that you have the following routines in your > *_EXTERNALS class: > > feature -- Something here > > foo (str: STRING): STRING is > -- ... > require > str_not_void: str /= Void > local > c_str: ANY > do > !! Result.make (0) > c_str := str.to_c > Result.from_c (c_foo ($c_str)) > ensure > foo_not_void: Result /= Void > end > > feature {NONE} -- Externals > > c_foo (str: POINTER): POINTER is > -- ... > require > str_not_null: str /= default_pointer > external > "C" > alias > "...." > ensure > c_foo_not_null: Result /= default_pointer > end > > and provide different implementations for the different Eiffel > compilers. This is in my opinion the only safe way with respect > to moving GC to implement calls to C functions with pointers > to Eiffel objects. > > It may look cumbersome at first, but it is actually cleaner > because the public interface of this class does not involve > POINTER, only pure Eiffel types. So if one day expat is > ported to .Net or JVM you will have less work to do since > the only class aware of the C language will be this class. > > Furthermore having this class *_EXTERNAL duplicated over > the spec/[ise|se|ve|hact] clusters (once again yo can > use 'gepp' to make its implementation and maintenance > easier) has the other advantage of allowing you to use > the different external C syntax enhancements provided > by the different Eiffel compilers. We all know that they > are not portable and we are stuck with the: > > external "C" > > syntax in order to have something portable, but since > we already have the spec/[ise|se|ve|hact] clusters > we can now take advantage of non-portable syntax. > > BTW, the routines above are functions, not procedures. > So I suggest to name them `new_...' instead of `make_...'. Thanks I look into that. thanks for reviewing the code, Andreas |