www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How do I do this?

reply Shachar Shemesh <shachar weka.io> writes:
The problem: I'm writing a library. This library has logging facilities, 
but where it's going to be used there are better logging facilities. 
Under C, that wouldn't be a big issue:

log.h:
#ifdef REAL_LOG_LIBRARY
#include REAL_LOG_LIBRARY
#else

// Declarations go here

#endif


I can now inject from my build system -DREAL_LOG_LIBRARY=real/impl/log.h 
into the compilation command line, and I'm done.

Under D, there is no facility to transfer a string from the command line 
to the code, so I can't use that approach.

I seem to remember that D had an option of importing an external file as 
something (string? code? anything would do for my purposes). I cannot 
seem to find it, however. A search for "string import" and "import 
mixin" brought back nothing useful.

Help?
Shachar
Aug 03
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
Shachar Shemesh wrote:

 Under D, there is no facility to transfer a string from the command line 
 to the code, so I can't use that approach.
module a; void mylog (string) { ... } module b; void mylog (string) { ... } module c; version(loga) import a; else import b; .. mylog("boo!"); .. rdmd -version=loga c.d p.s.: `mixin(import("myfile.d"));` -- C-like #include
Aug 03
prev sibling next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 3 August 2017 at 10:46:06 UTC, Shachar Shemesh wrote:
 I seem to remember that D had an option of importing an 
 external file as something (string? code? anything would do for 
 my purposes). I cannot seem to find it, however. A search for 
 "string import" and "import mixin" brought back nothing useful.
import("path/to/file") takes a file's contents as a string and you can mixin it. Needs -Jbase/path passed to dmd. But he way I'd do this is to actually write two files for the same module: old_log.d module logging; // declarations new_log.d module logging; // declarations Then when you compile, do `dmd mainmodule.d old_log.d` to use the old one and `dmd mainmodule.d new_log.d` to use the new one. In mainmodule, you `import logging;` and the file passed on the command line is the one it will refer to. Though, if you have a complex build this might be trickier.
Aug 03
prev sibling next sibling parent reply Shachar Shemesh <shachar weka.io> writes:
No sooner did I send out this question I have found the D feature I've 
been looking for. This is what I have:

module log;

version(alternate_logger) {
mixin("public import " ~ import("alternate_logger.txt") ~ ";");
} else {

// Default implementation goes here

}

Can't say I'm thrilled with this, but it does get the job done. 
Suggestions more than welcome.

Shachar

On 03/08/17 13:46, Shachar Shemesh wrote:
 The problem: I'm writing a library. This library has logging facilities, 
 but where it's going to be used there are better logging facilities. 
 Under C, that wouldn't be a big issue:
 
 log.h:
 #ifdef REAL_LOG_LIBRARY
 #include REAL_LOG_LIBRARY
 #else
 
 // Declarations go here
 
 #endif
 
 
 I can now inject from my build system -DREAL_LOG_LIBRARY=real/impl/log.h 
 into the compilation command line, and I'm done.
 
 Under D, there is no facility to transfer a string from the command line 
 to the code, so I can't use that approach.
 
 I seem to remember that D had an option of importing an external file as 
 something (string? code? anything would do for my purposes). I cannot 
 seem to find it, however. A search for "string import" and "import 
 mixin" brought back nothing useful.
 
 Help?
 Shachar
Aug 03
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 08/03/2017 07:00 AM, Shachar Shemesh wrote:
 No sooner did I send out this question I have found the D feature I've 
 been looking for. This is what I have:
 
 module log;
 
 version(alternate_logger) {
 mixin("public import " ~ import("alternate_logger.txt") ~ ";");
 } else {
 
 // Default implementation goes here
 
 }
 
 Can't say I'm thrilled with this, but it does get the job done. 
 Suggestions more than welcome.
There's a bit of irony you can read a file during compilation but not pass a string. The version can be dropped as well, but always requires the existence of the intermediate file: private alternateLogger = import("alternate_logger.txt"); static if (alternateLogger.length) { mixin("public import " ~ alternateLogger ~ ";"); } else { ... } Andrei
Aug 03
parent Johan Engelen <j j.nl> writes:
On Thursday, 3 August 2017 at 12:33:54 UTC, Andrei Alexandrescu 
wrote:
 There's a bit of irony you can read a file during compilation 
 but not pass a string.
I always wondered about this. It makes things more cumbersome than needed. Is it a conscious decision to not allow passing a string directly? -Johan
Aug 03
prev sibling next sibling parent wxcvb <wxcvb wxcvb.vb> writes:
On Thursday, 3 August 2017 at 10:46:06 UTC, Shachar Shemesh wrote:
 The problem: I'm writing a library. This library has logging 
 facilities, but where it's going to be used there are better 
 logging facilities. Under C, that wouldn't be a big issue:

 log.h:
 #ifdef REAL_LOG_LIBRARY
 #include REAL_LOG_LIBRARY
 #else

 // Declarations go here

 #endif


 I can now inject from my build system 
 -DREAL_LOG_LIBRARY=real/impl/log.h into the compilation command 
 line, and I'm done.

 Under D, there is no facility to transfer a string from the 
 command line to the code, so I can't use that approach.

 I seem to remember that D had an option of importing an 
 external file as something (string? code? anything would do for 
 my purposes). I cannot seem to find it, however. A search for 
 "string import" and "import mixin" brought back nothing useful.

 Help?
 Shachar
You can rely on the file passed to the compiler like this too: ``` enum canImport(string mod) = is(typeof((){mixin("import " ~ mod ~ ";");})); static assert(canImport!"std.traits"); static assert(!canImport!"std.craps"); ``` Although, tbh, i'm not sure very it solves the issue
Aug 03
prev sibling parent Kagamin <spam here.lot> writes:
dmd has a feature that a file passed directly to the compiler 
overrides file system for module search.
reallogger/impl/pluglogger.di
---
module mylogger.logger;
public import reallogger.impl.logger;
---

main.d
---
import mylogger.logger;
...stuff
---

dmd main.d - imports mylogger/logger.d
dmd main.d reallogger/impl/pluglogger.di - uses reallogger
Aug 04