Imported from the mailing list archives: 268, 329.

I've extended the board load API a bit: io_plugins can donate a function that can read the file, looking for some header or pattern and decide if the file looks like one they can handle.

In practice this means the core can probe files before really trying to parse them. This will reduce error messages on load: previously we just tried to load all files with all io_ plugins and as each file could be loaded only with one of them, the others tended to give error messages.

Implementation details

When the core needs to load a file of unknown/unspecified format, it does the following steps:

1. opens the file (throws an error if the file can't be open for read)

2. acquires a list of all io_ pluginst that can load boards, ordered by load-priority (^1)

3. ask each of them to take a look at the file and decide if it looks valid to them

4. if none said valid, we can't load the file, return error

5. iterate over all io_ plugins that said the file was valid and call them to parse the file; the order of iteration is that of point 2.; the process stops after first io_ plugin that manages to parse through the file without an error; all error messages are relayed to the message log

6. if none of the io_ plugins could actually parse the file, throw an error

When the core loads a file with a format explicitly specified by the user (using the LoadFrom() action):

1. same as above

2. get a list only of those io_plugins whose metadata says they can handle the format specified

3. same as above

4. same as above, plus if multiple plugins said the file was valid, inform the user because his format specification is probably not exact enough (but go on with the process anyway)

5. same as above

6. same as above

rationale

We need to open various file types with a dynamic number of plugins. Originally we just tried to open any file with all IO plugins but that resulted in a lot of error messages when lihata or kicad tried to parse .pcb or vice versa.

The fix is that each IO plugin gets a chance to look at the file before really parsing it and report if the file looks like one it could parse. This is called a "test parse": we just read through the file, no real parser involved, and look for familiar patterns. Then say "yay" or "nay" and the loader will call the real parser only on the "yay-sayers".

For a .pcb file the test parse looks for the # release info or PCB[ or PCB(, ignoring all comments. Anything familiar needs to happen in the first 16 non-comment-non-empty lines and then we say we could try it, else we say no (so we don't need to read through a 4 gigabyte movie the user accidentally tried to open).

Unfortunately footprint is yet another special case with the gEDA/PCB format. It obviously doesn't have a PCB[] becase it's not a board, but for some reason it doesn't have # release either. We also need accept if the file has a line starting with Element[ or Element( in the first 16 significant lines (leading whitepsace is stripped).