rugged 0.26.7 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/rugged/rugged_blame.c +6 -3
  4. data/ext/rugged/rugged_branch_collection.c +3 -6
  5. data/ext/rugged/rugged_commit.c +56 -0
  6. data/ext/rugged/rugged_config.c +44 -9
  7. data/ext/rugged/rugged_diff.c +3 -14
  8. data/ext/rugged/rugged_diff_hunk.c +1 -3
  9. data/ext/rugged/rugged_index.c +1 -5
  10. data/ext/rugged/rugged_note.c +1 -4
  11. data/ext/rugged/rugged_patch.c +1 -4
  12. data/ext/rugged/rugged_reference_collection.c +1 -7
  13. data/ext/rugged/rugged_remote.c +5 -8
  14. data/ext/rugged/rugged_remote_collection.c +1 -6
  15. data/ext/rugged/rugged_repo.c +16 -48
  16. data/ext/rugged/rugged_revwalk.c +7 -16
  17. data/ext/rugged/rugged_settings.c +28 -0
  18. data/ext/rugged/rugged_submodule_collection.c +3 -4
  19. data/ext/rugged/rugged_tag_collection.c +1 -5
  20. data/ext/rugged/rugged_tree.c +2 -3
  21. data/lib/rugged/repository.rb +43 -0
  22. data/lib/rugged/version.rb +1 -1
  23. data/vendor/libgit2/AUTHORS +1 -0
  24. data/vendor/libgit2/CMakeLists.txt +61 -510
  25. data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +14 -0
  26. data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +25 -8
  27. data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +27 -8
  28. data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +20 -0
  29. data/vendor/libgit2/cmake/Modules/IdeSplitSources.cmake +22 -0
  30. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +3 -0
  31. data/vendor/libgit2/deps/regex/CMakeLists.txt +2 -0
  32. data/vendor/libgit2/deps/winhttp/CMakeLists.txt +26 -0
  33. data/vendor/libgit2/deps/zlib/CMakeLists.txt +4 -0
  34. data/vendor/libgit2/include/git2/config.h +29 -2
  35. data/vendor/libgit2/include/git2/describe.h +1 -1
  36. data/vendor/libgit2/include/git2/diff.h +59 -8
  37. data/vendor/libgit2/include/git2/graph.h +3 -0
  38. data/vendor/libgit2/include/git2/merge.h +6 -0
  39. data/vendor/libgit2/include/git2/message.h +43 -3
  40. data/vendor/libgit2/include/git2/notes.h +89 -0
  41. data/vendor/libgit2/include/git2/odb.h +8 -1
  42. data/vendor/libgit2/include/git2/patch.h +2 -2
  43. data/vendor/libgit2/include/git2/pathspec.h +35 -18
  44. data/vendor/libgit2/include/git2/refs.h +3 -0
  45. data/vendor/libgit2/include/git2/remote.h +34 -4
  46. data/vendor/libgit2/include/git2/repository.h +6 -6
  47. data/vendor/libgit2/include/git2/reset.h +4 -4
  48. data/vendor/libgit2/include/git2/status.h +4 -0
  49. data/vendor/libgit2/include/git2/sys/config.h +4 -1
  50. data/vendor/libgit2/include/git2/sys/odb_backend.h +2 -1
  51. data/vendor/libgit2/include/git2/tree.h +4 -3
  52. data/vendor/libgit2/include/git2/types.h +1 -0
  53. data/vendor/libgit2/include/git2/version.h +4 -4
  54. data/vendor/libgit2/include/git2/worktree.h +1 -1
  55. data/vendor/libgit2/src/CMakeLists.txt +463 -0
  56. data/vendor/libgit2/src/annotated_commit.c +1 -1
  57. data/vendor/libgit2/src/annotated_commit.h +2 -0
  58. data/vendor/libgit2/src/apply.c +2 -1
  59. data/vendor/libgit2/src/apply.h +2 -0
  60. data/vendor/libgit2/src/attr.c +24 -4
  61. data/vendor/libgit2/src/attr.h +2 -0
  62. data/vendor/libgit2/src/attr_file.c +9 -2
  63. data/vendor/libgit2/src/attr_file.h +2 -0
  64. data/vendor/libgit2/src/attrcache.c +9 -1
  65. data/vendor/libgit2/src/attrcache.h +2 -0
  66. data/vendor/libgit2/src/blame.c +1 -0
  67. data/vendor/libgit2/src/blame.h +2 -1
  68. data/vendor/libgit2/src/blame_git.c +1 -0
  69. data/vendor/libgit2/src/blame_git.h +2 -0
  70. data/vendor/libgit2/src/blob.c +2 -2
  71. data/vendor/libgit2/src/blob.h +2 -0
  72. data/vendor/libgit2/src/branch.c +8 -1
  73. data/vendor/libgit2/src/branch.h +2 -0
  74. data/vendor/libgit2/src/buf_text.c +7 -7
  75. data/vendor/libgit2/src/buf_text.h +3 -3
  76. data/vendor/libgit2/src/buffer.c +31 -1
  77. data/vendor/libgit2/src/buffer.h +3 -0
  78. data/vendor/libgit2/src/cache.c +2 -2
  79. data/vendor/libgit2/src/cache.h +2 -0
  80. data/vendor/libgit2/src/cc-compat.h +3 -3
  81. data/vendor/libgit2/src/checkout.c +30 -19
  82. data/vendor/libgit2/src/checkout.h +2 -0
  83. data/vendor/libgit2/src/cherrypick.c +1 -0
  84. data/vendor/libgit2/src/clone.c +2 -1
  85. data/vendor/libgit2/src/clone.h +4 -0
  86. data/vendor/libgit2/src/commit.c +2 -1
  87. data/vendor/libgit2/src/commit.h +2 -0
  88. data/vendor/libgit2/src/commit_list.c +1 -1
  89. data/vendor/libgit2/src/commit_list.h +2 -0
  90. data/vendor/libgit2/src/common.h +11 -5
  91. data/vendor/libgit2/src/config.c +12 -10
  92. data/vendor/libgit2/src/config.h +2 -0
  93. data/vendor/libgit2/src/config_cache.c +1 -0
  94. data/vendor/libgit2/src/config_file.c +287 -786
  95. data/vendor/libgit2/src/config_file.h +4 -3
  96. data/vendor/libgit2/src/config_parse.c +525 -0
  97. data/vendor/libgit2/src/config_parse.h +64 -0
  98. data/vendor/libgit2/src/crlf.c +2 -1
  99. data/vendor/libgit2/src/delta.c +28 -30
  100. data/vendor/libgit2/src/delta.h +1 -0
  101. data/vendor/libgit2/src/describe.c +3 -1
  102. data/vendor/libgit2/src/diff.c +148 -2
  103. data/vendor/libgit2/src/diff.h +3 -1
  104. data/vendor/libgit2/src/diff_driver.c +12 -9
  105. data/vendor/libgit2/src/diff_driver.h +4 -1
  106. data/vendor/libgit2/src/diff_file.c +7 -4
  107. data/vendor/libgit2/src/diff_file.h +1 -0
  108. data/vendor/libgit2/src/diff_generate.c +6 -3
  109. data/vendor/libgit2/src/diff_generate.h +6 -1
  110. data/vendor/libgit2/src/diff_parse.c +5 -4
  111. data/vendor/libgit2/src/diff_parse.h +2 -0
  112. data/vendor/libgit2/src/diff_print.c +2 -0
  113. data/vendor/libgit2/src/diff_stats.c +2 -0
  114. data/vendor/libgit2/src/diff_tform.c +2 -1
  115. data/vendor/libgit2/src/diff_tform.h +4 -1
  116. data/vendor/libgit2/src/diff_xdiff.c +5 -2
  117. data/vendor/libgit2/src/diff_xdiff.h +2 -0
  118. data/vendor/libgit2/src/errors.c +2 -0
  119. data/vendor/libgit2/src/features.h.in +36 -0
  120. data/vendor/libgit2/src/fetch.c +2 -2
  121. data/vendor/libgit2/src/fetch.h +4 -0
  122. data/vendor/libgit2/src/fetchhead.c +3 -3
  123. data/vendor/libgit2/src/fetchhead.h +3 -0
  124. data/vendor/libgit2/src/filebuf.c +2 -1
  125. data/vendor/libgit2/src/filebuf.h +2 -0
  126. data/vendor/libgit2/src/fileops.c +12 -1
  127. data/vendor/libgit2/src/fileops.h +7 -1
  128. data/vendor/libgit2/src/filter.c +2 -1
  129. data/vendor/libgit2/src/filter.h +1 -0
  130. data/vendor/libgit2/src/fnmatch.c +2 -2
  131. data/vendor/libgit2/src/fnmatch.h +3 -4
  132. data/vendor/libgit2/src/global.c +4 -3
  133. data/vendor/libgit2/src/global.h +1 -5
  134. data/vendor/libgit2/src/graph.c +2 -0
  135. data/vendor/libgit2/src/hash.c +0 -1
  136. data/vendor/libgit2/src/hash.h +3 -1
  137. data/vendor/libgit2/src/hash/hash_collisiondetect.h +3 -3
  138. data/vendor/libgit2/src/hash/hash_common_crypto.h +18 -5
  139. data/vendor/libgit2/src/hash/hash_generic.c +2 -2
  140. data/vendor/libgit2/src/hash/hash_generic.h +5 -3
  141. data/vendor/libgit2/src/hash/hash_openssl.h +3 -3
  142. data/vendor/libgit2/src/hash/hash_win32.c +57 -14
  143. data/vendor/libgit2/src/hash/hash_win32.h +4 -3
  144. data/vendor/libgit2/src/hashsig.c +3 -0
  145. data/vendor/libgit2/src/ident.c +2 -0
  146. data/vendor/libgit2/src/idxmap.h +2 -1
  147. data/vendor/libgit2/src/ignore.c +14 -2
  148. data/vendor/libgit2/src/ignore.h +2 -0
  149. data/vendor/libgit2/src/index.c +20 -40
  150. data/vendor/libgit2/src/index.h +2 -0
  151. data/vendor/libgit2/src/indexer.c +13 -5
  152. data/vendor/libgit2/src/indexer.h +5 -1
  153. data/vendor/libgit2/src/integer.h +1 -1
  154. data/vendor/libgit2/src/iterator.c +44 -3
  155. data/vendor/libgit2/src/iterator.h +3 -0
  156. data/vendor/libgit2/src/map.h +1 -1
  157. data/vendor/libgit2/src/merge.c +155 -33
  158. data/vendor/libgit2/src/merge.h +2 -0
  159. data/vendor/libgit2/src/merge_driver.c +2 -2
  160. data/vendor/libgit2/src/merge_driver.h +2 -0
  161. data/vendor/libgit2/src/merge_file.c +3 -0
  162. data/vendor/libgit2/src/message.h +3 -1
  163. data/vendor/libgit2/src/mwindow.c +1 -1
  164. data/vendor/libgit2/src/mwindow.h +2 -0
  165. data/vendor/libgit2/src/netops.c +75 -62
  166. data/vendor/libgit2/src/netops.h +2 -1
  167. data/vendor/libgit2/src/notes.c +164 -48
  168. data/vendor/libgit2/src/notes.h +1 -1
  169. data/vendor/libgit2/src/object.c +14 -3
  170. data/vendor/libgit2/src/object.h +4 -0
  171. data/vendor/libgit2/src/object_api.c +3 -2
  172. data/vendor/libgit2/src/odb.c +104 -38
  173. data/vendor/libgit2/src/odb.h +3 -1
  174. data/vendor/libgit2/src/odb_loose.c +414 -267
  175. data/vendor/libgit2/src/odb_mempack.c +1 -0
  176. data/vendor/libgit2/src/odb_pack.c +2 -1
  177. data/vendor/libgit2/src/offmap.h +1 -0
  178. data/vendor/libgit2/src/oid.c +2 -1
  179. data/vendor/libgit2/src/oid.h +3 -8
  180. data/vendor/libgit2/src/oidarray.c +2 -1
  181. data/vendor/libgit2/src/oidarray.h +1 -0
  182. data/vendor/libgit2/src/oidmap.h +1 -0
  183. data/vendor/libgit2/src/pack-objects.c +5 -1
  184. data/vendor/libgit2/src/pack-objects.h +1 -1
  185. data/vendor/libgit2/src/pack.c +2 -6
  186. data/vendor/libgit2/src/pack.h +2 -1
  187. data/vendor/libgit2/src/parse.c +121 -0
  188. data/vendor/libgit2/src/parse.h +61 -0
  189. data/vendor/libgit2/src/patch.c +9 -2
  190. data/vendor/libgit2/src/patch.h +2 -0
  191. data/vendor/libgit2/src/patch_generate.c +6 -5
  192. data/vendor/libgit2/src/patch_generate.h +1 -0
  193. data/vendor/libgit2/src/patch_parse.c +265 -276
  194. data/vendor/libgit2/src/patch_parse.h +6 -11
  195. data/vendor/libgit2/src/path.c +24 -181
  196. data/vendor/libgit2/src/path.h +14 -73
  197. data/vendor/libgit2/src/pathspec.c +2 -1
  198. data/vendor/libgit2/src/pathspec.h +2 -1
  199. data/vendor/libgit2/src/pool.c +8 -0
  200. data/vendor/libgit2/src/pool.h +1 -0
  201. data/vendor/libgit2/src/posix.c +2 -1
  202. data/vendor/libgit2/src/posix.h +1 -0
  203. data/vendor/libgit2/src/pqueue.c +1 -0
  204. data/vendor/libgit2/src/pqueue.h +2 -0
  205. data/vendor/libgit2/src/proxy.c +2 -1
  206. data/vendor/libgit2/src/proxy.h +3 -1
  207. data/vendor/libgit2/src/push.c +4 -171
  208. data/vendor/libgit2/src/push.h +2 -0
  209. data/vendor/libgit2/src/rebase.c +1 -0
  210. data/vendor/libgit2/src/refdb.c +2 -3
  211. data/vendor/libgit2/src/refdb.h +2 -0
  212. data/vendor/libgit2/src/refdb_fs.c +5 -3
  213. data/vendor/libgit2/src/refdb_fs.h +4 -0
  214. data/vendor/libgit2/src/reflog.c +1 -0
  215. data/vendor/libgit2/src/reflog.h +2 -1
  216. data/vendor/libgit2/src/refs.c +1 -0
  217. data/vendor/libgit2/src/refs.h +2 -1
  218. data/vendor/libgit2/src/refspec.c +2 -2
  219. data/vendor/libgit2/src/refspec.h +2 -0
  220. data/vendor/libgit2/src/remote.c +56 -10
  221. data/vendor/libgit2/src/remote.h +2 -0
  222. data/vendor/libgit2/src/repository.c +16 -14
  223. data/vendor/libgit2/src/repository.h +2 -0
  224. data/vendor/libgit2/src/reset.c +6 -5
  225. data/vendor/libgit2/src/revert.c +1 -0
  226. data/vendor/libgit2/src/revparse.c +3 -5
  227. data/vendor/libgit2/src/revwalk.c +2 -2
  228. data/vendor/libgit2/src/revwalk.h +2 -0
  229. data/vendor/libgit2/src/settings.c +6 -8
  230. data/vendor/libgit2/src/sha1_lookup.c +2 -216
  231. data/vendor/libgit2/src/sha1_lookup.h +2 -6
  232. data/vendor/libgit2/src/signature.c +8 -3
  233. data/vendor/libgit2/src/signature.h +2 -0
  234. data/vendor/libgit2/src/sortedcache.c +7 -0
  235. data/vendor/libgit2/src/sortedcache.h +2 -0
  236. data/vendor/libgit2/src/stash.c +1 -0
  237. data/vendor/libgit2/src/status.c +14 -9
  238. data/vendor/libgit2/src/status.h +2 -0
  239. data/vendor/libgit2/src/{curl_stream.c → streams/curl.c} +2 -0
  240. data/vendor/libgit2/src/{curl_stream.h → streams/curl.h} +4 -2
  241. data/vendor/libgit2/src/{openssl_stream.c → streams/openssl.c} +47 -18
  242. data/vendor/libgit2/src/{openssl_stream.h → streams/openssl.h} +6 -2
  243. data/vendor/libgit2/src/{socket_stream.c → streams/socket.c} +2 -2
  244. data/vendor/libgit2/src/{socket_stream.h → streams/socket.h} +4 -2
  245. data/vendor/libgit2/src/{stransport_stream.c → streams/stransport.c} +4 -2
  246. data/vendor/libgit2/src/{stransport_stream.h → streams/stransport.h} +4 -2
  247. data/vendor/libgit2/src/{tls_stream.c → streams/tls.c} +4 -3
  248. data/vendor/libgit2/src/{tls_stream.h → streams/tls.h} +4 -2
  249. data/vendor/libgit2/src/submodule.c +28 -80
  250. data/vendor/libgit2/src/submodule.h +2 -13
  251. data/vendor/libgit2/src/sysdir.c +75 -8
  252. data/vendor/libgit2/src/sysdir.h +2 -1
  253. data/vendor/libgit2/src/tag.c +2 -2
  254. data/vendor/libgit2/src/tag.h +2 -0
  255. data/vendor/libgit2/src/thread-utils.c +1 -0
  256. data/vendor/libgit2/src/thread-utils.h +1 -1
  257. data/vendor/libgit2/src/trace.c +2 -2
  258. data/vendor/libgit2/src/trace.h +2 -0
  259. data/vendor/libgit2/src/trailer.c +416 -0
  260. data/vendor/libgit2/src/transaction.c +2 -1
  261. data/vendor/libgit2/src/transport.c +2 -0
  262. data/vendor/libgit2/src/transports/auth.c +2 -1
  263. data/vendor/libgit2/src/transports/auth.h +4 -3
  264. data/vendor/libgit2/src/transports/auth_negotiate.c +2 -1
  265. data/vendor/libgit2/src/transports/auth_negotiate.h +3 -3
  266. data/vendor/libgit2/src/transports/cred.c +2 -0
  267. data/vendor/libgit2/src/transports/cred.h +4 -2
  268. data/vendor/libgit2/src/transports/cred_helpers.c +1 -0
  269. data/vendor/libgit2/src/transports/git.c +3 -1
  270. data/vendor/libgit2/src/transports/http.c +10 -14
  271. data/vendor/libgit2/src/transports/http.h +23 -0
  272. data/vendor/libgit2/src/transports/local.c +23 -5
  273. data/vendor/libgit2/src/transports/smart.c +3 -1
  274. data/vendor/libgit2/src/transports/smart.h +23 -16
  275. data/vendor/libgit2/src/transports/smart_pkt.c +114 -130
  276. data/vendor/libgit2/src/transports/smart_protocol.c +26 -22
  277. data/vendor/libgit2/src/transports/ssh.c +12 -7
  278. data/vendor/libgit2/src/transports/ssh.h +4 -2
  279. data/vendor/libgit2/src/transports/winhttp.c +19 -21
  280. data/vendor/libgit2/src/tree-cache.c +1 -0
  281. data/vendor/libgit2/src/tree-cache.h +1 -0
  282. data/vendor/libgit2/src/tree.c +20 -14
  283. data/vendor/libgit2/src/tree.h +2 -0
  284. data/vendor/libgit2/src/tsort.c +0 -1
  285. data/vendor/libgit2/src/unix/map.c +4 -1
  286. data/vendor/libgit2/src/unix/posix.h +8 -4
  287. data/vendor/libgit2/src/unix/pthread.h +1 -1
  288. data/vendor/libgit2/src/unix/realpath.c +4 -1
  289. data/vendor/libgit2/src/util.c +6 -5
  290. data/vendor/libgit2/src/util.h +39 -111
  291. data/vendor/libgit2/src/varint.c +0 -1
  292. data/vendor/libgit2/src/varint.h +2 -0
  293. data/vendor/libgit2/src/vector.c +1 -1
  294. data/vendor/libgit2/src/win32/dir.c +3 -0
  295. data/vendor/libgit2/src/win32/dir.h +4 -3
  296. data/vendor/libgit2/src/win32/error.c +1 -1
  297. data/vendor/libgit2/src/win32/error.h +4 -2
  298. data/vendor/libgit2/src/win32/findfile.c +2 -1
  299. data/vendor/libgit2/src/win32/findfile.h +4 -2
  300. data/vendor/libgit2/src/win32/map.c +2 -0
  301. data/vendor/libgit2/src/win32/mingw-compat.h +3 -3
  302. data/vendor/libgit2/src/win32/msvc-compat.h +3 -3
  303. data/vendor/libgit2/src/win32/path_w32.c +7 -12
  304. data/vendor/libgit2/src/win32/path_w32.h +3 -2
  305. data/vendor/libgit2/src/win32/posix.h +2 -2
  306. data/vendor/libgit2/src/win32/posix_w32.c +11 -5
  307. data/vendor/libgit2/src/win32/precompiled.h +2 -1
  308. data/vendor/libgit2/src/win32/reparse.h +2 -2
  309. data/vendor/libgit2/src/win32/thread.c +1 -0
  310. data/vendor/libgit2/src/win32/thread.h +2 -2
  311. data/vendor/libgit2/src/win32/utf-conv.c +0 -1
  312. data/vendor/libgit2/src/win32/utf-conv.h +4 -3
  313. data/vendor/libgit2/src/win32/w32_buffer.c +1 -1
  314. data/vendor/libgit2/src/win32/w32_buffer.h +4 -2
  315. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +2 -1
  316. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +85 -2
  317. data/vendor/libgit2/src/win32/w32_stack.c +2 -1
  318. data/vendor/libgit2/src/win32/w32_stack.h +5 -3
  319. data/vendor/libgit2/src/win32/w32_util.h +4 -2
  320. data/vendor/libgit2/src/win32/win32-compat.h +3 -3
  321. data/vendor/libgit2/src/worktree.c +4 -5
  322. data/vendor/libgit2/src/worktree.h +2 -0
  323. data/vendor/libgit2/src/xdiff/xdiff.h +22 -13
  324. data/vendor/libgit2/src/xdiff/xdiffi.c +523 -81
  325. data/vendor/libgit2/src/xdiff/xdiffi.h +2 -2
  326. data/vendor/libgit2/src/xdiff/xemit.c +63 -39
  327. data/vendor/libgit2/src/xdiff/xemit.h +2 -2
  328. data/vendor/libgit2/src/xdiff/xhistogram.c +0 -1
  329. data/vendor/libgit2/src/xdiff/xinclude.h +3 -2
  330. data/vendor/libgit2/src/xdiff/xmacros.h +2 -2
  331. data/vendor/libgit2/src/xdiff/xmerge.c +80 -20
  332. data/vendor/libgit2/src/xdiff/xpatience.c +41 -9
  333. data/vendor/libgit2/src/xdiff/xprepare.c +2 -2
  334. data/vendor/libgit2/src/xdiff/xprepare.h +2 -2
  335. data/vendor/libgit2/src/xdiff/xtypes.h +2 -2
  336. data/vendor/libgit2/src/xdiff/xutils.c +47 -27
  337. data/vendor/libgit2/src/xdiff/xutils.h +2 -5
  338. data/vendor/libgit2/src/zstream.c +65 -45
  339. data/vendor/libgit2/src/zstream.h +9 -2
  340. metadata +27 -13
  341. data/vendor/libgit2/include/git2/sys/remote.h +0 -16
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  #include "common.h"
9
+
9
10
  #include "git2/object.h"
10
11
  #include "git2/sys/odb_backend.h"
11
12
  #include "git2/sys/mempack.h"
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  #include "common.h"
9
+
9
10
  #include <zlib.h>
10
11
  #include "git2/repository.h"
11
12
  #include "git2/indexer.h"
@@ -209,7 +210,7 @@ static int packfile_load__cb(void *data, git_buf *path)
209
210
  for (i = 0; i < backend->packs.length; ++i) {
210
211
  struct git_pack_file *p = git_vector_get(&backend->packs, i);
211
212
 
212
- if (strncmp(p->pack_name, path_str, cmp_len) == 0)
213
+ if (memcmp(p->pack_name, path_str, cmp_len) == 0)
213
214
  return 0;
214
215
  }
215
216
 
@@ -8,6 +8,7 @@
8
8
  #define INCLUDE_offmap_h__
9
9
 
10
10
  #include "common.h"
11
+
11
12
  #include "git2/types.h"
12
13
 
13
14
  #define kmalloc git__malloc
@@ -5,7 +5,8 @@
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
7
 
8
- #include "common.h"
8
+ #include "oid.h"
9
+
9
10
  #include "git2/oid.h"
10
11
  #include "repository.h"
11
12
  #include "global.h"
@@ -7,6 +7,8 @@
7
7
  #ifndef INCLUDE_oid_h__
8
8
  #define INCLUDE_oid_h__
9
9
 
10
+ #include "common.h"
11
+
10
12
  #include "git2/oid.h"
11
13
 
12
14
  /**
@@ -22,14 +24,7 @@ char *git_oid_allocfmt(const git_oid *id);
22
24
 
23
25
  GIT_INLINE(int) git_oid__hashcmp(const unsigned char *sha1, const unsigned char *sha2)
24
26
  {
25
- int i;
26
-
27
- for (i = 0; i < GIT_OID_RAWSZ; i++, sha1++, sha2++) {
28
- if (*sha1 != *sha2)
29
- return *sha1 - *sha2;
30
- }
31
-
32
- return 0;
27
+ return memcmp(sha1, sha2, GIT_OID_RAWSZ);
33
28
  }
34
29
 
35
30
  /*
@@ -5,8 +5,9 @@
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
7
 
8
- #include "git2/oidarray.h"
9
8
  #include "oidarray.h"
9
+
10
+ #include "git2/oidarray.h"
10
11
  #include "array.h"
11
12
 
12
13
  void git_oidarray_free(git_oidarray *arr)
@@ -8,6 +8,7 @@
8
8
  #define INCLUDE_oidarray_h__
9
9
 
10
10
  #include "common.h"
11
+
11
12
  #include "git2/oidarray.h"
12
13
  #include "array.h"
13
14
 
@@ -8,6 +8,7 @@
8
8
  #define INCLUDE_oidmap_h__
9
9
 
10
10
  #include "common.h"
11
+
11
12
  #include "git2/oid.h"
12
13
 
13
14
  #define kmalloc git__malloc
@@ -1642,7 +1642,7 @@ int insert_tree(git_packbuilder *pb, git_tree *tree)
1642
1642
  if ((error = retrieve_object(&obj, pb, git_tree_id(tree))) < 0)
1643
1643
  return error;
1644
1644
 
1645
- if (obj->seen)
1645
+ if (obj->seen || obj->uninteresting)
1646
1646
  return 0;
1647
1647
 
1648
1648
  obj->seen = 1;
@@ -1666,6 +1666,10 @@ int insert_tree(git_packbuilder *pb, git_tree *tree)
1666
1666
 
1667
1667
  break;
1668
1668
  case GIT_OBJ_BLOB:
1669
+ if ((error = retrieve_object(&obj, pb, git_tree_id(tree))) < 0)
1670
+ return error;
1671
+ if (obj->uninteresting)
1672
+ continue;
1669
1673
  name = git_tree_entry_name(entry);
1670
1674
  if ((error = git_packbuilder_insert(pb, entry_id, name)) < 0)
1671
1675
  return error;
@@ -104,4 +104,4 @@ struct git_packbuilder {
104
104
 
105
105
  int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb);
106
106
 
107
- #endif /* INCLUDE_pack_objects_h__ */
107
+ #endif
@@ -5,9 +5,9 @@
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
7
 
8
- #include "common.h"
9
- #include "odb.h"
10
8
  #include "pack.h"
9
+
10
+ #include "odb.h"
11
11
  #include "delta.h"
12
12
  #include "sha1_lookup.h"
13
13
  #include "mwindow.h"
@@ -1319,11 +1319,7 @@ static int pack_entry_find_offset(
1319
1319
  short_oid->id[0], short_oid->id[1], short_oid->id[2], lo, hi, p->num_objects);
1320
1320
  #endif
1321
1321
 
1322
- #ifdef GIT_USE_LOOKUP
1323
- pos = sha1_entry_pos(index, stride, 0, lo, hi, p->num_objects, short_oid->id);
1324
- #else
1325
1322
  pos = sha1_position(index, stride, lo, hi, short_oid->id);
1326
- #endif
1327
1323
 
1328
1324
  if (pos >= 0) {
1329
1325
  /* An object matching exactly the oid was found */
@@ -8,11 +8,12 @@
8
8
  #ifndef INCLUDE_pack_h__
9
9
  #define INCLUDE_pack_h__
10
10
 
11
+ #include "common.h"
12
+
11
13
  #include <zlib.h>
12
14
 
13
15
  #include "git2/oid.h"
14
16
 
15
- #include "common.h"
16
17
  #include "map.h"
17
18
  #include "mwindow.h"
18
19
  #include "odb.h"
@@ -0,0 +1,121 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+ #include "parse.h"
8
+
9
+ int git_parse_ctx_init(git_parse_ctx *ctx, const char *content, size_t content_len)
10
+ {
11
+ if (content_len)
12
+ ctx->content = content;
13
+ else
14
+ ctx->content = NULL;
15
+
16
+ ctx->content_len = content_len;
17
+ ctx->remain = ctx->content;
18
+ ctx->remain_len = ctx->content_len;
19
+ ctx->line = ctx->remain;
20
+ ctx->line_len = git__linenlen(ctx->line, ctx->remain_len);
21
+ ctx->line_num = 1;
22
+
23
+ return 0;
24
+ }
25
+
26
+ void git_parse_ctx_clear(git_parse_ctx *ctx)
27
+ {
28
+ memset(ctx, 0, sizeof(*ctx));
29
+ }
30
+
31
+ void git_parse_advance_line(git_parse_ctx *ctx)
32
+ {
33
+ ctx->line += ctx->line_len;
34
+ ctx->remain_len -= ctx->line_len;
35
+ ctx->line_len = git__linenlen(ctx->line, ctx->remain_len);
36
+ ctx->line_num++;
37
+ }
38
+
39
+ void git_parse_advance_chars(git_parse_ctx *ctx, size_t char_cnt)
40
+ {
41
+ ctx->line += char_cnt;
42
+ ctx->remain_len -= char_cnt;
43
+ ctx->line_len -= char_cnt;
44
+ }
45
+
46
+ int git_parse_advance_expected(
47
+ git_parse_ctx *ctx,
48
+ const char *expected,
49
+ size_t expected_len)
50
+ {
51
+ if (ctx->line_len < expected_len)
52
+ return -1;
53
+
54
+ if (memcmp(ctx->line, expected, expected_len) != 0)
55
+ return -1;
56
+
57
+ git_parse_advance_chars(ctx, expected_len);
58
+ return 0;
59
+ }
60
+
61
+ int git_parse_advance_ws(git_parse_ctx *ctx)
62
+ {
63
+ int ret = -1;
64
+
65
+ while (ctx->line_len > 0 &&
66
+ ctx->line[0] != '\n' &&
67
+ git__isspace(ctx->line[0])) {
68
+ ctx->line++;
69
+ ctx->line_len--;
70
+ ctx->remain_len--;
71
+ ret = 0;
72
+ }
73
+
74
+ return ret;
75
+ }
76
+
77
+ int git_parse_advance_nl(git_parse_ctx *ctx)
78
+ {
79
+ if (ctx->line_len != 1 || ctx->line[0] != '\n')
80
+ return -1;
81
+
82
+ git_parse_advance_line(ctx);
83
+ return 0;
84
+ }
85
+
86
+ int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base)
87
+ {
88
+ const char *end;
89
+ int ret;
90
+
91
+ if (ctx->line_len < 1 || !git__isdigit(ctx->line[0]))
92
+ return -1;
93
+
94
+ if ((ret = git__strntol64(out, ctx->line, ctx->line_len, &end, base)) < 0)
95
+ return -1;
96
+
97
+ git_parse_advance_chars(ctx, (end - ctx->line));
98
+ return 0;
99
+ }
100
+
101
+ int git_parse_peek(char *out, git_parse_ctx *ctx, int flags)
102
+ {
103
+ size_t remain = ctx->line_len;
104
+ const char *ptr = ctx->line;
105
+
106
+ while (remain) {
107
+ char c = *ptr;
108
+
109
+ if ((flags & GIT_PARSE_PEEK_SKIP_WHITESPACE) &&
110
+ git__isspace(c)) {
111
+ remain--;
112
+ ptr++;
113
+ continue;
114
+ }
115
+
116
+ *out = c;
117
+ return 0;
118
+ }
119
+
120
+ return -1;
121
+ }
@@ -0,0 +1,61 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+ #ifndef INCLUDE_parse_h__
8
+ #define INCLUDE_parse_h__
9
+
10
+ #include "common.h"
11
+
12
+ typedef struct {
13
+ /* Original content buffer */
14
+ const char *content;
15
+ size_t content_len;
16
+
17
+ /* The remaining (unparsed) buffer */
18
+ const char *remain;
19
+ size_t remain_len;
20
+
21
+ const char *line;
22
+ size_t line_len;
23
+ size_t line_num;
24
+ } git_parse_ctx;
25
+
26
+ int git_parse_ctx_init(git_parse_ctx *ctx, const char *content, size_t content_len);
27
+ void git_parse_ctx_clear(git_parse_ctx *ctx);
28
+
29
+ #define git_parse_err(...) \
30
+ ( giterr_set(GITERR_PATCH, __VA_ARGS__), -1 )
31
+
32
+ #define git_parse_ctx_contains_s(ctx, str) \
33
+ git_parse_ctx_contains(ctx, str, sizeof(str) - 1)
34
+
35
+ GIT_INLINE(bool) git_parse_ctx_contains(
36
+ git_parse_ctx *ctx, const char *str, size_t len)
37
+ {
38
+ return (ctx->line_len >= len && memcmp(ctx->line, str, len) == 0);
39
+ }
40
+
41
+ void git_parse_advance_line(git_parse_ctx *ctx);
42
+ void git_parse_advance_chars(git_parse_ctx *ctx, size_t char_cnt);
43
+ int git_parse_advance_expected(
44
+ git_parse_ctx *ctx,
45
+ const char *expected,
46
+ size_t expected_len);
47
+
48
+ #define git_parse_advance_expected_str(ctx, str) \
49
+ git_parse_advance_expected(ctx, str, strlen(str))
50
+
51
+ int git_parse_advance_ws(git_parse_ctx *ctx);
52
+ int git_parse_advance_nl(git_parse_ctx *ctx);
53
+ int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base);
54
+
55
+ enum GIT_PARSE_PEEK_FLAGS {
56
+ GIT_PARSE_PEEK_SKIP_WHITESPACE = (1 << 0)
57
+ };
58
+
59
+ int git_parse_peek(char *out, git_parse_ctx *ctx, int flags);
60
+
61
+ #endif
@@ -1,7 +1,14 @@
1
- #include "git2/patch.h"
2
- #include "diff.h"
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+
3
8
  #include "patch.h"
4
9
 
10
+ #include "git2/patch.h"
11
+ #include "diff.h"
5
12
 
6
13
  int git_patch__invoke_callbacks(
7
14
  git_patch *patch,
@@ -7,6 +7,8 @@
7
7
  #ifndef INCLUDE_patch_h__
8
8
  #define INCLUDE_patch_h__
9
9
 
10
+ #include "common.h"
11
+
10
12
  #include "git2/patch.h"
11
13
  #include "array.h"
12
14
 
@@ -4,13 +4,14 @@
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
- #include "common.h"
7
+
8
+ #include "patch_generate.h"
9
+
8
10
  #include "git2/blob.h"
9
11
  #include "diff.h"
10
12
  #include "diff_generate.h"
11
13
  #include "diff_file.h"
12
14
  #include "diff_driver.h"
13
- #include "patch_generate.h"
14
15
  #include "diff_xdiff.h"
15
16
  #include "delta.h"
16
17
  #include "zstream.h"
@@ -138,7 +139,7 @@ static int patch_generated_alloc_from_diff(
138
139
 
139
140
  if (!(error = patch_generated_init(patch, diff, delta_index))) {
140
141
  patch->flags |= GIT_PATCH_GENERATED_ALLOCATED;
141
- GIT_REFCOUNT_INC(patch);
142
+ GIT_REFCOUNT_INC(&patch->base);
142
143
  } else {
143
144
  git__free(patch);
144
145
  patch = NULL;
@@ -641,7 +642,7 @@ int git_patch_from_blob_and_buffer(
641
642
  git_patch **out,
642
643
  const git_blob *old_blob,
643
644
  const char *old_path,
644
- const char *buf,
645
+ const void *buf,
645
646
  size_t buflen,
646
647
  const char *buf_path,
647
648
  const git_diff_options *opts)
@@ -680,7 +681,7 @@ int git_patch_from_buffers(
680
681
  const void *old_buf,
681
682
  size_t old_len,
682
683
  const char *old_path,
683
- const char *new_buf,
684
+ const void *new_buf,
684
685
  size_t new_len,
685
686
  const char *new_path,
686
687
  const git_diff_options *opts)
@@ -8,6 +8,7 @@
8
8
  #define INCLUDE_patch_generate_h__
9
9
 
10
10
  #include "common.h"
11
+
11
12
  #include "diff.h"
12
13
  #include "diff_file.h"
13
14
  #include "patch.h"
@@ -4,15 +4,14 @@
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
+
8
+ #include "patch_parse.h"
9
+
7
10
  #include "git2/patch.h"
8
11
  #include "patch.h"
9
- #include "patch_parse.h"
10
12
  #include "diff_parse.h"
11
13
  #include "path.h"
12
14
 
13
- #define parse_err(...) \
14
- ( giterr_set(GITERR_PATCH, __VA_ARGS__), -1 )
15
-
16
15
  typedef struct {
17
16
  git_patch base;
18
17
 
@@ -34,104 +33,34 @@ typedef struct {
34
33
  char *old_prefix, *new_prefix;
35
34
  } git_patch_parsed;
36
35
 
37
-
38
- GIT_INLINE(bool) parse_ctx_contains(
39
- git_patch_parse_ctx *ctx, const char *str, size_t len)
40
- {
41
- return (ctx->line_len >= len && memcmp(ctx->line, str, len) == 0);
42
- }
43
-
44
- #define parse_ctx_contains_s(ctx, str) \
45
- parse_ctx_contains(ctx, str, sizeof(str) - 1)
46
-
47
- static void parse_advance_line(git_patch_parse_ctx *ctx)
48
- {
49
- ctx->line += ctx->line_len;
50
- ctx->remain_len -= ctx->line_len;
51
- ctx->line_len = git__linenlen(ctx->line, ctx->remain_len);
52
- ctx->line_num++;
53
- }
54
-
55
- static void parse_advance_chars(git_patch_parse_ctx *ctx, size_t char_cnt)
56
- {
57
- ctx->line += char_cnt;
58
- ctx->remain_len -= char_cnt;
59
- ctx->line_len -= char_cnt;
60
- }
61
-
62
- static int parse_advance_expected(
63
- git_patch_parse_ctx *ctx,
64
- const char *expected,
65
- size_t expected_len)
66
- {
67
- if (ctx->line_len < expected_len)
68
- return -1;
69
-
70
- if (memcmp(ctx->line, expected, expected_len) != 0)
71
- return -1;
72
-
73
- parse_advance_chars(ctx, expected_len);
74
- return 0;
75
- }
76
-
77
- #define parse_advance_expected_str(ctx, str) \
78
- parse_advance_expected(ctx, str, strlen(str))
79
-
80
- static int parse_advance_ws(git_patch_parse_ctx *ctx)
81
- {
82
- int ret = -1;
83
-
84
- while (ctx->line_len > 0 &&
85
- ctx->line[0] != '\n' &&
86
- git__isspace(ctx->line[0])) {
87
- ctx->line++;
88
- ctx->line_len--;
89
- ctx->remain_len--;
90
- ret = 0;
91
- }
92
-
93
- return ret;
94
- }
95
-
96
- static int parse_advance_nl(git_patch_parse_ctx *ctx)
97
- {
98
- if (ctx->line_len != 1 || ctx->line[0] != '\n')
99
- return -1;
100
-
101
- parse_advance_line(ctx);
102
- return 0;
103
- }
104
-
105
36
  static int header_path_len(git_patch_parse_ctx *ctx)
106
37
  {
107
38
  bool inquote = 0;
108
- bool quoted = (ctx->line_len > 0 && ctx->line[0] == '"');
39
+ bool quoted = git_parse_ctx_contains_s(&ctx->parse_ctx, "\"");
109
40
  size_t len;
110
41
 
111
- for (len = quoted; len < ctx->line_len; len++) {
112
- if (!quoted && git__isspace(ctx->line[len]))
42
+ for (len = quoted; len < ctx->parse_ctx.line_len; len++) {
43
+ if (!quoted && git__isspace(ctx->parse_ctx.line[len]))
113
44
  break;
114
- else if (quoted && !inquote && ctx->line[len] == '"') {
45
+ else if (quoted && !inquote && ctx->parse_ctx.line[len] == '"') {
115
46
  len++;
116
47
  break;
117
48
  }
118
49
 
119
- inquote = (!inquote && ctx->line[len] == '\\');
50
+ inquote = (!inquote && ctx->parse_ctx.line[len] == '\\');
120
51
  }
121
52
 
122
53
  return len;
123
54
  }
124
55
 
125
- static int parse_header_path_buf(git_buf *path, git_patch_parse_ctx *ctx)
56
+ static int parse_header_path_buf(git_buf *path, git_patch_parse_ctx *ctx, size_t path_len)
126
57
  {
127
- int path_len, error = 0;
128
-
129
- path_len = header_path_len(ctx);
58
+ int error;
130
59
 
131
- if ((error = git_buf_put(path, ctx->line, path_len)) < 0)
60
+ if ((error = git_buf_put(path, ctx->parse_ctx.line, path_len)) < 0)
132
61
  goto done;
133
62
 
134
- parse_advance_chars(ctx, path_len);
63
+ git_parse_advance_chars(&ctx->parse_ctx, path_len);
135
64
 
136
65
  git_buf_rtrim(path);
137
66
 
@@ -150,7 +79,7 @@ done:
150
79
  static int parse_header_path(char **out, git_patch_parse_ctx *ctx)
151
80
  {
152
81
  git_buf path = GIT_BUF_INIT;
153
- int error = parse_header_path_buf(&path, ctx);
82
+ int error = parse_header_path_buf(&path, ctx, header_path_len(ctx));
154
83
 
155
84
  *out = git_buf_detach(&path);
156
85
 
@@ -160,35 +89,48 @@ static int parse_header_path(char **out, git_patch_parse_ctx *ctx)
160
89
  static int parse_header_git_oldpath(
161
90
  git_patch_parsed *patch, git_patch_parse_ctx *ctx)
162
91
  {
163
- return parse_header_path(&patch->old_path, ctx);
92
+ git_buf old_path = GIT_BUF_INIT;
93
+ int error;
94
+
95
+ if ((error = parse_header_path_buf(&old_path, ctx, ctx->parse_ctx.line_len - 1)) < 0)
96
+ goto out;
97
+
98
+ patch->old_path = git_buf_detach(&old_path);
99
+
100
+ out:
101
+ git_buf_free(&old_path);
102
+ return error;
164
103
  }
165
104
 
166
105
  static int parse_header_git_newpath(
167
106
  git_patch_parsed *patch, git_patch_parse_ctx *ctx)
168
107
  {
169
- return parse_header_path(&patch->new_path, ctx);
108
+ git_buf new_path = GIT_BUF_INIT;
109
+ int error;
110
+
111
+ if ((error = parse_header_path_buf(&new_path, ctx, ctx->parse_ctx.line_len - 1)) < 0)
112
+ goto out;
113
+
114
+ patch->new_path = git_buf_detach(&new_path);
115
+
116
+ out:
117
+ git_buf_free(&new_path);
118
+ return error;
170
119
  }
171
120
 
172
121
  static int parse_header_mode(uint16_t *mode, git_patch_parse_ctx *ctx)
173
122
  {
174
- const char *end;
175
- int32_t m;
176
- int ret;
177
-
178
- if (ctx->line_len < 1 || !git__isdigit(ctx->line[0]))
179
- return parse_err("invalid file mode at line %"PRIuZ, ctx->line_num);
123
+ int64_t m;
180
124
 
181
- if ((ret = git__strntol32(&m, ctx->line, ctx->line_len, &end, 8)) < 0)
182
- return ret;
125
+ if ((git_parse_advance_digit(&m, &ctx->parse_ctx, 8)) < 0)
126
+ return git_parse_err("invalid file mode at line %"PRIuZ, ctx->parse_ctx.line_num);
183
127
 
184
128
  if (m > UINT16_MAX)
185
129
  return -1;
186
130
 
187
131
  *mode = (uint16_t)m;
188
132
 
189
- parse_advance_chars(ctx, (end - ctx->line));
190
-
191
- return ret;
133
+ return 0;
192
134
  }
193
135
 
194
136
  static int parse_header_oid(
@@ -198,17 +140,17 @@ static int parse_header_oid(
198
140
  {
199
141
  size_t len;
200
142
 
201
- for (len = 0; len < ctx->line_len && len < GIT_OID_HEXSZ; len++) {
202
- if (!git__isxdigit(ctx->line[len]))
143
+ for (len = 0; len < ctx->parse_ctx.line_len && len < GIT_OID_HEXSZ; len++) {
144
+ if (!git__isxdigit(ctx->parse_ctx.line[len]))
203
145
  break;
204
146
  }
205
147
 
206
148
  if (len < GIT_OID_MINPREFIXLEN || len > GIT_OID_HEXSZ ||
207
- git_oid_fromstrn(oid, ctx->line, len) < 0)
208
- return parse_err("invalid hex formatted object id at line %"PRIuZ,
209
- ctx->line_num);
149
+ git_oid_fromstrn(oid, ctx->parse_ctx.line, len) < 0)
150
+ return git_parse_err("invalid hex formatted object id at line %"PRIuZ,
151
+ ctx->parse_ctx.line_num);
210
152
 
211
- parse_advance_chars(ctx, len);
153
+ git_parse_advance_chars(&ctx->parse_ctx, len);
212
154
 
213
155
  *oid_len = (uint16_t)len;
214
156
 
@@ -218,17 +160,19 @@ static int parse_header_oid(
218
160
  static int parse_header_git_index(
219
161
  git_patch_parsed *patch, git_patch_parse_ctx *ctx)
220
162
  {
163
+ char c;
164
+
221
165
  if (parse_header_oid(&patch->base.delta->old_file.id,
222
166
  &patch->base.delta->old_file.id_abbrev, ctx) < 0 ||
223
- parse_advance_expected_str(ctx, "..") < 0 ||
167
+ git_parse_advance_expected_str(&ctx->parse_ctx, "..") < 0 ||
224
168
  parse_header_oid(&patch->base.delta->new_file.id,
225
169
  &patch->base.delta->new_file.id_abbrev, ctx) < 0)
226
170
  return -1;
227
171
 
228
- if (ctx->line_len > 0 && ctx->line[0] == ' ') {
172
+ if (git_parse_peek(&c, &ctx->parse_ctx, 0) == 0 && c == ' ') {
229
173
  uint16_t mode;
230
174
 
231
- parse_advance_chars(ctx, 1);
175
+ git_parse_advance_chars(&ctx->parse_ctx, 1);
232
176
 
233
177
  if (parse_header_mode(&mode, ctx) < 0)
234
178
  return -1;
@@ -287,7 +231,7 @@ static int parse_header_rename(
287
231
  {
288
232
  git_buf path = GIT_BUF_INIT;
289
233
 
290
- if (parse_header_path_buf(&path, ctx) < 0)
234
+ if (parse_header_path_buf(&path, ctx, header_path_len(ctx)) < 0)
291
235
  return -1;
292
236
 
293
237
  /* Note: the `rename from` and `rename to` lines include the literal
@@ -327,19 +271,15 @@ static int parse_header_copyto(
327
271
 
328
272
  static int parse_header_percent(uint16_t *out, git_patch_parse_ctx *ctx)
329
273
  {
330
- int32_t val;
331
- const char *end;
274
+ int64_t val;
332
275
 
333
- if (ctx->line_len < 1 || !git__isdigit(ctx->line[0]) ||
334
- git__strntol32(&val, ctx->line, ctx->line_len, &end, 10) < 0)
276
+ if (git_parse_advance_digit(&val, &ctx->parse_ctx, 10) < 0)
335
277
  return -1;
336
278
 
337
- parse_advance_chars(ctx, (end - ctx->line));
338
-
339
- if (parse_advance_expected_str(ctx, "%") < 0)
279
+ if (git_parse_advance_expected_str(&ctx->parse_ctx, "%") < 0)
340
280
  return -1;
341
281
 
342
- if (val > 100)
282
+ if (val < 0 || val > 100)
343
283
  return -1;
344
284
 
345
285
  *out = val;
@@ -350,8 +290,8 @@ static int parse_header_similarity(
350
290
  git_patch_parsed *patch, git_patch_parse_ctx *ctx)
351
291
  {
352
292
  if (parse_header_percent(&patch->base.delta->similarity, ctx) < 0)
353
- return parse_err("invalid similarity percentage at line %"PRIuZ,
354
- ctx->line_num);
293
+ return git_parse_err("invalid similarity percentage at line %"PRIuZ,
294
+ ctx->parse_ctx.line_num);
355
295
 
356
296
  return 0;
357
297
  }
@@ -362,39 +302,98 @@ static int parse_header_dissimilarity(
362
302
  uint16_t dissimilarity;
363
303
 
364
304
  if (parse_header_percent(&dissimilarity, ctx) < 0)
365
- return parse_err("invalid similarity percentage at line %"PRIuZ,
366
- ctx->line_num);
305
+ return git_parse_err("invalid similarity percentage at line %"PRIuZ,
306
+ ctx->parse_ctx.line_num);
367
307
 
368
308
  patch->base.delta->similarity = 100 - dissimilarity;
369
309
 
370
310
  return 0;
371
311
  }
372
312
 
313
+ static int parse_header_start(git_patch_parsed *patch, git_patch_parse_ctx *ctx)
314
+ {
315
+ if (parse_header_path(&patch->header_old_path, ctx) < 0)
316
+ return git_parse_err("corrupt old path in git diff header at line %"PRIuZ,
317
+ ctx->parse_ctx.line_num);
318
+
319
+ if (git_parse_advance_ws(&ctx->parse_ctx) < 0 ||
320
+ parse_header_path(&patch->header_new_path, ctx) < 0)
321
+ return git_parse_err("corrupt new path in git diff header at line %"PRIuZ,
322
+ ctx->parse_ctx.line_num);
323
+
324
+ /*
325
+ * We cannot expect to be able to always parse paths correctly at this
326
+ * point. Due to the possibility of unquoted names, whitespaces in
327
+ * filenames and custom prefixes we have to allow that, though, and just
328
+ * proceeed here. We then hope for the "---" and "+++" lines to fix that
329
+ * for us.
330
+ */
331
+ if (!git_parse_ctx_contains(&ctx->parse_ctx, "\n", 1)) {
332
+ git_parse_advance_chars(&ctx->parse_ctx, ctx->parse_ctx.line_len - 1);
333
+
334
+ git__free(patch->header_old_path);
335
+ patch->header_old_path = NULL;
336
+ git__free(patch->header_new_path);
337
+ patch->header_new_path = NULL;
338
+ }
339
+
340
+ return 0;
341
+ }
342
+
343
+ typedef enum {
344
+ STATE_START,
345
+
346
+ STATE_DIFF,
347
+ STATE_FILEMODE,
348
+ STATE_MODE,
349
+ STATE_INDEX,
350
+ STATE_PATH,
351
+
352
+ STATE_SIMILARITY,
353
+ STATE_RENAME,
354
+ STATE_COPY,
355
+
356
+ STATE_END,
357
+ } parse_header_state;
358
+
373
359
  typedef struct {
374
360
  const char *str;
361
+ parse_header_state expected_state;
362
+ parse_header_state next_state;
375
363
  int(*fn)(git_patch_parsed *, git_patch_parse_ctx *);
376
- } header_git_op;
377
-
378
- static const header_git_op header_git_ops[] = {
379
- { "diff --git ", NULL },
380
- { "@@ -", NULL },
381
- { "GIT binary patch", NULL },
382
- { "Binary files ", NULL },
383
- { "--- ", parse_header_git_oldpath },
384
- { "+++ ", parse_header_git_newpath },
385
- { "index ", parse_header_git_index },
386
- { "old mode ", parse_header_git_oldmode },
387
- { "new mode ", parse_header_git_newmode },
388
- { "deleted file mode ", parse_header_git_deletedfilemode },
389
- { "new file mode ", parse_header_git_newfilemode },
390
- { "rename from ", parse_header_renamefrom },
391
- { "rename to ", parse_header_renameto },
392
- { "rename old ", parse_header_renamefrom },
393
- { "rename new ", parse_header_renameto },
394
- { "copy from ", parse_header_copyfrom },
395
- { "copy to ", parse_header_copyto },
396
- { "similarity index ", parse_header_similarity },
397
- { "dissimilarity index ", parse_header_dissimilarity },
364
+ } parse_header_transition;
365
+
366
+ static const parse_header_transition transitions[] = {
367
+ /* Start */
368
+ { "diff --git " , STATE_START, STATE_DIFF, parse_header_start },
369
+
370
+ { "deleted file mode " , STATE_DIFF, STATE_FILEMODE, parse_header_git_deletedfilemode },
371
+ { "new file mode " , STATE_DIFF, STATE_FILEMODE, parse_header_git_newfilemode },
372
+ { "old mode " , STATE_DIFF, STATE_MODE, parse_header_git_oldmode },
373
+ { "new mode " , STATE_MODE, STATE_END, parse_header_git_newmode },
374
+
375
+ { "index " , STATE_FILEMODE, STATE_INDEX, parse_header_git_index },
376
+ { "index " , STATE_DIFF, STATE_INDEX, parse_header_git_index },
377
+ { "index " , STATE_END, STATE_INDEX, parse_header_git_index },
378
+
379
+ { "--- " , STATE_INDEX, STATE_PATH, parse_header_git_oldpath },
380
+ { "+++ " , STATE_PATH, STATE_END, parse_header_git_newpath },
381
+ { "GIT binary patch" , STATE_INDEX, STATE_END, NULL },
382
+ { "Binary files " , STATE_INDEX, STATE_END, NULL },
383
+
384
+ { "similarity index " , STATE_DIFF, STATE_SIMILARITY, parse_header_similarity },
385
+ { "dissimilarity index ", STATE_DIFF, STATE_SIMILARITY, parse_header_dissimilarity },
386
+ { "rename from " , STATE_SIMILARITY, STATE_RENAME, parse_header_renamefrom },
387
+ { "rename old " , STATE_SIMILARITY, STATE_RENAME, parse_header_renamefrom },
388
+ { "copy from " , STATE_SIMILARITY, STATE_COPY, parse_header_copyfrom },
389
+ { "rename to " , STATE_RENAME, STATE_END, parse_header_renameto },
390
+ { "rename new " , STATE_RENAME, STATE_END, parse_header_renameto },
391
+ { "copy to " , STATE_COPY, STATE_END, parse_header_copyto },
392
+
393
+ /* Next patch */
394
+ { "diff --git " , STATE_END, 0, NULL },
395
+ { "@@ -" , STATE_END, 0, NULL },
396
+ { "-- " , STATE_END, 0, NULL },
398
397
  };
399
398
 
400
399
  static int parse_header_git(
@@ -403,65 +402,58 @@ static int parse_header_git(
403
402
  {
404
403
  size_t i;
405
404
  int error = 0;
406
-
407
- /* Parse the diff --git line */
408
- if (parse_advance_expected_str(ctx, "diff --git ") < 0)
409
- return parse_err("corrupt git diff header at line %"PRIuZ, ctx->line_num);
410
-
411
- if (parse_header_path(&patch->header_old_path, ctx) < 0)
412
- return parse_err("corrupt old path in git diff header at line %"PRIuZ,
413
- ctx->line_num);
414
-
415
- if (parse_advance_ws(ctx) < 0 ||
416
- parse_header_path(&patch->header_new_path, ctx) < 0)
417
- return parse_err("corrupt new path in git diff header at line %"PRIuZ,
418
- ctx->line_num);
405
+ parse_header_state state = STATE_START;
419
406
 
420
407
  /* Parse remaining header lines */
421
- for (parse_advance_line(ctx);
422
- ctx->remain_len > 0;
423
- parse_advance_line(ctx)) {
424
-
408
+ for (; ctx->parse_ctx.remain_len > 0; git_parse_advance_line(&ctx->parse_ctx)) {
425
409
  bool found = false;
426
410
 
427
- if (ctx->line_len == 0 || ctx->line[ctx->line_len - 1] != '\n')
411
+ if (ctx->parse_ctx.line_len == 0 || ctx->parse_ctx.line[ctx->parse_ctx.line_len - 1] != '\n')
428
412
  break;
429
413
 
430
- for (i = 0; i < ARRAY_SIZE(header_git_ops); i++) {
431
- const header_git_op *op = &header_git_ops[i];
432
- size_t op_len = strlen(op->str);
414
+ for (i = 0; i < ARRAY_SIZE(transitions); i++) {
415
+ const parse_header_transition *transition = &transitions[i];
416
+ size_t op_len = strlen(transition->str);
433
417
 
434
- if (memcmp(ctx->line, op->str, min(op_len, ctx->line_len)) != 0)
418
+ if (transition->expected_state != state ||
419
+ git__prefixcmp(ctx->parse_ctx.line, transition->str) != 0)
435
420
  continue;
436
421
 
422
+ state = transition->next_state;
423
+
437
424
  /* Do not advance if this is the patch separator */
438
- if (op->fn == NULL)
425
+ if (transition->fn == NULL)
439
426
  goto done;
440
427
 
441
- parse_advance_chars(ctx, op_len);
428
+ git_parse_advance_chars(&ctx->parse_ctx, op_len);
442
429
 
443
- if ((error = op->fn(patch, ctx)) < 0)
430
+ if ((error = transition->fn(patch, ctx)) < 0)
444
431
  goto done;
445
432
 
446
- parse_advance_ws(ctx);
433
+ git_parse_advance_ws(&ctx->parse_ctx);
447
434
 
448
- if (parse_advance_expected_str(ctx, "\n") < 0 ||
449
- ctx->line_len > 0) {
450
- error = parse_err("trailing data at line %"PRIuZ, ctx->line_num);
435
+ if (git_parse_advance_expected_str(&ctx->parse_ctx, "\n") < 0 ||
436
+ ctx->parse_ctx.line_len > 0) {
437
+ error = git_parse_err("trailing data at line %"PRIuZ, ctx->parse_ctx.line_num);
451
438
  goto done;
452
439
  }
453
440
 
454
441
  found = true;
455
442
  break;
456
443
  }
457
-
444
+
458
445
  if (!found) {
459
- error = parse_err("invalid patch header at line %"PRIuZ,
460
- ctx->line_num);
446
+ error = git_parse_err("invalid patch header at line %"PRIuZ,
447
+ ctx->parse_ctx.line_num);
461
448
  goto done;
462
449
  }
463
450
  }
464
451
 
452
+ if (state != STATE_END) {
453
+ error = git_parse_err("unexpected header line %"PRIuZ, ctx->parse_ctx.line_num);
454
+ goto done;
455
+ }
456
+
465
457
  done:
466
458
  return error;
467
459
  }
@@ -471,17 +463,17 @@ static int parse_number(git_off_t *out, git_patch_parse_ctx *ctx)
471
463
  const char *end;
472
464
  int64_t num;
473
465
 
474
- if (!git__isdigit(ctx->line[0]))
466
+ if (!git__isdigit(ctx->parse_ctx.line[0]))
475
467
  return -1;
476
468
 
477
- if (git__strntol64(&num, ctx->line, ctx->line_len, &end, 10) < 0)
469
+ if (git__strntol64(&num, ctx->parse_ctx.line, ctx->parse_ctx.line_len, &end, 10) < 0)
478
470
  return -1;
479
471
 
480
472
  if (num < 0)
481
473
  return -1;
482
474
 
483
475
  *out = num;
484
- parse_advance_chars(ctx, (end - ctx->line));
476
+ git_parse_advance_chars(&ctx->parse_ctx, (end - ctx->parse_ctx.line));
485
477
 
486
478
  return 0;
487
479
  }
@@ -490,7 +482,7 @@ static int parse_int(int *out, git_patch_parse_ctx *ctx)
490
482
  {
491
483
  git_off_t num;
492
484
 
493
- if (parse_number(&num, ctx) < 0 || !git__is_int(num))
485
+ if (git_parse_advance_digit(&num, &ctx->parse_ctx, 10) < 0 || !git__is_int(num))
494
486
  return -1;
495
487
 
496
488
  *out = (int)num;
@@ -501,43 +493,44 @@ static int parse_hunk_header(
501
493
  git_patch_hunk *hunk,
502
494
  git_patch_parse_ctx *ctx)
503
495
  {
504
- const char *header_start = ctx->line;
496
+ const char *header_start = ctx->parse_ctx.line;
497
+ char c;
505
498
 
506
499
  hunk->hunk.old_lines = 1;
507
500
  hunk->hunk.new_lines = 1;
508
501
 
509
- if (parse_advance_expected_str(ctx, "@@ -") < 0 ||
502
+ if (git_parse_advance_expected_str(&ctx->parse_ctx, "@@ -") < 0 ||
510
503
  parse_int(&hunk->hunk.old_start, ctx) < 0)
511
504
  goto fail;
512
505
 
513
- if (ctx->line_len > 0 && ctx->line[0] == ',') {
514
- if (parse_advance_expected_str(ctx, ",") < 0 ||
506
+ if (git_parse_peek(&c, &ctx->parse_ctx, 0) == 0 && c == ',') {
507
+ if (git_parse_advance_expected_str(&ctx->parse_ctx, ",") < 0 ||
515
508
  parse_int(&hunk->hunk.old_lines, ctx) < 0)
516
509
  goto fail;
517
510
  }
518
511
 
519
- if (parse_advance_expected_str(ctx, " +") < 0 ||
512
+ if (git_parse_advance_expected_str(&ctx->parse_ctx, " +") < 0 ||
520
513
  parse_int(&hunk->hunk.new_start, ctx) < 0)
521
514
  goto fail;
522
515
 
523
- if (ctx->line_len > 0 && ctx->line[0] == ',') {
524
- if (parse_advance_expected_str(ctx, ",") < 0 ||
516
+ if (git_parse_peek(&c, &ctx->parse_ctx, 0) == 0 && c == ',') {
517
+ if (git_parse_advance_expected_str(&ctx->parse_ctx, ",") < 0 ||
525
518
  parse_int(&hunk->hunk.new_lines, ctx) < 0)
526
519
  goto fail;
527
520
  }
528
521
 
529
- if (parse_advance_expected_str(ctx, " @@") < 0)
522
+ if (git_parse_advance_expected_str(&ctx->parse_ctx, " @@") < 0)
530
523
  goto fail;
531
524
 
532
- parse_advance_line(ctx);
525
+ git_parse_advance_line(&ctx->parse_ctx);
533
526
 
534
527
  if (!hunk->hunk.old_lines && !hunk->hunk.new_lines)
535
528
  goto fail;
536
529
 
537
- hunk->hunk.header_len = ctx->line - header_start;
530
+ hunk->hunk.header_len = ctx->parse_ctx.line - header_start;
538
531
  if (hunk->hunk.header_len > (GIT_DIFF_HUNK_HEADER_SIZE - 1))
539
- return parse_err("oversized patch hunk header at line %"PRIuZ,
540
- ctx->line_num);
532
+ return git_parse_err("oversized patch hunk header at line %"PRIuZ,
533
+ ctx->parse_ctx.line_num);
541
534
 
542
535
  memcpy(hunk->hunk.header, header_start, hunk->hunk.header_len);
543
536
  hunk->hunk.header[hunk->hunk.header_len] = '\0';
@@ -546,7 +539,7 @@ static int parse_hunk_header(
546
539
 
547
540
  fail:
548
541
  giterr_set(GITERR_PATCH, "invalid patch hunk header at line %"PRIuZ,
549
- ctx->line_num);
542
+ ctx->parse_ctx.line_num);
550
543
  return -1;
551
544
  }
552
545
 
@@ -562,23 +555,27 @@ static int parse_hunk_body(
562
555
  int newlines = hunk->hunk.new_lines;
563
556
 
564
557
  for (;
565
- ctx->remain_len > 1 &&
558
+ ctx->parse_ctx.remain_len > 1 &&
566
559
  (oldlines || newlines) &&
567
- (ctx->remain_len <= 4 || memcmp(ctx->line, "@@ -", 4) != 0);
568
- parse_advance_line(ctx)) {
560
+ !git_parse_ctx_contains_s(&ctx->parse_ctx, "@@ -");
561
+ git_parse_advance_line(&ctx->parse_ctx)) {
569
562
 
563
+ char c;
570
564
  int origin;
571
565
  int prefix = 1;
572
566
 
573
- if (ctx->line_len == 0 || ctx->line[ctx->line_len - 1] != '\n') {
574
- error = parse_err("invalid patch instruction at line %"PRIuZ,
575
- ctx->line_num);
567
+ if (ctx->parse_ctx.line_len == 0 || ctx->parse_ctx.line[ctx->parse_ctx.line_len - 1] != '\n') {
568
+ error = git_parse_err("invalid patch instruction at line %"PRIuZ,
569
+ ctx->parse_ctx.line_num);
576
570
  goto done;
577
571
  }
578
572
 
579
- switch (ctx->line[0]) {
573
+ git_parse_peek(&c, &ctx->parse_ctx, 0);
574
+
575
+ switch (c) {
580
576
  case '\n':
581
577
  prefix = 0;
578
+ /* fall through */
582
579
 
583
580
  case ' ':
584
581
  origin = GIT_DIFF_LINE_CONTEXT;
@@ -597,7 +594,7 @@ static int parse_hunk_body(
597
594
  break;
598
595
 
599
596
  default:
600
- error = parse_err("invalid patch hunk at line %"PRIuZ, ctx->line_num);
597
+ error = git_parse_err("invalid patch hunk at line %"PRIuZ, ctx->parse_ctx.line_num);
601
598
  goto done;
602
599
  }
603
600
 
@@ -606,16 +603,16 @@ static int parse_hunk_body(
606
603
 
607
604
  memset(line, 0x0, sizeof(git_diff_line));
608
605
 
609
- line->content = ctx->line + prefix;
610
- line->content_len = ctx->line_len - prefix;
611
- line->content_offset = ctx->content_len - ctx->remain_len;
606
+ line->content = ctx->parse_ctx.line + prefix;
607
+ line->content_len = ctx->parse_ctx.line_len - prefix;
608
+ line->content_offset = ctx->parse_ctx.content_len - ctx->parse_ctx.remain_len;
612
609
  line->origin = origin;
613
610
 
614
611
  hunk->line_count++;
615
612
  }
616
613
 
617
614
  if (oldlines || newlines) {
618
- error = parse_err(
615
+ error = git_parse_err(
619
616
  "invalid patch hunk, expected %d old lines and %d new lines",
620
617
  hunk->hunk.old_lines, hunk->hunk.new_lines);
621
618
  goto done;
@@ -626,19 +623,19 @@ static int parse_hunk_body(
626
623
  * localized. Because `diff` optimizes for the case where you
627
624
  * want to apply the patch by hand.
628
625
  */
629
- if (parse_ctx_contains_s(ctx, "\\ ") &&
626
+ if (git_parse_ctx_contains_s(&ctx->parse_ctx, "\\ ") &&
630
627
  git_array_size(patch->base.lines) > 0) {
631
628
 
632
629
  line = git_array_get(patch->base.lines, git_array_size(patch->base.lines) - 1);
633
630
 
634
631
  if (line->content_len < 1) {
635
- error = parse_err("cannot trim trailing newline of empty line");
632
+ error = git_parse_err("cannot trim trailing newline of empty line");
636
633
  goto done;
637
634
  }
638
635
 
639
636
  line->content_len--;
640
637
 
641
- parse_advance_line(ctx);
638
+ git_parse_advance_line(&ctx->parse_ctx);
642
639
  }
643
640
 
644
641
  done:
@@ -651,18 +648,15 @@ static int parse_patch_header(
651
648
  {
652
649
  int error = 0;
653
650
 
654
- for (ctx->line = ctx->remain;
655
- ctx->remain_len > 0;
656
- parse_advance_line(ctx)) {
657
-
651
+ for (; ctx->parse_ctx.remain_len > 0; git_parse_advance_line(&ctx->parse_ctx)) {
658
652
  /* This line is too short to be a patch header. */
659
- if (ctx->line_len < 6)
653
+ if (ctx->parse_ctx.line_len < 6)
660
654
  continue;
661
655
 
662
656
  /* This might be a hunk header without a patch header, provide a
663
657
  * sensible error message. */
664
- if (parse_ctx_contains_s(ctx, "@@ -")) {
665
- size_t line_num = ctx->line_num;
658
+ if (git_parse_ctx_contains_s(&ctx->parse_ctx, "@@ -")) {
659
+ size_t line_num = ctx->parse_ctx.line_num;
666
660
  git_patch_hunk hunk;
667
661
 
668
662
  /* If this cannot be parsed as a hunk header, it's just leading
@@ -673,17 +667,17 @@ static int parse_patch_header(
673
667
  continue;
674
668
  }
675
669
 
676
- error = parse_err("invalid hunk header outside patch at line %"PRIuZ,
670
+ error = git_parse_err("invalid hunk header outside patch at line %"PRIuZ,
677
671
  line_num);
678
672
  goto done;
679
673
  }
680
674
 
681
675
  /* This buffer is too short to contain a patch. */
682
- if (ctx->remain_len < ctx->line_len + 6)
676
+ if (ctx->parse_ctx.remain_len < ctx->parse_ctx.line_len + 6)
683
677
  break;
684
678
 
685
679
  /* A proper git patch */
686
- if (parse_ctx_contains_s(ctx, "diff --git ")) {
680
+ if (git_parse_ctx_contains_s(&ctx->parse_ctx, "diff --git ")) {
687
681
  error = parse_header_git(patch, ctx);
688
682
  goto done;
689
683
  }
@@ -708,27 +702,30 @@ static int parse_patch_binary_side(
708
702
  git_off_t len;
709
703
  int error = 0;
710
704
 
711
- if (parse_ctx_contains_s(ctx, "literal ")) {
705
+ if (git_parse_ctx_contains_s(&ctx->parse_ctx, "literal ")) {
712
706
  type = GIT_DIFF_BINARY_LITERAL;
713
- parse_advance_chars(ctx, 8);
714
- } else if (parse_ctx_contains_s(ctx, "delta ")) {
707
+ git_parse_advance_chars(&ctx->parse_ctx, 8);
708
+ } else if (git_parse_ctx_contains_s(&ctx->parse_ctx, "delta ")) {
715
709
  type = GIT_DIFF_BINARY_DELTA;
716
- parse_advance_chars(ctx, 6);
710
+ git_parse_advance_chars(&ctx->parse_ctx, 6);
717
711
  } else {
718
- error = parse_err(
719
- "unknown binary delta type at line %"PRIuZ, ctx->line_num);
712
+ error = git_parse_err(
713
+ "unknown binary delta type at line %"PRIuZ, ctx->parse_ctx.line_num);
720
714
  goto done;
721
715
  }
722
716
 
723
- if (parse_number(&len, ctx) < 0 || parse_advance_nl(ctx) < 0 || len < 0) {
724
- error = parse_err("invalid binary size at line %"PRIuZ, ctx->line_num);
717
+ if (git_parse_advance_digit(&len, &ctx->parse_ctx, 10) < 0 ||
718
+ git_parse_advance_nl(&ctx->parse_ctx) < 0 || len < 0) {
719
+ error = git_parse_err("invalid binary size at line %"PRIuZ, ctx->parse_ctx.line_num);
725
720
  goto done;
726
721
  }
727
722
 
728
- while (ctx->line_len) {
729
- char c = ctx->line[0];
723
+ while (ctx->parse_ctx.line_len) {
724
+ char c;
730
725
  size_t encoded_len, decoded_len = 0, decoded_orig = decoded.size;
731
726
 
727
+ git_parse_peek(&c, &ctx->parse_ctx, 0);
728
+
732
729
  if (c == '\n')
733
730
  break;
734
731
  else if (c >= 'A' && c <= 'Z')
@@ -737,32 +734,32 @@ static int parse_patch_binary_side(
737
734
  decoded_len = c - 'a' + (('z' - 'a') + 1) + 1;
738
735
 
739
736
  if (!decoded_len) {
740
- error = parse_err("invalid binary length at line %"PRIuZ, ctx->line_num);
737
+ error = git_parse_err("invalid binary length at line %"PRIuZ, ctx->parse_ctx.line_num);
741
738
  goto done;
742
739
  }
743
740
 
744
- parse_advance_chars(ctx, 1);
741
+ git_parse_advance_chars(&ctx->parse_ctx, 1);
745
742
 
746
743
  encoded_len = ((decoded_len / 4) + !!(decoded_len % 4)) * 5;
747
744
 
748
- if (encoded_len > ctx->line_len - 1) {
749
- error = parse_err("truncated binary data at line %"PRIuZ, ctx->line_num);
745
+ if (encoded_len > ctx->parse_ctx.line_len - 1) {
746
+ error = git_parse_err("truncated binary data at line %"PRIuZ, ctx->parse_ctx.line_num);
750
747
  goto done;
751
748
  }
752
749
 
753
750
  if ((error = git_buf_decode_base85(
754
- &decoded, ctx->line, encoded_len, decoded_len)) < 0)
751
+ &decoded, ctx->parse_ctx.line, encoded_len, decoded_len)) < 0)
755
752
  goto done;
756
753
 
757
754
  if (decoded.size - decoded_orig != decoded_len) {
758
- error = parse_err("truncated binary data at line %"PRIuZ, ctx->line_num);
755
+ error = git_parse_err("truncated binary data at line %"PRIuZ, ctx->parse_ctx.line_num);
759
756
  goto done;
760
757
  }
761
758
 
762
- parse_advance_chars(ctx, encoded_len);
759
+ git_parse_advance_chars(&ctx->parse_ctx, encoded_len);
763
760
 
764
- if (parse_advance_nl(ctx) < 0) {
765
- error = parse_err("trailing data at line %"PRIuZ, ctx->line_num);
761
+ if (git_parse_advance_nl(&ctx->parse_ctx) < 0) {
762
+ error = git_parse_err("trailing data at line %"PRIuZ, ctx->parse_ctx.line_num);
766
763
  goto done;
767
764
  }
768
765
  }
@@ -784,27 +781,27 @@ static int parse_patch_binary(
784
781
  {
785
782
  int error;
786
783
 
787
- if (parse_advance_expected_str(ctx, "GIT binary patch") < 0 ||
788
- parse_advance_nl(ctx) < 0)
789
- return parse_err("corrupt git binary header at line %"PRIuZ, ctx->line_num);
784
+ if (git_parse_advance_expected_str(&ctx->parse_ctx, "GIT binary patch") < 0 ||
785
+ git_parse_advance_nl(&ctx->parse_ctx) < 0)
786
+ return git_parse_err("corrupt git binary header at line %"PRIuZ, ctx->parse_ctx.line_num);
790
787
 
791
788
  /* parse old->new binary diff */
792
789
  if ((error = parse_patch_binary_side(
793
790
  &patch->base.binary.new_file, ctx)) < 0)
794
791
  return error;
795
792
 
796
- if (parse_advance_nl(ctx) < 0)
797
- return parse_err("corrupt git binary separator at line %"PRIuZ,
798
- ctx->line_num);
793
+ if (git_parse_advance_nl(&ctx->parse_ctx) < 0)
794
+ return git_parse_err("corrupt git binary separator at line %"PRIuZ,
795
+ ctx->parse_ctx.line_num);
799
796
 
800
797
  /* parse new->old binary diff */
801
798
  if ((error = parse_patch_binary_side(
802
799
  &patch->base.binary.old_file, ctx)) < 0)
803
800
  return error;
804
801
 
805
- if (parse_advance_nl(ctx) < 0)
806
- return parse_err("corrupt git binary patch separator at line %"PRIuZ,
807
- ctx->line_num);
802
+ if (git_parse_advance_nl(&ctx->parse_ctx) < 0)
803
+ return git_parse_err("corrupt git binary patch separator at line %"PRIuZ,
804
+ ctx->parse_ctx.line_num);
808
805
 
809
806
  patch->base.binary.contains_data = 1;
810
807
  patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY;
@@ -815,13 +812,13 @@ static int parse_patch_binary_nodata(
815
812
  git_patch_parsed *patch,
816
813
  git_patch_parse_ctx *ctx)
817
814
  {
818
- if (parse_advance_expected_str(ctx, "Binary files ") < 0 ||
819
- parse_advance_expected_str(ctx, patch->header_old_path) < 0 ||
820
- parse_advance_expected_str(ctx, " and ") < 0 ||
821
- parse_advance_expected_str(ctx, patch->header_new_path) < 0 ||
822
- parse_advance_expected_str(ctx, " differ") < 0 ||
823
- parse_advance_nl(ctx) < 0)
824
- return parse_err("corrupt git binary header at line %"PRIuZ, ctx->line_num);
815
+ if (git_parse_advance_expected_str(&ctx->parse_ctx, "Binary files ") < 0 ||
816
+ git_parse_advance_expected_str(&ctx->parse_ctx, patch->header_old_path) < 0 ||
817
+ git_parse_advance_expected_str(&ctx->parse_ctx, " and ") < 0 ||
818
+ git_parse_advance_expected_str(&ctx->parse_ctx, patch->header_new_path) < 0 ||
819
+ git_parse_advance_expected_str(&ctx->parse_ctx, " differ") < 0 ||
820
+ git_parse_advance_nl(&ctx->parse_ctx) < 0)
821
+ return git_parse_err("corrupt git binary header at line %"PRIuZ, ctx->parse_ctx.line_num);
825
822
 
826
823
  patch->base.binary.contains_data = 0;
827
824
  patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY;
@@ -835,7 +832,7 @@ static int parse_patch_hunks(
835
832
  git_patch_hunk *hunk;
836
833
  int error = 0;
837
834
 
838
- while (parse_ctx_contains_s(ctx, "@@ -")) {
835
+ while (git_parse_ctx_contains_s(&ctx->parse_ctx, "@@ -")) {
839
836
  hunk = git_array_alloc(patch->base.hunks);
840
837
  GITERR_CHECK_ALLOC(hunk);
841
838
 
@@ -858,9 +855,9 @@ done:
858
855
  static int parse_patch_body(
859
856
  git_patch_parsed *patch, git_patch_parse_ctx *ctx)
860
857
  {
861
- if (parse_ctx_contains_s(ctx, "GIT binary patch"))
858
+ if (git_parse_ctx_contains_s(&ctx->parse_ctx, "GIT binary patch"))
862
859
  return parse_patch_binary(patch, ctx);
863
- else if (parse_ctx_contains_s(ctx, "Binary files "))
860
+ else if (git_parse_ctx_contains_s(&ctx->parse_ctx, "Binary files "))
864
861
  return parse_patch_binary_nodata(patch, ctx);
865
862
  else
866
863
  return parse_patch_hunks(patch, ctx);
@@ -876,10 +873,10 @@ int check_header_names(
876
873
  return 0;
877
874
 
878
875
  if (two_null && strcmp(two, "/dev/null") != 0)
879
- return parse_err("expected %s path of '/dev/null'", old_or_new);
876
+ return git_parse_err("expected %s path of '/dev/null'", old_or_new);
880
877
 
881
878
  else if (!two_null && strcmp(one, two) != 0)
882
- return parse_err("mismatched %s path names", old_or_new);
879
+ return git_parse_err("mismatched %s path names", old_or_new);
883
880
 
884
881
  return 0;
885
882
  }
@@ -912,7 +909,7 @@ static int check_prefix(
912
909
  }
913
910
 
914
911
  if (remain_len || !*path)
915
- return parse_err(
912
+ return git_parse_err(
916
913
  "header filename does not contain %"PRIuZ" path components",
917
914
  prefix_len);
918
915
 
@@ -931,10 +928,10 @@ static int check_filenames(git_patch_parsed *patch)
931
928
  bool deleted = (patch->base.delta->status == GIT_DELTA_DELETED);
932
929
 
933
930
  if (patch->old_path && !patch->new_path)
934
- return parse_err("missing new path");
931
+ return git_parse_err("missing new path");
935
932
 
936
933
  if (!patch->old_path && patch->new_path)
937
- return parse_err("missing old path");
934
+ return git_parse_err("missing old path");
938
935
 
939
936
  /* Ensure (non-renamed) paths match */
940
937
  if (check_header_names(
@@ -967,7 +964,7 @@ static int check_filenames(git_patch_parsed *patch)
967
964
 
968
965
  if (!patch->base.delta->old_file.path &&
969
966
  !patch->base.delta->new_file.path)
970
- return parse_err("git diff header lacks old / new paths");
967
+ return git_parse_err("git diff header lacks old / new paths");
971
968
 
972
969
  return 0;
973
970
  }
@@ -988,7 +985,7 @@ static int check_patch(git_patch_parsed *patch)
988
985
  !(delta->flags & GIT_DIFF_FLAG_BINARY) &&
989
986
  delta->new_file.mode == delta->old_file.mode &&
990
987
  git_array_size(patch->base.hunks) == 0)
991
- return parse_err("patch with no hunks");
988
+ return git_parse_err("patch with no hunks");
992
989
 
993
990
  if (delta->status == GIT_DELTA_ADDED) {
994
991
  memset(&delta->old_file.id, 0x0, sizeof(git_oid));
@@ -1014,19 +1011,11 @@ git_patch_parse_ctx *git_patch_parse_ctx_init(
1014
1011
  if ((ctx = git__calloc(1, sizeof(git_patch_parse_ctx))) == NULL)
1015
1012
  return NULL;
1016
1013
 
1017
- if (content_len) {
1018
- if ((ctx->content = git__malloc(content_len)) == NULL) {
1019
- git__free(ctx);
1020
- return NULL;
1021
- }
1022
-
1023
- memcpy((char *)ctx->content, content, content_len);
1014
+ if ((git_parse_ctx_init(&ctx->parse_ctx, content, content_len)) < 0) {
1015
+ git__free(ctx);
1016
+ return NULL;
1024
1017
  }
1025
1018
 
1026
- ctx->content_len = content_len;
1027
- ctx->remain = ctx->content;
1028
- ctx->remain_len = ctx->content_len;
1029
-
1030
1019
  if (opts)
1031
1020
  memcpy(&ctx->opts, opts, sizeof(git_patch_options));
1032
1021
  else
@@ -1041,7 +1030,7 @@ static void patch_parse_ctx_free(git_patch_parse_ctx *ctx)
1041
1030
  if (!ctx)
1042
1031
  return;
1043
1032
 
1044
- git__free((char *)ctx->content);
1033
+ git_parse_ctx_clear(&ctx->parse_ctx);
1045
1034
  git__free(ctx);
1046
1035
  }
1047
1036
 
@@ -1116,21 +1105,21 @@ int git_patch_parse(
1116
1105
  patch->base.delta->status = GIT_DELTA_MODIFIED;
1117
1106
  patch->base.delta->nfiles = 2;
1118
1107
 
1119
- start = ctx->remain_len;
1108
+ start = ctx->parse_ctx.remain_len;
1120
1109
 
1121
1110
  if ((error = parse_patch_header(patch, ctx)) < 0 ||
1122
1111
  (error = parse_patch_body(patch, ctx)) < 0 ||
1123
1112
  (error = check_patch(patch)) < 0)
1124
1113
  goto done;
1125
1114
 
1126
- used = start - ctx->remain_len;
1127
- ctx->remain += used;
1115
+ used = start - ctx->parse_ctx.remain_len;
1116
+ ctx->parse_ctx.remain += used;
1128
1117
 
1129
1118
  patch->base.diff_opts.old_prefix = patch->old_prefix;
1130
1119
  patch->base.diff_opts.new_prefix = patch->new_prefix;
1131
1120
  patch->base.diff_opts.flags |= GIT_DIFF_SHOW_BINARY;
1132
1121
 
1133
- GIT_REFCOUNT_INC(patch);
1122
+ GIT_REFCOUNT_INC(&patch->base);
1134
1123
  *out = &patch->base;
1135
1124
 
1136
1125
  done: