-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix the parsing of filenames coming from GNU/git diff
Co-authored-by: Marek Kubica <[email protected]>
- Loading branch information
1 parent
6a754d0
commit ae28123
Showing
8 changed files
with
187 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
val parse : string -> (string option, string) result | ||
(** [parse s] parses [s] and returns a filename or [None] if the filename | ||
is equivalent to [/dev/null]. | ||
Returns [Error msg] in case of error. *) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
{ | ||
module String = Patch_lib.String | ||
|
||
type lexer_output = | ||
| Quoted of string | ||
| Unquoted | ||
| Error of string | ||
|
||
exception Cant_parse_octal | ||
|
||
let ascii_zero = Char.code '0' | ||
let octal_to_char c1 c2 c3 = | ||
let char_to_digit c = Char.code c - ascii_zero in | ||
try | ||
Char.chr ( | ||
(char_to_digit c1 lsl 6) lor | ||
(char_to_digit c2 lsl 3) lor | ||
char_to_digit c3 | ||
) | ||
with Invalid_argument _ -> raise Cant_parse_octal | ||
} | ||
|
||
let octal = ['0'-'7'] | ||
|
||
rule lex_quoted_filename buf = parse | ||
| "\\a" { Buffer.add_char buf '\007'; lex_quoted_filename buf lexbuf } | ||
| "\\b" { Buffer.add_char buf '\b'; lex_quoted_filename buf lexbuf } | ||
| "\\f" { Buffer.add_char buf '\012'; lex_quoted_filename buf lexbuf } | ||
| "\\n" { Buffer.add_char buf '\n'; lex_quoted_filename buf lexbuf } | ||
| "\\r" { Buffer.add_char buf '\r'; lex_quoted_filename buf lexbuf } | ||
| "\\t" { Buffer.add_char buf '\t'; lex_quoted_filename buf lexbuf } | ||
| "\\v" { Buffer.add_char buf '\011'; lex_quoted_filename buf lexbuf } | ||
| "\\\\" { Buffer.add_char buf '\\'; lex_quoted_filename buf lexbuf } | ||
| "\\\"" { Buffer.add_char buf '"'; lex_quoted_filename buf lexbuf } | ||
| '\\' (['0'-'3'] as c1) (octal as c2) (octal as c3) | ||
{ | ||
match octal_to_char c1 c2 c3 with | ||
| octal -> | ||
Buffer.add_char buf octal; | ||
lex_quoted_filename buf lexbuf | ||
| exception Cant_parse_octal -> Unquoted | ||
} | ||
| '\\' _ { Unquoted } | ||
| '"' eof { Quoted (Buffer.contents buf) } | ||
| '"' _ { Unquoted } | ||
| _ as c { Buffer.add_char buf c; lex_quoted_filename buf lexbuf } | ||
| eof { Unquoted } | ||
|
||
and lex_filename buf = parse | ||
| '"' { lex_quoted_filename buf lexbuf } | ||
| _ { Unquoted } | ||
| eof { Error "empty filename" } | ||
|
||
{ | ||
let parse s = | ||
let filename, _date = | ||
match String.cut '\t' s with | ||
| None -> (s, "") | ||
| Some x -> x | ||
in | ||
if filename = "/dev/null" then | ||
Ok None | ||
else | ||
let lexbuf = Lexing.from_string filename in | ||
match lex_filename (Buffer.create 128) lexbuf with | ||
| Quoted x -> Ok (Some x) | ||
| Unquoted -> Ok (Some filename) | ||
| Error msg -> Error msg | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
module String = struct | ||
let is_prefix ~prefix str = | ||
let pl = String.length prefix in | ||
if String.length str < pl then | ||
false | ||
else | ||
String.sub str 0 (String.length prefix) = prefix | ||
|
||
let is_suffix ~suffix str = | ||
let pl = String.length suffix in | ||
if String.length str < pl then | ||
false | ||
else | ||
String.sub str (String.length str - pl) pl = suffix | ||
|
||
let cut sep str = | ||
try | ||
let idx = String.index str sep | ||
and l = String.length str | ||
in | ||
let sidx = succ idx in | ||
Some (String.sub str 0 idx, String.sub str sidx (l - sidx)) | ||
with | ||
Not_found -> None | ||
|
||
let cuts sep str = | ||
let rec doit acc s = | ||
match cut sep s with | ||
| None -> List.rev (s :: acc) | ||
| Some (a, b) -> doit (a :: acc) b | ||
in | ||
doit [] str | ||
|
||
let slice ?(start = 0) ?stop str = | ||
let stop = match stop with | ||
| None -> String.length str | ||
| Some x -> x | ||
in | ||
let len = stop - start in | ||
String.sub str start len | ||
|
||
let trim = String.trim | ||
|
||
let get = String.get | ||
|
||
let concat = String.concat | ||
|
||
let length = String.length | ||
|
||
let equal = String.equal | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module String : sig | ||
val is_prefix : prefix:string -> string -> bool | ||
val is_suffix : suffix:string -> string -> bool | ||
val cut : char -> string -> (string * string) option | ||
val cuts : char -> string -> string list | ||
val slice : ?start:int -> ?stop:int -> string -> string | ||
val trim : string -> string | ||
val get : string -> int -> char | ||
val concat : string -> string list -> string | ||
val length : string -> int | ||
val equal : string -> string -> bool | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters