0

My goal is to search the file line by line until it finds a variable declaration in the format of varName = varValue. Count up the bytes to the beginning of that line, then replace that line with the same varName but a new value.

This is a very simple configuration file handler, I'm writing it from scratch to avoid any dependencies. The reason I'm doing it this way and not just dumping a string[string] associative array is because I want to preserve comments. I also wish to refrain from reading the entire file into memory, as it has the potential to get large.

This is the code I have written, but nothing happens and the file remains unchanged when using setVariable.

import std.stdio: File;
import std.string: indexOf, strip, stripRight, split, startsWith;
import std.range: enumerate;

ptrdiff_t getVarPosition(File configFile, const string varName) {
    size_t countedBytes = 0;

    foreach (line, text; configFile.byLine().enumerate(1)) {
        if (text.strip().startsWith(varName))
            return countedBytes;

        countedBytes += text.length;
    }

    return -1;
}

void setVariable(File configFile, const string varName, const string varValue) {
    ptrdiff_t varPosition = getVarPosition(configFile, varName);

    if (varPosition == -1)
        return; // For now, just return. This variable doesn't exist.
        // Will handle this later, it needs to append to the bottom of the file.

    configFile.seek(varPosition);
    configFile.write(varName ~ " = " ~ varValue);
}
Jacob Birkett
  • 1,927
  • 3
  • 24
  • 49
  • Try minimizing the your code to hone down to the problem. I am not sure what your actual problem is. Is `readConfig` really reliant to the problem? Where is `File configFile` opened? Show a sample config file and add `main` function that will shows how it is not working. (btw, you are creating a dependency it is just a first party dependency :) So, is the advantage of no third party library size or licensing? :) ) – Lupus Ossorum Jul 23 '18 at 22:46

1 Answers1

0

There's a few parts of your code missing, which makes diagnosis hard. The most important question may be 'How do you open your config file?'. This code does what I expect it to:

unittest {
    auto f = File("foo.txt", "r+");
    setVariable(f, "var3", "foo");
    f.flush();
}

That is, it finds the line starting with "var3", and replaces part of the file with the new value. However, your getVarPosition function doesn't count newlines, so the offset is wrong. Also, consider what happens when the new varValue is a different length from the old value. If you have "var = hello world", and call setVariable(f, "var", "bye"), you'll end up with "var = byelo world". If it's longer than the existing value, it will overwrite the next variable(s).

BioTronic
  • 2,279
  • 13
  • 15