48 Commits

Author SHA1 Message Date
Billy Keyes 08f3e635d6 Run 'go fix' to modernize code (#69)
This only updates to Go 1.21 baseline, which is what the module still
specifies as the minimum version. I'll need to run this again when
moving to Go 1.25 or 1.26 as minimum.
2026-05-25 09:11:07 -07:00
Billy Keyes 0a4e55f9a1 Return preamble when a patch has no files (#46)
While empty patches with only a header were parsable, the parser
discarded the preamble content. This meant callers had to handle this
case specially. Now, if we reach the end of the input without finding a
file, Parse() returns the full content of the patch as the preamble.
2024-07-14 20:44:16 -07:00
Billy Keyes 13e8639a0b Clarify that Parse expects a single patch 2024-02-25 12:39:09 -08:00
Billy Keyes 3d1274d16e Remove unused LineReader interface
This is no longer used for text application, so revert the parser back
to using StringReader.
2020-01-25 16:57:23 -08:00
Billy Keyes a1f934e852 Add LineReader and StringReader interfaces
LineReader is a wrapper around StringReader that counts line numbers.
This is not currently used by the parser, but will be used by the apply
functions.
2020-01-04 12:02:37 -08:00
Billy Keyes f65047b165 Avoid buffering when reader supports ReadString 2019-04-27 16:15:50 -07:00
Billy Keyes 1c950ee854 Split source files by patch type (text/binary)
The tests were already split up in this way, so it makes sense to have
the parsing functions split as well.
2019-04-17 21:36:46 -07:00
Billy Keyes ef3359a969 Add a package-level documentation comment 2019-04-14 19:44:06 -07:00
Billy Keyes 8ce8cba533 Fix binary chunk decoding and inflating
Git uses a unique Base85 encoding with different characters than the
ascii85 encoding implemented by Go, so add a custom decoding function.
Once decoded, use zlib instead of the raw DEFLATE algorithm to
decompress the data.

These issues were caught by some basic parsing tests which are added
here as well.
2019-04-13 22:32:25 -07:00
Billy Keyes 22fb5076be Add test for binary fragment header parsing 2019-04-13 15:54:52 -07:00
Billy Keyes ddafbc8ba3 Split up binary parsing to match text parsing
Parse the fragment header separately from the fragment chunk, which
makes each function a bit more understandable.
2019-04-10 23:03:19 -07:00
Billy Keyes 5a521ed05f Implement binary fragment parsing
Parse forward and optionally reverse fragments, decoding and inflating
the ascii85 encoded data in a binary patch. This is completely untested
at the moment and probably has obvious and stupid bugs.
2019-04-09 22:54:41 -07:00
Billy Keyes 013e581989 Fix error return in ParseBinaryMarker 2019-04-08 23:09:19 -07:00
Billy Keyes b101b0d812 Add binary patch types and binary marker parsing
The binary marker is the text that appears where a text fragment
normally would and indicates that the file is binary. It's not quite a
header, because content is optional in a binary patch. If the patch does
include binary fragments, they have their own format, with a header.
2019-04-07 21:24:17 -07:00
Billy Keyes a0b33e37b4 Rename types in preparation for binary parsing
Fragment is now TextFragment to distinguish from a future
BinaryFragment. Also rename FragmentLine to Line, since the
text-orientation is implied by the name.
2019-04-07 20:33:21 -07:00
Billy Keyes 69e4444419 Return preamble content when parsing files
This allows callers to provide patches with commit or email headers and
then retrieve that leading content for additional parsing without
having to identify where the first file in the patch starts.
2019-04-07 19:57:11 -07:00
Billy Keyes 09c686917c Add test for multiple files in one patch
For simplicity, use the same fragments in both of these files and in the
single file test.
2019-04-06 19:13:42 -07:00
Billy Keyes 7b9443bc1c Add tests for ParseTextFragments
Covers that multiple fragments actually works and the unique error
contidions, but otherwise relies on the lower level tests for
correctness. Also update some comments and the README based on
observations from writing/debugging these tests.
2019-04-01 22:55:09 -07:00
Billy Keyes 8753644cc0 Add tests for single fragment parsing
To make output better, also add some (temporary?) String() functions and
fix an assumption about the smallest fragment header I discovered was
wrong while looking at sample patches.
2019-03-31 21:32:39 -07:00
Billy Keyes 4e8b7b5088 Fix no newline handling in fragment parser
Correctly process "\ No newline..." marker lines when parsing fragments,
triming the new line from the last read line and advancing the parser.

Also fix the text chunk parser to follow the invariant of not advancing
past the end of the object in the event of an error. The error in
question now has a correct line number as well.
2019-03-31 21:14:27 -07:00
Billy Keyes 2ca83404e5 Fix EOF and line number handling in parser
The parser now returns an EOF on the first call to Next() if the input
is empty and increments the line number before returning EOF for the
first time.
2019-03-30 22:43:24 -07:00
Billy Keyes 69ca8017bc Restructure fragment parsing to support binary
Binary patch support is still unimplemented, but the functions are
stubbed and the overall structure seems to make sense. This also renames
the existing fragment functions to have "Text" in their names (for
clarity) and moves the parsing of fragment lines to a new "chunk"
function, which will match how binary parsing works.
2019-03-30 21:10:02 -07:00
Billy Keyes 2c9be20fca Improve fragment validation, track context lines
Track leading and trailing context lines because it's easy and Git
includes this information in the fragment type. Add validation for when
the fragment does not agree with the header or with the new/deleted
state of the file.
2019-03-29 22:31:27 -07:00
Billy Keyes 7483884180 Add basic fragment parsing function
This should work, but does no validation on the fragment after parsing.
2019-03-28 23:10:41 -07:00
Billy Keyes 9b0fc30459 Document and enforce parser invariants
After considering fragment parsing, it made sense to change the
invariant estabilished in the previous commit. Specifically, parser
functions now assume they are call on the first line of their object and
return with the parser on the first line after their object. This means
code can call parse function immediately after each other without
advancing the parser in between.

It's possible this will change back later on... there seem to be
annoying edge cases with either choice, but I think making the functions
consistent is important.
2019-03-27 23:10:47 -07:00
Billy Keyes 4b25230457 Check for expected input in parsing functions
Instead of checking that a line has a certain prefix before calling a
header parsing function, the functions now check this and return nil
objects when called on the wrong line type. If the line passes this
basic check but is still invalid, and error is returned as before.
2019-03-25 22:27:31 -07:00
Billy Keyes dc8fb6fdb5 Support adjustable read-ahead in parser
At the moment, we need only to read three lines, but now the value is
easy to adjust as needed. I've only seen the Git implementation read two
lines ahead so far, but it has the whole input in memory and may read
more in other places.
2019-03-25 21:30:08 -07:00
Billy Keyes ccf0c58db8 Change parser interface to be more iterator-like
Call Next() to advance the parser state until it returns a non-nil
error, then check if the error is io.EOF. This makes EOF handling easier
and also means that Line() and PeekLine() can be called multiple times
without changing state.

The next step is to update parse functions to return an internal marker
error if they are called on an invalid line. This should improve
correctness and remove the duplication of testing a condition and then
calling a parse function, which checks the same condition.
2019-03-24 22:03:53 -07:00
Billy Keyes 699084298b Accept comments when parsing fragment headers
Also parse the header directly instead of using a regexp. This allows
finer-grained errors.
2019-03-24 20:49:27 -07:00
Billy Keyes 47a74884a3 Add parameter to fix line numbers in errors
In certain cases, the error is generated from the peeked next line or a
line that was read in the past. The delta flag corrects for this,
producing accurate error messages.
2019-03-23 23:11:38 -07:00
Billy Keyes 6b7e4cd811 Move all header functions to file_header.go
Even though these are defined on *parser, it makes more sense to have
them in this file.
2019-03-21 22:51:19 -07:00
Billy Keyes cf2f946a66 Implement traditional file header parsing
While I think this works, this is mostly for completeness. I (and I
expect most other users, if any) intend to use this with git patches.
2019-03-21 22:47:52 -07:00
Billy Keyes 412e7a39b1 Add more tests for git file header parsing
Also fix a bug with EOF handling in the parsing function and make sure
the test does not ignore unexpected errors.
2019-03-20 22:20:21 -07:00
Billy Keyes b8b0c25c1e Move file header functions to a new file 2019-03-19 22:00:11 -07:00
Billy Keyes cbd3915448 Add final tests for git header parsing functions
This gets 100% test coverage for the functions involved in parsing
Git-style file headers. Whether that actually makes it correct remains
to be seen.
2019-03-19 21:50:50 -07:00
Billy Keyes a1f92fec30 Fix and test old/new file name verification 2019-03-18 23:05:15 -07:00
Billy Keyes 6daf604b25 Add tests for git header data parsing
Fix parseGitHeaderIndex to allow abbreviated OIDs and add a note about
this to the README. The behavior might change again later, based on some
experimentation with Git.
2019-03-17 21:38:14 -07:00
Billy Keyes 3f641b393f Add tests and fix bugs with name parsing
Also convert all table tests to use maps instead of structs with name
fields and standardize other field names.
2019-03-17 20:21:58 -07:00
Billy Keyes ea5b8bceea Finish parsing filenames from Git headers
Adds "default" name handling, error checks for missing names, and prefix
and double-slash stripping.
2019-03-17 15:34:03 -07:00
Billy Keyes 303b32d463 Add "header" to header parsing function names 2019-03-17 14:04:43 -07:00
Billy Keyes c928ba2827 Implement index header line parsing 2019-03-16 22:42:14 -07:00
Billy Keyes 3cca171e73 Refactor git header parser to use function array
This is slightly more code, but I think is a bit cleaner, especially for
functions that set or could set multiple values, like the currently
unimplemented index parsing. It also removes the string manipulation as
a side-effect of case match thing, which was weird.
2019-03-16 18:29:21 -07:00
Billy Keyes 4f50b85d06 Implement file name parsing for git headers
Also change how error handling works for similarity score parsing.
2019-03-16 17:46:05 -07:00
Billy Keyes 2a2f704b96 Add incomplete git header parsing functions
I believe the structure is correct, but there are a lot of details to
fill in - translating the C string parsing logic into Go is not always
straightforward.
2019-03-14 23:09:41 -07:00
Billy Keyes bca8d0806e Detach parseFragmentHeader from parser struct
This operates on a single line and doesn't need any parser state.
2019-03-14 21:55:06 -07:00
Billy Keyes 4ddf1d962d Implement fragment header parsing
Use a regexp for simplicity, unlike the direct parsing in Git.
2019-03-13 23:04:01 -07:00
Billy Keyes d8a0cc90d1 Implement ParseNextFileHeader
This follows the structure and logic of find_header() in git/apply.c.
Calls to helper functions are currently stubbed.
2019-03-12 22:41:20 -07:00
Billy Keyes 42914c81df Create parser skeleton and utilities 2019-03-10 21:48:59 -07:00