views:

209

answers:

3

My program is reading a text file containing various lines of text for a settings file. Some of the lines could get very large. Currently the buffer size is 4096 chars. It is possible that some lines could exceed this, whether through maliciousness or due to various factors operating within the program.

The current routines were rather tedious to write and now I want to expand the possible contents of the file which will require more of this tedious repetitive code. (This is for a settings type file, consisting of name value pairs and the occasional section header. Some numerical values need to be read as strings due to multiple precision).

The main thing I want is to read an arbitrary length line without buffer overflow. I've just discovered getline can do this for me, but, is there for heavens sake a library that will just do the whole lot of this tediousness for me?

edit:

I don't wish to be forced to place an = sign between the name and values, a blank space should suffice as separator.

By widespread, I mean the library should be available in the standard packages of the popular Linux distributions.

I'm aware of libconfig but it seems complete overkill for my requirements.

+4  A: 

Look into libini, sounds about right. It is quite old and not exactly undergoing frantic development, but if it already works for your problem, that should be fine.

A more up to date library, with a bunch of other benefits, is glib, it has a key-value-parser API.

unwind
I've decided against the glib option as, again, it's overkill for my requirements. The answer chosen as correct, although does not directly solve the library question, has made it easier for me to continue and does not break any existing file specification in use in the existing data files.
James Morris
@James: That's fine, I guess ... Although I would be inclined to think that for any non-trivial C program, glib is a healthy dependency to have since it adds lots of things that are often needed in such programs anyway.
unwind
A: 

My suggestion is, DIY, since it's quite easy.

Read each line, count chars until your separator and after your separator, allocate buffers, and read name value pairs with sscanf like:

sscanf(line, "%[^:]: %[^\n]", key, value)

You will be safe since you counted chars before sccanf.

piotr
in this case I also suggest writing it, it seems trivial enough. The only issue is how you will store your table, if this is pure C then no std::map for you, but I guess you have your own data-structures already?
John
Thanks for the sscanf %[..] tip, but after testing, you're missing a caret: `"%[^:]:%[^\n]"`, cheers, I'm going to go this route.
James Morris
Corrected. Sorry for the missing caret.
piotr
A: 

I maintain a updated fork of libini at CCAN. It also contains a very useful dictionary implementation as well as some simple hashing algorithms. Rusty put it in the repo, so I guess I did a reasonably good job of bringing it up to date and fixing the few minor bugs.

The latest version of the library can be found if you poke through this tree, it contains basic token support as well as basic transaction support (useful for re-reading configuration files and reverting if there's a parsing error). It also contains a much more updated set of unit tests. I plan on updating CCAN sometime in the next 30 - 45 days.

Tim Post