├── .github └── workflows │ └── main.yml ├── .gitignore ├── Gemfile ├── LICENCE ├── README.md ├── Rakefile ├── TODO.txt ├── bin └── cm ├── docurium.gemspec ├── lib ├── docurium.rb ├── docurium │ ├── cli.rb │ ├── cparser.rb │ ├── css.css │ ├── debug.rb │ ├── docparser.rb │ ├── layout.mustache │ ├── layout.rb │ └── version.rb └── libdetect.rb ├── site ├── css │ └── style.css ├── images │ └── search_icon.png ├── index.html ├── js │ ├── backbone.js │ ├── docurium.js │ ├── json2.js │ └── underscore.js └── shared │ ├── css │ ├── documentation.css │ └── pygments.css │ ├── images │ ├── active-arrow.png │ ├── background-v2.png │ ├── background-white.png │ ├── dropdown_sprites.jpg │ ├── footer_logo.png │ ├── logo.png │ ├── nav-rule.png │ ├── next_step_arrow.gif │ └── qmark.png │ └── js │ └── jquery.js └── test ├── docurium_test.rb ├── fixtures └── git2 │ ├── api.docurium │ ├── blob.h │ ├── callback.h │ ├── cherrypick.h │ ├── commit.h │ ├── common.h │ ├── errors.h │ ├── index.h │ ├── object.h │ ├── odb.h │ ├── odb_backend.h │ ├── oid.h │ ├── refs.h │ ├── repository.h │ ├── revwalk.h │ ├── signature.h │ ├── tag.h │ ├── thread-utils.h │ ├── tree.h │ └── types.h ├── gen_test.rb ├── parser_test.rb └── test_helper.rb /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Docurium 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | test: 11 | 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | ruby: [head, 3.0, 2.7, 2.6] 16 | llvm: ["6.0", 7, 8, 9, 10] 17 | os: [ ubuntu-18.04 ] 18 | include: 19 | - os: macos-latest 20 | ruby: 2.6 21 | llvm: ~ # system 22 | 23 | name: Ruby ${{ matrix.ruby }} / LLVM ${{ matrix.llvm }} on ${{ matrix.os }} 24 | runs-on: ${{ matrix.os }} 25 | continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }} 26 | 27 | steps: 28 | - uses: actions/checkout@v2 29 | - name: Install Linux packages 30 | if: runner.os == 'Linux' 31 | run: | 32 | sudo apt update 33 | sudo apt install -y python-pygments libclang-${{ matrix.llvm }}-dev llvm-${{ matrix.llvm }} clang-${{ matrix.llvm }} 34 | - name: Set up Ruby ${{ matrix.ruby }} 35 | uses: ruby/setup-ruby@v1 36 | with: 37 | ruby-version: ${{ matrix.ruby }} 38 | bundler-cache: true 39 | - name: Run tests 40 | run: | 41 | [ -x /usr/bin/llvm-config-${{ matrix.llvm }} ] && export LLVM_CONFIG=llvm-config-${{ matrix.llvm }} 42 | bundle exec rake 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | docs/ 2 | site/*.json 3 | *.gem 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.0.0') 4 | platforms :rbx do 5 | gem 'rubysl', '~> 2.2' 6 | end 7 | end 8 | 9 | gemspec 10 | 11 | # vim:ft=ruby 12 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Scott Chacon 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docurium 2 | 3 | Docurium is a lightweight Doxygen replacement. It generates static HTML from the header files of a C project. It is meant to be simple, easy to navigate and git-tag aware. It is only meant to document your public interface, so it only knows about your header files. 4 | 5 | I built it to replace the Doxygen generated documentation for the libgit2 project, so I'm only currently testing it against that. So, it is only known to include support for features and keywords used in that project currently. If you have a C library project you try this on and something is amiss, please file an issue or better yet, a pull request. 6 | 7 | Though Docurium can generate your docs into a subdirectory, it is meant to be served from a webserver, not locally. It uses XMLHttpRequest calls, which cannot be done locally, so you can't just open the index.html file locally and have it work - you need to either run a webserver in the output directory or push it to a website to view it properly. I use Pow (pow.cx) or GitHub Pages. 8 | 9 | # Usage 10 | 11 | Run the `cm` binary and pass it your Docurium config file. 12 | 13 | $ cm doc api.docurium 14 | * generating docs 15 | - processing version v0.1.0 16 | - processing version v0.2.0 17 | - processing version v0.3.0 18 | - processing version v0.8.0 19 | - processing version v0.10.0 20 | - processing version v0.11.0 21 | - processing version v0.12.0 22 | - processing version HEAD 23 | * checking your api 24 | - unmatched params in 25 | git_commit_create 26 | git_config_set_int 27 | git_object_lookup_prefix 28 | - signature changes in 29 | git_index_get 30 | git_repository_path 31 | git_tree_entry_byindex 32 | * writing to branch gh-pages 33 | wrote tree 87f0f3cb1622b9dc3d6d5d39106e863608b3b504 34 | wrote commit 5cee46f4d491e9611abab218604db893b70202f3 35 | updated gh-pages 36 | 37 | Docurium will tell you if you have unmatched @params entries in header docs and if you've changed signatures in functions in HEAD, just to help you know what's happening and if you've written your docs properly. 38 | 39 | The Docurium config file looks like this: 40 | 41 | { 42 | "name": "libgit2", 43 | "github": "libgit2/libgit2", 44 | "input": "include/git2", 45 | "prefix": "git_", 46 | "branch": "gh-pages", 47 | "examples": "examples", 48 | "legacy": { 49 | "input": {"src/git": ["v0.1.0"], 50 | "src/git2": ["v0.2.0", "v0.3.0"]} 51 | } 52 | } 53 | 54 | Docurium will write your docs directly into the specified Git branch. 55 | 56 | # Installing 57 | 58 | $ gem install docurium 59 | 60 | # Contributing 61 | 62 | If you want to fix or change something, please fork on GitHub, push your change to a branch named after your change and send me a pull request. 63 | 64 | # License 65 | 66 | MIT, see LICENCE file 67 | 68 | 69 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake/testtask' 2 | require 'rubygems' 3 | require 'rubygems/package_task' 4 | 5 | task :default => :test 6 | 7 | gemspec = Gem::Specification::load(File.expand_path('../docurium.gemspec', __FILE__)) 8 | Gem::PackageTask.new(gemspec) do |pkg| 9 | end 10 | 11 | Rake::TestTask.new do |t| 12 | t.libs << 'libs' << 'test' 13 | t.pattern = 'test/**/*_test.rb' 14 | end 15 | -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | TODO 2 | 3 | * broken changelog & index page highlighting 4 | 5 | 6 | * version history for types, too 7 | 8 | * only update certain tags / HEAD, force full update 9 | 10 | * doc other branches (specify in config file) 11 | 12 | * highlight menu item when selected 13 | 14 | -------------------------------------------------------------------------------- /bin/cm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib' 3 | 4 | require 'rubygems' 5 | require 'gli' 6 | require 'docurium' 7 | require 'docurium/cli' 8 | 9 | include GLI::App 10 | 11 | version Docurium::Version 12 | 13 | desc 'Generate HTML documentation' 14 | long_desc 'Generate HTML docs from a Docurium config file' 15 | command :doc do |c| 16 | c.flag :for, :desc => "The version to generate", :multiple => true 17 | c.switch [:n, "dry-run"], :desc => "Dry-run" 18 | c.switch [:d, "debug"], :desc => "Enable debug log" 19 | c.flag "debug-file", :desc => "Enable debug output for header", :multiple => true 20 | c.flag "debug-function", :desc => "Show debug output when processing function", :multiple => true 21 | c.flag "debug-type", :desc => "Show debug output when processing type", :multiple => true 22 | c.action do |global_options,options,args| 23 | file = args.first 24 | Docurium::CLI.doc(file, options) 25 | end 26 | end 27 | 28 | desc 'Check documentation for warnings' 29 | long_desc 'Check a project\'s documentation for issues' 30 | command :check do |c| 31 | c.action do |global_options,options,args| 32 | file = args.first 33 | Docurium::CLI.check(file, options) 34 | end 35 | end 36 | 37 | desc 'Generate Docurium config file template' 38 | long_desc 'Generate Docurium config file template' 39 | command :gen do |c| 40 | c.action do |global_options,options,args| 41 | file = args.first || 'api.docurium' 42 | Docurium::CLI.gen(file) 43 | end 44 | end 45 | 46 | 47 | pre { |global,command,options,args| true } 48 | 49 | post { |global,command,options,args| true } 50 | 51 | on_error do |exception| 52 | if !exception.is_a?(SystemExit) 53 | puts exception 54 | puts exception.backtrace 55 | end 56 | end 57 | 58 | exit run(ARGV) 59 | -------------------------------------------------------------------------------- /docurium.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require 'docurium/version' 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "docurium" 7 | s.version = Docurium::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.authors = ["Carlos Martín Nieto", "Scott Chacon"] 10 | s.email = ["cmn@dwim.me", "schacon@gmail.com"] 11 | s.homepage = "https://github.com/libgit2/docurium" 12 | s.summary = "A simpler, prettier Doxygen replacement." 13 | s.description = s.summary 14 | s.license = 'MIT' 15 | 16 | s.add_dependency "version_sorter", "~>2.0" 17 | s.add_dependency "mustache", "~> 1.1" 18 | s.add_dependency "rocco", "~>0.8" 19 | s.add_dependency "gli", "~>2.5" 20 | s.add_dependency "rugged", "~>1.1" 21 | s.add_dependency "redcarpet", "~>3.0" 22 | s.add_dependency "ffi-clang", "~> 0.5" 23 | s.add_dependency "parallel", "~> 1.20" 24 | s.add_development_dependency "rake", "~> 13" 25 | s.add_development_dependency "minitest", "~> 5.11" 26 | 27 | s.files = `git ls-files`.split("\n") 28 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 29 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 30 | s.require_paths = ["lib"] 31 | end 32 | 33 | -------------------------------------------------------------------------------- /lib/docurium/cli.rb: -------------------------------------------------------------------------------- 1 | class Docurium 2 | class CLI 3 | 4 | def self.doc(idir, options) 5 | doc = Docurium.new(idir, options) 6 | doc.generate_docs 7 | end 8 | 9 | def self.check(idir, options) 10 | doc = Docurium.new(idir) 11 | doc.check_warnings(options) 12 | end 13 | 14 | def self.gen(file) 15 | 16 | temp = <<-TEMPLATE 17 | { 18 | "name": "project", 19 | "github": "user/project", 20 | "input": "include/lib", 21 | "prefix": "lib_", 22 | "branch": "gh-pages" 23 | } 24 | TEMPLATE 25 | puts "Writing to #{file}" 26 | File.open(file, 'w+') do |f| 27 | f.write(temp) 28 | end 29 | end 30 | 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/docurium/cparser.rb: -------------------------------------------------------------------------------- 1 | class Docurium 2 | class CParser 3 | 4 | # Remove common prefix of all lines in comment. 5 | # Otherwise tries to preserve formatting in case it is relevant. 6 | def cleanup_comment(comment) 7 | return "" unless comment 8 | 9 | lines = 0 10 | prefixed = 0 11 | shortest = nil 12 | 13 | compacted = comment.sub(/^\n+/,"").sub(/\n\s*$/, "\n") 14 | 15 | compacted.split(/\n/).each do |line| 16 | lines += 1 17 | if line =~ /^\s*\*\s*$/ || line =~ /^\s*$/ 18 | # don't count length of blank lines or lines with just a " * " on 19 | # them towards shortest common prefix 20 | prefixed += 1 21 | shortest = line if shortest.nil? 22 | elsif line =~ /^(\s*\*\s*)/ 23 | prefixed += 1 24 | shortest = $1 if shortest.nil? || shortest.length > $1.length 25 | end 26 | end 27 | 28 | if shortest =~ /\s$/ 29 | shortest = Regexp.quote(shortest.chop) + "[ \t]" 30 | elsif shortest 31 | shortest = Regexp.quote(shortest) 32 | end 33 | 34 | if lines == prefixed && !shortest.nil? && shortest.length > 0 35 | if shortest =~ /\*/ 36 | return comment.gsub(/^#{shortest}/, "").gsub(/^\s*\*\s*\n/, "\n") 37 | else 38 | return comment.gsub(/^#{shortest}/, "") 39 | end 40 | else 41 | return comment 42 | end 43 | end 44 | 45 | # Find the shortest common prefix of an array of strings 46 | def shortest_common_prefix(arr) 47 | arr.inject do |pfx,str| 48 | pfx = pfx.chop while pfx != str[0...pfx.length]; pfx 49 | end 50 | end 51 | 52 | # Match #define A(B) or #define A 53 | # and convert a series of simple #defines into an enum 54 | def detect_define(d) 55 | if d[:body] =~ /\A\#\s*define\s+((\w+)\([^\)]+\))/ 56 | d[:type] = :macro 57 | d[:decl] = $1.strip 58 | d[:name] = $2 59 | d[:tdef] = nil 60 | elsif d[:body] =~ /\A\#\s*define\s+(\w+)/ 61 | names = [] 62 | d[:body].scan(/\#\s*define\s+(\w+)/) { |m| names << m[0].to_s } 63 | d[:tdef] = nil 64 | names.uniq! 65 | if names.length == 1 66 | d[:type] = :define 67 | d[:decl] = names[0] 68 | d[:name] = names[0] 69 | elsif names.length > 1 70 | d[:type] = :enum 71 | d[:decl] = names 72 | d[:name] = shortest_common_prefix(names) 73 | d[:name].sub!(/_*$/, '') 74 | end 75 | end 76 | end 77 | 78 | # Take a multi-line #define and join into a simple definition 79 | def join_define(text) 80 | text = text.split("\n\n", 2).first || "" 81 | 82 | # Ruby 1.8 does not support negative lookbehind regex so let's 83 | # get the joined macro definition a slightly more awkward way 84 | text.split(/\s*\n\s*/).inject("\\") do |val, line| 85 | (val[-1] == ?\\) ? val = val.chop.strip + " " + line : val 86 | end.strip.gsub(/^\s*\\*\s*/, '') 87 | end 88 | 89 | # Process #define A(B) macros 90 | def parse_macro(d) 91 | if d[:body] =~ /define\s+#{Regexp.quote(d[:name])}\([^\)]*\)[ \t]*(.*)/m 92 | d[:value] = join_define($1) 93 | end 94 | d[:comments] = d[:rawComments].strip 95 | end 96 | 97 | # Process #define A ... macros 98 | def parse_define(d) 99 | if d[:body] =~ /define\s+#{Regexp.quote(d[:name])}[ \t]*(.*)/ 100 | d[:value] = join_define($1) 101 | end 102 | d[:comments] = d[:rawComments].strip 103 | end 104 | 105 | # Match enum {} (and possibly a typedef thereof) 106 | def detect_enum(d) 107 | if d[:body] =~ /\A(typedef)?\s*enum\s*\{([^\}]+)\}\s*([^;]+)?;/i 108 | typedef, values, name = $1, $2, $3 109 | d[:type] = :enum 110 | d[:decl] = values.strip.split(/\s*,\s*/).map do |v| 111 | v.split(/\s*=\s*/)[0].strip 112 | end 113 | if typedef.nil? 114 | d[:name] = shortest_common_prefix(d[:decl]) 115 | d[:name].sub!(/_*$/, '') 116 | # Using the common prefix for grouping enum values is a little 117 | # overly aggressive in some cases. If we ended up with too short 118 | # a prefix or a prefix which is too generic, then skip it. 119 | d[:name] = nil unless d[:name].scan('_').length > 1 120 | else 121 | d[:name] = name 122 | end 123 | d[:tdef] = typedef 124 | end 125 | end 126 | 127 | # Process enum definitions 128 | def parse_enum(d) 129 | if d[:decl].respond_to? :map 130 | d[:block] = d[:decl].map { |v| v.strip }.join("\n") 131 | else 132 | d[:block] = d[:decl] 133 | end 134 | d[:comments] = d[:rawComments].strip 135 | end 136 | 137 | # Match struct {} (and typedef thereof) or opaque struct typedef 138 | def detect_struct(d) 139 | if d[:body] =~ /\A(typedef)?\s*struct\s*(\w+)?\s*\{([^\}]+)\}\s*([^;]+)?/i 140 | typedef, name1, fields, name2 = $1, $2, $3, $4 141 | d[:type] = :struct 142 | d[:name] = typedef.nil? ? name1 : name2; 143 | d[:tdef] = typedef 144 | d[:decl] = fields.strip.split(/\s*\;\s*/).map do |x| 145 | x.strip.gsub(/\s+/, " ").gsub(/\(\s+/,"(") 146 | end 147 | elsif d[:body] =~ /\A(typedef)\s+struct\s+\w+\s+(\w+)/ 148 | d[:type] = :struct 149 | d[:decl] = "" 150 | d[:name] = $2 151 | d[:tdef] = $1 152 | end 153 | end 154 | 155 | # Process struct definition 156 | def parse_struct(d) 157 | if d[:decl].respond_to? :map 158 | d[:block] = d[:decl].map { |v| v.strip }.join("\n") 159 | else 160 | d[:block] = d[:decl] 161 | end 162 | d[:comments] = d[:rawComments].strip 163 | end 164 | 165 | # Match other typedefs, checking explicitly for function pointers 166 | # but otherwise just trying to extract a name as simply as possible. 167 | def detect_typedef(d) 168 | if d[:body] =~ /\Atypedef\s+([^;]+);/ 169 | d[:decl] = $1.strip 170 | if d[:decl] =~ /\S+\s+\(\*([^\)]+)\)\(/ 171 | d[:type] = :fnptr 172 | d[:name] = $1 173 | else 174 | d[:type] = :typedef 175 | d[:name] = d[:decl].split(/\s+/).last 176 | end 177 | end 178 | end 179 | 180 | # Process typedef definition 181 | def parse_typedef(d) 182 | d[:comments] = d[:rawComments].strip 183 | end 184 | 185 | # Process function pointer typedef definition 186 | def parse_fnptr(d) 187 | d[:comments] = d[:rawComments].strip 188 | end 189 | 190 | # Match function prototypes or inline function declarations 191 | def detect_function(d) 192 | if d[:body] =~ /[;\{]/ 193 | d[:type] = :file 194 | d[:decl] = "" 195 | 196 | proto = d[:body].split(/[;\{]/, 2).first.strip 197 | if proto[-1] == ?) 198 | (proto.length - 1).downto(0) do |p| 199 | tail = proto[p .. -1] 200 | if tail.count(")") == tail.count("(") 201 | if proto[0..p] =~ /(\w+)\(\z/ 202 | d[:name] = $1 203 | d[:type] = :function 204 | d[:decl] = proto 205 | end 206 | break 207 | end 208 | end 209 | end 210 | end 211 | end 212 | 213 | # Process function prototype and comments 214 | def parse_function(d) 215 | d[:args] = [] 216 | 217 | rval, argline = d[:decl].split(/\s*#{Regexp.quote(d[:name])}\(\s*/, 2) 218 | 219 | # clean up rval if it is like "extern static int" or "GIT_EXTERN(int)" 220 | while rval =~ /[A-Za-z0-9_]+\(([^\)]+)\)$/i 221 | rval = $1 222 | end 223 | rval.gsub!(/extern|static/, '') 224 | rval.strip! 225 | d[:return] = { :type => rval } 226 | 227 | # we removed the opening parenthesis, which this is expecting 228 | argline = '(' + argline 229 | # clean up argline 230 | argline = argline.slice(1..-2) while argline[0] == ?( && argline[-1] == ?) 231 | d[:argline] = argline.strip 232 | d[:args] = [] 233 | left = 0 234 | 235 | # parse argline 236 | (0 .. argline.length).each do |i| 237 | next unless argline[i] == ?, || argline.length == i 238 | 239 | s = argline.slice(left .. i) 240 | next unless s.count("(") == s.count(")") 241 | 242 | s.chop! if argline[i] == ?, 243 | s.strip! 244 | 245 | if s =~ /\(\s*\*\s*(\w+)\s*\)\s*\(/ 246 | argname = $1 247 | d[:args] << { 248 | :name => argname, 249 | :type => s.sub(/\s*#{Regexp.quote(argname)}\s*/, '').strip 250 | } 251 | elsif s =~ /\W(\w+)$/ 252 | argname = $1 253 | d[:args] << { 254 | :name => argname, 255 | :type => s[0 ... - argname.length].strip, 256 | } 257 | else 258 | # argline is probably something like "(void)" 259 | end 260 | 261 | left = i + 1 262 | end 263 | 264 | # parse comments 265 | if d[:rawComments] =~ /\@(param|return)/i 266 | d[:args].each do |arg| 267 | param_comment = /\@param\s+#{Regexp.quote(arg[:name])}/.match(d[:rawComments]) 268 | if param_comment 269 | after = param_comment.post_match 270 | end_comment = after.index(/(?:@param|@return|\Z)/) 271 | arg[:comment] = after[0 ... end_comment].strip.gsub(/\s+/, ' ') 272 | end 273 | end 274 | 275 | return_comment = /\@return\s+/.match(d[:rawComments]) 276 | if return_comment 277 | after = return_comment.post_match 278 | d[:return][:comment] = after[0 ... after.index(/(?:@param|\Z)/)].strip.gsub(/\s+/, ' ') 279 | end 280 | else 281 | # support for TomDoc params 282 | end 283 | 284 | # add in inline parameter comments 285 | if d[:inlines] # array of [param line]/[comment] pairs 286 | d[:inlines].each do |inl| 287 | d[:args].find do |arg| 288 | if inl[0] =~ /\b#{Regexp.quote(arg[:name])}$/ 289 | arg[:comment] += "\n#{inl[1]}" 290 | end 291 | end 292 | end 293 | end 294 | 295 | # generate function signature 296 | d[:sig] = d[:args].map { |a| a[:type].to_s }.join('::') 297 | 298 | # pull off function description 299 | if d[:rawComments] =~ /^\s*(public|internal|deprecated):/i 300 | # support for TomDoc description 301 | else 302 | desc, comments = d[:rawComments].split("\n\n", 2) 303 | d[:description] = desc.strip 304 | d[:comments] = comments || "" 305 | params_start = d[:comments].index(/\s?\@(?:param|return)/) 306 | d[:comments] = d[:comments].slice(0, params_start) if params_start 307 | end 308 | end 309 | 310 | # Match otherwise unrecognized commented blocks 311 | def detect_catchall(d) 312 | d[:type] = :file 313 | d[:decl] = "" 314 | end 315 | 316 | # Process comment blocks that are only associated with the whole file. 317 | def parse_file(d) 318 | m = [] 319 | d[:brief] = m[1] if m = /@brief (.*?)$/.match(d[:rawComments]) 320 | d[:defgroup] = m[1] if m = /@defgroup (.*?)$/.match(d[:rawComments]) 321 | d[:ingroup] = m[1] if m = /@ingroup (.*?)$/.match(d[:rawComments]) 322 | comments = d[:rawComments].gsub(/^@.*$/, '').strip + "\n" 323 | if d[:comments] 324 | d[:comments] = d[:comments].strip + "\n\n" + comments 325 | else 326 | d[:comments] = comments 327 | end 328 | end 329 | 330 | # Array of detectors to execute in order 331 | DETECTORS = %w(define enum struct typedef function catchall) 332 | 333 | # Given a commented chunk of file, try to parse it. 334 | def parse_declaration_block(d) 335 | # skip uncommented declarations 336 | return unless d[:rawComments].length > 0 337 | 338 | # remove inline comments in declaration 339 | while comment = d[:body].index("/*") do 340 | end_comment = d[:body].index("*/", comment) 341 | d[:body].slice!(comment, end_comment - comment + 2) 342 | end 343 | 344 | # if there are multiple #ifdef'ed declarations, we'll just 345 | # strip out the #if/#ifdef and use the first one 346 | d[:body].sub!(/[^\n]+\n/, '') if d[:body] =~ /\A\#\s*if/ 347 | 348 | # try detectors until one assigns a :type to the declaration 349 | # it's going to be one of: 350 | # - :define -> #defines + convert a series of simple ones to :enum 351 | # - :enum -> (typedef)? enum { ... }; 352 | # - :struct -> (typedef)? struct { ... }; 353 | # - :fnptr -> typedef x (*fn)(...); 354 | # - :typedef -> typedef x y; (not enum, struct, fnptr) 355 | # - :function -> rval something(like this); 356 | # - :file -> everything else goes to "file" scope 357 | DETECTORS.find { |p| method("detect_#{p}").call(d); d.has_key?(:type) } 358 | 359 | # if we detected something, call a parser for that type of thing 360 | method("parse_#{d[:type]}").call(d) if d[:type] 361 | end 362 | 363 | # Parse a chunk of text as a header file 364 | def parse_text(filename, content) 365 | # break into comments and non-comments with line numbers 366 | content = "/** */" + content if content[0..2] != "/**" 367 | recs = [] 368 | lineno = 1 369 | openblock = false 370 | 371 | content.split(/\/\*\*/).each do |chunk| 372 | c, b = chunk.split(/[ \t]*\*\//, 2) 373 | next unless c || b 374 | 375 | lineno += c.scan("\n").length if c 376 | 377 | # special handling for /**< ... */ inline comments or 378 | # for /** ... */ inside an open block 379 | if openblock || c[0] == ?< 380 | c = c.sub(/^ filename, 410 | :line => lineno + (b.start_with?("\n") ? 1 : 0), 411 | :body => b, 412 | :rawComments => cleanup_comment(c), 413 | } 414 | 415 | lineno += b.scan("\n").length if b 416 | end 417 | 418 | # try parsers on each chunk of commented header 419 | recs.each do |r| 420 | r[:body].strip! 421 | r[:rawComments].strip! 422 | r[:lineto] = r[:line] + r[:body].scan("\n").length 423 | parse_declaration_block(r) 424 | end 425 | 426 | recs 427 | end 428 | end 429 | end 430 | -------------------------------------------------------------------------------- /lib/docurium/css.css: -------------------------------------------------------------------------------- 1 | /*--------------------- Layout and Typography ----------------------------*/ 2 | body { 3 | font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; 4 | font-size: 16px; 5 | line-height: 24px; 6 | color: #252519; 7 | margin: 0; padding: 0; 8 | } 9 | a { 10 | color: #261a3b; 11 | } 12 | a:visited { 13 | color: #261a3b; 14 | } 15 | p { 16 | margin: 0 0 15px 0; 17 | } 18 | h1, h2, h3, h4, h5, h6 { 19 | margin: 40px 0 15px 0; 20 | } 21 | h2, h3, h4, h5, h6 { 22 | margin-top: 0; 23 | } 24 | #container { 25 | position: relative; 26 | } 27 | #background { 28 | position: fixed; 29 | top: 0; left: 580px; right: 0; bottom: 0; 30 | background: #f5f5ff; 31 | border-left: 1px solid #e5e5ee; 32 | z-index: -1; 33 | } 34 | #jump_to, #jump_page { 35 | background: white; 36 | -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; 37 | -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; 38 | font: 10px Arial; 39 | text-transform: uppercase; 40 | cursor: pointer; 41 | text-align: right; 42 | } 43 | #jump_to, #jump_wrapper { 44 | position: fixed; 45 | right: 0; top: 0; 46 | padding: 5px 10px; 47 | } 48 | #jump_wrapper { 49 | padding: 0; 50 | display: none; 51 | } 52 | #jump_to:hover #jump_wrapper { 53 | display: block; 54 | } 55 | #jump_page { 56 | padding: 5px 0 3px; 57 | margin: 0 0 25px 25px; 58 | } 59 | #jump_page .source { 60 | display: block; 61 | padding: 5px 10px; 62 | text-decoration: none; 63 | border-top: 1px solid #eee; 64 | } 65 | #jump_page .source:hover { 66 | background: #f5f5ff; 67 | } 68 | #jump_page .source:first-child { 69 | } 70 | table td { 71 | border: 0; 72 | outline: 0; 73 | } 74 | td.docs, th.docs { 75 | max-width: 500px; 76 | min-width: 500px; 77 | min-height: 5px; 78 | padding: 10px 25px 1px 50px; 79 | vertical-align: top; 80 | text-align: left; 81 | } 82 | .docs pre { 83 | margin: 15px 0 15px; 84 | padding-left: 15px; 85 | } 86 | .docs p tt, .docs p code { 87 | background: #f8f8ff; 88 | border: 1px solid #dedede; 89 | font-size: 12px; 90 | padding: 0 0.2em; 91 | } 92 | .octowrap { 93 | position: relative; 94 | } 95 | .octothorpe { 96 | font: 12px Arial; 97 | text-decoration: none; 98 | color: #454545; 99 | position: absolute; 100 | top: 3px; left: -20px; 101 | padding: 1px 2px; 102 | opacity: 0; 103 | -webkit-transition: opacity 0.2s linear; 104 | } 105 | td.docs:hover .octothorpe { 106 | opacity: 1; 107 | } 108 | td.code, th.code { 109 | padding: 14px 15px 16px 50px; 110 | width: 100%; 111 | vertical-align: top; 112 | background: #f5f5ff; 113 | border-left: 1px solid #e5e5ee; 114 | } 115 | .code pre, .docs p code { 116 | font-size: 12px; 117 | } 118 | pre, tt, code { 119 | line-height: 18px; 120 | font-family: Monaco, Consolas, "Lucida Console", monospace; 121 | margin: 0; padding: 0; 122 | } 123 | 124 | 125 | /*---------------------- Syntax Highlighting -----------------------------*/ 126 | td.linenos { background-color: #f0f0f0; padding-right: 10px; } 127 | span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } 128 | body .hll { background-color: #ffffcc } 129 | body .c { color: #408080; font-style: italic } /* Comment */ 130 | body .err { border: 1px solid #FF0000 } /* Error */ 131 | body .k { color: #954121 } /* Keyword */ 132 | body .o { color: #666666 } /* Operator */ 133 | body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ 134 | body .cp { color: #BC7A00 } /* Comment.Preproc */ 135 | body .c1 { color: #408080; font-style: italic } /* Comment.Single */ 136 | body .cs { color: #408080; font-style: italic } /* Comment.Special */ 137 | body .gd { color: #A00000 } /* Generic.Deleted */ 138 | body .ge { font-style: italic } /* Generic.Emph */ 139 | body .gr { color: #FF0000 } /* Generic.Error */ 140 | body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 141 | body .gi { color: #00A000 } /* Generic.Inserted */ 142 | body .go { color: #808080 } /* Generic.Output */ 143 | body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ 144 | body .gs { font-weight: bold } /* Generic.Strong */ 145 | body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 146 | body .gt { color: #0040D0 } /* Generic.Traceback */ 147 | body .kc { color: #954121 } /* Keyword.Constant */ 148 | body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ 149 | body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ 150 | body .kp { color: #954121 } /* Keyword.Pseudo */ 151 | body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ 152 | body .kt { color: #B00040 } /* Keyword.Type */ 153 | body .m { color: #666666 } /* Literal.Number */ 154 | body .s { color: #219161 } /* Literal.String */ 155 | body .na { color: #7D9029 } /* Name.Attribute */ 156 | body .nb { color: #954121 } /* Name.Builtin */ 157 | body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ 158 | body .no { color: #880000 } /* Name.Constant */ 159 | body .nd { color: #AA22FF } /* Name.Decorator */ 160 | body .ni { color: #999999; font-weight: bold } /* Name.Entity */ 161 | body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ 162 | body .nf { color: #0000FF } /* Name.Function */ 163 | body .nl { color: #A0A000 } /* Name.Label */ 164 | body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ 165 | body .nt { color: #954121; font-weight: bold } /* Name.Tag */ 166 | body .nv { color: #19469D } /* Name.Variable */ 167 | body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ 168 | body .w { color: #bbbbbb } /* Text.Whitespace */ 169 | body .mf { color: #666666 } /* Literal.Number.Float */ 170 | body .mh { color: #666666 } /* Literal.Number.Hex */ 171 | body .mi { color: #666666 } /* Literal.Number.Integer */ 172 | body .mo { color: #666666 } /* Literal.Number.Oct */ 173 | body .sb { color: #219161 } /* Literal.String.Backtick */ 174 | body .sc { color: #219161 } /* Literal.String.Char */ 175 | body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ 176 | body .s2 { color: #219161 } /* Literal.String.Double */ 177 | body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ 178 | body .sh { color: #219161 } /* Literal.String.Heredoc */ 179 | body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ 180 | body .sx { color: #954121 } /* Literal.String.Other */ 181 | body .sr { color: #BB6688 } /* Literal.String.Regex */ 182 | body .s1 { color: #219161 } /* Literal.String.Single */ 183 | body .ss { color: #19469D } /* Literal.String.Symbol */ 184 | body .bp { color: #954121 } /* Name.Builtin.Pseudo */ 185 | body .vc { color: #19469D } /* Name.Variable.Class */ 186 | body .vg { color: #19469D } /* Name.Variable.Global */ 187 | body .vi { color: #19469D } /* Name.Variable.Instance */ 188 | body .il { color: #666666 } /* Literal.Number.Integer.Long */ 189 | 190 | -------------------------------------------------------------------------------- /lib/docurium/debug.rb: -------------------------------------------------------------------------------- 1 | $debug_stack = [false] 2 | 3 | def debug_enabled 4 | $debug_stack[-1] 5 | end 6 | 7 | def debug(str = nil) 8 | puts str if debug_enabled 9 | end 10 | 11 | def debug_enable 12 | $debug_stack.push true 13 | end 14 | 15 | def debug_silence 16 | $debug_stack.push false 17 | end 18 | 19 | def debug_set val 20 | $debug_stack.push val 21 | end 22 | 23 | def debug_pass 24 | $debug_stack.push debug_enabled 25 | end 26 | 27 | def debug_restore 28 | $debug_stack.pop 29 | end 30 | 31 | def with_debug(&block) 32 | debug_enable 33 | block.call 34 | debug_restore 35 | end 36 | 37 | def without_debug(&block) 38 | debug_silence 39 | block.call 40 | debug_restore 41 | end -------------------------------------------------------------------------------- /lib/docurium/docparser.rb: -------------------------------------------------------------------------------- 1 | require 'tempfile' 2 | require 'fileutils' 3 | require 'ffi/clang' 4 | require 'open3' 5 | include FFI::Clang 6 | 7 | class Docurium 8 | class DocParser 9 | # The include directory where clang has its basic type definitions is not 10 | # included in our default search path, so as a workaround we execute clang 11 | # in verbose mode and grab its include paths from the output. 12 | def find_clang_includes 13 | @includes ||= 14 | begin 15 | clang = if ENV["LLVM_CONFIG"] 16 | bindir = `#{ENV["LLVM_CONFIG"]} --bindir`.strip 17 | "#{bindir}/clang" 18 | else 19 | "clang" 20 | end 21 | 22 | output, _status = Open3.capture2e("#{clang} -v -x c -", :stdin_data => "") 23 | includes = [] 24 | output.each_line do |line| 25 | if line =~ %r{^\s+/(.*usr|.*lib/clang.*)/include} 26 | includes << line.strip 27 | end 28 | end 29 | 30 | includes 31 | end 32 | end 33 | 34 | def self.with_files(files, opts = {}) 35 | parser = self.new(files, opts) 36 | yield parser 37 | parser.cleanup! 38 | end 39 | 40 | def initialize(files, opts = {}) 41 | # unfortunately Clang wants unsaved files to exist on disk, so 42 | # we need to create at least empty files for each unsaved file 43 | # we're given. 44 | 45 | prefix = (opts[:prefix] ? opts[:prefix] + "-" : nil) 46 | @tmpdir = Dir.mktmpdir(prefix) 47 | @unsaved = files.map do |name, contents| 48 | full_path = File.join(@tmpdir, name) 49 | dirname = File.dirname(full_path) 50 | FileUtils.mkdir_p(dirname) unless Dir.exist? dirname 51 | File.new(full_path, File::CREAT).close() 52 | UnsavedFile.new(full_path, contents) 53 | end 54 | end 55 | 56 | def cleanup! 57 | FileUtils.remove_entry(@tmpdir) 58 | end 59 | 60 | # Entry point for this parser 61 | # Parse `filename` out of the hash `files` 62 | def parse_file(orig_filename, opts = {}) 63 | 64 | includes = find_clang_includes + [@tmpdir] 65 | 66 | # Override the path we want to filter by 67 | filename = File.join(@tmpdir, orig_filename) 68 | debug_enable if opts[:debug] 69 | debug "parsing #{filename} #{@tmpdir}" 70 | args = includes.map { |path| "-I#{path}" } 71 | args << '-ferror-limit=1' 72 | 73 | tu = Index.new(true, true).parse_translation_unit(filename, args, @unsaved, {:detailed_preprocessing_record => 1}) 74 | 75 | recs = [] 76 | 77 | tu.cursor.visit_children do |cursor, parent| 78 | location = cursor.location 79 | next :continue if location.file == nil 80 | next :continue unless location.file == filename 81 | 82 | loc = "%d:%d-%d:%d" % [cursor.extent.start.line, cursor.extent.start.column, cursor.extent.end.line, cursor.extent.end.column] 83 | debug "#{cursor.location.file}:#{loc} - visiting #{cursor.kind}: #{cursor.spelling}, comment is #{cursor.comment.kind}" 84 | 85 | #cursor.visit_children do |c| 86 | # puts " child #{c.kind}, #{c.spelling}, #{c.comment.kind}" 87 | # :continue 88 | #end 89 | 90 | next :continue if cursor.comment.kind == :comment_null 91 | next :continue if cursor.spelling == "" 92 | 93 | extent = cursor.extent 94 | rec = { 95 | :file => orig_filename, 96 | :line => extent.start.line, 97 | :lineto => extent.end.line, 98 | :tdef => nil, 99 | } 100 | 101 | extract = case cursor.kind 102 | when :cursor_function 103 | debug "have function #{cursor.spelling}" 104 | rec.update extract_function(cursor) 105 | when :cursor_enum_decl 106 | debug "have enum #{cursor.spelling}" 107 | rec.update extract_enum(cursor) 108 | when :cursor_struct 109 | debug "have struct #{cursor.spelling}" 110 | rec.update extract_struct(cursor) 111 | when :cursor_typedef_decl 112 | debug "have typedef #{cursor.spelling} #{cursor.underlying_type.spelling}" 113 | rec.update extract_typedef(cursor) 114 | else 115 | raise "No idea how to deal with #{cursor.kind}" 116 | end 117 | 118 | rec.merge! extract 119 | 120 | recs << rec 121 | :continue 122 | end 123 | 124 | if debug_enabled 125 | puts "parse_file: parsed #{recs.size} records for #{filename}:" 126 | recs.each do |r| 127 | puts "\t#{r}" 128 | end 129 | end 130 | 131 | debug_restore 132 | 133 | recs 134 | end 135 | 136 | def extract_typedef(cursor) 137 | child = nil 138 | cursor.visit_children { |c| child = c; :break } 139 | rec = { 140 | :name => cursor.spelling, 141 | :underlying_type => cursor.underlying_type.spelling, 142 | :tdef => :typedef, 143 | } 144 | 145 | if not child 146 | return rec 147 | end 148 | 149 | #puts "have typedef #{child.kind}, #{cursor.extent.start.line}" 150 | case child.kind 151 | when :cursor_type_ref 152 | #puts "pure typedef, #{cursor.spelling}" 153 | if child.type.kind == :type_record 154 | rec[:type] = :struct 155 | subject, desc = extract_subject_desc(cursor.comment) 156 | rec[:decl] = cursor.spelling 157 | rec[:description] = subject 158 | rec[:comments] = desc 159 | else 160 | rec[:name] = cursor.spelling 161 | end 162 | when :cursor_enum_decl 163 | rec.merge! extract_enum(child) 164 | when :cursor_struct 165 | #puts "typed struct, #{cursor.spelling}" 166 | rec.merge! extract_struct(child) 167 | when :cursor_parm_decl 168 | rec.merge! extract_function(cursor) 169 | rec[:type] = :callback 170 | # this is wasteful, but we don't get the array from outside 171 | cmt = extract_function_comment(cursor.comment) 172 | ret = { 173 | :type => extract_callback_result(rec[:underlying_type]), 174 | :comment => cmt[:return] 175 | } 176 | rec[:return] = ret 177 | else 178 | raise "No idea how to handle #{child.kind}" 179 | end 180 | # let's make sure we override the empty name the extract 181 | # functions stored 182 | rec[:name] = cursor.spelling 183 | rec 184 | end 185 | 186 | def extract_callback_result(type) 187 | type[0..(type.index('(') - 1)].strip 188 | end 189 | 190 | def extract_function_args(cursor, cmt) 191 | # We only want to look at parm_decl to avoid looking at a return 192 | # struct as a parameter 193 | children(cursor) 194 | .select {|c| c.kind == :cursor_parm_decl } 195 | .map do |arg| 196 | { 197 | :name => arg.display_name, 198 | :type => arg.type.spelling, 199 | :comment => cmt[:args][arg.display_name], 200 | } 201 | end 202 | end 203 | 204 | def extract_subject_desc(comment) 205 | subject = comment.child.text 206 | debug "\t\tsubject: #{subject}" 207 | paras = comment.find_all { |cmt| cmt.kind == :comment_paragraph }.drop(1).map { |p| p.text } 208 | desc = paras.join("\n\n") 209 | debug "\t\tdesc: #{desc}" 210 | return subject, desc 211 | end 212 | 213 | def extract_function(cursor) 214 | comment = cursor.comment 215 | 216 | $buggy_functions = %w() 217 | debug_set ($buggy_functions.include? cursor.spelling) 218 | if debug_enabled 219 | puts "\tlooking at function #{cursor.spelling}, #{cursor.display_name}" 220 | puts "\tcomment: #{comment}, #{comment.kind}" 221 | cursor.visit_children do |cur, parent| 222 | puts "\t\tchild: #{cur.spelling}, #{cur.kind}" 223 | :continue 224 | end 225 | end 226 | 227 | cmt = extract_function_comment(comment) 228 | args = extract_function_args(cursor, cmt) 229 | #args = args.reject { |arg| arg[:comment].nil? } 230 | 231 | ret = { 232 | :type => cursor.result_type.spelling, 233 | :comment => cmt[:return] 234 | } 235 | 236 | # generate function signature 237 | sig = args.map { |a| a[:type].to_s }.join('::') 238 | 239 | argline = args.map { |a| 240 | # pointers don't have a separation between '*' and the name 241 | if a[:type].end_with? "*" 242 | "#{a[:type]}#{a[:name]}" 243 | else 244 | "#{a[:type]} #{a[:name]}" 245 | end 246 | }.join(', ') 247 | 248 | decl = "#{ret[:type]} #{cursor.spelling}(#{argline})" 249 | body = "#{decl};" 250 | 251 | debug_restore 252 | #puts cursor.display_name 253 | # Return the format that docurium expects 254 | { 255 | :type => :function, 256 | :name => cursor.spelling, 257 | :body => body, 258 | :description => cmt[:description], 259 | :comments => cmt[:comments], 260 | :sig => sig, 261 | :args => args, 262 | :return => ret, 263 | :decl => decl, 264 | :argline => argline 265 | } 266 | end 267 | 268 | def extract_function_comment(comment) 269 | subject, desc = extract_subject_desc(comment) 270 | debug "\t\textract_function_comment: #{comment}, #{comment.kind}, #{subject}, #{desc}" 271 | 272 | args = {} 273 | (comment.find_all { |cmt| cmt.kind == :comment_param_command }).each do |param| 274 | args[param.name] = param.comment.strip 275 | end 276 | 277 | ret = nil 278 | comment.each do |block| 279 | next unless block.kind == :comment_block_command 280 | next unless block.name == "return" 281 | 282 | ret = block.paragraph.text 283 | 284 | break 285 | end 286 | 287 | { 288 | :description => subject, 289 | :comments => desc, 290 | :args => args, 291 | :return => ret, 292 | } 293 | end 294 | 295 | def extract_fields(cursor) 296 | fields = [] 297 | cursor.visit_children do |cchild, cparent| 298 | field = { 299 | :type => cchild.type.spelling, 300 | :name => cchild.spelling, 301 | :comments => cchild.comment.find_all {|c| c.kind == :comment_paragraph }.map(&:text).join("\n\n") 302 | } 303 | 304 | if cursor.kind == :cursor_enum_decl 305 | field.merge!({:value => cchild.enum_value}) 306 | end 307 | 308 | fields << field 309 | :continue 310 | end 311 | 312 | fields 313 | end 314 | 315 | def extract_enum(cursor) 316 | subject, desc = extract_subject_desc(cursor.comment) 317 | 318 | decl = [] 319 | cursor.visit_children do |cchild, cparent| 320 | decl << cchild.spelling 321 | :continue 322 | end 323 | 324 | block = decl.join("\n") 325 | #return the docurium object 326 | { 327 | :type => :enum, 328 | :name => cursor.spelling, 329 | :description => subject, 330 | :comments => desc, 331 | :fields => extract_fields(cursor), 332 | :block => block, 333 | :decl => decl, 334 | } 335 | end 336 | 337 | def extract_struct(cursor) 338 | subject, desc = extract_subject_desc(cursor.comment) 339 | 340 | values = [] 341 | cursor.visit_children do |cchild, cparent| 342 | values << "#{cchild.type.spelling} #{cchild.spelling}" 343 | :continue 344 | end 345 | 346 | debug "\tstruct value #{values}" 347 | 348 | rec = { 349 | :type => :struct, 350 | :name => cursor.spelling, 351 | :description => subject, 352 | :comments => desc, 353 | :fields => extract_fields(cursor), 354 | :decl => values, 355 | } 356 | 357 | rec[:block] = values.join("\n") unless values.empty? 358 | rec 359 | end 360 | 361 | def children(cursor) 362 | list = [] 363 | cursor.visit_children do |ccursor, cparent| 364 | list << ccursor 365 | :continue 366 | end 367 | 368 | list 369 | end 370 | 371 | end 372 | end 373 | -------------------------------------------------------------------------------- /lib/docurium/layout.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ title }} 6 | 7 | 11 | 12 | 13 |
14 |
15 |
16 | Jump To … 17 |
18 |
19 | API Docs 20 | {{#sources}} 21 | {{ basename }} 22 | {{/sources}} 23 |
24 |
25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | {{#sections}} 35 | 36 | 42 | 45 | 46 | {{/sections}} 47 |

{{ title }}

37 |
38 | 39 |
40 | {{{ docs }}} 41 |
43 |
{{{ code }}}
44 |
48 |
49 | 50 | -------------------------------------------------------------------------------- /lib/docurium/layout.rb: -------------------------------------------------------------------------------- 1 | # adding some stuff I need 2 | class Rocco::Layout 3 | attr_accessor :version 4 | end 5 | -------------------------------------------------------------------------------- /lib/docurium/version.rb: -------------------------------------------------------------------------------- 1 | class Docurium 2 | Version = VERSION = '0.7.0' 3 | end 4 | -------------------------------------------------------------------------------- /lib/libdetect.rb: -------------------------------------------------------------------------------- 1 | require 'rbconfig' 2 | require 'mkmf' 3 | 4 | # This is pretty terrible, but we need to have the environment set up 5 | # before we require the ffi-clang module. 6 | 7 | module LibDetect 8 | 9 | DARWIN_LIBCLANG = '/Library/Developer/CommandLineTools/usr/lib/libclang.dylib' 10 | 11 | host_os = RbConfig::CONFIG['host_os'] 12 | case host_os 13 | when /darwin/ 14 | File.exist? DARWIN_LIBCLANG 15 | ENV['LIBCLANG'] = DARWIN_LIBCLANG 16 | when /linux/ 17 | prog = 'llvm-config' 18 | if find_executable(prog) and not ENV.has_key?('LLVM_CONFIG') 19 | ENV['LLVM_CONFIG'] = prog 20 | end 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /site/css/style.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100%; 3 | } 4 | 5 | /* Remove Below */ 6 | 7 | #header a.logo { 8 | font-size: 35px; 9 | font-weight: bold; 10 | color: #014d65; 11 | padding-top: 12px; 12 | } 13 | 14 | #header { 15 | height:81px; 16 | } 17 | #main { 18 | background-position-y: -10px 19 | } 20 | #search-field { 21 | margin: 0px; 22 | } 23 | 24 | #versions li h3 { 25 | padding: 10px; 26 | } 27 | 28 | h3 #version { 29 | display: inline; 30 | color: #743; 31 | } 32 | 33 | .category_index { float: left; margin: 0.25em; width:19em; } 34 | .category_index h2 { background: #ddd; text-align: center; padding: 0.25em; margin-bottom: 0.5em; } 35 | .category_index dt, .category_index dd { margin-right: 0.5em; } 36 | .category_index dt { margin-left: 0.5em !important; } 37 | .category_index dd { margin-left: 1.5em !important; } 38 | 39 | 40 | /*********************/ 41 | /* Sidebar */ 42 | /*********************/ 43 | 44 | #guides .guide .sidebar h3 { 45 | padding: 4px; 46 | margin: .2em 0; 47 | } 48 | #guides .guide .sidebar h3:focus { outline: none; } 49 | 50 | .sidebar dl { padding: 0 0.5em 0.5em 0.5em; } 51 | .sidebar dt { 52 | font-weight: bold; 53 | margin-top: 0.5em; 54 | } 55 | 56 | .ui-icon { 57 | display: inline-block; 58 | width: 16px; 59 | height: 16px; 60 | background-color: white; 61 | background-position: -2px 2px; 62 | background-repeat: no-repeat; 63 | } 64 | .ui-icon-triangle-expand { background-image: url(../images/expand.png); } 65 | .ui-icon-triangle-collapse { background-image: url(../images/collapse.png); } 66 | 67 | div.sidebar-shell { 68 | margin: 0 0; 69 | } 70 | 71 | div.sidebar-module { 72 | width: 232px; 73 | } 74 | 75 | .hidden { 76 | display: none; 77 | } 78 | 79 | .content { 80 | width: 660px; 81 | } 82 | 83 | input.search { 84 | font-size: 12px; 85 | width: 200px; 86 | padding: 5px 5px 5px 23px; 87 | margin-bottom: 8px; 88 | font-family: Helvetica,Arial,freesans,sans-serif; 89 | border: 1px solid #DDD; 90 | border-top-color: #CCC; 91 | border-bottom-color: #EAEAEA; 92 | -webkit-border-radius: 3px; 93 | -moz-border-radius: 3px; 94 | border-radius: 3px; 95 | background: url(../images/search_icon.png) 5px 50% no-repeat white; 96 | } 97 | 98 | a small { 99 | font-size: 0.8em; 100 | color: #aaa; 101 | } 102 | 103 | h2 small { 104 | font-size: 0.8em; 105 | font-weight: normal; 106 | color: #666; 107 | } 108 | 109 | table.methods { 110 | width: 100%; 111 | } 112 | table.methods tr td { 113 | padding: 4px 8px; 114 | border-bottom: 1px solid #eee; 115 | } 116 | table.methods tr td.methodName a { 117 | font-weight: bold; 118 | } 119 | 120 | table.funcTable tr td, 121 | table.structTable tr td { 122 | padding: 5px 10px; 123 | border-bottom: 1px solid #eee; 124 | } 125 | 126 | .enumTable .var, 127 | .funcTable .var, 128 | .structTable .var { 129 | font-weight: bold; 130 | color: #833; 131 | } 132 | 133 | .enumTable .type, 134 | .funcTable .type, 135 | .structTable .type { 136 | text-align: right; 137 | } 138 | 139 | code.params { 140 | white-space: pre-wrap; /* css-3 */ 141 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 142 | white-space: -pre-wrap; /* Opera 4-6 */ 143 | white-space: -o-pre-wrap; /* Opera 7 */ 144 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 145 | } 146 | 147 | .example { 148 | padding: 10px; 149 | background: #efe; 150 | margin-top: 10px; 151 | margin-bottom: 10px; 152 | border: 1px solid #7a7; 153 | } 154 | .example h3 { 155 | margin: 8px 0; 156 | margin-top: 0; 157 | color: #585; 158 | } 159 | 160 | .returns { margin-bottom: 15px; } 161 | 162 | h1.funcTitle, 163 | h1.enumTitle, 164 | h1.structTitle { 165 | font-size: 1.6em; 166 | } 167 | h3.funcDesc { 168 | font-size: 1.0em; 169 | font-weight: normal; 170 | color: #686; 171 | padding-bottom: 10px; 172 | margin: 0; 173 | } 174 | 175 | h1.funcTitle small { 176 | font-size: 0.8em; 177 | font-weight: normal; 178 | color: #888; 179 | margin-left: 10px; 180 | } 181 | 182 | .also { 183 | padding: 10px; 184 | border-top: 1px solid #ddd; 185 | background: #eee; 186 | } 187 | 188 | .sidebar-module ul ul li span.divide { 189 | background: #eee; 190 | cursor: default; 191 | } 192 | 193 | .fileLink { 194 | padding: 10px; 195 | } 196 | 197 | .signatures { 198 | padding: 10px; 199 | } 200 | 201 | .funcEx { 202 | padding: 10px; 203 | } 204 | 205 | .signatures a { 206 | background: #ddd; 207 | padding: 4px; 208 | margin: 0; 209 | color: #000; 210 | } 211 | 212 | .signatures a.changed { 213 | background: #ffd4aa; 214 | } 215 | 216 | .signatures a.current { 217 | border-bottom: 3px solid #933; 218 | } 219 | 220 | .signatures h3 { 221 | margin: 8px 0; 222 | margin-top: 0; 223 | } 224 | 225 | .signatures ul { 226 | list-style: none outside none; 227 | float: left; 228 | } 229 | 230 | .signatures ul li { 231 | list-style: none; 232 | float: left; 233 | display: block; 234 | } 235 | 236 | h2.funcGroup { 237 | border: 0; 238 | margin: 5px 0; 239 | margin-top: 8px; 240 | padding: 5px 0; 241 | border-bottom: 1px solid #eee; 242 | } 243 | p.functionList { 244 | border: 0; 245 | margin: 0; 246 | padding: 0; 247 | } 248 | 249 | p.functionList a.changed { 250 | background: #ffd4aa; 251 | } 252 | 253 | p.functionList a.introd { 254 | background: #cec; 255 | } 256 | 257 | .changelog li.adds a { 258 | color: #393; 259 | } 260 | .changelog li.changes a { 261 | color: #993; 262 | } 263 | .changelog li.deletes { 264 | color: #933; 265 | } 266 | 267 | -------------------------------------------------------------------------------- /site/images/search_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libgit2/docurium/043a78750c7256e5c5d08099a7764d1e1ac6169d/site/images/search_icon.png -------------------------------------------------------------------------------- /site/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | API Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 32 | 33 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 68 | 108 | 109 | 110 | 123 | 180 | 181 | 182 | 195 | 196 | 229 | 230 | 231 | 252 | 253 | 254 | 281 | 282 | 312 | 313 | 324 | 325 | 360 | 370 | 371 | 372 | 373 | -------------------------------------------------------------------------------- /site/js/json2.js: -------------------------------------------------------------------------------- 1 | 2 | var JSON;if(!JSON){JSON={};} 3 | (function(){"use strict";function f(n){return n<10?'0'+n:n;} 4 | if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+ 5 | f(this.getUTCMonth()+1)+'-'+ 6 | f(this.getUTCDate())+'T'+ 7 | f(this.getUTCHours())+':'+ 8 | f(this.getUTCMinutes())+':'+ 9 | f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};} 10 | var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';} 11 | function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);} 12 | if(typeof rep==='function'){value=rep.call(holder,key,value);} 13 | switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';} 14 | gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i rel_path, :oid => id, :mode => 0100644) 20 | end 21 | 22 | @path = File.dirname(__FILE__) + '/fixtures/git2/api.docurium' 23 | @doc = Docurium.new(@path, {}, @repo) 24 | @data = @doc.parse_headers(index, 'HEAD') 25 | end 26 | 27 | def teardown 28 | FileUtils.remove_entry(@dir) 29 | end 30 | 31 | def test_can_parse 32 | refute_nil @data 33 | assert_equal [:files, :functions, :callbacks, :globals, :types, :prefix, :groups], @data.keys 34 | files = %w(blob.h callback.h cherrypick.h commit.h common.h errors.h index.h object.h odb.h odb_backend.h oid.h refs.h repository.h revwalk.h signature.h tag.h tree.h types.h) 35 | assert_equal files, @data[:files].map {|d| d[:file] } 36 | end 37 | 38 | def test_can_parse_headers 39 | keys = @data.keys.map { |k| k.to_s }.sort 40 | assert_equal ['callbacks', 'files', 'functions', 'globals', 'groups', 'prefix', 'types'], keys 41 | assert_equal 155, @data[:functions].size 42 | end 43 | 44 | def test_can_extract_enum_from_define 45 | skip("this isn't something we do") 46 | assert_equal 41, @data[:globals].size 47 | idxentry = @data[:types].find { |a| a[0] == 'GIT_IDXENTRY' } 48 | assert idxentry 49 | assert_equal 75, idxentry[1][:lineto] 50 | # this one is on the last doc block 51 | assert idxentry[1][:block].include? 'GIT_IDXENTRY_EXTENDED2' 52 | # from an earlier block, should not get overwritten 53 | assert idxentry[1][:block].include? 'GIT_IDXENTRY_UPDATE' 54 | end 55 | 56 | def test_can_extract_structs_and_enums 57 | skip("we don't auto-create enums, so the number is wrong") 58 | assert_equal 25, @data[:types].size 59 | end 60 | 61 | def test_can_find_type_usage 62 | oid = @data[:types].find {|a| a[0] == 'git_oid' } 63 | oid_returns = [ 64 | "git_commit_id", 65 | "git_commit_parent_oid", 66 | "git_commit_tree_oid", 67 | "git_object_id", 68 | "git_odb_object_id", 69 | "git_oid_shorten_new", 70 | "git_reference_oid", 71 | "git_tag_id", 72 | "git_tag_target_oid", 73 | "git_tree_entry_id", 74 | "git_tree_id" 75 | ] 76 | assert_equal oid_returns, oid[1][:used][:returns] 77 | oid_needs = [ 78 | "git_blob_create_frombuffer", 79 | "git_blob_create_fromfile", 80 | "git_blob_lookup", 81 | "git_commit_create", 82 | "git_commit_create_o", 83 | "git_commit_create_ov", 84 | "git_commit_create_v", 85 | "git_commit_lookup", 86 | "git_object_lookup", 87 | "git_odb_exists", 88 | "git_odb_hash", 89 | "git_odb_open_rstream", 90 | "git_odb_read", 91 | "git_odb_read_header", 92 | "git_odb_write", 93 | "git_oid_allocfmt", 94 | "git_oid_cmp", 95 | "git_oid_cpy", 96 | "git_oid_fmt", 97 | "git_oid_mkraw", 98 | "git_oid_mkstr", 99 | "git_oid_pathfmt", 100 | "git_oid_shorten_add", 101 | "git_oid_shorten_free", 102 | "git_oid_to_string", 103 | "git_reference_create_oid", 104 | "git_reference_create_oid_f", 105 | "git_reference_set_oid", 106 | "git_revwalk_hide", 107 | "git_revwalk_next", 108 | "git_revwalk_push", 109 | "git_tag_create", 110 | "git_tag_create_f", 111 | "git_tag_create_fo", 112 | "git_tag_create_frombuffer", 113 | "git_tag_create_o", 114 | "git_tag_lookup", 115 | "git_tree_create_fromindex", 116 | "git_tree_lookup", 117 | "git_treebuilder_insert", 118 | "git_treebuilder_write" 119 | ] 120 | assert_equal oid_needs, oid[1][:used][:needs].sort 121 | end 122 | 123 | def test_can_parse_normal_functions 124 | func = @data[:functions]['git_blob_rawcontent'] 125 | assert_equal "

Get a read-only buffer with the raw content of a blob.

\n", func[:description] 126 | assert_equal 'const void *', func[:return][:type] 127 | assert_equal ' the pointer; NULL if the blob has no contents', func[:return][:comment] 128 | assert_equal 84, func[:line] 129 | assert_equal 84, func[:lineto] 130 | assert_equal 'blob.h', func[:file] 131 | assert_equal 'git_blob *blob',func[:argline] 132 | assert_equal 'blob', func[:args][0][:name] 133 | assert_equal 'git_blob *', func[:args][0][:type] 134 | assert_equal 'pointer to the blob', func[:args][0][:comment] 135 | end 136 | 137 | def test_can_parse_defined_functions 138 | func = @data[:functions]['git_tree_lookup'] 139 | assert_equal 'int', func[:return][:type] 140 | assert_equal ' 0 on success; error code otherwise', func[:return][:comment] 141 | assert_equal 50, func[:line] 142 | assert_equal 'tree.h', func[:file] 143 | assert_equal 'id', func[:args][2][:name] 144 | assert_equal 'const git_oid *', func[:args][2][:type] 145 | assert_equal 'identity of the tree to locate.', func[:args][2][:comment] 146 | end 147 | 148 | def test_can_parse_function_cast_args 149 | func = @data[:functions]['git_reference_listcb'] 150 | assert_equal 'int', func[:return][:type] 151 | assert_equal ' 0 on success; error code otherwise', func[:return][:comment] 152 | assert_equal 321, func[:line] 153 | assert_equal 'refs.h', func[:file] 154 | assert_equal 'repo', func[:args][0][:name] 155 | assert_equal 'git_repository *', func[:args][0][:type] 156 | assert_equal 'list_flags', func[:args][1][:name] 157 | assert_equal 'unsigned int', func[:args][1][:type] 158 | assert_equal 'callback', func[:args][2][:name] 159 | assert_equal 'int (*)(const char *, void *)', func[:args][2][:type] 160 | assert_equal 'Function which will be called for every listed ref', func[:args][2][:comment] 161 | expect_comment =<<-EOF 162 |

The listed references may be filtered by type, or using 163 | a bitwise OR of several types. Use the magic value 164 | GIT_REF_LISTALL to obtain all references, including 165 | packed ones.

166 | 167 |

The callback function will be called for each of the references 168 | in the repository, and will receive the name of the reference and 169 | the payload value passed to this method.

170 | EOF 171 | assert_equal expect_comment.split("\n"), func[:comments].split("\n") 172 | end 173 | 174 | def test_can_handle_bulleted_lists 175 | type = @data[:types].find {|name, data| name == 'git_repository_init_options' } 176 | refute_nil type 177 | expect_comment = <<-EOF 178 |

This contains extra options for git_repository_init_ext that enable 179 | additional initialization features. The fields are:

180 | 181 | 204 | EOF 205 | assert_equal expect_comment, type[1][:comments] 206 | end 207 | 208 | def test_can_get_the_full_description_from_multi_liners 209 | func = @data[:functions]['git_commit_create_o'] 210 | desc = "

Create a new commit in the repository using git_object\n instances as parameters.

\n" 211 | assert_equal desc, func[:description] 212 | end 213 | 214 | def test_can_group_functions 215 | groups = %w(blob cherrypick commit index lasterror object odb oid reference repository revwalk signature strerror tag tree treebuilder work) 216 | assert_equal groups, @data[:groups].map {|g| g[0]}.sort 217 | group, funcs = @data[:groups].first 218 | assert_equal 'blob', group 219 | assert_equal 6, funcs.size 220 | end 221 | 222 | def test_can_store_mutliple_enum_doc_sections 223 | skip("this isn't something we do") 224 | idxentry = @data[:types].find { |a| a[0] == 'GIT_IDXENTRY' } 225 | assert idxentry, "GIT_IDXENTRY did not get automatically created" 226 | assert_equal 2, idxentry[1][:sections].size 227 | end 228 | 229 | def test_can_parse_callback 230 | cb = @data[:callbacks]['git_callback_do_work'] 231 | # we can mostly assume that the rest works as it's the same as for the functions 232 | assert_equal 'int', cb[:return][:type] 233 | end 234 | 235 | end 236 | -------------------------------------------------------------------------------- /test/fixtures/git2/api.docurium: -------------------------------------------------------------------------------- 1 | { 2 | "name": "libgit2", 3 | "github": "libgit2/libgit2", 4 | "prefix": "git_", 5 | "branch": "gh-pages" 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/git2/blob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_blob_h__ 26 | #define INCLUDE_git_blob_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | #include "object.h" 32 | 33 | /** 34 | * @file git2/blob.h 35 | * @brief Git blob load and write routines 36 | * @defgroup git_blob Git blob load and write routines 37 | * @ingroup Git 38 | * @{ 39 | */ 40 | GIT_BEGIN_DECL 41 | 42 | /** 43 | * Lookup a blob object from a repository. 44 | * 45 | * @param blob pointer to the looked up blob 46 | * @param repo the repo to use when locating the blob. 47 | * @param id identity of the blob to locate. 48 | * @return 0 on success; error code otherwise 49 | */ 50 | GIT_INLINE(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git_oid *id) 51 | { 52 | return git_object_lookup((git_object **)blob, repo, id, GIT_OBJ_BLOB); 53 | } 54 | 55 | /** 56 | * Close an open blob 57 | * 58 | * This is a wrapper around git_object_close() 59 | * 60 | * IMPORTANT: 61 | * It *is* necessary to call this method when you stop 62 | * using a blob. Failure to do so will cause a memory leak. 63 | * 64 | * @param blob the blob to close 65 | */ 66 | 67 | GIT_INLINE(void) git_blob_close(git_blob *blob) 68 | { 69 | git_object_close((git_object *) blob); 70 | } 71 | 72 | 73 | /** 74 | * Get a read-only buffer with the raw content of a blob. 75 | * 76 | * A pointer to the raw content of a blob is returned; 77 | * this pointer is owned internally by the object and shall 78 | * not be free'd. The pointer may be invalidated at a later 79 | * time. 80 | * 81 | * @param blob pointer to the blob 82 | * @return the pointer; NULL if the blob has no contents 83 | */ 84 | GIT_EXTERN(const void *) git_blob_rawcontent(git_blob *blob); 85 | 86 | /** 87 | * Get the size in bytes of the contents of a blob 88 | * 89 | * @param blob pointer to the blob 90 | * @return size on bytes 91 | */ 92 | GIT_EXTERN(int) git_blob_rawsize(git_blob *blob); 93 | 94 | /** 95 | * Read a file from the working folder of a repository 96 | * and write it to the Object Database as a loose blob 97 | * 98 | * @param oid return the id of the written blob 99 | * @param repo repository where the blob will be written. 100 | * this repository cannot be bare 101 | * @param path file from which the blob will be created, 102 | * relative to the repository's working dir 103 | * @return 0 on success; error code otherwise 104 | */ 105 | GIT_EXTERN(int) git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path); 106 | 107 | 108 | /** 109 | * Write an in-memory buffer to the ODB as a blob 110 | * 111 | * @param oid return the oid of the written blob 112 | * @param repo repository where to blob will be written 113 | * @param buffer data to be written into the blob 114 | * @param len length of the data 115 | * @return 0 on success; error code otherwise 116 | */ 117 | GIT_EXTERN(int) git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len); 118 | 119 | /** @} */ 120 | GIT_END_DECL 121 | #endif 122 | -------------------------------------------------------------------------------- /test/fixtures/git2/callback.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is to create a function which takes a callback in order 3 | * to test that we detect it correctly and will write it out. 4 | */ 5 | 6 | #include "common.h" 7 | 8 | /** 9 | * Worker which does soemthing to its pointer 10 | */ 11 | typedef int (*git_callback_do_work)(int *foo); 12 | 13 | /** 14 | * Schedule some work to happen for a particular function 15 | */ 16 | GIT_EXTERN(int) git_work_schedule(git_callback_do_work worker); 17 | -------------------------------------------------------------------------------- /test/fixtures/git2/cherrypick.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_git_blob_h__ 2 | #define INCLUDE_git_blob_h__ 3 | 4 | #include "common.h" 5 | #include "types.h" 6 | 7 | GIT_BEGIN_DECL 8 | 9 | /** 10 | * Perform a cherry-pick 11 | * 12 | * @param input dummy input 13 | * @returns the usual 14 | */ 15 | GIT_EXTERN(int) git_cherrypick(char *input); 16 | 17 | GIT_END_DECL 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /test/fixtures/git2/commit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_commit_h__ 26 | #define INCLUDE_git_commit_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | #include "object.h" 32 | 33 | /** 34 | * @file git2/commit.h 35 | * @brief Git commit parsing, formatting routines 36 | * @defgroup git_commit Git commit parsing, formatting routines 37 | * @ingroup Git 38 | * @{ 39 | */ 40 | GIT_BEGIN_DECL 41 | 42 | /** 43 | * Lookup a commit object from a repository. 44 | * 45 | * @param commit pointer to the looked up commit 46 | * @param repo the repo to use when locating the commit. 47 | * @param id identity of the commit to locate. If the object is 48 | * an annotated tag it will be peeled back to the commit. 49 | * @return 0 on success; error code otherwise 50 | */ 51 | GIT_INLINE(int) git_commit_lookup(git_commit **commit, git_repository *repo, const git_oid *id) 52 | { 53 | return git_object_lookup((git_object **)commit, repo, id, GIT_OBJ_COMMIT); 54 | } 55 | 56 | /** 57 | * Close an open commit 58 | * 59 | * This is a wrapper around git_object_close() 60 | * 61 | * IMPORTANT: 62 | * It *is* necessary to call this method when you stop 63 | * using a commit. Failure to do so will cause a memory leak. 64 | * 65 | * @param commit the commit to close 66 | */ 67 | 68 | GIT_INLINE(void) git_commit_close(git_commit *commit) 69 | { 70 | git_object_close((git_object *) commit); 71 | } 72 | 73 | /** 74 | * Get the id of a commit. 75 | * 76 | * @param commit a previously loaded commit. 77 | * @return object identity for the commit. 78 | */ 79 | GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit); 80 | 81 | /** 82 | * Get the short (one line) message of a commit. 83 | * 84 | * @param commit a previously loaded commit. 85 | * @return the short message of a commit 86 | */ 87 | GIT_EXTERN(const char *) git_commit_message_short(git_commit *commit); 88 | 89 | /** 90 | * Get the full message of a commit. 91 | * 92 | * @param commit a previously loaded commit. 93 | * @return the message of a commit 94 | */ 95 | GIT_EXTERN(const char *) git_commit_message(git_commit *commit); 96 | 97 | /** 98 | * Get the commit time (i.e. committer time) of a commit. 99 | * 100 | * @param commit a previously loaded commit. 101 | * @return the time of a commit 102 | */ 103 | GIT_EXTERN(git_time_t) git_commit_time(git_commit *commit); 104 | 105 | /** 106 | * Get the commit timezone offset (i.e. committer's preferred timezone) of a commit. 107 | * 108 | * @param commit a previously loaded commit. 109 | * @return positive or negative timezone offset, in minutes from UTC 110 | */ 111 | GIT_EXTERN(int) git_commit_time_offset(git_commit *commit); 112 | 113 | /** 114 | * Get the committer of a commit. 115 | * 116 | * @param commit a previously loaded commit. 117 | * @return the committer of a commit 118 | */ 119 | GIT_EXTERN(const git_signature *) git_commit_committer(git_commit *commit); 120 | 121 | /** 122 | * Get the author of a commit. 123 | * 124 | * @param commit a previously loaded commit. 125 | * @return the author of a commit 126 | */ 127 | GIT_EXTERN(const git_signature *) git_commit_author(git_commit *commit); 128 | 129 | /** 130 | * Get the tree pointed to by a commit. 131 | * 132 | * @param tree_out pointer where to store the tree object 133 | * @param commit a previously loaded commit. 134 | * @return 0 on success; error code otherwise 135 | */ 136 | GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, git_commit *commit); 137 | 138 | /** 139 | * Get the id of the tree pointed to by a commit. This differs from 140 | * `git_commit_tree` in that no attempts are made to fetch an object 141 | * from the ODB. 142 | * 143 | * @param commit a previously loaded commit. 144 | * @return the id of tree pointed to by commit. 145 | */ 146 | GIT_EXTERN(const git_oid *) git_commit_tree_oid(git_commit *commit); 147 | 148 | /** 149 | * Get the number of parents of this commit 150 | * 151 | * @param commit a previously loaded commit. 152 | * @return integer of count of parents 153 | */ 154 | GIT_EXTERN(unsigned int) git_commit_parentcount(git_commit *commit); 155 | 156 | /** 157 | * Get the specified parent of the commit. 158 | * 159 | * @param parent Pointer where to store the parent commit 160 | * @param commit a previously loaded commit. 161 | * @param n the position of the parent (from 0 to `parentcount`) 162 | * @return 0 on success; error code otherwise 163 | */ 164 | GIT_EXTERN(int) git_commit_parent(git_commit **parent, git_commit *commit, unsigned int n); 165 | 166 | /** 167 | * Get the oid of a specified parent for a commit. This is different from 168 | * `git_commit_parent`, which will attempt to load the parent commit from 169 | * the ODB. 170 | * 171 | * @param commit a previously loaded commit. 172 | * @param n the position of the parent (from 0 to `parentcount`) 173 | * @return the id of the parent, NULL on error. 174 | */ 175 | GIT_EXTERN(const git_oid *) git_commit_parent_oid(git_commit *commit, unsigned int n); 176 | 177 | /** 178 | * Create a new commit in the repository 179 | * 180 | * 181 | * @param oid Pointer where to store the OID of the 182 | * newly created commit 183 | * 184 | * @param repo Repository where to store the commit 185 | * 186 | * @param update_ref If not NULL, name of the reference that 187 | * will be updated to point to this commit. If the reference 188 | * is not direct, it will be resolved to a direct reference. 189 | * Use "HEAD" to update the HEAD of the current branch and 190 | * make it point to this commit 191 | * 192 | * @param author Signature representing the author and the authory 193 | * time of this commit 194 | * 195 | * @param committer Signature representing the committer and the 196 | * commit time of this commit 197 | * 198 | * @param message Full message for this commit 199 | * 200 | * @param tree_oid Object ID of the tree for this commit. Note that 201 | * no validation is performed on this OID. Use the _o variants of 202 | * this method to assure a proper tree is passed to the commit. 203 | * 204 | * @param parent_count Number of parents for this commit 205 | * 206 | * @param parents Array of pointers to parent OIDs for this commit. 207 | * Note that no validation is performed on these OIDs. Use the _o 208 | * variants of this method to assure that are parents for the commit 209 | * are proper objects. 210 | * 211 | * @return 0 on success; error code otherwise 212 | * The created commit will be written to the Object Database and 213 | * the given reference will be updated to point to it 214 | */ 215 | GIT_EXTERN(int) git_commit_create( 216 | git_oid *oid, 217 | git_repository *repo, 218 | const char *update_ref, 219 | const git_signature *author, 220 | const git_signature *committer, 221 | const char *message, 222 | const git_oid *tree_oid, 223 | int parent_count, 224 | const git_oid *parent_oids[]); 225 | 226 | /** 227 | * Create a new commit in the repository using `git_object` 228 | * instances as parameters. 229 | * 230 | * The `tree_oid` and `parent_oids` paremeters now take a instance 231 | * of `git_tree` and `git_commit`, respectively. 232 | * 233 | * All other parameters remain the same 234 | * 235 | * @see git_commit_create 236 | */ 237 | GIT_EXTERN(int) git_commit_create_o( 238 | git_oid *oid, 239 | git_repository *repo, 240 | const char *update_ref, 241 | const git_signature *author, 242 | const git_signature *committer, 243 | const char *message, 244 | const git_tree *tree, 245 | int parent_count, 246 | const git_commit *parents[]); 247 | 248 | /** 249 | * Create a new commit in the repository using `git_object` 250 | * instances and a variable argument list. 251 | * 252 | * The `tree_oid` paremeter now takes a instance 253 | * of `const git_tree *`. 254 | * 255 | * The parents for the commit are specified as a variable 256 | * list of pointers to `const git_commit *`. Note that this 257 | * is a convenience method which may not be safe to export 258 | * for certain languages or compilers 259 | * 260 | * All other parameters remain the same 261 | * 262 | * @see git_commit_create 263 | */ 264 | GIT_EXTERN(int) git_commit_create_ov( 265 | git_oid *oid, 266 | git_repository *repo, 267 | const char *update_ref, 268 | const git_signature *author, 269 | const git_signature *committer, 270 | const char *message, 271 | const git_tree *tree, 272 | int parent_count, 273 | ...); 274 | 275 | 276 | /** 277 | * Create a new commit in the repository using 278 | * a variable argument list. 279 | * 280 | * The parents for the commit are specified as a variable 281 | * list of pointers to `const git_oid *`. Note that this 282 | * is a convenience method which may not be safe to export 283 | * for certain languages or compilers 284 | * 285 | * All other parameters remain the same 286 | * 287 | * @see git_commit_create 288 | */ 289 | GIT_EXTERN(int) git_commit_create_v( 290 | git_oid *oid, 291 | git_repository *repo, 292 | const char *update_ref, 293 | const git_signature *author, 294 | const git_signature *committer, 295 | const char *message, 296 | const git_oid *tree_oid, 297 | int parent_count, 298 | ...); 299 | 300 | /** @} */ 301 | GIT_END_DECL 302 | #endif 303 | -------------------------------------------------------------------------------- /test/fixtures/git2/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_common_h__ 26 | #define INCLUDE_git_common_h__ 27 | 28 | #include "thread-utils.h" 29 | #include 30 | #include 31 | #include 32 | 33 | #ifdef __cplusplus 34 | # define GIT_BEGIN_DECL extern "C" { 35 | # define GIT_END_DECL } 36 | #else 37 | /** Start declarations in C mode */ 38 | # define GIT_BEGIN_DECL /* empty */ 39 | /** End declarations in C mode */ 40 | # define GIT_END_DECL /* empty */ 41 | #endif 42 | 43 | /** Declare a public function exported for application use. */ 44 | #ifdef __GNUC__ 45 | # define GIT_EXTERN(type) extern \ 46 | __attribute__((visibility("default"))) \ 47 | type 48 | #elif defined(_MSC_VER) 49 | # define GIT_EXTERN(type) __declspec(dllexport) type 50 | #else 51 | # define GIT_EXTERN(type) extern type 52 | #endif 53 | 54 | /** Declare a public TLS symbol exported for application use. */ 55 | #ifdef __GNUC__ 56 | # define GIT_EXTERN_TLS(type) extern \ 57 | __attribute__((visibility("default"))) \ 58 | GIT_TLS \ 59 | type 60 | #elif defined(_MSC_VER) 61 | # define GIT_EXTERN_TLS(type) __declspec(dllexport) GIT_TLS type 62 | #else 63 | # define GIT_EXTERN_TLS(type) extern GIT_TLS type 64 | #endif 65 | 66 | /** Declare a function as always inlined. */ 67 | #if defined(_MSC_VER) 68 | # define GIT_INLINE(type) static __inline type 69 | #else 70 | # define GIT_INLINE(type) static inline type 71 | #endif 72 | 73 | /** Declare a function's takes printf style arguments. */ 74 | #ifdef __GNUC__ 75 | # define GIT_FORMAT_PRINTF(a,b) __attribute__((format (printf, a, b))) 76 | #else 77 | # define GIT_FORMAT_PRINTF(a,b) /* empty */ 78 | #endif 79 | 80 | /** 81 | * @file git2/common.h 82 | * @brief Git common platform definitions 83 | * @defgroup git_common Git common platform definitions 84 | * @ingroup Git 85 | * @{ 86 | */ 87 | 88 | GIT_BEGIN_DECL 89 | 90 | typedef struct { 91 | char **strings; 92 | size_t count; 93 | } git_strarray; 94 | 95 | GIT_EXTERN(void) git_strarray_free(git_strarray *array); 96 | 97 | /** @} */ 98 | GIT_END_DECL 99 | #endif 100 | -------------------------------------------------------------------------------- /test/fixtures/git2/errors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_errors_h__ 26 | #define INCLUDE_git_errors_h__ 27 | 28 | #include "common.h" 29 | 30 | /** 31 | * @file git2/errors.h 32 | * @brief Git error handling routines and variables 33 | * @ingroup Git 34 | * @{ 35 | */ 36 | GIT_BEGIN_DECL 37 | 38 | /** Operation completed successfully. */ 39 | #define GIT_SUCCESS 0 40 | 41 | /** 42 | * Operation failed, with unspecified reason. 43 | * This value also serves as the base error code; all other 44 | * error codes are subtracted from it such that all errors 45 | * are < 0, in typical POSIX C tradition. 46 | */ 47 | #define GIT_ERROR -1 48 | 49 | /** Input was not a properly formatted Git object id. */ 50 | #define GIT_ENOTOID (GIT_ERROR - 1) 51 | 52 | /** Input does not exist in the scope searched. */ 53 | #define GIT_ENOTFOUND (GIT_ERROR - 2) 54 | 55 | /** Not enough space available. */ 56 | #define GIT_ENOMEM (GIT_ERROR - 3) 57 | 58 | /** Consult the OS error information. */ 59 | #define GIT_EOSERR (GIT_ERROR - 4) 60 | 61 | /** The specified object is of invalid type */ 62 | #define GIT_EOBJTYPE (GIT_ERROR - 5) 63 | 64 | /** The specified object has its data corrupted */ 65 | #define GIT_EOBJCORRUPTED (GIT_ERROR - 6) 66 | 67 | /** The specified repository is invalid */ 68 | #define GIT_ENOTAREPO (GIT_ERROR - 7) 69 | 70 | /** The object type is invalid or doesn't match */ 71 | #define GIT_EINVALIDTYPE (GIT_ERROR - 8) 72 | 73 | /** The object cannot be written because it's missing internal data */ 74 | #define GIT_EMISSINGOBJDATA (GIT_ERROR - 9) 75 | 76 | /** The packfile for the ODB is corrupted */ 77 | #define GIT_EPACKCORRUPTED (GIT_ERROR - 10) 78 | 79 | /** Failed to acquire or release a file lock */ 80 | #define GIT_EFLOCKFAIL (GIT_ERROR - 11) 81 | 82 | /** The Z library failed to inflate/deflate an object's data */ 83 | #define GIT_EZLIB (GIT_ERROR - 12) 84 | 85 | /** The queried object is currently busy */ 86 | #define GIT_EBUSY (GIT_ERROR - 13) 87 | 88 | /** The index file is not backed up by an existing repository */ 89 | #define GIT_EBAREINDEX (GIT_ERROR - 14) 90 | 91 | /** The name of the reference is not valid */ 92 | #define GIT_EINVALIDREFNAME (GIT_ERROR - 15) 93 | 94 | /** The specified reference has its data corrupted */ 95 | #define GIT_EREFCORRUPTED (GIT_ERROR - 16) 96 | 97 | /** The specified symbolic reference is too deeply nested */ 98 | #define GIT_ETOONESTEDSYMREF (GIT_ERROR - 17) 99 | 100 | /** The pack-refs file is either corrupted or its format is not currently supported */ 101 | #define GIT_EPACKEDREFSCORRUPTED (GIT_ERROR - 18) 102 | 103 | /** The path is invalid */ 104 | #define GIT_EINVALIDPATH (GIT_ERROR - 19) 105 | 106 | /** The revision walker is empty; there are no more commits left to iterate */ 107 | #define GIT_EREVWALKOVER (GIT_ERROR - 20) 108 | 109 | /** The state of the reference is not valid */ 110 | #define GIT_EINVALIDREFSTATE (GIT_ERROR - 21) 111 | 112 | /** This feature has not been implemented yet */ 113 | #define GIT_ENOTIMPLEMENTED (GIT_ERROR - 22) 114 | 115 | /** A reference with this name already exists */ 116 | #define GIT_EEXISTS (GIT_ERROR - 23) 117 | 118 | /** The given integer literal is too large to be parsed */ 119 | #define GIT_EOVERFLOW (GIT_ERROR - 24) 120 | 121 | /** The given literal is not a valid number */ 122 | #define GIT_ENOTNUM (GIT_ERROR - 25) 123 | 124 | /** Streaming error */ 125 | #define GIT_ESTREAM (GIT_ERROR - 26) 126 | 127 | /** invalid arguments to function */ 128 | #define GIT_EINVALIDARGS (GIT_ERROR - 27) 129 | 130 | /** 131 | * Return a detailed error string with the latest error 132 | * that occurred in the library. 133 | * @return a string explaining the error 134 | */ 135 | GIT_EXTERN(const char *) git_lasterror(void); 136 | 137 | /** 138 | * strerror() for the Git library 139 | * 140 | * Get a string description for a given error code. 141 | * NOTE: This method will be eventually deprecated in favor 142 | * of the new `git_lasterror`. 143 | * 144 | * @param num The error code to explain 145 | * @return a string explaining the error code 146 | */ 147 | GIT_EXTERN(const char *) git_strerror(int num); 148 | 149 | /** @} */ 150 | GIT_END_DECL 151 | #endif 152 | -------------------------------------------------------------------------------- /test/fixtures/git2/index.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_index_h__ 26 | #define INCLUDE_git_index_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | 32 | /** 33 | * @file git2/index.h 34 | * @brief Git index parsing and manipulation routines 35 | * @defgroup git_index Git index parsing and manipulation routines 36 | * @ingroup Git 37 | * @{ 38 | */ 39 | GIT_BEGIN_DECL 40 | 41 | #define GIT_IDXENTRY_NAMEMASK (0x0fff) 42 | #define GIT_IDXENTRY_STAGEMASK (0x3000) 43 | #define GIT_IDXENTRY_EXTENDED (0x4000) 44 | #define GIT_IDXENTRY_VALID (0x8000) 45 | #define GIT_IDXENTRY_STAGESHIFT 12 46 | 47 | /** 48 | * Flags are divided into two parts: in-memory flags and 49 | * on-disk ones. Flags in GIT_IDXENTRY_EXTENDED_FLAGS 50 | * will get saved on-disk. 51 | * 52 | * In-memory only flags: 53 | */ 54 | #define GIT_IDXENTRY_UPDATE (1 << 0) 55 | #define GIT_IDXENTRY_REMOVE (1 << 1) 56 | #define GIT_IDXENTRY_UPTODATE (1 << 2) 57 | #define GIT_IDXENTRY_ADDED (1 << 3) 58 | 59 | #define GIT_IDXENTRY_HASHED (1 << 4) 60 | #define GIT_IDXENTRY_UNHASHED (1 << 5) 61 | #define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */ 62 | #define GIT_IDXENTRY_CONFLICTED (1 << 7) 63 | 64 | #define GIT_IDXENTRY_UNPACKED (1 << 8) 65 | #define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9) 66 | 67 | /** 68 | * Extended on-disk flags: 69 | */ 70 | #define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13) 71 | #define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14) 72 | /* GIT_IDXENTRY_EXTENDED2 is for future extension */ 73 | #define GIT_IDXENTRY_EXTENDED2 (1 << 15) 74 | 75 | #define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE) 76 | 77 | /** Time used in a git index entry */ 78 | typedef struct { 79 | git_time_t seconds; 80 | /* nsec should not be stored as time_t compatible */ 81 | unsigned int nanoseconds; 82 | } git_index_time; 83 | 84 | /** Memory representation of a file entry in the index. */ 85 | typedef struct git_index_entry { 86 | git_index_time ctime; 87 | git_index_time mtime; 88 | 89 | unsigned int dev; 90 | unsigned int ino; 91 | unsigned int mode; 92 | unsigned int uid; 93 | unsigned int gid; 94 | git_off_t file_size; 95 | 96 | git_oid oid; 97 | 98 | unsigned short flags; 99 | unsigned short flags_extended; 100 | 101 | char *path; 102 | } git_index_entry; 103 | 104 | 105 | /** 106 | * Create a new Git index object as a memory representation 107 | * of the Git index file in 'index_path', without a repository 108 | * to back it. 109 | * 110 | * Since there is no ODB behind this index, any Index methods 111 | * which rely on the ODB (e.g. index_add) will fail with the 112 | * GIT_EBAREINDEX error code. 113 | * 114 | * @param index the pointer for the new index 115 | * @param index_path the path to the index file in disk 116 | * @return 0 on success; error code otherwise 117 | */ 118 | GIT_EXTERN(int) git_index_open_bare(git_index **index, const char *index_path); 119 | 120 | /** 121 | * Open the Index inside the git repository pointed 122 | * by 'repo'. 123 | * 124 | * @param index the pointer for the new index 125 | * @param repo the git repo which owns the index 126 | * @return 0 on success; error code otherwise 127 | */ 128 | GIT_EXTERN(int) git_index_open_inrepo(git_index **index, git_repository *repo); 129 | 130 | /** 131 | * Clear the contents (all the entries) of an index object. 132 | * This clears the index object in memory; changes must be manually 133 | * written to disk for them to take effect. 134 | * 135 | * @param index an existing index object 136 | */ 137 | GIT_EXTERN(void) git_index_clear(git_index *index); 138 | 139 | /** 140 | * Free an existing index object. 141 | * 142 | * @param index an existing index object 143 | */ 144 | GIT_EXTERN(void) git_index_free(git_index *index); 145 | 146 | /** 147 | * Update the contents of an existing index object in memory 148 | * by reading from the hard disk. 149 | * 150 | * @param index an existing index object 151 | * @return 0 on success, otherwise an error code 152 | */ 153 | GIT_EXTERN(int) git_index_read(git_index *index); 154 | 155 | /** 156 | * Write an existing index object from memory back to disk 157 | * using an atomic file lock. 158 | * 159 | * @param index an existing index object 160 | * @return 0 on success, otherwise an error code 161 | */ 162 | GIT_EXTERN(int) git_index_write(git_index *index); 163 | 164 | /** 165 | * Find the first index of any entries which point to given 166 | * path in the Git index. 167 | * 168 | * @param index an existing index object 169 | * @param path path to search 170 | * @return an index >= 0 if found, -1 otherwise 171 | */ 172 | GIT_EXTERN(int) git_index_find(git_index *index, const char *path); 173 | 174 | /** 175 | * Add or update an index entry from a file in disk 176 | * 177 | * The file `path` must be relative to the repository's 178 | * working folder and must be readable. 179 | * 180 | * This method will fail in bare index instances. 181 | * 182 | * @param index an existing index object 183 | * @param path filename to add 184 | * @param stage stage for the entry 185 | * @return 0 on success, otherwise an error code 186 | */ 187 | GIT_EXTERN(int) git_index_add(git_index *index, const char *path, int stage); 188 | 189 | /** 190 | * Add or update an index entry from an in-memory struct 191 | * 192 | * A full copy (including the 'path' string) of the given 193 | * 'source_entry' will be inserted on the index. 194 | * 195 | * @param index an existing index object 196 | * @param source_entry new entry object 197 | * @return 0 on success, otherwise an error code 198 | */ 199 | GIT_EXTERN(int) git_index_add2(git_index *index, const git_index_entry *source_entry); 200 | 201 | /** 202 | * Add (append) an index entry from a file in disk 203 | * 204 | * A new entry will always be inserted into the index; 205 | * if the index already contains an entry for such 206 | * path, the old entry will **not** be replaced. 207 | * 208 | * The file `path` must be relative to the repository's 209 | * working folder and must be readable. 210 | * 211 | * This method will fail in bare index instances. 212 | * 213 | * @param index an existing index object 214 | * @param path filename to add 215 | * @param stage stage for the entry 216 | * @return 0 on success, otherwise an error code 217 | */ 218 | GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage); 219 | 220 | /** 221 | * Add (append) an index entry from an in-memory struct 222 | * 223 | * A new entry will always be inserted into the index; 224 | * if the index already contains an entry for the path 225 | * in the `entry` struct, the old entry will **not** be 226 | * replaced. 227 | * 228 | * A full copy (including the 'path' string) of the given 229 | * 'source_entry' will be inserted on the index. 230 | * 231 | * @param index an existing index object 232 | * @param source_entry new entry object 233 | * @return 0 on success, otherwise an error code 234 | */ 235 | GIT_EXTERN(int) git_index_append2(git_index *index, const git_index_entry *source_entry); 236 | 237 | /** 238 | * Remove an entry from the index 239 | * 240 | * @param index an existing index object 241 | * @param position position of the entry to remove 242 | * @return 0 on success, otherwise an error code 243 | */ 244 | GIT_EXTERN(int) git_index_remove(git_index *index, int position); 245 | 246 | 247 | /** 248 | * Get a pointer to one of the entries in the index 249 | * 250 | * This entry can be modified, and the changes will be written 251 | * back to disk on the next write() call. 252 | * 253 | * @param index an existing index object 254 | * @param n the position of the entry 255 | * @return a pointer to the entry; NULL if out of bounds 256 | */ 257 | GIT_EXTERN(git_index_entry *) git_index_get(git_index *index, int n); 258 | 259 | /** 260 | * Get the count of entries currently in the index 261 | * 262 | * @param index an existing index object 263 | * @return integer of count of current entries 264 | */ 265 | GIT_EXTERN(unsigned int) git_index_entrycount(git_index *index); 266 | 267 | 268 | /** @} */ 269 | GIT_END_DECL 270 | #endif 271 | -------------------------------------------------------------------------------- /test/fixtures/git2/object.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_object_h__ 26 | #define INCLUDE_git_object_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | 32 | /** 33 | * @file git2/object.h 34 | * @brief Git revision object management routines 35 | * @defgroup git_object Git revision object management routines 36 | * @ingroup Git 37 | * @{ 38 | */ 39 | GIT_BEGIN_DECL 40 | 41 | /** 42 | * Lookup a reference to one of the objects in a repostory. 43 | * 44 | * The generated reference is owned by the repository and 45 | * should be closed with the `git_object_close` method 46 | * instead of free'd manually. 47 | * 48 | * The 'type' parameter must match the type of the object 49 | * in the odb; the method will fail otherwise. 50 | * The special value 'GIT_OBJ_ANY' may be passed to let 51 | * the method guess the object's type. 52 | * 53 | * @param object pointer to the looked-up object 54 | * @param repo the repository to look up the object 55 | * @param id the unique identifier for the object 56 | * @param type the type of the object 57 | * @return a reference to the object 58 | */ 59 | GIT_EXTERN(int) git_object_lookup(git_object **object, git_repository *repo, const git_oid *id, git_otype type); 60 | 61 | /** 62 | * Get the id (SHA1) of a repository object 63 | * 64 | * @param obj the repository object 65 | * @return the SHA1 id 66 | */ 67 | GIT_EXTERN(const git_oid *) git_object_id(const git_object *obj); 68 | 69 | /** 70 | * Get the object type of an object 71 | * 72 | * @param obj the repository object 73 | * @return the object's type 74 | */ 75 | GIT_EXTERN(git_otype) git_object_type(const git_object *obj); 76 | 77 | /** 78 | * Get the repository that owns this object 79 | * 80 | * @param obj the object 81 | * @return the repository who owns this object 82 | */ 83 | GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj); 84 | 85 | /** 86 | * Close an open object 87 | * 88 | * This method instructs the library to close an existing 89 | * object; note that git_objects are owned and cached by the repository 90 | * so the object may or may not be freed after this library call, 91 | * depending on how agressive is the caching mechanism used 92 | * by the repository. 93 | * 94 | * IMPORTANT: 95 | * It *is* necessary to call this method when you stop using 96 | * an object. Failure to do so will cause a memory leak. 97 | * 98 | * @param object the object to close 99 | */ 100 | GIT_EXTERN(void) git_object_close(git_object *object); 101 | 102 | /** 103 | * Convert an object type to it's string representation. 104 | * 105 | * The result is a pointer to a string in static memory and 106 | * should not be free()'ed. 107 | * 108 | * @param type object type to convert. 109 | * @return the corresponding string representation. 110 | */ 111 | GIT_EXTERN(const char *) git_object_type2string(git_otype type); 112 | 113 | /** 114 | * Convert a string object type representation to it's git_otype. 115 | * 116 | * @param str the string to convert. 117 | * @return the corresponding git_otype. 118 | */ 119 | GIT_EXTERN(git_otype) git_object_string2type(const char *str); 120 | 121 | /** 122 | * Determine if the given git_otype is a valid loose object type. 123 | * 124 | * @param type object type to test. 125 | * @return true if the type represents a valid loose object type, 126 | * false otherwise. 127 | */ 128 | GIT_EXTERN(int) git_object_typeisloose(git_otype type); 129 | 130 | /** 131 | * Get the size in bytes for the structure which 132 | * acts as an in-memory representation of any given 133 | * object type. 134 | * 135 | * For all the core types, this would the equivalent 136 | * of calling `sizeof(git_commit)` if the core types 137 | * were not opaque on the external API. 138 | * 139 | * @param type object type to get its size 140 | * @return size in bytes of the object 141 | */ 142 | GIT_EXTERN(size_t) git_object__size(git_otype type); 143 | 144 | /** @} */ 145 | GIT_END_DECL 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /test/fixtures/git2/odb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_odb_h__ 26 | #define INCLUDE_git_odb_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | #include "odb_backend.h" 32 | 33 | /** 34 | * @file git2/odb.h 35 | * @brief Git object database routines 36 | * @defgroup git_odb Git object database routines 37 | * @ingroup Git 38 | * @{ 39 | */ 40 | GIT_BEGIN_DECL 41 | 42 | /** 43 | * Create a new object database with no backends. 44 | * 45 | * Before the ODB can be used for read/writing, a custom database 46 | * backend must be manually added using `git_odb_add_backend()` 47 | * 48 | * @param out location to store the database pointer, if opened. 49 | * Set to NULL if the open failed. 50 | * @return GIT_SUCCESS if the database was created; otherwise an error 51 | * code describing why the open was not possible. 52 | */ 53 | GIT_EXTERN(int) git_odb_new(git_odb **out); 54 | 55 | /** 56 | * Create a new object database and automatically add 57 | * the two default backends: 58 | * 59 | * - git_odb_backend_loose: read and write loose object files 60 | * from disk, assuming `objects_dir` as the Objects folder 61 | * 62 | * - git_odb_backend_pack: read objects from packfiles, 63 | * assuming `objects_dir` as the Objects folder which 64 | * contains a 'pack/' folder with the corresponding data 65 | * 66 | * @param out location to store the database pointer, if opened. 67 | * Set to NULL if the open failed. 68 | * @param objects_dir path of the backends' "objects" directory. 69 | * @return GIT_SUCCESS if the database opened; otherwise an error 70 | * code describing why the open was not possible. 71 | */ 72 | GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir); 73 | 74 | /** 75 | * Add a custom backend to an existing Object DB 76 | * 77 | * Read for more information. 78 | * 79 | * @param odb database to add the backend to 80 | * @paramm backend pointer to a git_odb_backend instance 81 | * @return 0 on sucess; error code otherwise 82 | */ 83 | GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority); 84 | 85 | /** 86 | * Add a custom backend to an existing Object DB; this 87 | * backend will work as an alternate. 88 | * 89 | * Alternate backends are always checked for objects *after* 90 | * all the main backends have been exhausted. 91 | * 92 | * Writing is disabled on alternate backends. 93 | * 94 | * Read for more information. 95 | * 96 | * @param odb database to add the backend to 97 | * @paramm backend pointer to a git_odb_backend instance 98 | * @return 0 on sucess; error code otherwise 99 | */ 100 | GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority); 101 | 102 | /** 103 | * Close an open object database. 104 | * 105 | * @param db database pointer to close. If NULL no action is taken. 106 | */ 107 | GIT_EXTERN(void) git_odb_close(git_odb *db); 108 | 109 | /** 110 | * Read an object from the database. 111 | * 112 | * This method queries all avaiable ODB backends 113 | * trying to read the given OID. 114 | * 115 | * The returned object is reference counted and 116 | * internally cached, so it should be closed 117 | * by the user once it's no longer in use. 118 | * 119 | * @param out pointer where to store the read object 120 | * @param db database to search for the object in. 121 | * @param id identity of the object to read. 122 | * @return 123 | * - GIT_SUCCESS if the object was read; 124 | * - GIT_ENOTFOUND if the object is not in the database. 125 | */ 126 | GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id); 127 | 128 | /** 129 | * Read the header of an object from the database, without 130 | * reading its full contents. 131 | * 132 | * The header includes the length and the type of an object. 133 | * 134 | * Note that most backends do not support reading only the header 135 | * of an object, so the whole object will be read and then the 136 | * header will be returned. 137 | * 138 | * @param len_p pointer where to store the length 139 | * @param type_p pointer where to store the type 140 | * @param db database to search for the object in. 141 | * @param id identity of the object to read. 142 | * @return 143 | * - GIT_SUCCESS if the object was read; 144 | * - GIT_ENOTFOUND if the object is not in the database. 145 | */ 146 | GIT_EXTERN(int) git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id); 147 | 148 | /** 149 | * Determine if the given object can be found in the object database. 150 | * 151 | * @param db database to be searched for the given object. 152 | * @param id the object to search for. 153 | * @return 154 | * - 1, if the object was found 155 | * - 0, otherwise 156 | */ 157 | GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id); 158 | 159 | /** 160 | * Write an object directly into the ODB 161 | * 162 | * This method writes a full object straight into the ODB. 163 | * For most cases, it is preferred to write objects through a write 164 | * stream, which is both faster and less memory intensive, specially 165 | * for big objects. 166 | * 167 | * This method is provided for compatibility with custom backends 168 | * which are not able to support streaming writes 169 | * 170 | * @param oid pointer to store the OID result of the write 171 | * @param odb object database where to store the object 172 | * @param data buffer with the data to storr 173 | * @param len size of the buffer 174 | * @param type type of the data to store 175 | * @return 0 on success; error code otherwise 176 | */ 177 | GIT_EXTERN(int) git_odb_write(git_oid *oid, git_odb *odb, const void *data, size_t len, git_otype type); 178 | 179 | /** 180 | * Open a stream to write an object into the ODB 181 | * 182 | * The type and final length of the object must be specified 183 | * when opening the stream. 184 | * 185 | * The returned stream will be of type `GIT_STREAM_WRONLY` and 186 | * will have the following methods: 187 | * 188 | * - stream->write: write `n` bytes into the stream 189 | * - stream->finalize_write: close the stream and store the object in 190 | * the odb 191 | * - stream->free: free the stream 192 | * 193 | * The streaming write won't be effective until `stream->finalize_write` 194 | * is called and returns without an error 195 | * 196 | * The stream must always be free'd or will leak memory. 197 | * 198 | * @see git_odb_stream 199 | * 200 | * @param stream pointer where to store the stream 201 | * @param db object database where the stream will write 202 | * @param size final size of the object that will be written 203 | * @param type type of the object that will be written 204 | * @return 0 if the stream was created; error code otherwise 205 | */ 206 | GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_t size, git_otype type); 207 | 208 | /** 209 | * Open a stream to read an object from the ODB 210 | * 211 | * Note that most backends do *not* support streaming reads 212 | * because they store their objects as compressed/delta'ed blobs. 213 | * 214 | * It's recommended to use `git_odb_read` instead, which is 215 | * assured to work on all backends. 216 | * 217 | * The returned stream will be of type `GIT_STREAM_RDONLY` and 218 | * will have the following methods: 219 | * 220 | * - stream->read: read `n` bytes from the stream 221 | * - stream->free: free the stream 222 | * 223 | * The stream must always be free'd or will leak memory. 224 | * 225 | * @see git_odb_stream 226 | * 227 | * @param stream pointer where to store the stream 228 | * @param db object database where the stream will read from 229 | * @param oid oid of the object the stream will read from 230 | * @return 0 if the stream was created; error code otherwise 231 | */ 232 | GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oid); 233 | 234 | /** 235 | * Determine the object-ID (sha1 hash) of a data buffer 236 | * 237 | * The resulting SHA-1 OID will the itentifier for the data 238 | * buffer as if the data buffer it were to written to the ODB. 239 | * 240 | * @param id the resulting object-ID. 241 | * @param data data to hash 242 | * @param len size of the data 243 | * @param type of the data to hash 244 | * @return 0 on success; error code otherwise 245 | */ 246 | GIT_EXTERN(int) git_odb_hash(git_oid *id, const void *data, size_t len, git_otype type); 247 | 248 | /** 249 | * Close an ODB object 250 | * 251 | * This method must always be called once a `git_odb_object` is no 252 | * longer needed, otherwise memory will leak. 253 | * 254 | * @param object object to close 255 | */ 256 | GIT_EXTERN(void) git_odb_object_close(git_odb_object *object); 257 | 258 | /** 259 | * Return the OID of an ODB object 260 | * 261 | * This is the OID from which the object was read from 262 | * 263 | * @param object the object 264 | * @return a pointer to the OID 265 | */ 266 | GIT_EXTERN(const git_oid *) git_odb_object_id(git_odb_object *object); 267 | 268 | /** 269 | * Return the data of an ODB object 270 | * 271 | * This is the uncompressed, raw data as read from the ODB, 272 | * without the leading header. 273 | * 274 | * This pointer is owned by the object and shall not be free'd. 275 | * 276 | * @param object the object 277 | * @return a pointer to the data 278 | */ 279 | GIT_EXTERN(const void *) git_odb_object_data(git_odb_object *object); 280 | 281 | /** 282 | * Return the size of an ODB object 283 | * 284 | * This is the real size of the `data` buffer, not the 285 | * actual size of the object. 286 | * 287 | * @param object the object 288 | * @return the size 289 | */ 290 | GIT_EXTERN(size_t) git_odb_object_size(git_odb_object *object); 291 | 292 | /** 293 | * Return the type of an ODB object 294 | * 295 | * @param object the object 296 | * @return the type 297 | */ 298 | GIT_EXTERN(git_otype) git_odb_object_type(git_odb_object *object); 299 | 300 | /** @} */ 301 | GIT_END_DECL 302 | #endif 303 | -------------------------------------------------------------------------------- /test/fixtures/git2/odb_backend.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_odb_backend_h__ 26 | #define INCLUDE_git_odb_backend_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | 32 | /** 33 | * @file git2/backend.h 34 | * @brief Git custom backend functions 35 | * @defgroup git_backend Git custom backend API 36 | * @ingroup Git 37 | * @{ 38 | */ 39 | GIT_BEGIN_DECL 40 | 41 | struct git_odb_stream; 42 | 43 | /** An instance for a custom backend */ 44 | struct git_odb_backend { 45 | git_odb *odb; 46 | 47 | int (* read)( 48 | void **, size_t *, git_otype *, 49 | struct git_odb_backend *, 50 | const git_oid *); 51 | 52 | int (* read_header)( 53 | size_t *, git_otype *, 54 | struct git_odb_backend *, 55 | const git_oid *); 56 | 57 | int (* write)( 58 | git_oid *, 59 | struct git_odb_backend *, 60 | const void *, 61 | size_t, 62 | git_otype); 63 | 64 | int (* writestream)( 65 | struct git_odb_stream **, 66 | struct git_odb_backend *, 67 | size_t, 68 | git_otype); 69 | 70 | int (* readstream)( 71 | struct git_odb_stream **, 72 | struct git_odb_backend *, 73 | const git_oid *); 74 | 75 | int (* exists)( 76 | struct git_odb_backend *, 77 | const git_oid *); 78 | 79 | void (* free)(struct git_odb_backend *); 80 | }; 81 | 82 | /** A stream to read/write from a backend */ 83 | struct git_odb_stream { 84 | struct git_odb_backend *backend; 85 | int mode; 86 | 87 | int (*read)(struct git_odb_stream *stream, char *buffer, size_t len); 88 | int (*write)(struct git_odb_stream *stream, const char *buffer, size_t len); 89 | int (*finalize_write)(git_oid *oid_p, struct git_odb_stream *stream); 90 | void (*free)(struct git_odb_stream *stream); 91 | }; 92 | 93 | /** Streaming mode */ 94 | typedef enum { 95 | GIT_STREAM_RDONLY = (1 << 1), 96 | GIT_STREAM_WRONLY = (1 << 2), 97 | GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY), 98 | } git_odb_streammode; 99 | 100 | 101 | GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir); 102 | GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **backend_out, const char *objects_dir); 103 | GIT_EXTERN(int) git_odb_backend_sqlite(git_odb_backend **backend_out, const char *sqlite_db); 104 | 105 | GIT_END_DECL 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /test/fixtures/git2/oid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_oid_h__ 26 | #define INCLUDE_git_oid_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | 31 | /** 32 | * @file git2/oid.h 33 | * @brief Git object id routines 34 | * @defgroup git_oid Git object id routines 35 | * @ingroup Git 36 | * @{ 37 | */ 38 | GIT_BEGIN_DECL 39 | 40 | /** Size (in bytes) of a raw/binary oid */ 41 | #define GIT_OID_RAWSZ 20 42 | 43 | /** Size (in bytes) of a hex formatted oid */ 44 | #define GIT_OID_HEXSZ (GIT_OID_RAWSZ * 2) 45 | 46 | /** Unique identity of any object (commit, tree, blob, tag). */ 47 | typedef struct { 48 | /** raw binary formatted id */ 49 | unsigned char id[GIT_OID_RAWSZ]; 50 | } git_oid; 51 | 52 | /** 53 | * Parse a hex formatted object id into a git_oid. 54 | * @param out oid structure the result is written into. 55 | * @param str input hex string; must be pointing at the start of 56 | * the hex sequence and have at least the number of bytes 57 | * needed for an oid encoded in hex (40 bytes). 58 | * @return GIT_SUCCESS if valid; GIT_ENOTOID on failure. 59 | */ 60 | GIT_EXTERN(int) git_oid_mkstr(git_oid *out, const char *str); 61 | 62 | /** 63 | * Copy an already raw oid into a git_oid structure. 64 | * @param out oid structure the result is written into. 65 | * @param raw the raw input bytes to be copied. 66 | */ 67 | GIT_EXTERN(void) git_oid_mkraw(git_oid *out, const unsigned char *raw); 68 | 69 | /** 70 | * Format a git_oid into a hex string. 71 | * @param str output hex string; must be pointing at the start of 72 | * the hex sequence and have at least the number of bytes 73 | * needed for an oid encoded in hex (40 bytes). Only the 74 | * oid digits are written; a '\\0' terminator must be added 75 | * by the caller if it is required. 76 | * @param oid oid structure to format. 77 | */ 78 | GIT_EXTERN(void) git_oid_fmt(char *str, const git_oid *oid); 79 | 80 | /** 81 | * Format a git_oid into a loose-object path string. 82 | *

83 | * The resulting string is "aa/...", where "aa" is the first two 84 | * hex digitis of the oid and "..." is the remaining 38 digits. 85 | * 86 | * @param str output hex string; must be pointing at the start of 87 | * the hex sequence and have at least the number of bytes 88 | * needed for an oid encoded in hex (41 bytes). Only the 89 | * oid digits are written; a '\\0' terminator must be added 90 | * by the caller if it is required. 91 | * @param oid oid structure to format. 92 | */ 93 | GIT_EXTERN(void) git_oid_pathfmt(char *str, const git_oid *oid); 94 | 95 | /** 96 | * Format a gid_oid into a newly allocated c-string. 97 | * @param oid the oid structure to format 98 | * @return the c-string; NULL if memory is exhausted. Caller must 99 | * deallocate the string with free(). 100 | */ 101 | GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *oid); 102 | 103 | /** 104 | * Format a git_oid into a buffer as a hex format c-string. 105 | *

106 | * If the buffer is smaller than GIT_OID_HEXSZ+1, then the resulting 107 | * oid c-string will be truncated to n-1 characters. If there are 108 | * any input parameter errors (out == NULL, n == 0, oid == NULL), 109 | * then a pointer to an empty string is returned, so that the return 110 | * value can always be printed. 111 | * 112 | * @param out the buffer into which the oid string is output. 113 | * @param n the size of the out buffer. 114 | * @param oid the oid structure to format. 115 | * @return the out buffer pointer, assuming no input parameter 116 | * errors, otherwise a pointer to an empty string. 117 | */ 118 | GIT_EXTERN(char *) git_oid_to_string(char *out, size_t n, const git_oid *oid); 119 | 120 | /** 121 | * Copy an oid from one structure to another. 122 | * @param out oid structure the result is written into. 123 | * @param src oid structure to copy from. 124 | */ 125 | GIT_EXTERN(void) git_oid_cpy(git_oid *out, const git_oid *src); 126 | 127 | /** 128 | * Compare two oid structures. 129 | * @param a first oid structure. 130 | * @param b second oid structure. 131 | * @return <0, 0, >0 if a < b, a == b, a > b. 132 | */ 133 | GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b); 134 | 135 | /** 136 | * OID Shortener object 137 | */ 138 | typedef struct git_oid_shorten git_oid_shorten; 139 | 140 | /** 141 | * Create a new OID shortener. 142 | * 143 | * The OID shortener is used to process a list of OIDs 144 | * in text form and return the shortest length that would 145 | * uniquely identify all of them. 146 | * 147 | * E.g. look at the result of `git log --abbrev`. 148 | * 149 | * @param min_length The minimal length for all identifiers, 150 | * which will be used even if shorter OIDs would still 151 | * be unique. 152 | * @return a `git_oid_shorten` instance, NULL if OOM 153 | */ 154 | git_oid_shorten *git_oid_shorten_new(size_t min_length); 155 | 156 | /** 157 | * Add a new OID to set of shortened OIDs and calculate 158 | * the minimal length to uniquely identify all the OIDs in 159 | * the set. 160 | * 161 | * The OID is expected to be a 40-char hexadecimal string. 162 | * The OID is owned by the user and will not be modified 163 | * or freed. 164 | * 165 | * For performance reasons, there is a hard-limit of how many 166 | * OIDs can be added to a single set (around ~22000, assuming 167 | * a mostly randomized distribution), which should be enough 168 | * for any kind of program, and keeps the algorithm fast and 169 | * memory-efficient. 170 | * 171 | * Attempting to add more than those OIDs will result in a 172 | * GIT_ENOMEM error 173 | * 174 | * @param os a `git_oid_shorten` instance 175 | * @param text_oid an OID in text form 176 | * @return the minimal length to uniquely identify all OIDs 177 | * added so far to the set; or an error code (<0) if an 178 | * error occurs. 179 | */ 180 | int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid); 181 | 182 | /** 183 | * Free an OID shortener instance 184 | * 185 | * @param os a `git_oid_shorten` instance 186 | */ 187 | void git_oid_shorten_free(git_oid_shorten *os); 188 | 189 | /** @} */ 190 | GIT_END_DECL 191 | #endif 192 | -------------------------------------------------------------------------------- /test/fixtures/git2/refs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_refs_h__ 26 | #define INCLUDE_git_refs_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | 32 | /** 33 | * @file git2/refs.h 34 | * @brief Git reference management routines 35 | * @defgroup git_reference Git reference management routines 36 | * @ingroup Git 37 | * @{ 38 | */ 39 | GIT_BEGIN_DECL 40 | 41 | /** 42 | * Lookup a reference by its name in a repository. 43 | * 44 | * The generated reference is owned by the repository and 45 | * should not be freed by the user. 46 | * 47 | * @param reference_out pointer to the looked-up reference 48 | * @param repo the repository to look up the reference 49 | * @param name the long name for the reference (e.g. HEAD, ref/heads/master, refs/tags/v0.1.0, ...) 50 | * @return 0 on success; error code otherwise 51 | */ 52 | GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_repository *repo, const char *name); 53 | 54 | /** 55 | * Create a new symbolic reference. 56 | * 57 | * The reference will be created in the repository and written 58 | * to the disk. 59 | * 60 | * This reference is owned by the repository and shall not 61 | * be free'd by the user. 62 | * 63 | * @param ref_out Pointer to the newly created reference 64 | * @param repo Repository where that reference will live 65 | * @param name The name of the reference 66 | * @param target The target of the reference 67 | * @return 0 on success; error code otherwise 68 | */ 69 | GIT_EXTERN(int) git_reference_create_symbolic(git_reference **ref_out, git_repository *repo, const char *name, const char *target); 70 | 71 | /** 72 | * Create a new symbolic reference, overwriting an existing one with 73 | * the same name, if it exists. 74 | * 75 | * If the new reference isn't a symbolic one, any pointers to the old 76 | * reference become invalid. 77 | * 78 | * The reference will be created in the repository and written 79 | * to the disk. 80 | * 81 | * This reference is owned by the repository and shall not 82 | * be free'd by the user. 83 | * 84 | * @param ref_out Pointer to the newly created reference 85 | * @param repo Repository where that reference will live 86 | * @param name The name of the reference 87 | * @param target The target of the reference 88 | * @return 0 on success; error code otherwise 89 | */ 90 | GIT_EXTERN(int) git_reference_create_symbolic_f(git_reference **ref_out, git_repository *repo, const char *name, const char *target); 91 | 92 | /** 93 | * Create a new object id reference. 94 | * 95 | * The reference will be created in the repository and written 96 | * to the disk. 97 | * 98 | * This reference is owned by the repository and shall not 99 | * be free'd by the user. 100 | * 101 | * @param ref_out Pointer to the newly created reference 102 | * @param repo Repository where that reference will live 103 | * @param name The name of the reference 104 | * @param id The object id pointed to by the reference. 105 | * @return 0 on success; error code otherwise 106 | */ 107 | GIT_EXTERN(int) git_reference_create_oid(git_reference **ref_out, git_repository *repo, const char *name, const git_oid *id); 108 | 109 | /** 110 | * Create a new object id reference, overwriting an existing one with 111 | * the same name, if it exists. 112 | * 113 | * If the new reference isn't an object id one, any pointers to the 114 | * old reference become invalid. 115 | * 116 | * The reference will be created in the repository and written 117 | * to the disk. 118 | * 119 | * This reference is owned by the repository and shall not 120 | * be free'd by the user. 121 | * 122 | * @param ref_out Pointer to the newly created reference 123 | * @param repo Repository where that reference will live 124 | * @param name The name of the reference 125 | * @param id The object id pointed to by the reference. 126 | * @return 0 on success; error code otherwise 127 | */ 128 | GIT_EXTERN(int) git_reference_create_oid_f(git_reference **ref_out, git_repository *repo, const char *name, const git_oid *id); 129 | 130 | /** 131 | * Get the OID pointed to by a reference. 132 | * 133 | * Only available if the reference is direct (i.e. not symbolic) 134 | * 135 | * @param ref The reference 136 | * @return a pointer to the oid if available, NULL otherwise 137 | */ 138 | GIT_EXTERN(const git_oid *) git_reference_oid(git_reference *ref); 139 | 140 | /** 141 | * Get full name to the reference pointed by this reference 142 | * 143 | * Only available if the reference is symbolic 144 | * 145 | * @param ref The reference 146 | * @return a pointer to the name if available, NULL otherwise 147 | */ 148 | GIT_EXTERN(const char *) git_reference_target(git_reference *ref); 149 | 150 | /** 151 | * Get the type of a reference 152 | * 153 | * Either direct (GIT_REF_OID) or symbolic (GIT_REF_SYMBOLIC) 154 | * 155 | * @param ref The reference 156 | * @return the type 157 | */ 158 | GIT_EXTERN(git_rtype) git_reference_type(git_reference *ref); 159 | 160 | /** 161 | * Get the full name of a reference 162 | * 163 | * @param ref The reference 164 | * @return the full name for the ref 165 | */ 166 | GIT_EXTERN(const char *) git_reference_name(git_reference *ref); 167 | 168 | /** 169 | * Resolve a symbolic reference 170 | * 171 | * Thie method iteratively peels a symbolic reference 172 | * until it resolves to a direct reference to an OID. 173 | * 174 | * If a direct reference is passed as an argument, 175 | * that reference is returned immediately 176 | * 177 | * @param resolved_ref Pointer to the peeled reference 178 | * @param ref The reference 179 | * @return 0 on success; error code otherwise 180 | */ 181 | GIT_EXTERN(int) git_reference_resolve(git_reference **resolved_ref, git_reference *ref); 182 | 183 | /** 184 | * Get the repository where a reference resides 185 | * 186 | * @param ref The reference 187 | * @return a pointer to the repo 188 | */ 189 | GIT_EXTERN(git_repository *) git_reference_owner(git_reference *ref); 190 | 191 | /** 192 | * Set the symbolic target of a reference. 193 | * 194 | * The reference must be a symbolic reference, otherwise 195 | * this method will fail. 196 | * 197 | * The reference will be automatically updated in 198 | * memory and on disk. 199 | * 200 | * @param ref The reference 201 | * @param target The new target for the reference 202 | * @return 0 on success; error code otherwise 203 | */ 204 | GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target); 205 | 206 | /** 207 | * Set the OID target of a reference. 208 | * 209 | * The reference must be a direct reference, otherwise 210 | * this method will fail. 211 | * 212 | * The reference will be automatically updated in 213 | * memory and on disk. 214 | * 215 | * @param ref The reference 216 | * @param target The new target OID for the reference 217 | * @return 0 on success; error code otherwise 218 | */ 219 | GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id); 220 | 221 | /** 222 | * Rename an existing reference 223 | * 224 | * This method works for both direct and symbolic references. 225 | * The new name will be checked for validity and may be 226 | * modified into a normalized form. 227 | * 228 | * The refernece will be immediately renamed in-memory 229 | * and on disk. 230 | * 231 | */ 232 | GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name); 233 | 234 | /** 235 | * Rename an existing reference, overwriting an existing one with the 236 | * same name, if it exists. 237 | * 238 | * This method works for both direct and symbolic references. 239 | * The new name will be checked for validity and may be 240 | * modified into a normalized form. 241 | * 242 | * The refernece will be immediately renamed in-memory 243 | * and on disk. 244 | * 245 | */ 246 | GIT_EXTERN(int) git_reference_rename_f(git_reference *ref, const char *new_name); 247 | 248 | /** 249 | * Delete an existing reference 250 | * 251 | * This method works for both direct and symbolic references. 252 | * 253 | * The reference will be immediately removed on disk and from 254 | * memory. The given reference pointer will no longer be valid. 255 | * 256 | */ 257 | GIT_EXTERN(int) git_reference_delete(git_reference *ref); 258 | 259 | /** 260 | * Pack all the loose references in the repository 261 | * 262 | * This method will load into the cache all the loose 263 | * references on the repository and update the 264 | * `packed-refs` file with them. 265 | * 266 | * Once the `packed-refs` file has been written properly, 267 | * the loose references will be removed from disk. 268 | * 269 | * WARNING: calling this method may invalidate any existing 270 | * references previously loaded on the cache. 271 | * 272 | * @param repo Repository where the loose refs will be packed 273 | * @return 0 on success; error code otherwise 274 | */ 275 | GIT_EXTERN(int) git_reference_packall(git_repository *repo); 276 | 277 | /** 278 | * Fill a list with all the references that can be found 279 | * in a repository. 280 | * 281 | * The listed references may be filtered by type, or using 282 | * a bitwise OR of several types. Use the magic value 283 | * `GIT_REF_LISTALL` to obtain all references, including 284 | * packed ones. 285 | * 286 | * The string array will be filled with the names of all 287 | * references; these values are owned by the user and 288 | * should be free'd manually when no longer needed, using 289 | * `git_strarray_free`. 290 | * 291 | * @param array Pointer to a git_strarray structure where 292 | * the reference names will be stored 293 | * @param repo Repository where to find the refs 294 | * @param list_flags Filtering flags for the reference 295 | * listing. 296 | * @return 0 on success; error code otherwise 297 | */ 298 | GIT_EXTERN(int) git_reference_listall(git_strarray *array, git_repository *repo, unsigned int list_flags); 299 | 300 | 301 | /** 302 | * List all the references in the repository, calling a custom 303 | * callback for each one. 304 | * 305 | * The listed references may be filtered by type, or using 306 | * a bitwise OR of several types. Use the magic value 307 | * `GIT_REF_LISTALL` to obtain all references, including 308 | * packed ones. 309 | * 310 | * The `callback` function will be called for each of the references 311 | * in the repository, and will receive the name of the reference and 312 | * the `payload` value passed to this method. 313 | * 314 | * @param repo Repository where to find the refs 315 | * @param list_flags Filtering flags for the reference 316 | * listing. 317 | * @param callback Function which will be called for every listed ref 318 | * @param payload Additional data to pass to the callback 319 | * @return 0 on success; error code otherwise 320 | */ 321 | GIT_EXTERN(int) git_reference_listcb(git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload); 322 | 323 | /** @} */ 324 | GIT_END_DECL 325 | #endif 326 | -------------------------------------------------------------------------------- /test/fixtures/git2/repository.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_repository_h__ 26 | #define INCLUDE_git_repository_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | 32 | /** 33 | * @file git2/repository.h 34 | * @brief Git repository management routines 35 | * @defgroup git_repository Git repository management routines 36 | * @ingroup Git 37 | * @{ 38 | */ 39 | GIT_BEGIN_DECL 40 | 41 | /** 42 | * Open a git repository. 43 | * 44 | * The 'path' argument must point to an existing git repository 45 | * folder, e.g. 46 | * 47 | * /path/to/my_repo/.git/ (normal repository) 48 | * objects/ 49 | * index 50 | * HEAD 51 | * 52 | * /path/to/bare_repo/ (bare repository) 53 | * objects/ 54 | * index 55 | * HEAD 56 | * 57 | * The method will automatically detect if 'path' is a normal 58 | * or bare repository or fail is 'path' is neither. 59 | * 60 | * @param repository pointer to the repo which will be opened 61 | * @param path the path to the repository 62 | * @return 0 on success; error code otherwise 63 | */ 64 | GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *path); 65 | 66 | 67 | /** 68 | * Open a git repository by manually specifying all its paths 69 | * 70 | * @param repository pointer to the repo which will be opened 71 | * 72 | * @param git_dir The full path to the repository folder 73 | * e.g. a '.git' folder for live repos, any folder for bare 74 | * Equivalent to $GIT_DIR. 75 | * Cannot be NULL. 76 | * 77 | * @param git_object_directory The full path to the ODB folder. 78 | * the folder where all the loose and packed objects are stored 79 | * Equivalent to $GIT_OBJECT_DIRECTORY. 80 | * If NULL, "$GIT_DIR/objects/" is assumed. 81 | * 82 | * @param git_index_file The full path to the index (dircache) file 83 | * Equivalent to $GIT_INDEX_FILE. 84 | * If NULL, "$GIT_DIR/index" is assumed. 85 | * 86 | * @param git_work_tree The full path to the working tree of the repository, 87 | * if the repository is not bare. 88 | * Equivalent to $GIT_WORK_TREE. 89 | * If NULL, the repository is assumed to be bare. 90 | * 91 | * @return 0 on success; error code otherwise 92 | */ 93 | GIT_EXTERN(int) git_repository_open2(git_repository **repository, 94 | const char *git_dir, 95 | const char *git_object_directory, 96 | const char *git_index_file, 97 | const char *git_work_tree); 98 | 99 | 100 | /** 101 | * Open a git repository by manually specifying its paths and 102 | * the object database it will use. 103 | * 104 | * @param repository pointer to the repo which will be opened 105 | * 106 | * @param git_dir The full path to the repository folder 107 | * e.g. a '.git' folder for live repos, any folder for bare 108 | * Equivalent to $GIT_DIR. 109 | * Cannot be NULL. 110 | * 111 | * @param object_database A pointer to a git_odb created & initialized 112 | * by the user (e.g. with custom backends). This object database 113 | * will be owned by the repository and will be automatically free'd. 114 | * It should not be manually free'd by the user, or this 115 | * git_repository object will become invalid. 116 | * 117 | * @param git_index_file The full path to the index (dircache) file 118 | * Equivalent to $GIT_INDEX_FILE. 119 | * If NULL, "$GIT_DIR/index" is assumed. 120 | * 121 | * @param git_work_tree The full path to the working tree of the repository, 122 | * if the repository is not bare. 123 | * Equivalent to $GIT_WORK_TREE. 124 | * If NULL, the repository is assumed to be bare. 125 | * 126 | * @return 0 on success; error code otherwise 127 | */ 128 | 129 | GIT_EXTERN(int) git_repository_open3(git_repository **repository, 130 | const char *git_dir, 131 | git_odb *object_database, 132 | const char *git_index_file, 133 | const char *git_work_tree); 134 | 135 | /** 136 | * Get the object database behind a Git repository 137 | * 138 | * @param repo a repository object 139 | * @return a pointer to the object db 140 | */ 141 | GIT_EXTERN(git_odb *) git_repository_database(git_repository *repo); 142 | 143 | /** 144 | * Get the Index file of a Git repository 145 | * 146 | * This is a cheap operation; the index is only opened on the first call, 147 | * and subsequent calls only retrieve the previous pointer. 148 | * 149 | * @param index Pointer where to store the index 150 | * @param repo a repository object 151 | * @return 0 on success; error code if the index could not be opened 152 | */ 153 | GIT_EXTERN(int) git_repository_index(git_index **index, git_repository *repo); 154 | 155 | /** 156 | * Free a previously allocated repository 157 | * 158 | * Note that after a repository is free'd, all the objects it has spawned 159 | * will still exist until they are manually closed by the user 160 | * with `git_object_close`, but accessing any of the attributes of 161 | * an object without a backing repository will result in undefined 162 | * behavior 163 | * 164 | * @param repo repository handle to close. If NULL nothing occurs. 165 | */ 166 | GIT_EXTERN(void) git_repository_free(git_repository *repo); 167 | 168 | /** 169 | * Creates a new Git repository in the given folder. 170 | * 171 | * TODO: 172 | * - Reinit the repository 173 | * - Create config files 174 | * 175 | * @param repo_out pointer to the repo which will be created or reinitialized 176 | * @param path the path to the repository 177 | * @param is_bare if true, a Git repository without a working directory is created 178 | * at the pointed path. If false, provided path will be considered as the working 179 | * directory into which the .git directory will be created. 180 | * 181 | * @return 0 on success; error code otherwise 182 | */ 183 | GIT_EXTERN(int) git_repository_init(git_repository **repo_out, const char *path, unsigned is_bare); 184 | 185 | /** 186 | * Check if a repository is empty 187 | * 188 | * An empty repository has just been initialized and contains 189 | * no commits. 190 | * 191 | * @param repo Repo to test 192 | * @return 1 if the repository is empty, 0 if it isn't, error code 193 | * if the repository is corrupted 194 | */ 195 | GIT_EXTERN(int) git_repository_is_empty(git_repository *repo); 196 | 197 | /** 198 | * Get the normalized path to the git repository. 199 | * 200 | * @param repo a repository object 201 | * @return absolute path to the git directory 202 | */ 203 | GIT_EXTERN(const char *) git_repository_path(git_repository *repo); 204 | 205 | /** 206 | * Get the normalized path to the working directory of the repository. 207 | * 208 | * If the repository is bare, there is no working directory and NULL we be returned. 209 | * 210 | * @param repo a repository object 211 | * @return NULL if the repository is bare; absolute path to the working directory otherwise. 212 | */ 213 | GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo); 214 | 215 | /** 216 | * Extended options structure for `git_repository_init_ext`. 217 | * 218 | * This contains extra options for `git_repository_init_ext` that enable 219 | * additional initialization features. The fields are: 220 | * 221 | * * flags - Combination of GIT_REPOSITORY_INIT flags above. 222 | * * mode - Set to one of the standard GIT_REPOSITORY_INIT_SHARED_... 223 | * constants above, or to a custom value that you would like. 224 | * * workdir_path - The path to the working dir or NULL for default (i.e. 225 | * repo_path parent on non-bare repos). IF THIS IS RELATIVE PATH, 226 | * IT WILL BE EVALUATED RELATIVE TO THE REPO_PATH. If this is not 227 | * the "natural" working directory, a .git gitlink file will be 228 | * created here linking to the repo_path. 229 | * * description - If set, this will be used to initialize the "description" 230 | * file in the repository, instead of using the template content. 231 | * * template_path - When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set, 232 | * this contains the path to use for the template directory. If 233 | * this is NULL, the config or default directory options will be 234 | * used instead. 235 | * * initial_head - The name of the head to point HEAD at. If NULL, then 236 | * this will be treated as "master" and the HEAD ref will be set 237 | * to "refs/heads/master". If this begins with "refs/" it will be 238 | * used verbatim; otherwise "refs/heads/" will be prefixed. 239 | * * origin_url - If this is non-NULL, then after the rest of the 240 | * repository initialization is completed, an "origin" remote 241 | * will be added pointing to this URL. 242 | */ 243 | typedef struct { 244 | unsigned int version; 245 | uint32_t flags; 246 | uint32_t mode; 247 | const char *workdir_path; 248 | const char *description; 249 | const char *template_path; 250 | const char *initial_head; 251 | const char *origin_url; 252 | } git_repository_init_options; 253 | 254 | /** @} */ 255 | GIT_END_DECL 256 | #endif 257 | -------------------------------------------------------------------------------- /test/fixtures/git2/revwalk.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_revwalk_h__ 26 | #define INCLUDE_git_revwalk_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | 32 | /** 33 | * @file git2/revwalk.h 34 | * @brief Git revision traversal routines 35 | * @defgroup git_revwalk Git revision traversal routines 36 | * @ingroup Git 37 | * @{ 38 | */ 39 | GIT_BEGIN_DECL 40 | 41 | /** 42 | * Sort the repository contents in no particular ordering; 43 | * this sorting is arbitrary, implementation-specific 44 | * and subject to change at any time. 45 | * This is the default sorting for new walkers. 46 | */ 47 | #define GIT_SORT_NONE (0) 48 | 49 | /** 50 | * Sort the repository contents in topological order 51 | * (parents before children); this sorting mode 52 | * can be combined with time sorting. 53 | */ 54 | #define GIT_SORT_TOPOLOGICAL (1 << 0) 55 | 56 | /** 57 | * Sort the repository contents by commit time; 58 | * this sorting mode can be combined with 59 | * topological sorting. 60 | */ 61 | #define GIT_SORT_TIME (1 << 1) 62 | 63 | /** 64 | * Iterate through the repository contents in reverse 65 | * order; this sorting mode can be combined with 66 | * any of the above. 67 | */ 68 | #define GIT_SORT_REVERSE (1 << 2) 69 | 70 | /** 71 | * Allocate a new revision walker to iterate through a repo. 72 | * 73 | * This revision walker uses a custom memory pool and an internal 74 | * commit cache, so it is relatively expensive to allocate. 75 | * 76 | * For maximum performance, this revision walker should be 77 | * reused for different walks. 78 | * 79 | * This revision walker is *not* thread safe: it may only be 80 | * used to walk a repository on a single thread; however, 81 | * it is possible to have several revision walkers in 82 | * several different threads walking the same repository. 83 | * 84 | * @param walker pointer to the new revision walker 85 | * @param repo the repo to walk through 86 | * @return 0 on success; error code otherwise 87 | */ 88 | GIT_EXTERN(int) git_revwalk_new(git_revwalk **walker, git_repository *repo); 89 | 90 | /** 91 | * Reset the revision walker for reuse. 92 | * 93 | * This will clear all the pushed and hidden commits, and 94 | * leave the walker in a blank state (just like at 95 | * creation) ready to receive new commit pushes and 96 | * start a new walk. 97 | * 98 | * The revision walk is automatically reset when a walk 99 | * is over. 100 | * 101 | * @param walker handle to reset. 102 | */ 103 | GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker); 104 | 105 | /** 106 | * Mark a commit to start traversal from. 107 | * 108 | * The given OID must belong to a commit on the walked 109 | * repository. 110 | * 111 | * The given commit will be used as one of the roots 112 | * when starting the revision walk. At least one commit 113 | * must be pushed the repository before a walk can 114 | * be started. 115 | * 116 | * @param walker the walker being used for the traversal. 117 | * @param oid the oid of the commit to start from. 118 | * @return 0 on success; error code otherwise 119 | */ 120 | GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *oid); 121 | 122 | 123 | /** 124 | * Mark a commit (and its ancestors) uninteresting for the output. 125 | * 126 | * The given OID must belong to a commit on the walked 127 | * repository. 128 | * 129 | * The resolved commit and all its parents will be hidden from the 130 | * output on the revision walk. 131 | * 132 | * @param walker the walker being used for the traversal. 133 | * @param commit the commit that will be ignored during the traversal 134 | * @return 0 on success; error code otherwise 135 | */ 136 | GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *oid); 137 | 138 | /** 139 | * Get the next commit from the revision walk. 140 | * 141 | * The initial call to this method is *not* blocking when 142 | * iterating through a repo with a time-sorting mode. 143 | * 144 | * Iterating with Topological or inverted modes makes the initial 145 | * call blocking to preprocess the commit list, but this block should be 146 | * mostly unnoticeable on most repositories (topological preprocessing 147 | * times at 0.3s on the git.git repo). 148 | * 149 | * The revision walker is reset when the walk is over. 150 | * 151 | * @param oid Pointer where to store the oid of the next commit 152 | * @param walk the walker to pop the commit from. 153 | * @return GIT_SUCCESS if the next commit was found; 154 | * GIT_EREVWALKOVER if there are no commits left to iterate 155 | */ 156 | GIT_EXTERN(int) git_revwalk_next(git_oid *oid, git_revwalk *walk); 157 | 158 | /** 159 | * Change the sorting mode when iterating through the 160 | * repository's contents. 161 | * 162 | * Changing the sorting mode resets the walker. 163 | * 164 | * @param walk the walker being used for the traversal. 165 | * @param sort_mode combination of GIT_SORT_XXX flags 166 | */ 167 | GIT_EXTERN(void) git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode); 168 | 169 | /** 170 | * Free a revision walker previously allocated. 171 | * 172 | * @param walk traversal handle to close. If NULL nothing occurs. 173 | */ 174 | GIT_EXTERN(void) git_revwalk_free(git_revwalk *walk); 175 | 176 | /** 177 | * Return the repository on which this walker 178 | * is operating. 179 | * 180 | * @param walk the revision walker 181 | * @return the repository being walked 182 | */ 183 | GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk); 184 | 185 | /** @} */ 186 | GIT_END_DECL 187 | #endif 188 | -------------------------------------------------------------------------------- /test/fixtures/git2/signature.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_signature_h__ 26 | #define INCLUDE_git_signature_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | 31 | /** 32 | * @file git2/signature.h 33 | * @brief Git signature creation 34 | * @defgroup git_signature Git signature creation 35 | * @ingroup Git 36 | * @{ 37 | */ 38 | GIT_BEGIN_DECL 39 | 40 | /** 41 | * Create a new action signature. The signature must be freed 42 | * manually or using git_signature_free 43 | * 44 | * @param name name of the person 45 | * @param mail email of the person 46 | * @param time time when the action happened 47 | * @param offset timezone offset in minutes for the time 48 | * @return the new sig, NULL on out of memory 49 | */ 50 | GIT_EXTERN(git_signature *) git_signature_new(const char *name, const char *email, git_time_t time, int offset); 51 | 52 | /** 53 | * Create a new action signature with a timestamp of 'now'. The 54 | * signature must be freed manually or using git_signature_free 55 | * 56 | * @param name name of the person 57 | * @param email email of the person 58 | * @return the new sig, NULL on out of memory 59 | */ 60 | GIT_EXTERN(git_signature *) git_signature_now(const char *name, const char *email); 61 | 62 | 63 | /** 64 | * Create a copy of an existing signature. 65 | * 66 | * All internal strings are also duplicated. 67 | * @param sig signature to duplicated 68 | * @return a copy of sig, NULL on out of memory 69 | */ 70 | GIT_EXTERN(git_signature *) git_signature_dup(const git_signature *sig); 71 | 72 | /** 73 | * Free an existing signature 74 | * 75 | * @param sig signature to free 76 | */ 77 | GIT_EXTERN(void) git_signature_free(git_signature *sig); 78 | 79 | /** @} */ 80 | GIT_END_DECL 81 | #endif 82 | -------------------------------------------------------------------------------- /test/fixtures/git2/tag.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_tag_h__ 26 | #define INCLUDE_git_tag_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | #include "object.h" 32 | 33 | /** 34 | * @file git2/tag.h 35 | * @brief Git tag parsing routines 36 | * @defgroup git_tag Git tag management 37 | * @ingroup Git 38 | * @{ 39 | */ 40 | GIT_BEGIN_DECL 41 | 42 | /** 43 | * Lookup a tag object from the repository. 44 | * 45 | * @param tag pointer to the looked up tag 46 | * @param repo the repo to use when locating the tag. 47 | * @param id identity of the tag to locate. 48 | * @return 0 on success; error code otherwise 49 | */ 50 | GIT_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oid *id) 51 | { 52 | return git_object_lookup((git_object **)tag, repo, id, (git_otype)GIT_OBJ_TAG); 53 | } 54 | 55 | /** 56 | * Close an open tag 57 | * 58 | * This is a wrapper around git_object_close() 59 | * 60 | * IMPORTANT: 61 | * It *is* necessary to call this method when you stop 62 | * using a tag. Failure to do so will cause a memory leak. 63 | * 64 | * @param tag the tag to close 65 | */ 66 | 67 | GIT_INLINE(void) git_tag_close(git_tag *tag) 68 | { 69 | git_object_close((git_object *) tag); 70 | } 71 | 72 | 73 | /** 74 | * Get the id of a tag. 75 | * 76 | * @param tag a previously loaded tag. 77 | * @return object identity for the tag. 78 | */ 79 | GIT_EXTERN(const git_oid *) git_tag_id(git_tag *tag); 80 | 81 | /** 82 | * Get the tagged object of a tag 83 | * 84 | * This method performs a repository lookup for the 85 | * given object and returns it 86 | * 87 | * @param target pointer where to store the target 88 | * @param tag a previously loaded tag. 89 | * @return 0 on success; error code otherwise 90 | */ 91 | GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *t); 92 | 93 | /** 94 | * Get the OID of the tagged object of a tag 95 | * 96 | * @param tag a previously loaded tag. 97 | * @return pointer to the OID 98 | */ 99 | GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *t); 100 | 101 | /** 102 | * Get the type of a tag's tagged object 103 | * 104 | * @param tag a previously loaded tag. 105 | * @return type of the tagged object 106 | */ 107 | GIT_EXTERN(git_otype) git_tag_type(git_tag *t); 108 | 109 | /** 110 | * Get the name of a tag 111 | * 112 | * @param tag a previously loaded tag. 113 | * @return name of the tag 114 | */ 115 | GIT_EXTERN(const char *) git_tag_name(git_tag *t); 116 | 117 | /** 118 | * Get the tagger (author) of a tag 119 | * 120 | * @param tag a previously loaded tag. 121 | * @return reference to the tag's author 122 | */ 123 | GIT_EXTERN(const git_signature *) git_tag_tagger(git_tag *t); 124 | 125 | /** 126 | * Get the message of a tag 127 | * 128 | * @param tag a previously loaded tag. 129 | * @return message of the tag 130 | */ 131 | GIT_EXTERN(const char *) git_tag_message(git_tag *t); 132 | 133 | 134 | /** 135 | * Create a new tag in the repository from an OID 136 | * 137 | * @param oid Pointer where to store the OID of the 138 | * newly created tag 139 | * 140 | * @param repo Repository where to store the tag 141 | * 142 | * @param tag_name Name for the tag; this name is validated 143 | * for consistency. It should also not conflict with an 144 | * already existing tag name 145 | * 146 | * @param target OID to which this tag points; note that no 147 | * validation is done on this OID. Use the _o version of this 148 | * method to assure a proper object is being tagged 149 | * 150 | * @param target_type Type of the tagged OID; note that no 151 | * validation is performed here either 152 | * 153 | * @param tagger Signature of the tagger for this tag, and 154 | * of the tagging time 155 | * 156 | * @param message Full message for this tag 157 | * 158 | * @return 0 on success; error code otherwise. 159 | * A tag object is written to the ODB, and a proper reference 160 | * is written in the /refs/tags folder, pointing to it 161 | */ 162 | GIT_EXTERN(int) git_tag_create( 163 | git_oid *oid, 164 | git_repository *repo, 165 | const char *tag_name, 166 | const git_oid *target, 167 | git_otype target_type, 168 | const git_signature *tagger, 169 | const char *message); 170 | 171 | 172 | /** 173 | * Create a new tag in the repository from an existing 174 | * `git_object` instance 175 | * 176 | * This method replaces the `target` and `target_type` 177 | * paremeters of `git_tag_create` by a single instance 178 | * of a `const git_object *`, which is assured to be 179 | * a proper object in the ODB and hence will create 180 | * a valid tag 181 | * 182 | * @see git_tag_create 183 | */ 184 | GIT_EXTERN(int) git_tag_create_o( 185 | git_oid *oid, 186 | git_repository *repo, 187 | const char *tag_name, 188 | const git_object *target, 189 | const git_signature *tagger, 190 | const char *message); 191 | 192 | /** 193 | * Create a new tag in the repository from a buffer 194 | * 195 | * @param oid Pointer where to store the OID of the newly created tag 196 | * 197 | * @param repo Repository where to store the tag 198 | * 199 | * @param buffer Raw tag data 200 | */ 201 | GIT_EXTERN(int) git_tag_create_frombuffer( 202 | git_oid *oid, 203 | git_repository *repo, 204 | const char *buffer); 205 | 206 | /** 207 | * Create a new tag in the repository from an OID 208 | * and overwrite an already existing tag reference, if any. 209 | * 210 | * @param oid Pointer where to store the OID of the 211 | * newly created tag 212 | * 213 | * @param repo Repository where to store the tag 214 | * 215 | * @param tag_name Name for the tag; this name is validated 216 | * for consistency. 217 | * 218 | * @param target OID to which this tag points; note that no 219 | * validation is done on this OID. Use the _fo version of this 220 | * method to assure a proper object is being tagged 221 | * 222 | * @param target_type Type of the tagged OID; note that no 223 | * validation is performed here either 224 | * 225 | * @param tagger Signature of the tagger for this tag, and 226 | * of the tagging time 227 | * 228 | * @param message Full message for this tag 229 | * 230 | * @return 0 on success; error code otherwise. 231 | * A tag object is written to the ODB, and a proper reference 232 | * is written in the /refs/tags folder, pointing to it 233 | */ 234 | GIT_EXTERN(int) git_tag_create_f( 235 | git_oid *oid, 236 | git_repository *repo, 237 | const char *tag_name, 238 | const git_oid *target, 239 | git_otype target_type, 240 | const git_signature *tagger, 241 | const char *message); 242 | 243 | /** 244 | * Create a new tag in the repository from an existing 245 | * `git_object` instance and overwrite an already existing 246 | * tag reference, if any. 247 | * 248 | * This method replaces the `target` and `target_type` 249 | * paremeters of `git_tag_create_f` by a single instance 250 | * of a `const git_object *`, which is assured to be 251 | * a proper object in the ODB and hence will create 252 | * a valid tag 253 | * 254 | * @see git_tag_create_f 255 | */ 256 | GIT_EXTERN(int) git_tag_create_fo( 257 | git_oid *oid, 258 | git_repository *repo, 259 | const char *tag_name, 260 | const git_object *target, 261 | const git_signature *tagger, 262 | const char *message); 263 | 264 | /** 265 | * Delete an existing tag reference. 266 | * 267 | * @param repo Repository where lives the tag 268 | * 269 | * @param tag_name Name of the tag to be deleted; 270 | * this name is validated for consistency. 271 | * 272 | * @return 0 on success; error code otherwise. 273 | */ 274 | GIT_EXTERN(int) git_tag_delete( 275 | git_repository *repo, 276 | const char *tag_name); 277 | 278 | /** 279 | * Fill a list with all the tags in the Repository 280 | * 281 | * The string array will be filled with the names of the 282 | * matching tags; these values are owned by the user and 283 | * should be free'd manually when no longer needed, using 284 | * `git_strarray_free`. 285 | * 286 | * @param array Pointer to a git_strarray structure where 287 | * the tag names will be stored 288 | * @param repo Repository where to find the tags 289 | * @return 0 on success; error code otherwise 290 | */ 291 | GIT_EXTERN(int) git_tag_list( 292 | git_strarray *tag_names, 293 | git_repository *repo); 294 | 295 | /** @} */ 296 | GIT_END_DECL 297 | #endif 298 | -------------------------------------------------------------------------------- /test/fixtures/git2/thread-utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_thread_utils_h__ 26 | #define INCLUDE_git_thread_utils_h__ 27 | 28 | /* 29 | * How TLS works is compiler+platform dependant 30 | * Sources: http://en.wikipedia.org/wiki/Thread-Specific_Storage 31 | * http://predef.sourceforge.net/precomp.html 32 | */ 33 | 34 | #define GIT_HAS_TLS 1 35 | 36 | #if defined(__APPLE__) && defined(__MACH__) 37 | # undef GIT_TLS 38 | # define GIT_TLS 39 | 40 | #elif defined(__GNUC__) || \ 41 | defined(__SUNPRO_C) || \ 42 | defined(__SUNPRO_CC) || \ 43 | defined(__xlc__) || \ 44 | defined(__xlC__) 45 | # define GIT_TLS __thread 46 | 47 | #elif defined(__INTEL_COMPILER) 48 | # if defined(_WIN32) || defined(_WIN32_CE) 49 | # define GIT_TLS __declspec(thread) 50 | # else 51 | # define GIT_TLS __thread 52 | # endif 53 | 54 | #elif defined(_WIN32) || \ 55 | defined(_WIN32_CE) || \ 56 | defined(__BORLANDC__) 57 | # define GIT_TLS __declspec(thread) 58 | 59 | #else 60 | # undef GIT_HAS_TLS 61 | # define GIT_TLS /* nothing: tls vars are thread-global */ 62 | #endif 63 | 64 | /* sparse and cygwin don't grok thread-local variables */ 65 | #if defined(__CHECKER__) || defined(__CYGWIN__) 66 | # undef GIT_HAS_TLS 67 | # undef GIT_TLS 68 | # define GIT_TLS 69 | #endif 70 | 71 | #endif /* INCLUDE_git_thread_utils_h__ */ 72 | -------------------------------------------------------------------------------- /test/fixtures/git2/tree.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_tree_h__ 26 | #define INCLUDE_git_tree_h__ 27 | 28 | #include "common.h" 29 | #include "types.h" 30 | #include "oid.h" 31 | #include "object.h" 32 | 33 | /** 34 | * @file git2/tree.h 35 | * @brief Git tree parsing, loading routines 36 | * @defgroup git_tree Git tree parsing, loading routines 37 | * @ingroup Git 38 | * @{ 39 | */ 40 | GIT_BEGIN_DECL 41 | 42 | /** 43 | * Lookup a tree object from the repository. 44 | * 45 | * @param tree pointer to the looked up tree 46 | * @param repo the repo to use when locating the tree. 47 | * @param id identity of the tree to locate. 48 | * @return 0 on success; error code otherwise 49 | */ 50 | GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git_oid *id) 51 | { 52 | return git_object_lookup((git_object **)tree, repo, id, GIT_OBJ_TREE); 53 | } 54 | 55 | /** 56 | * Close an open tree 57 | * 58 | * This is a wrapper around git_object_close() 59 | * 60 | * IMPORTANT: 61 | * It *is* necessary to call this method when you stop 62 | * using a tree. Failure to do so will cause a memory leak. 63 | * 64 | * @param tree the tree to close 65 | */ 66 | 67 | GIT_INLINE(void) git_tree_close(git_tree *tree) 68 | { 69 | git_object_close((git_object *) tree); 70 | } 71 | 72 | 73 | /** 74 | * Get the id of a tree. 75 | * 76 | * @param tree a previously loaded tree. 77 | * @return object identity for the tree. 78 | */ 79 | GIT_EXTERN(const git_oid *) git_tree_id(git_tree *tree); 80 | 81 | /** 82 | * Get the number of entries listed in a tree 83 | * 84 | * @param tree a previously loaded tree. 85 | * @return the number of entries in the tree 86 | */ 87 | GIT_EXTERN(size_t) git_tree_entrycount(git_tree *tree); 88 | 89 | /** 90 | * Lookup a tree entry by its filename 91 | * 92 | * @param tree a previously loaded tree. 93 | * @param filename the filename of the desired entry 94 | * @return the tree entry; NULL if not found 95 | */ 96 | GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(git_tree *tree, const char *filename); 97 | 98 | /** 99 | * Lookup a tree entry by its position in the tree 100 | * 101 | * @param tree a previously loaded tree. 102 | * @param idx the position in the entry list 103 | * @return the tree entry; NULL if not found 104 | */ 105 | GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(git_tree *tree, int idx); 106 | 107 | /** 108 | * Get the UNIX file attributes of a tree entry 109 | * 110 | * @param entry a tree entry 111 | * @return attributes as an integer 112 | */ 113 | GIT_EXTERN(unsigned int) git_tree_entry_attributes(const git_tree_entry *entry); 114 | 115 | /** 116 | * Get the filename of a tree entry 117 | * 118 | * @param entry a tree entry 119 | * @return the name of the file 120 | */ 121 | GIT_EXTERN(const char *) git_tree_entry_name(const git_tree_entry *entry); 122 | 123 | /** 124 | * Get the id of the object pointed by the entry 125 | * 126 | * @param entry a tree entry 127 | * @return the oid of the object 128 | */ 129 | GIT_EXTERN(const git_oid *) git_tree_entry_id(const git_tree_entry *entry); 130 | 131 | /** 132 | * Convert a tree entry to the git_object it points too. 133 | * 134 | * @param object pointer to the converted object 135 | * @param repo repository where to lookup the pointed object 136 | * @param entry a tree entry 137 | * @return 0 on success; error code otherwise 138 | */ 139 | GIT_EXTERN(int) git_tree_entry_2object(git_object **object_out, git_repository *repo, const git_tree_entry *entry); 140 | 141 | /** 142 | * Write a tree to the ODB from the index file 143 | * 144 | * This method will scan the index and write a representation 145 | * of its current state back to disk; it recursively creates 146 | * tree objects for each of the subtrees stored in the index, 147 | * but only returns the OID of the root tree. This is the OID 148 | * that can be used e.g. to create a commit. 149 | * 150 | * The index instance cannot be bare, and needs to be associated 151 | * to an existing repository. 152 | * 153 | * @param oid Pointer where to store the written tree 154 | * @param index Index to write 155 | * @return 0 on success; error code otherwise 156 | */ 157 | GIT_EXTERN(int) git_tree_create_fromindex(git_oid *oid, git_index *index); 158 | 159 | /** 160 | * Create a new tree builder. 161 | * 162 | * The tree builder can be used to create or modify 163 | * trees in memory and write them as tree objects to the 164 | * database. 165 | * 166 | * If the `source` parameter is not NULL, the tree builder 167 | * will be initialized with the entries of the given tree. 168 | * 169 | * If the `source` parameter is NULL, the tree builder will 170 | * have no entries and will have to be filled manually. 171 | * 172 | * @param builder_p Pointer where to store the tree builder 173 | * @param source Source tree to initialize the builder (optional) 174 | * @return 0 on sucess; error code otherwise 175 | */ 176 | GIT_EXTERN(int) git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source); 177 | 178 | /** 179 | * Clear all the entires in the builder 180 | * 181 | * @param bld Builder to clear 182 | */ 183 | GIT_EXTERN(void) git_treebuilder_clear(git_treebuilder *bld); 184 | 185 | /** 186 | * Free a tree builder 187 | * 188 | * This will clear all the entries and free to builder. 189 | * Failing to free the builder after you're done using it 190 | * will result in a memory leak 191 | * 192 | * @param bld Builder to free 193 | */ 194 | GIT_EXTERN(void) git_treebuilder_free(git_treebuilder *bld); 195 | 196 | /** 197 | * Get an entry from the builder from its filename 198 | * 199 | * The returned entry is owned by the builder and should 200 | * not be freed manually. 201 | * 202 | * @param bld Tree builder 203 | * @param filename Name of the entry 204 | * @return pointer to the entry; NULL if not found 205 | */ 206 | GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, const char *filename); 207 | 208 | /** 209 | * Add or update an entry to the builder 210 | * 211 | * Insert a new entry for `filename` in the builder with the 212 | * given attributes. 213 | * 214 | * if an entry named `filename` already exists, its attributes 215 | * will be updated with the given ones. 216 | * 217 | * The optional pointer `entry_out` can be used to retrieve a 218 | * pointer to the newly created/updated entry. 219 | * 220 | * @param entry_out Pointer to store the entry (optional) 221 | * @param bld Tree builder 222 | * @param filename Filename of the entry 223 | * @param id SHA1 oid of the entry 224 | * @param attributes Folder attributes of the entry 225 | * @return 0 on success; error code otherwise 226 | */ 227 | GIT_EXTERN(int) git_treebuilder_insert(git_tree_entry **entry_out, git_treebuilder *bld, const char *filename, const git_oid *id, unsigned int attributes); 228 | 229 | /** 230 | * Remove an entry from the builder by its filename 231 | * 232 | * @param bld Tree builder 233 | * @param filename Filename of the entry to remove 234 | */ 235 | GIT_EXTERN(int) git_treebuilder_remove(git_treebuilder *bld, const char *filename); 236 | 237 | /** 238 | * Filter the entries in the tree 239 | * 240 | * The `filter` callback will be called for each entry 241 | * in the tree with a pointer to the entry and the 242 | * provided `payload`: if the callback returns 1, the 243 | * entry will be filtered (removed from the builder). 244 | * 245 | * @param bld Tree builder 246 | * @param filter Callback to filter entries 247 | */ 248 | GIT_EXTERN(void) git_treebuilder_filter(git_treebuilder *bld, int (*filter)(const git_tree_entry *, void *), void *payload); 249 | 250 | /** 251 | * Write the contents of the tree builder as a tree object 252 | * 253 | * The tree builder will be written to the given `repo`, and 254 | * it's identifying SHA1 hash will be stored in the `oid` 255 | * pointer. 256 | * 257 | * @param oid Pointer where to store the written OID 258 | * @param repo Repository where to store the object 259 | * @param bld Tree builder to write 260 | * @return 0 on success; error code otherwise 261 | */ 262 | GIT_EXTERN(int) git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld); 263 | 264 | /** @} */ 265 | GIT_END_DECL 266 | #endif 267 | -------------------------------------------------------------------------------- /test/fixtures/git2/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License, version 2, 4 | * as published by the Free Software Foundation. 5 | * 6 | * In addition to the permissions in the GNU General Public License, 7 | * the authors give you unlimited permission to link the compiled 8 | * version of this file into combinations with other programs, 9 | * and to distribute those combinations without any restriction 10 | * coming from the use of this file. (The General Public License 11 | * restrictions do apply in other respects; for example, they cover 12 | * modification of the file, and distribution when not linked into 13 | * a combined executable.) 14 | * 15 | * This file is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; see the file COPYING. If not, write to 22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23 | * Boston, MA 02110-1301, USA. 24 | */ 25 | #ifndef INCLUDE_git_types_h__ 26 | #define INCLUDE_git_types_h__ 27 | 28 | #include "common.h" 29 | 30 | /** 31 | * @file git2/types.h 32 | * @brief libgit2 base & compatibility types 33 | * @ingroup Git 34 | * @{ 35 | */ 36 | GIT_BEGIN_DECL 37 | 38 | /** 39 | * Cross-platform compatibility types for off_t / time_t 40 | * 41 | * NOTE: This needs to be in a public header so that both the library 42 | * implementation and client applications both agree on the same types. 43 | * Otherwise we get undefined behavior. 44 | * 45 | * Use the "best" types that each platform provides. Currently we truncate 46 | * these intermediate representations for compatibility with the git ABI, but 47 | * if and when it changes to support 64 bit types, our code will naturally 48 | * adapt. 49 | * NOTE: These types should match those that are returned by our internal 50 | * stat() functions, for all platforms. 51 | */ 52 | #include 53 | 54 | #if defined(_MSC_VER) 55 | 56 | typedef __int64 git_off_t; 57 | typedef __time64_t git_time_t; 58 | 59 | #elif defined(__MINGW32__) 60 | 61 | typedef off64_t git_off_t; 62 | typedef __time64_t git_time_t; 63 | 64 | #else /* POSIX */ 65 | 66 | /* 67 | * Note: Can't use off_t since if a client program includes 68 | * before us (directly or indirectly), they'll get 32 bit off_t in their client 69 | * app, even though /we/ define _FILE_OFFSET_BITS=64. 70 | */ 71 | typedef int64_t git_off_t; 72 | typedef int64_t git_time_t; 73 | 74 | #endif 75 | 76 | /** Basic type (loose or packed) of any Git object. */ 77 | typedef enum { 78 | GIT_OBJ_ANY = -2, /**< Object can be any of the following */ 79 | GIT_OBJ_BAD = -1, /**< Object is invalid. */ 80 | GIT_OBJ__EXT1 = 0, /**< Reserved for future use. */ 81 | GIT_OBJ_COMMIT = 1, /**< A commit object. */ 82 | GIT_OBJ_TREE = 2, /**< A tree (directory listing) object. */ 83 | GIT_OBJ_BLOB = 3, /**< A file revision object. */ 84 | GIT_OBJ_TAG = 4, /**< An annotated tag object. */ 85 | GIT_OBJ__EXT2 = 5, /**< Reserved for future use. */ 86 | GIT_OBJ_OFS_DELTA = 6, /**< A delta, base is given by an offset. */ 87 | GIT_OBJ_REF_DELTA = 7, /**< A delta, base is given by object id. */ 88 | } git_otype; 89 | 90 | /** An open object database handle. */ 91 | typedef struct git_odb git_odb; 92 | 93 | /** A custom backend in an ODB */ 94 | typedef struct git_odb_backend git_odb_backend; 95 | 96 | /** An object read from the ODB */ 97 | typedef struct git_odb_object git_odb_object; 98 | 99 | /** A stream to read/write from the ODB */ 100 | typedef struct git_odb_stream git_odb_stream; 101 | 102 | /** 103 | * Representation of an existing git repository, 104 | * including all its object contents 105 | */ 106 | typedef struct git_repository git_repository; 107 | 108 | /** Representation of a generic object in a repository */ 109 | typedef struct git_object git_object; 110 | 111 | /** Representation of an in-progress walk through the commits in a repo */ 112 | typedef struct git_revwalk git_revwalk; 113 | 114 | /** Parsed representation of a tag object. */ 115 | typedef struct git_tag git_tag; 116 | 117 | /** In-memory representation of a blob object. */ 118 | typedef struct git_blob git_blob; 119 | 120 | /** Parsed representation of a commit object. */ 121 | typedef struct git_commit git_commit; 122 | 123 | /** Representation of each one of the entries in a tree object. */ 124 | typedef struct git_tree_entry git_tree_entry; 125 | 126 | /** Representation of a tree object. */ 127 | typedef struct git_tree git_tree; 128 | 129 | /** Constructor for in-memory trees */ 130 | typedef struct git_treebuilder git_treebuilder; 131 | 132 | /** Memory representation of an index file. */ 133 | typedef struct git_index git_index; 134 | 135 | /** Time in a signature */ 136 | typedef struct git_time { 137 | git_time_t time; /** time in seconds from epoch */ 138 | int offset; /** timezone offset, in minutes */ 139 | } git_time; 140 | 141 | /** An action signature (e.g. for committers, taggers, etc) */ 142 | typedef struct git_signature { 143 | char *name; /** full name of the author */ 144 | char *email; /** email of the author */ 145 | git_time when; /** time when the action happened */ 146 | } git_signature; 147 | 148 | /** In-memory representation of a reference. */ 149 | typedef struct git_reference git_reference; 150 | 151 | /** Basic type of any Git reference. */ 152 | typedef enum { 153 | GIT_REF_INVALID = 0, /** Invalid reference */ 154 | GIT_REF_OID = 1, /** A reference which points at an object id */ 155 | GIT_REF_SYMBOLIC = 2, /** A reference which points at another reference */ 156 | GIT_REF_PACKED = 4, 157 | GIT_REF_HAS_PEEL = 8, 158 | GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC|GIT_REF_PACKED, 159 | } git_rtype; 160 | 161 | /** @} */ 162 | GIT_END_DECL 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /test/gen_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'docurium' 3 | require 'docurium/cli' 4 | require 'tempfile' 5 | 6 | class GenTest < Minitest::Test 7 | 8 | # make sure we can read what we give the user 9 | def test_read_generated_file 10 | file = Tempfile.new 'docurium' 11 | capture_io do 12 | Docurium::CLI.gen(file.path) 13 | end 14 | 15 | assert_raises(Rugged::RepositoryError) { Docurium.new file.path } 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /test/parser_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'docurium' 3 | require 'pp' 4 | 5 | class ParserTest < Minitest::Test 6 | 7 | def teardown 8 | @parser.cleanup! if @parser 9 | end 10 | 11 | # e.g. parse('git2/refs.h') 12 | # contents is either a string (the contents of "path") 13 | # or a hash of paths => contents 14 | def parse(path, contents) 15 | contents = [[path, contents]] if contents.is_a? String 16 | @parser = Docurium::DocParser.new(contents) 17 | @parser.parse_file(path) 18 | end 19 | 20 | def test_single_function 21 | 22 | name = 'function.h' 23 | contents = < "function.h", 37 | :line => 9, 38 | :lineto => 9, 39 | :tdef => nil, 40 | :type => :function, 41 | :name => 'some_function', 42 | :body => 'int some_function(char *string);', 43 | :description => ' Do something', 44 | :comments => " More explanation of what we do\n\n ", 45 | :sig => 'char *', 46 | :args => [{ 47 | :name => 'string', 48 | :type => 'char *', 49 | :comment => 'a sequence of characters' 50 | }], 51 | :return => { 52 | :type => 'int', 53 | :comment => ' an integer value' 54 | }, 55 | :decl => 'int some_function(char *string)', 56 | :argline => 'char *string', 57 | }] 58 | 59 | assert_equal expected, actual 60 | end 61 | 62 | def test_single_multiline_function 63 | 64 | name = 'function.h' 65 | contents = < 67 | /** 68 | * Do something 69 | * 70 | * More explanation of what we do 71 | * 72 | * @param string a sequence of characters 73 | * @return an integer value 74 | */ 75 | int some_function( 76 | char *string, 77 | int len); 78 | EOF 79 | 80 | actual = parse(name, contents) 81 | expected = [{:file => "function.h", 82 | :line => 10, 83 | :lineto => 12, 84 | :tdef => nil, 85 | :type => :function, 86 | :name => 'some_function', 87 | :body => "int some_function(char *string, int len);", 88 | :description => ' Do something', 89 | :comments => " More explanation of what we do\n\n ", 90 | :sig => 'char *::int', 91 | :args => [{ 92 | :name => 'string', 93 | :type => 'char *', 94 | :comment => 'a sequence of characters' 95 | }, 96 | { 97 | :name => 'len', 98 | :type => 'int', 99 | :comment => nil 100 | }], 101 | :return => { 102 | :type => 'int', 103 | :comment => ' an integer value' 104 | }, 105 | :decl => "int some_function(char *string, int len)", 106 | :argline => "char *string, int len", 107 | }] 108 | 109 | assert_equal expected, actual 110 | end 111 | 112 | def test_parsing_with_extern 113 | 114 | name_a = 'common.h' 115 | contents_a = < "function.h", 135 | :line => 6, 136 | :lineto => 6, 137 | :tdef => nil, 138 | :type => :function, 139 | :name => "some_public_function", 140 | :body => "int some_public_function(int val);", 141 | :description => " Awesomest API", 142 | :comments => "", 143 | :sig => "int", 144 | :args => [{ 145 | :name=>"val", 146 | :type=>"int", 147 | :comment=>nil 148 | }], 149 | :return => { 150 | :type=>"int", 151 | :comment=>nil 152 | }, 153 | :decl =>"int some_public_function(int val)", 154 | :argline =>"int val" 155 | }] 156 | 157 | assert_equal expected, actual 158 | 159 | end 160 | 161 | 162 | def test_return_struct 163 | name = 'tree.h' 164 | contents = < "tree.h", 177 | :line => 7, 178 | :lineto => 7, 179 | :tdef => nil, 180 | :type => :function, 181 | :name => "git_tree_owner", 182 | :body => "git_repository * git_tree_owner(git_tree *tree);", 183 | :description => " Weak owner ref", 184 | :comments => "", 185 | :sig => "git_tree *", 186 | :args => [{ 187 | :name => "tree", 188 | :type => "git_tree *", 189 | :comment => nil 190 | }], 191 | :return => { 192 | :type => "git_repository *", 193 | :comment => nil 194 | }, 195 | :decl => "git_repository * git_tree_owner(git_tree *tree)", 196 | :argline => "git_tree *tree" 197 | }] 198 | 199 | assert_equal expected, actual 200 | 201 | end 202 | 203 | def test_parse_struct 204 | 205 | name = 'struct.h' 206 | 207 | contents = < "struct.h", 221 | :line => 4, 222 | :lineto => 7, 223 | :tdef => :typedef, 224 | :type => :struct, 225 | :name => "git_foo", 226 | :underlying_type => 'struct git_foo', 227 | :description => " Foo to the bar", 228 | :comments => "", 229 | :fields => [ 230 | { 231 | :type => "int", 232 | :name => "val", 233 | :comments => "", 234 | }, 235 | { 236 | :type => "char *", 237 | :name => "name", 238 | :comments => "", 239 | } 240 | ], 241 | :decl => ["int val", "char * name"], 242 | :block => "int val\nchar * name" 243 | }] 244 | 245 | assert_equal expected, actual 246 | 247 | end 248 | 249 | def test_parse_struct_with_field_docs 250 | 251 | name = 'struct.h' 252 | 253 | contents = < "struct.h", 274 | :line => 4, 275 | :lineto => 15, 276 | :tdef => :typedef, 277 | :type => :struct, 278 | :name => "git_foo", 279 | :underlying_type => 'struct git_foo', 280 | :description => " Foo to the bar", 281 | :comments => "", 282 | :fields => [ 283 | { 284 | :type => "int", 285 | :name => "val", 286 | :comments => " This stores a value", 287 | }, 288 | { 289 | :type => "char *", 290 | :name => "name", 291 | :comments => " And this stores its name\n\n Which should be pretty descriptive", 292 | } 293 | ], 294 | :decl => ["int val", "char * name"], 295 | :block => "int val\nchar * name" 296 | }] 297 | 298 | assert_equal expected, actual 299 | 300 | end 301 | 302 | def test_parse_enum 303 | 304 | name = 'enum.h' 305 | contents = < 'enum.h', 319 | :line => 4, 320 | :lineto => 8, 321 | :tdef => :typedef, 322 | :type => :enum, 323 | :name => "git_merge_action", 324 | :underlying_type => 'enum git_merge_action', 325 | :description => " Magical enum of power", 326 | :comments => "", 327 | :fields => [{ 328 | :type => "int", 329 | :name => "FF", 330 | :comments => "", 331 | :value => 0, 332 | }, 333 | { 334 | :type => "int", 335 | :name => "NO_FF", 336 | :comments => " Do not allow fast-forwards ", 337 | :value => 4, 338 | }], 339 | :block => "FF\nNO_FF", 340 | :decl => ["FF", "NO_FF"] 341 | }] 342 | 343 | assert_equal expected, actual 344 | 345 | end 346 | 347 | def test_parse_define 348 | 349 | name = 'define.h' 350 | contents = < "typeref.h", 377 | :line => 4, 378 | :lineto => 4, 379 | :tdef => :typedef, 380 | :name => "my_type", 381 | :underlying_type => "int" 382 | }] 383 | 384 | assert_equal expected, actual 385 | 386 | name = 'typeref.h' 387 | contents = < "typeref.h", 397 | :line => 4, 398 | :lineto => 4, 399 | :tdef => :typedef, 400 | :name => "my_type", 401 | :decl => 'my_type', 402 | :underlying_type => "struct my_type", 403 | :type => :struct, 404 | :description => ' My very own type', 405 | :comments => '', 406 | }] 407 | 408 | assert_equal expected, actual 409 | 410 | 411 | end 412 | 413 | def test_callaback 414 | name = 'typeref.h' 415 | contents = < "typeref.h", 427 | :line => 6, 428 | :lineto => 6, 429 | :tdef => :typedef, 430 | :name => "some_callback", 431 | :underlying_type => "int (*)(int *)", 432 | :type => :callback, 433 | :body => ' some_callback(int *foo);', 434 | :description => ' This is a callback type', 435 | :comments => ' ', 436 | :sig => "int *", 437 | :args => [{:name => "foo", 438 | :type => "int *", 439 | :comment => nil, 440 | }], 441 | :return => {:type => 'int', 442 | :comment => " whether to reschedule"}, 443 | :decl => ' some_callback(int *foo)', 444 | :argline => 'int *foo', 445 | }] 446 | 447 | assert_equal actual, expected 448 | end 449 | 450 | end 451 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | dir = File.dirname(File.expand_path(__FILE__)) 2 | $LOAD_PATH.unshift dir + '/../lib' 3 | $TESTING = true 4 | require 'test/unit' 5 | require 'rubygems' 6 | require 'docurium' 7 | require 'pp' 8 | 9 | ## 10 | # test/spec/mini 3 11 | # http://gist.github.com/25455 12 | # chris@ozmm.org 13 | # 14 | def context(*args, &block) 15 | return super unless (name = args.first) && block 16 | require 'test/unit' 17 | klass = Class.new(defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase : Test::Unit::TestCase) do 18 | def self.test(name, &block) 19 | define_method("test_#{name.gsub(/\W/,'_')}", &block) if block 20 | end 21 | def self.xtest(*args) end 22 | def self.setup(&block) define_method(:setup, &block) end 23 | def self.teardown(&block) define_method(:teardown, &block) end 24 | end 25 | (class << klass; self end).send(:define_method, :name) { name.gsub(/\W/,'_') } 26 | klass.class_eval &block 27 | ($contexts ||= []) << klass # make sure klass doesn't get GC'd 28 | klass 29 | end 30 | --------------------------------------------------------------------------------