take 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30a3eaeb64d8a7145710c1b21b61ef49438c2ce9
4
- data.tar.gz: 7b6088a71e656c266783e00ccced336c40a6dbef
3
+ metadata.gz: d4f683117b5d40dc796e5fef18255f3f16a3f005
4
+ data.tar.gz: 2107ea1194a5da5ffc14658b1f248b43410b563a
5
5
  SHA512:
6
- metadata.gz: 0c94995f202f6a12a982ae5eb551382752619111d80545fe0a10a5302eb9c95b934e847cab5ee346dca50b6aa36e6bb7b04d49002b131c2537674bfa864f4fc2
7
- data.tar.gz: 12248c0b1533fe39e896152c1e8076652801b825e6a066b92d8d595126f3f999fcad96899c50546d0e36f2c2cdfb5df845ffb754590481db4efdbc710e74fb9b
6
+ metadata.gz: 51ab66ab98bd63428cd1d8dce72282ee97348189cc18cfbe9cd6bb6e383b440c02bf30941df98196eb08d628b0b35c6ac8b9825132b817b6627d710f57fd8a83
7
+ data.tar.gz: 086c7c3f47d0863fa575d3822f568c7b90668f13c2971bb7a174f9e25008100df6738ee2c927ef2277d6f5f6342608f19bc4c40a8d2b651c15e449a45163d7e8
data/lib/take.rb CHANGED
@@ -3,5 +3,5 @@ require "take/unit"
3
3
  require "take/project"
4
4
 
5
5
  module Take
6
- # Your code goes here...
6
+
7
7
  end
@@ -0,0 +1,5 @@
1
+ module Take
2
+ module Compiler
3
+
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ module Take
2
+ module Compiler
3
+ class Base
4
+
5
+ def self.on_platform?
6
+ false
7
+ end
8
+
9
+ def self.command
10
+ raise NotImplementedError
11
+ end
12
+
13
+ def initialize
14
+ @options = { extra: {} }
15
+ end
16
+
17
+ def command
18
+ self.class.command
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,118 @@
1
+ module Take
2
+ module Compiler
3
+ class GCC < Base
4
+
5
+ DEBUG_OPTIONS = {
6
+ default: "0",
7
+ normal: "1",
8
+ more: "2",
9
+ max: "3",
10
+ debug: "g",
11
+ fast: "fast",
12
+ size: "s"
13
+ }.freeze
14
+
15
+ def self.on_platform?
16
+ @_on_platform ||= begin
17
+ runner = Command::Runner.new(command, "--version")
18
+ runner.run.successful?
19
+ end
20
+ end
21
+
22
+ def self.command
23
+ "gcc".freeze
24
+ end
25
+
26
+ def initialize
27
+ super
28
+ @options[:libraries] = []
29
+ @options[:directories] = { include: [],
30
+ quote: [],
31
+ library: [] }.freeze
32
+ @options[:defines] = {}
33
+ @options[:optimize] = DEBUG_OPTIONS.fetch(:default)
34
+ @options[:warnings] = ["all", "extra"]
35
+ end
36
+
37
+ def output=(file)
38
+ @options[:output] = file
39
+ end
40
+
41
+ def language=(lang)
42
+ @options[:lang] = lang || "none"
43
+ end
44
+
45
+ def standard=(standard)
46
+ if standard
47
+ @options[:std] = standard
48
+ else
49
+ @options.delete(:std)
50
+ end
51
+ end
52
+
53
+ def optimize_mode=(mode)
54
+ mode = :default unless mode
55
+ @options[:optimize] = DEBUG_OPTIONS.fetch(mode) do
56
+ DEBUG_OPTIONS.fetch(:default)
57
+ end
58
+ end
59
+
60
+ def []=(key, value)
61
+ @options[:extra][key] = value
62
+ end
63
+
64
+ def libraries
65
+ @options[:libraries]
66
+ end
67
+
68
+ def directories
69
+ @options[:directories]
70
+ end
71
+
72
+ def defines
73
+ @options[:defines]
74
+ end
75
+
76
+ def warnings
77
+ @options[:warnings]
78
+ end
79
+
80
+ def stop_after(stage = nil)
81
+ case stage
82
+ when :link
83
+ @options[:stop] = "c"
84
+ when :assemble
85
+ @options[:stop] = "S"
86
+ when :preprocess
87
+ @options[:stop] = "E"
88
+ else
89
+ @options.delete(:stop)
90
+ end
91
+ end
92
+
93
+ def object
94
+ stop_after :link
95
+ self
96
+ end
97
+
98
+ def run
99
+
100
+ end
101
+
102
+ private
103
+
104
+ def compile_options
105
+ compiled = ""
106
+
107
+ if @options.key?(:std)
108
+ compiled << "-std=#{@options[:std]} "
109
+ end
110
+
111
+ compiled << "-g#{@options[:optimize]} "
112
+ compiled << @options[:warnings].map { |w| "-W#{w}" }.join(" ")
113
+ compiled << "-fPIC "
114
+ compiled << @options[:directories][:include].map { |i| "-I#{i}"}
115
+ end
116
+ end
117
+ end
118
+ end
data/lib/take/lint.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "take/lint/base"
2
+
3
+
4
+ module Take
5
+ module Lint
6
+
7
+ end
8
+ end
@@ -0,0 +1,28 @@
1
+ module Take
2
+ module Lint
3
+
4
+ # Manages linting source files when building. Should be
5
+ # interesting to see how this pans out.
6
+ #
7
+ # @abstract
8
+ class Base
9
+
10
+ # Initializes the base linter. Requires only one parameter.
11
+ #
12
+ # @param file [Path] the file that will be linted.
13
+ def initialize(file)
14
+ @file = file
15
+ end
16
+
17
+ # Lints the given file. Returns an array of lint errors, which
18
+ # is used to give information about what could be fixed.
19
+ #
20
+ # @abstract
21
+ # @return [Array<Take::Lint::Error>]
22
+ def lint
23
+ raise NotImplementedError
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ module Take
2
+ module Lint
3
+ class Error
4
+
5
+ attr_accessor :type
6
+ attr_accessor :file
7
+ attr_accessor :line
8
+ attr_accessor :column
9
+ attr_accessor :description
10
+
11
+ def initialize(data = {})
12
+ data.each do |key, value|
13
+ key = :"#{key}="
14
+
15
+ if respond_to? key
16
+ send key, value
17
+ else
18
+ raise ArgumentError, "Bad key given"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,88 @@
1
+ require "pathname"
2
+ require "command/runner"
3
+ require "take/project/file"
4
+ require "take/project/actionable"
5
+ require "take/project/target"
6
+ require "take/project/convert"
7
+ require "take/project/definition"
8
+ require "take/project/requirement"
9
+
10
+ module Take
11
+
12
+ # Handles project information for a specific project. Tends to
13
+ # represent an entire directory.
14
+ class Project
15
+
16
+ # The name of the project. This is normally guessed from the
17
+ # directory name.
18
+ #
19
+ # @return [String]
20
+ attr_accessor :name
21
+
22
+ # Creates a new project with the block, and calls {#call}.
23
+ # Returns the created project. A name is not required.
24
+ #
25
+ # @param [String?] name the name of the project. If it is not
26
+ # given, it is assumed from the directory name.
27
+ # @return [Project]
28
+ # @todo FIX
29
+ def self.create(name = nil, path = nil, &block)
30
+ project = new(name, path, &block)
31
+ project.call
32
+ project
33
+ end
34
+
35
+ # Initialize the project.
36
+ def initialize(name = nil, path = nil, &block)
37
+ @block = block
38
+ @name = name
39
+ @groups = {}
40
+ @files = {}
41
+ @targets = []
42
+ if path
43
+ @_path = Pathname.new(path)
44
+ end
45
+ end
46
+
47
+ # Set the project name.
48
+ def project(name)
49
+ @name = name
50
+ end
51
+
52
+ # The path to the project.
53
+ #
54
+ # @return [Pathname]
55
+ def path
56
+ @_path ||= Pathname.new("/home/homer/projects/dash")
57
+ end
58
+
59
+ def call
60
+ @definition = Definition.new(self)
61
+ @definition.instance_exec(&@block)
62
+ p @definition
63
+ @definition
64
+ end
65
+
66
+ # Creates a Makefile syntax-based string of the project.
67
+ #
68
+ # @return [String]
69
+ def to_makefile
70
+ out = ""
71
+ out << @targets.
72
+ map { |target| target.to_makefile(self) }.join("\n\n")
73
+ out
74
+ end
75
+
76
+ def file(name)
77
+ index = File.normalize(name, path)
78
+ @files[index] ||= File.new(index)
79
+ end
80
+
81
+ def env
82
+ {
83
+ cc: "gcc"
84
+ }
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1,40 @@
1
+ module Take
2
+ class Project
3
+
4
+ # Handles actions that might be taken from within a build action;
5
+ # used in {Convert}s and {Target}s.
6
+ class Actionable
7
+
8
+ attr_reader :data
9
+
10
+ def initialize(&blk)
11
+ @data = {}
12
+ @block = blk
13
+ end
14
+
15
+ def run(command, arguments)
16
+ runner = Command::Runner.new(command, arguments)
17
+ runner.pass!
18
+ end
19
+
20
+ def call(project, data = {})
21
+ @data = data.merge(
22
+ :curdir => project.path,
23
+ :env => project.env)
24
+ instance_exec(@block)
25
+ end
26
+
27
+ def method_missing(method, *args, &block)
28
+ if @data.key?(method) && args.size == 0 && !block_given?
29
+ @data[method]
30
+ else
31
+ super
32
+ end
33
+ end
34
+
35
+ def respond_to_missing?(method, _)
36
+ @data.key?(method)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,47 @@
1
+ module Take
2
+ class Project
3
+
4
+ # Takes a file with a specific extension, and converts it to
5
+ # another file with a specific extension. Woop de do.
6
+ class Convert
7
+
8
+ def initialize(hash, &blk)
9
+ raise ArgumentError, "Expected a block" unless block_given?
10
+ handle_arguments(hash)
11
+ @action = Actionable.new(&blk)
12
+ end
13
+
14
+ def can_convert?(from, to)
15
+ from_ext, to_ext = [from, to].map do |file|
16
+ if file.respond_to?(:extname)
17
+ file.extname
18
+ else
19
+ ::File.extname(file)
20
+ end
21
+ end
22
+
23
+ @from == from_ext && @to == to_ext
24
+ end
25
+
26
+ def convert(project, from, to)
27
+ raise ArgumentError, "Cannot convert #{from.inspect} to " \
28
+ "#{to.inspect} with this converter!" \
29
+ unless can_convert?(from, to)
30
+
31
+ @action.call(project, :input => from, :output => to)
32
+ end
33
+
34
+ private
35
+
36
+ def handle_arguments(hash)
37
+ raise ArgumentError, "Expected hash to only have size 1" \
38
+ unless hash.to_a.size == 1
39
+
40
+ pair = hash.to_a[0]
41
+ @from = pair[0]
42
+ @to = pair[1]
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,31 @@
1
+ module Take
2
+ class Project
3
+ class Definition
4
+
5
+ def initialize(project)
6
+ @project = project
7
+ @targets = {}
8
+ @converts = []
9
+ @requirements = []
10
+ end
11
+
12
+ def target(hash, &blk)
13
+ ntarget = Target.new(hash, @project, &blk)
14
+ @targets[ntarget.name] = ntarget
15
+ end
16
+
17
+ def targets
18
+ @targets
19
+ end
20
+
21
+ def to_convert(*opts, &blk)
22
+ Convert.new(*opts, &blk).tap { |c| @converts << c }
23
+ end
24
+
25
+ def requires(hash, &blk)
26
+ Requirement.convert(hash, @project, &blk).
27
+ tap { |r| @requirements.concat(r) }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,47 @@
1
+ require 'forwardable'
2
+
3
+ module Take
4
+ class Project
5
+ class File
6
+
7
+ extend Forwardable
8
+
9
+ def self.normalize(file, path)
10
+ expanded = ::File.expand_path(file, path)
11
+ raise ArgumentError, "The given file cannot be placed in " \
12
+ "the project: #{file.inspect}" \
13
+ unless expanded.start_with?(path.to_s)
14
+ name = Pathname.new(expanded)
15
+ name.relative_path_from(path)
16
+ end
17
+
18
+ def_delegators :@name, :to_path, :to_s, :extname
19
+
20
+ def initialize(name)
21
+ @name = name
22
+ end
23
+
24
+ def type
25
+ @_type ||= begin
26
+ case @name.extname
27
+ when ".ta"
28
+ :library
29
+ when ".to", ".o"
30
+ :object
31
+ when ".c"
32
+ :source
33
+ when ""
34
+ :executable
35
+ else
36
+ :unknown
37
+ end
38
+ end
39
+ end
40
+
41
+
42
+ def sub_ext(ext)
43
+ File.new(@name.sub_ext(ext))
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,44 @@
1
+ require "take/project/requirement/base"
2
+ require "take/project/requirement/library"
3
+ require "take/project/requirement/header"
4
+ require "take/project/requirement/program"
5
+
6
+ module Take
7
+ class Project
8
+ module Requirement
9
+
10
+ def self.convert(hash, project, &blk)
11
+ if hash.size > 1
12
+ raise ArgumentError, "Cannot use a block for a " \
13
+ "multi-requirement!" if block_given?
14
+ end
15
+
16
+ requirements = []
17
+
18
+ hash.each do |key, value|
19
+ requirement_class = lookup(key)
20
+ requirement = requirement_class.new(key, value, project,
21
+ &blk)
22
+ requirements << requirement
23
+ end
24
+
25
+ requirements
26
+ end
27
+
28
+ def self.lookup(name)
29
+ case name
30
+ when :header
31
+ Header
32
+ when :library
33
+ Library
34
+ when :program
35
+ Program
36
+ when Class
37
+ name
38
+ else
39
+ raise ArgumentError, "Unknown requirement #{name.inspect}!"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,39 @@
1
+ module Take
2
+ class Project
3
+ module Requirement
4
+ class Base
5
+
6
+ def self.default_action(&blk)
7
+ if block_given?
8
+ @_default_action = blk
9
+ else
10
+ @_default_action
11
+ end
12
+ end
13
+
14
+ def initialize(type, data, project, &blk)
15
+ @type = type
16
+ @data = data
17
+ @block = blk
18
+ @project = project
19
+
20
+ raise ArgumentError, "Unexpected block for requirement " \
21
+ "#{self.class}" unless expected_block?
22
+ end
23
+
24
+ def fills_requirement?
25
+ block = @block || default_action
26
+ block.call(@data, @project)
27
+ end
28
+
29
+ def expected_block?
30
+ true
31
+ end
32
+
33
+ def default_action
34
+ self.class.default_action
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,26 @@
1
+ module Take
2
+ class Project
3
+ module Requirement
4
+ class Header < Base
5
+
6
+ default_action do |header, project|
7
+ file = Tempfile.new(['test', '.c'])
8
+ file.write("#include <#{header}>\n\nint main() " \
9
+ "{ return 0; }\n")
10
+ file.flush
11
+ out = Tempfile.new(['test', ''])
12
+
13
+ command = Command::Runner.new(project.env[:cc],
14
+ "-o {out} {in} -fPIC")
15
+ success = command.run(in: file.path, out: out.path) do |m|
16
+ p m
17
+ end.successful?
18
+
19
+ file.close(true)
20
+ out.close(true)
21
+ success
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module Take
2
+ class Project
3
+ module Requirement
4
+ class Library < Base
5
+
6
+ default_action do |library, project|
7
+ file = Tempfile.new(['test', '.c'])
8
+ file.write("#include <stdlib.h>\n\nint main() " \
9
+ "{ return 0; }\n")
10
+ file.flush
11
+ out = Tempfile.new(['test', ''])
12
+
13
+ command = Command::Runner.new(project.env[:cc],
14
+ "-o {out} {in} -fPIC -l{library}")
15
+ success = command.run(in: file.path, library: library,
16
+ out: out.path).successful?
17
+
18
+ file.close(true)
19
+ out.close(true)
20
+ success
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ module Take
2
+ class Project
3
+ module Requirement
4
+ class Program < Base
5
+
6
+ default_action do |program, project|
7
+ runner = Command::Runner.new(program, "")
8
+ runner.run.no_command?
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,102 @@
1
+ module Take
2
+ class Project
3
+
4
+ class Target
5
+
6
+ # Initializes the target.
7
+ #
8
+ # @param [Project] project the project that this target is
9
+ # a part of.
10
+ # @param [Hash] hash a hash of the options for this target. If
11
+ # the any key is not one of the below, it is assumed to be the
12
+ # target key-pair; there may only be one target key-pair (any
13
+ # more will cause an ArgumentError). If the key of the key
14
+ # pair is a symbol, it is considered an "invalid" target,
15
+ # meaning it _must not_ be a default target.
16
+ # @option hash [Symbol] :type The type of target it is. This is
17
+ # normally assumed from the extension.
18
+ # @option hash [Array<String>] :depends, :depends_on Files that
19
+ # the target depends on. This is normally set by the value
20
+ # of the target key pair.
21
+ # @option hash [Symbol, String] :name The name of the target.
22
+ # This is normally set by the key of the target key pair.
23
+ def initialize(hash, project, &block)
24
+ raise ArgumentError, "Targets require blocks" \
25
+ unless block_given?
26
+ @block = block
27
+ @project = project
28
+ @dependencies = []
29
+ handle_arguments(hash)
30
+ guess_type unless @type
31
+ end
32
+
33
+ def invalid?
34
+ @target.is_a?(Symbol)
35
+ end
36
+
37
+ def name
38
+ if invalid?
39
+ @target
40
+ else
41
+ @target.to_path
42
+ end
43
+ end
44
+
45
+ def sub(what, to)
46
+ @dependencies.map do |dep|
47
+ if dep.extname == what
48
+ dep.sub_ext(to)
49
+ else
50
+ dep
51
+ end
52
+ end
53
+ end
54
+
55
+ def to_a
56
+ @dependencies.map(&:to_path)
57
+ end
58
+
59
+ private
60
+
61
+ attr_reader :project
62
+
63
+ def guess_type
64
+ if invalid?
65
+ @type = :invalid
66
+ else
67
+ @type = @target.type
68
+ end
69
+ end
70
+
71
+ def handle_arguments(hash)
72
+ [:type, :depends, :depends_on, :name]
73
+ defined_target = false
74
+ raise ArgumentError, "Expected Hash, got #{hash.class}" \
75
+ unless hash.is_a?(Hash)
76
+
77
+ hash.each do |key, value|
78
+ case key
79
+ when :type
80
+ @type = value
81
+ when :depends, :depends_on
82
+ @dependencies.concat(Array(value))
83
+ when :name
84
+ @target = value
85
+ when String, Symbol
86
+ raise ArgumentError, "Target already defined! Maybe you" \
87
+ " misspelled. Unknown option #{key.inspect}." \
88
+ if defined_target
89
+ @target = key
90
+ defined_target = true
91
+ @dependencies.concat(Array(value))
92
+ else
93
+ raise ArgumentError, "Unknown option #{key.inspect}."
94
+ end
95
+ end
96
+
97
+ @target = project.file(@target) unless invalid?
98
+ @dependencies.map! { |dep| project.file(dep) }
99
+ end
100
+ end
101
+ end
102
+ end
@@ -76,7 +76,7 @@ CODE
76
76
  void test_#{group_name(node)}()
77
77
  {
78
78
  tests++;
79
- int test_success = 1;
79
+ int test_skip = 0, test_success = 1;
80
80
  output(TEXT_COLOR_MAGENTA "\\t\\tTEST \\"" TEXT_COLOR_BOLD_MAGENTA
81
81
  "#{node.name}" TEXT_COLOR_MAGENTA "\\": ");
82
82
 
@@ -86,7 +86,11 @@ CODE
86
86
  afters.each { |child| walk(child) }
87
87
  @output << <<-CODE
88
88
 
89
- if(test_success)
89
+ if(test_skip)
90
+ {
91
+ output(TEXT_COLOR_BOLD_YELLOW "PASS\\n");
92
+ }
93
+ else if(test_success)
90
94
  {
91
95
  #ifdef VERBOSE
92
96
  output("\\n\\t\\t\\t" TEXT_COLOR_GREEN "OK\\n");
data/lib/take/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Take
2
- VERSION = "0.0.10".freeze
2
+ VERSION = "0.0.11".freeze
3
3
  end
data/take.gemspec CHANGED
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.6"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_dependency "virtus", "~> 1.0"
24
+ spec.add_dependency "command-runner"
24
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: take
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Rodi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-29 00:00:00.000000000 Z
11
+ date: 2014-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: command-runner
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: Manage your C projects better.
56
70
  email:
57
71
  - redjazz96@gmail.com
@@ -65,6 +79,23 @@ files:
65
79
  - README.md
66
80
  - Rakefile
67
81
  - lib/take.rb
82
+ - lib/take/compiler.rb
83
+ - lib/take/compiler/base.rb
84
+ - lib/take/compiler/gcc.rb
85
+ - lib/take/lint.rb
86
+ - lib/take/lint/base.rb
87
+ - lib/take/lint/error.rb
88
+ - lib/take/project.rb
89
+ - lib/take/project/actionable.rb
90
+ - lib/take/project/convert.rb
91
+ - lib/take/project/definition.rb
92
+ - lib/take/project/file.rb
93
+ - lib/take/project/requirement.rb
94
+ - lib/take/project/requirement/base.rb
95
+ - lib/take/project/requirement/header.rb
96
+ - lib/take/project/requirement/library.rb
97
+ - lib/take/project/requirement/program.rb
98
+ - lib/take/project/target.rb
68
99
  - lib/take/unit.rb
69
100
  - lib/take/unit/ast.rb
70
101
  - lib/take/unit/ast/after.rb
@@ -107,3 +138,4 @@ signing_key:
107
138
  specification_version: 4
108
139
  summary: Manage your C projects better.
109
140
  test_files: []
141
+ has_rdoc: