0

Sometimes there is need to have tables (big or small) in source code.

ItemType const SomeTable[] = {
    //   id  name  min  max
    ITEM( 3, "Foo", 70, 180),
    ITEM(13, "Bar", 30,  50),
    ITEM(14, "Baz", 30,  60),
    ITEM(60, "Abc",  1,   4),
};

Over time new lines are added and existing ones changed:

ItemType const SomeTable[] = {
    //   id  name  min  max
    ITEM( 3, "Foo", 70, 180),
    ITEM(13, "BetterBar", 30,  50),
    ITEM(14, "Baz", BAZ_MIN, BAZ_MAX),
    ITEM(60, "Abc",  1,   4),
    ITEM(80, "AAAAAA", 0, A_COUNT),
    ITEM(81, "BBB  BBBB B", 0, B_COUNT),
};

That looks horrible. We can fix the alignment:

ItemType const SomeTable[] = {
    //   id  name               min      max
    ITEM( 3, "Foo"        ,      70,     180),
    ITEM(13, "BetterBar"  ,      30,      50),
    ITEM(14, "Baz"        , BAZ_MIN, BAZ_MAX),
    ITEM(60, "Abc"        ,       1,       4),
    ITEM(80, "AAAAAA"     ,       0, A_COUNT),
    ITEM(81, "BBB  BBBB B",       0, B_COUNT),
};

Looks better, but the actual change is lost. If you look at the version control diff, it's nearly impossible to see what was added as whole table has been rewritten. This is especially bad if tables are several hundred lines big, as they tend to be.

Estimating table sizes in advance is possible, but in practice they tend to be off: either too small, in which case they were useless, or too big in which case lot of readability is lost.

Surely someone has figured out a good strategy for handling these cases. It doesn't have to be perfect system, as long as it is reasonably readable.


Following things are out of the scope of the question:

  • Using external data files: Target platform may not have file system.

  • Using external script/conversion tool to convert data file into code: Introduces extra dependency, which may not be possible or preferred.


I'd like to keep this question language agnostic, but typical situation where I have this problem is in embedded C projects. For example, special purpose library for several different platforms. So I basically have only have the preprocesser at my disposal, and X-macros only go so far.

  • If you format the data as tabular data (preferably in a separate file / source file) then you would never run into this issue. Because then you formatted upfront and you won't have to change it. Issue you still have is that most diffs work per line (try adding/removing a comma at the end of a line). So then you know where the change is but you don't instantly see the real change only. What you then could do is format each row on many lines (json/yaml etc). At that point you should also consider: wrong tool for the job. You try to store data tables in a source file, there might be a better tool – Luc Franken Apr 16 '15 at 7:50
  • @LucFranken It is tabular data. Problem with is that some language (like C) compilers don't understand json/yaml formats, so introducing any of them requires some kind of additional tool, which is not always possible as mentioned in question. – user694733 Apr 16 '15 at 7:56
  • The first document doesn't look tabular but spaces indented. Maybe it's not shown well here. You could use the third one from the start, that's what I suggest, then you have a stable format which is extendable a bit. But still: That's your issue because of using the wrong tool. In some languages you might be able to store some json in a string and then parse it. In some scripting languages we have HERE docs en.wikipedia.org/wiki/Here_document which might be useful. But in the in clearly it might not be the best solution. Maybe check config files which could be more flexible. – Luc Franken Apr 16 '15 at 8:11
  • "That looks horrible." - I think it looks fine, and dislike the "fixed" alignment! See e.g. stackoverflow.com/q/29635875/3001761 – jonrsharpe Apr 16 '15 at 9:42
  • 2
    How about telling your version control diff to ignore whitespace? – Mike Nakis Apr 16 '15 at 11:04
2

One possible kludge which would allow you to keep you change history but align your code correctly would be to comment out the entire existing table. And add a new correctly aligned table after it.

This would/should be recorded as just two changes in the source code.

After the new table been saved in the repository you can delete the commented out section on the next change (again logged as a single change!).

This may or may not work depending on how clever your version control software is.

On a more general note I (nearly always when I am being good and someone may be watching) code tables like this as a separate class/function. This helps keep the main body of the code readable and allows for easy switching to an external file/xml/database/web service at a later date.

  • I am not entirely sure but what you gain by commenting out the old one. If you add 1 row to 300 row table, creating new aligned table stills shows up as 301 added lines in version control diff. I agree with the separation though: I keep tables in different source files from other code. – user694733 Apr 16 '15 at 7:35
2

If you look at the version control diff, it's nearly impossible to see what was added as whole table has been rewritten

Then don't look at the version control diff.

For instance WinMerge, which is free & runs on both Windows & Linux has an option " Line differences with Whitespace: Ignoring all".

Couldn't you use that? It won't show those alignment adjustments as changed lines.

And if your version control diff doesn't offer something similar, then why not email and ask them to add it? Or code it yourself, if your version control is FOSS.

  • While this might help when damage is already done, I am trying to find conventions and techniques to minimize putting these kind of change sets in repository. – user694733 Apr 16 '15 at 8:03
  • I am wracking my brains, but as you have said that don't want to guess suitable column positions in case they are too large or too small, it is difficult to come up with an idea... – Mawg Apr 16 '15 at 11:40
  • What is the actual problem with having the whitespace changes in your changeset alongside the functional changes, if you don't see them anyway? You don't have more patches/changesets, and they aren't less clear AFAICS. – Useless Apr 16 '15 at 11:58
0

What if you auto-generate the file which contains the table declaration?

Since it is auto-generated, you never need to diff that legible file itself. Diffing the input file will show only truly changed lines, since you will never reformat the input file to make it more legible.

Q.E.D :-)

  • File generation requires some external tool to do the work. That creates extra dependency for the project. See out-of-scope section in my question. – user694733 Apr 16 '15 at 11:50
  • Sorry, I think that I missed an update to the question – Mawg Apr 16 '15 at 11:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.