Reading all lines of a file can not deal with "[" character

Hello, can anybody please help me figure out what is going wrong with how i try to read all lines of a file. I have the following input file which i want to have line by line:

ExampleText[];
SecondExampleText;
[
AnotherExample;
EndOfFile;

Now im trying to read all lines and process each line separately:

file(STRINGS "${Path_to_the_input_file}" input_lines)
foreach(line IN LISTS input_lines)
	message(STATUS "${line}")
        ... more processing
endforeach()

However, the lines have not been properly read as it looks like the inclusion of a single “[” character (not the combination of “[” followed by “]”) corrupts all following lines. This is the output i see from my message in the loop over all input lines:

-- ExampleText[];
-- SecondExampleText;
-- [;AnotherExample;;EndOfFile;

I have already tried going with file(READ… and parsing the content with a regex instead but I seem to be unable to do it (particularly because doing it that way got me in trouble with all of my “;” characters in the input file).
Could anybody please explain to me how I can simply read all lines of an input file with a line being traditionally defined as ending with a newline character and NOT breaking at “[” or “;” or any other character?

CMake treats [ as an escape for ; in lists (I believe it’s to do with Windows registry formats). This is documented here, but rather easy to miss.

IOW, your file is read fine, it’s the foreach loop that gets confused. You can solve this by replacing the [ and ] characters with something else for CMake processing, and then replacing them back once necessary.

Here’s an example how you could do it, where I will simulate the processing by duplicating the contents of each line:

file(STRINGS "${Path_to_the_input_file}" input_lines)
string(REPLACE "^" "^!" input_lines "${input_lines}")
string(REPLACE "[" "^a" input_lines "${input_lines}")
string(REPLACE "]" "^b" input_lines "${input_lines}")
set(result "")
foreach(line IN LISTS input_lines)
  set(result "${result}${line}${line}\n")
endforeach()
string(REPLACE "^b" "]" result "${result}")
string(REPLACE "^a" "[" result "${result}")
string(REPLACE "^!" "^" result "${result}")
file(WRITE some/place.txt "${result}")

It’s not pretty, but it gets the job done.

2 Likes

Thank you very much! You are completely right, it is far from pretty but also gets the job done. Now the only problem remaining is to find a special character replacement sequence that is definitely not contained within my input file…

Note that my solution works with arbitrary contents of the source file, no need to look for an unused character (as long as you keep the order of substitutions).

1 Like

You are right, I didn’t realise it before but that is a clever way of substituting “^” before then using it again for all following substitutions. Thanks for the insight!

1 Like