hyperrealm / libconfig

C/C++ library for processing configuration files
https://hyperrealm.github.io/libconfig/
GNU Lesser General Public License v2.1
1.11k stars 362 forks source link

Bug: '@include' path isn't relative to the lib-loaded config file. #103

Open lowlevl opened 6 years ago

lowlevl commented 6 years ago

Hi @hyperrealm, I'm using your lib in my project, and I noticed a bug, @include isn't relative to the current file, but to the execution directory.

Here is my working environnement:

parentdir/
|- project/
|   |- sysconf/
|       |- main.cf
|       |- otherconf.cf 
|- project-build/
    |- project-executable

My main.cc is loading the main.cf like following because I execute the binary from the build directory:

  libconfig::Config config;
  try {
    config.readFile("../project/sysconf/main.cf");
  } catch (libconfig::ParseException e) {
    std::cout << std::string(e.getError()) << " on line: " << std::to_string(e.getLine())) << std::endl;
  }

From here there is no bug, now look to my main.cf:

@include "otherconf.cf"

Which produce: cannot open include file on line: 1.

But when I use this main.cf:

@include "../project/sysconf/otherconf.cf"

It works perfectly well.

Edit: I think I need to set and include directory ? Wouldn't it be better to treat @include path as relative ?

lowlevl commented 6 years ago

Sorry, I didn't really read the documentation, but relative path to the current file seemed so intuitive that, I'll transform this issue in an improvement request.

Edit: Of course I can help !

hyperrealm commented 5 years ago

It may be tricky to get the location of the file; may require platform-specific code for Unix, Windows, etc.. If you can write a patch to implement this, I'll be happy to look it over.

lowlevl commented 5 years ago

I don't think that would be too tricky :) Since the readFile() function passes a string with the loaded file path, we could just use on insert:

/* Pseudo-Code */
if(directive == "include")
{
    doInclude(dirname(filePath) + includePath);
}

Don't you think ? @hyperrealm

lowlevl commented 5 years ago

So somehow it would do:

/* Pseudo-Code */
doInclude("../project/sysconf/" + "otherconf.cf");

to recreate the @include "../project/sysconf/otherconf.cf".