summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/sntp/unity/auto/generate_module.rb
blob: 3db1a984cddb81309fcb3f338eb078b18b68604d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# ==========================================
#   Unity Project - A Test Framework for C
#   Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
#   [Released under MIT License. Please refer to license.txt for details]
# ========================================== 

# This script creates all the files with start code necessary for a new module.
# A simple module only requires a source file, header file, and test file.
# Triad modules require a source, header, and test file for each triad type (like model, conductor, and hardware).

require 'rubygems'
require 'fileutils'

HERE = File.expand_path(File.dirname(__FILE__)) + '/'

#help text when requested
HELP_TEXT = [ "\nGENERATE MODULE\n-------- ------",
              "\nUsage: ruby generate_module [options] module_name",
              "  -i\"include\" sets the path to output headers to 'include' (DEFAULT ../src)",
              "  -s\"../src\"  sets the path to output source to '../src'   (DEFAULT ../src)",
              "  -t\"C:/test\" sets the path to output source to 'C:/test'  (DEFAULT ../test)",
              "  -p\"MCH\"     sets the output pattern to MCH.",
              "              dh  - driver hardware.",
              "              dih - driver interrupt hardware.",
              "              mch - model conductor hardware.",
              "              mvp - model view presenter.",
              "              src - just a single source module. (DEFAULT)",
              "  -d          destroy module instead of creating it.",
              "  -u          update subversion too (requires subversion command line)",
              "  -y\"my.yml\"  selects a different yaml config file for module generation",
              "" ].join("\n")

#Built in patterns
PATTERNS = { 'src' => {''         => { :inc => [] } },
             'dh'  => {'Driver'   => { :inc => ['%1$sHardware.h'] }, 
                       'Hardware' => { :inc => [] } 
                      },
             'dih' => {'Driver'   => { :inc => ['%1$sHardware.h', '%1$sInterrupt.h'] }, 
                       'Interrupt'=> { :inc => ['%1$sHardware.h'] },
                       'Hardware' => { :inc => [] } 
                      },
             'mch' => {'Model'    => { :inc => [] }, 
                       'Conductor'=> { :inc => ['%1$sModel.h', '%1$sHardware.h'] },
                       'Hardware' => { :inc => [] } 
                      },
             'mvp' => {'Model'    => { :inc => [] }, 
                       'Presenter'=> { :inc => ['%1$sModel.h', '%1$sView.h'] },
                       'View'     => { :inc => [] } 
                      }
           }

#TEMPLATE_TST
TEMPLATE_TST = %q[#include "unity.h"
%2$s#include "%1$s.h"

void setUp(void)
{
}

void tearDown(void)
{
}

void test_%1$s_NeedToImplement(void)
{
    TEST_IGNORE();
}
]

#TEMPLATE_SRC
TEMPLATE_SRC = %q[%2$s#include "%1$s.h"
]

#TEMPLATE_INC
TEMPLATE_INC = %q[#ifndef _%3$s_H
#define _%3$s_H%2$s

#endif // _%3$s_H
]

# Parse the command line parameters.
ARGV.each do |arg|
  case(arg)
    when /^-d/      then @destroy = true
    when /^-u/      then @update_svn = true
    when /^-p(\w+)/ then @pattern = $1
    when /^-s(.+)/  then @path_src = $1
    when /^-i(.+)/  then @path_inc = $1
    when /^-t(.+)/  then @path_tst = $1
    when /^-y(.+)/  then @yaml_config = $1
    when /^(\w+)/
      raise "ERROR: You can't have more than one Module name specified!" unless @module_name.nil?
      @module_name = arg
    when /^-(h|-help)/ 
      puts HELP_TEXT
      exit
    else
      raise "ERROR: Unknown option specified '#{arg}'"
  end
end
raise "ERROR: You must have a Module name specified! (use option -h for help)" if @module_name.nil?

#load yaml file if one was requested
if @yaml_config
  require 'yaml'
  cfg = YAML.load_file(HERE + @yaml_config)[:generate_module]
  @path_src     = cfg[:defaults][:path_src]   if @path_src.nil?
  @path_inc     = cfg[:defaults][:path_inc]   if @path_inc.nil?
  @path_tst     = cfg[:defaults][:path_tst]   if @path_tst.nil?
  @update_svn   = cfg[:defaults][:update_svn] if @update_svn.nil?
  @extra_inc    = cfg[:includes]
  @boilerplates = cfg[:boilerplates]
else
  @boilerplates = {}
end

# Create default file paths if none were provided
@path_src = HERE + "../src/"  if @path_src.nil?
@path_inc = @path_src         if @path_inc.nil?
@path_tst = HERE + "../test/" if @path_tst.nil?
@path_src += '/'              unless (@path_src[-1] == 47)
@path_inc += '/'              unless (@path_inc[-1] == 47)
@path_tst += '/'              unless (@path_tst[-1] == 47)
@pattern  = 'src'             if @pattern.nil?
@includes = { :src => [], :inc => [], :tst => [] }
@includes.merge!(@extra_inc) unless @extra_inc.nil?

#create triad definition
TRIAD = [ { :ext => '.c', :path => @path_src,        :template => TEMPLATE_SRC, :inc => :src, :boilerplate => @boilerplates[:src] }, 
          { :ext => '.h', :path => @path_inc,        :template => TEMPLATE_INC, :inc => :inc, :boilerplate => @boilerplates[:inc] },
          { :ext => '.c', :path => @path_tst+'Test', :template => TEMPLATE_TST, :inc => :tst, :boilerplate => @boilerplates[:tst] },
        ]

#prepare the pattern for use
@patterns = PATTERNS[@pattern.downcase]
raise "ERROR: The design pattern specified isn't one that I recognize!" if @patterns.nil?

# Assemble the path/names of the files we need to work with.
files = []
TRIAD.each do |triad|
  @patterns.each_pair do |pattern_file, pattern_traits|
    files << {
      :path => "#{triad[:path]}#{@module_name}#{pattern_file}#{triad[:ext]}",
      :name => "#{@module_name}#{pattern_file}",
      :template => triad[:template],
      :boilerplate => triad[:boilerplate],
      :includes => case(triad[:inc])
                     when :src then @includes[:src] | pattern_traits[:inc].map{|f| f % [@module_name]}
                     when :inc then @includes[:inc]
                     when :tst then @includes[:tst] | pattern_traits[:inc].map{|f| "Mock#{f}"% [@module_name]}
                   end
    }
  end
end

# destroy files if that was what was requested
if @destroy
  files.each do |filespec|
    file = filespec[:path]
    if File.exist?(file)
      if @update_svn
        `svn delete \"#{file}\" --force` 
        puts "File #{file} deleted and removed from source control"
      else
        FileUtils.remove(file)
        puts "File #{file} deleted"
      end
    else
      puts "File #{file} does not exist so cannot be removed."
    end
  end
  puts "Destroy Complete"
  exit
end

#Abort if any module already exists
files.each do |file|
  raise "ERROR: File #{file[:name]} already exists. Exiting." if File.exist?(file[:path])
end

# Create Source Modules
files.each_with_index do |file, i|
  File.open(file[:path], 'w') do |f|
    f.write(file[:boilerplate] % [file[:name]]) unless file[:boilerplate].nil?
    f.write(file[:template] % [ file[:name], 
                                file[:includes].map{|f| "#include \"#{f}\"\n"}.join, 
                                file[:name].upcase ]
           )
  end
  if (@update_svn)
    `svn add \"#{file[:path]}\"` 
    if $?.exitstatus == 0
      puts "File #{file[:path]} created and added to source control"
    else
      puts "File #{file[:path]} created but FAILED adding to source control!"
    end
  else
    puts "File #{file[:path]} created"
  end
end

puts 'Generate Complete'
OpenPOWER on IntegriCloud