crusty 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/bin/crusty +396 -0
  3. metadata +45 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8a23d906a6655c552572437ee7c4e3c256ac3d50
4
+ data.tar.gz: 18e156ad48f97748d12e077f809f70e36400f340
5
+ SHA512:
6
+ metadata.gz: 40969c085b588fe8f3dc2d7fc303af716a3f61086d613466fd087ce93fefaee724639937a6a3c86ff3b82d6997894dab7464259a05c129908e71572d63b1567a
7
+ data.tar.gz: 227310078da63419a4907c91c8f21945d116dd8f153142ca024c18ab543def19dbea99cd35fe55e79cb60cad00dbcc5582a7a1d33e59d354e1e88260b4dc2f84
@@ -0,0 +1,396 @@
1
+ #!/usr/bin/env ruby
2
+ ###########################################################################
3
+ # Script to be called as an Xcode 4 run script which will attempt to
4
+ # uncrustify all source files in the open project.
5
+ #
6
+ # (c) Copyright 2012 David Wagner.
7
+ #
8
+ #*************************************************************************#
9
+ # IT WILL OVERWRITE YOUR SOURCE FILES WITHOUT WARNING SO IF YOU WANT TO #
10
+ # RESTORE WHAT YOU HAD BEFORE RUNNING IT, MAKE SURE YOUR FILES ARE UNDER #
11
+ # SOURCE CONTROL AND COMMITTED! #
12
+ #*************************************************************************#
13
+ #
14
+ # Assumptions this script makes
15
+ # =============================
16
+ #
17
+ # - You already have uncrustify installed. If not, install
18
+ # homebrew and use that to install it: `brew install uncrustfy`
19
+ # See: http://mxcl.github.com/homebrew/
20
+ #
21
+ # - If your project is called foo and located in bar, the script assumes
22
+ # your source layout is similar to:
23
+ #
24
+ # bar
25
+ # ├── foo
26
+ # │ └── <project source files>
27
+ # └── foo.xcodeproj
28
+ #
29
+ # That is, it will only look for source files in bar/foo/**
30
+ #
31
+ # - It only tries to process header files, Objective-C files,
32
+ # Objective-C++ files, C files and C++ files. It tries to guess
33
+ # the correct source type for the header files based on an
34
+ # associated source file with the same name (e.g. bob.h, bob.cpp)
35
+ #
36
+ # - The configuration used to format the files is stored at
37
+ # $PROJECT_DIR/uncrustify.cfg. If this file does not exist
38
+ # a default one will be created there. You can see the default
39
+ # at the end of this script after the __END__ tag.
40
+ #
41
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
42
+ # Licensed under the MIT license:
43
+ #
44
+ # http://www.opensource.org/licenses/mit-license.php
45
+ #
46
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
47
+ # of this software and associated documentation files (the "Software"), to deal
48
+ # in the Software without restriction, including without limitation the rights
49
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
50
+ # copies of the Software, and to permit persons to whom the Software is
51
+ # furnished to do so, subject to the following conditions:
52
+ #
53
+ # The above copyright notice and this permission notice shall be included in
54
+ # all copies or substantial portions of the Software.
55
+ #
56
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
58
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
59
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
60
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
61
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
62
+ # THE SOFTWARE.
63
+ ###########################################################################
64
+
65
+ # Location of uncrustify config. A default one will be created here if
66
+ # none exists
67
+ UNCRUSTIFY_CONFIG_FILE = File.join(ARGV[0], '../uncrustify.cfg')
68
+
69
+ # Valid extensions of file to uncrust
70
+ VALID_EXTENSIONS = ['m', 'mm', 'h', 'c', 'cc', 'cp', 'cpp']
71
+
72
+ #
73
+ # Given /foo/bar/thing.bob, it will
74
+ # return "/foo/bar", "thing.bob", "thing", ".bob"
75
+ #
76
+ def explode_filepath_to_dir_basename_name_ext(filepath)
77
+ dir = File.dirname(filepath)
78
+ basename = File.basename(filepath)
79
+ ext = File.extname(basename)
80
+ name = File.basename(basename, ext)
81
+
82
+ return dir, basename, name, ext
83
+ end
84
+
85
+ #
86
+ # Recursively gathers all files from the specified
87
+ # path who have one of the specifed extensions
88
+ #
89
+ def gather_all_sourcefiles(path, *extensions)
90
+ extension_glob = "*.{#{extensions.join(',')}}"
91
+ return Dir.glob(File.join(path, '**', extension_glob), File::FNM_CASEFOLD)
92
+ end
93
+
94
+ #
95
+ # Generates a array of uncrustfy specs from an array
96
+ # of file paths.
97
+ #
98
+ # A spec is simply a hash containing :source which
99
+ # is the source file full path and :forcetype which
100
+ # can optionally be used to force the filetype. If
101
+ # :forcetype is nil, leave it up to uncrustify to
102
+ # decide
103
+ #
104
+ def generate_uncrustify_specs(filelist)
105
+ file_specs = [];
106
+ filelist.each {
107
+ |file|
108
+ dir, filename, name, ext = explode_filepath_to_dir_basename_name_ext(file)
109
+
110
+ # If it's a header file, do some craziness to work out the file type
111
+ sourcetype = nil
112
+ if ext.downcase == '.h'
113
+ if filelist.any? { |companion| companion =~ /\/#{name}\.mm$/i }
114
+ sourcetype = "OC+"
115
+ elsif filelist.any? { |companion| companion =~ /\/#{name}\.(cc|cp|cpp)$/i }
116
+ sourcetype = "CPP"
117
+ elsif filelist.any? { |companion| companion =~ /\/#{name}\.c$/i }
118
+ sourcetype = "C"
119
+ else
120
+ # Assume Objective-C
121
+ sourcetype = "OC"
122
+ end
123
+ end
124
+
125
+ file_specs << {
126
+ :source => file,
127
+ :forcetype => sourcetype
128
+ }
129
+ }
130
+ return file_specs
131
+ end
132
+
133
+ #
134
+ # Runs the uncrustify command for the given spec
135
+ # dictionary. See generate_uncrustify_specs for
136
+ # a description of the spec.
137
+ #
138
+ def uncrust(spec)
139
+ config_path = File.join CRUSTY_PATH, "../", "uncrustify.cfg"
140
+ forcetype = spec[:forcetype] ? "-l #{spec[:forcetype]}" : ""
141
+ %x[#{UNCRUSTIFY_BIN} #{forcetype} -c #{config_path} --no-backup '#{spec[:source]}']
142
+ end
143
+
144
+ #
145
+ # Searches some likely locations for an executable
146
+ #
147
+ def find_binary(name)
148
+ fullpath = nil;
149
+ locations = [
150
+ '/usr/local/bin',
151
+ '/opt/local/bin',
152
+ '/usr/bin',
153
+ '/bin',
154
+ '/usr/local/sbin',
155
+ '/usr/sbin',
156
+ '/sbin'
157
+ ].any? { |path|
158
+ searchpath = File.join(path, name)
159
+ fullpath = searchpath if File.exist? searchpath
160
+ }
161
+ return fullpath
162
+ end
163
+
164
+ #
165
+ # Ensures the uncrustify.cfg
166
+ # exists, or creates it if not
167
+ #
168
+ def ensure_config_file
169
+ if not File.exist? UNCRUSTIFY_CONFIG_FILE
170
+ File.open(UNCRUSTIFY_CONFIG_FILE, 'w') {|f| DATA.each_line { |l| f.write l } }
171
+ end
172
+ end
173
+
174
+ #
175
+ # Can't find uncrustify, exit with an error
176
+ #
177
+ def error_no_uncrustify
178
+ $stderr.puts %{}
179
+ $stderr.puts %{Could not locate the uncrustify executable.}
180
+ $stderr.puts %{}
181
+ if find_binary('brew') != nil
182
+ $stderr.puts %{You can install it via homebrew:}
183
+ $stderr.puts %{ brew install uncrustify}
184
+ else
185
+ $stderr.puts %{You can install uncrustify via homebrew package manager.}
186
+ $stderr.puts %{}
187
+ $stderr.puts %{To install homebrew, see:}
188
+ $stderr.puts %{ http://mxcl.github.com/homebrew/}
189
+ end
190
+ exit 1
191
+ end
192
+
193
+ #
194
+ # Exit with an error message, but show usage
195
+ #
196
+ def error_show_usage_and_exit(message)
197
+ $stderr.puts %[#{message}]
198
+ $stderr.puts %[]
199
+
200
+ show_usage
201
+
202
+ exit 1
203
+ end
204
+
205
+ #
206
+ # Shows usage instructions
207
+ #
208
+ def show_usage
209
+ $stdout.puts "Usage"
210
+ $stdout.puts "====="
211
+ $stdout.puts ""
212
+ $stdout.puts "WARNING: Files are editied WITHOUT backup. You should protect"
213
+ $stdout.puts "the files with your version control system of choice before"
214
+ $stdout.puts "running this script!"
215
+ $stdout.puts ""
216
+ $stdout.puts "Examples:"
217
+ $stdout.puts ""
218
+ $stdout.puts " Uncrust from the current directory:"
219
+ $stdout.puts " #{File.basename(__FILE__)} ."
220
+ $stdout.puts ""
221
+ $stdout.puts " Uncrust files in directory './foo':"
222
+ $stdout.puts " #{File.basename(__FILE__)} foo"
223
+ $stdout.puts ""
224
+ $stdout.puts " Uncrust files in directory '/User/bob/dirtyproject':"
225
+ $stdout.puts " #{File.basename(__FILE__)} /User/bob/dirtyproject"
226
+ $stdout.puts ""
227
+ end
228
+
229
+ ###########################################################################
230
+ # Do eet
231
+ ###########################################################################
232
+
233
+ # Location of uncrustify
234
+ UNCRUSTIFY_BIN = find_binary "uncrustify"
235
+
236
+ error_no_uncrustify if UNCRUSTIFY_BIN == nil
237
+
238
+
239
+ error_show_usage_and_exit("No directory specified.") if ARGV.length == 0
240
+ error_show_usage_and_exit("Could not find #{ARGV[0]}") unless File.exist? ARGV[0]
241
+ error_show_usage_and_exit("#{ARGV[0]} is not a directory.") unless File.directory? ARGV[0]
242
+
243
+ CRUSTY_PATH = File.expand_path ARGV[0]
244
+
245
+ puts ""
246
+ puts "Uncrustifying files in:"
247
+ puts " #{CRUSTY_PATH} "
248
+ puts ""
249
+
250
+ ensure_config_file
251
+
252
+ FILES_TO_UNCRUST = gather_all_sourcefiles CRUSTY_PATH, *VALID_EXTENSIONS
253
+ FILE_SPECS = generate_uncrustify_specs FILES_TO_UNCRUST;
254
+
255
+ FILE_SPECS.each { |spec| uncrust spec }
256
+
257
+ ###########################################################################
258
+ # A reasonable default Objective-C uncrustify configuration
259
+ ###########################################################################
260
+ __END__
261
+ #
262
+ # uncrustify config file for objective-c and objective-c++
263
+ #
264
+
265
+ indent_with_tabs = 0 # 1=indent to level only, 2=indent with tabs
266
+ output_tab_size = 4 # new tab size
267
+ indent_columns = output_tab_size
268
+ indent_label = 2 # pos: absolute col, neg: relative column
269
+ indent_align_assign = FALSE
270
+
271
+ #
272
+ # Indenting
273
+ #
274
+
275
+ # indent_brace = 0
276
+ indent_switch_case = indent_columns
277
+
278
+ #
279
+ # Inter-symbol newlines
280
+ #
281
+
282
+ nl_enum_brace = add # "enum {" vs "enum \n {"
283
+ nl_union_brace = add # "union {" vs "union \n {"
284
+ nl_struct_brace = add # "struct {" vs "struct \n {"
285
+ nl_do_brace = add # "do {" vs "do \n {"
286
+ nl_if_brace = add # "if () {" vs "if () \n {"
287
+ nl_for_brace = add # "for () {" vs "for () \n {"
288
+ nl_else_brace = add # "else {" vs "else \n {"
289
+ nl_while_brace = add # "while () {" vs "while () \n {"
290
+ nl_switch_brace = add # "switch () {" vs "switch () \n {"
291
+ nl_brace_while = add # "} while" vs "} \n while" - cuddle while
292
+ nl_brace_else = add # "} else" vs "} \n else" - cuddle else
293
+ nl_func_var_def_blk = 1
294
+ nl_fcall_brace = add # "list_for_each() {" vs "list_for_each()\n{"
295
+ nl_fdef_brace = add # "int foo() {" vs "int foo()\n{"
296
+ # nl_after_return = TRUE;
297
+ # nl_before_case = 1
298
+
299
+
300
+ #
301
+ # Source code modifications
302
+ #
303
+
304
+ mod_paren_on_return = ignore # "return 1;" vs "return (1);"
305
+ mod_full_brace_if = add # "if (a) a--;" vs "if (a) { a--; }"
306
+ mod_full_brace_for = add # "for () a--;" vs "for () { a--; }"
307
+ mod_full_brace_do = add # "do a--; while ();" vs "do { a--; } while ();"
308
+ mod_full_brace_while = add # "while (a) a--;" vs "while (a) { a--; }"
309
+ mod_full_brace_nl = 3 # don't remove if more than 3 newlines
310
+ mod_add_long_ifdef_endif_comment = 20
311
+ mod_add_long_ifdef_else_comment = mod_add_long_ifdef_else_comment
312
+ mod_add_long_switch_closebrace_comment = mod_add_long_ifdef_else_comment
313
+ mod_add_long_function_closebrace_comment = mod_add_long_ifdef_else_comment
314
+
315
+ #
316
+ # Inter-character spacing options
317
+ #
318
+
319
+ sp_return_paren = add # "return (1);" vs "return(1);"
320
+ sp_sizeof_paren = remove # "sizeof (int)" vs "sizeof(int)"
321
+ sp_before_sparen = force # "if (" vs "if("
322
+ sp_after_sparen = force # "if () {" vs "if (){"
323
+ sp_after_cast = add # "(int) a" vs "(int)a"
324
+ sp_inside_braces = add # "{ 1 }" vs "{1}"
325
+ sp_inside_braces_struct = add # "{ 1 }" vs "{1}"
326
+ sp_inside_braces_enum = add # "{ 1 }" vs "{1}"
327
+ sp_inside_fparen = remove # "func( param )" vs "func(param)"
328
+ sp_paren_brace = force
329
+ sp_assign = add
330
+ sp_arith = add
331
+ sp_bool = add
332
+ sp_compare = add
333
+ sp_assign = add
334
+ sp_after_comma = add
335
+ sp_func_def_paren = remove # "int foo (){" vs "int foo(){"
336
+ sp_func_call_paren = remove # "foo (" vs "foo("
337
+ sp_func_proto_paren = remove # "int foo ();" vs "int foo();"
338
+ sp_before_ptr_star = force
339
+ sp_after_ptr_star = remove
340
+ sp_before_unnamed_ptr_star = ignore
341
+ sp_between_ptr_star = remove
342
+ sp_after_ptr_star_func = force
343
+ sp_before_ptr_star_func = force
344
+ sp_cmt_cpp_start = add
345
+ sp_cond_question = force
346
+ sp_cond_colon = force
347
+ sp_else_brace = force
348
+ sp_brace_else = force
349
+ sp_after_class_colon = force
350
+ sp_before_class_colon = force
351
+ sp_before_case_colon = remove
352
+ # Objective-C specifics
353
+ sp_before_oc_colon = remove
354
+ sp_after_oc_colon = remove
355
+ sp_after_oc_scope = force
356
+ sp_after_oc_type = remove
357
+ sp_after_oc_return_type = remove
358
+ sp_before_send_oc_colon = remove
359
+ sp_after_send_oc_colon = remove
360
+ sp_after_oc_at_sel = remove
361
+ sp_before_oc_block_caret = ignore
362
+ sp_after_oc_block_caret = remove
363
+
364
+ #
365
+ # Aligning stuff
366
+ #
367
+
368
+ align_with_tabs = False # use tabs to align
369
+ align_on_tabstop = False # align on tabstops
370
+ # align_keep_tabs = True
371
+ align_enum_equ_span = 4 # '=' in enum definition
372
+ # align_nl_cont = True
373
+ # align_var_def_span = 2
374
+ # align_var_def_inline = True
375
+ # align_var_def_star = False
376
+ # align_var_def_colon = True
377
+ # align_assign_span = 1
378
+ align_struct_init_span = 4 # align stuff in a structure init '= { }'
379
+ align_right_cmt_span = 8
380
+ align_right_cmt_gap = 8
381
+ align_pp_define_span = 8
382
+ #align_pp_define_gap = 8
383
+ align_oc_msg_colon_span = 1 # align parameters in an Obj-C message on the ':' but stop after this many lines (0=don't align)
384
+ align_oc_msg_spec_span = 0 # the span for aligning ObjC msg spec (0=don't align)
385
+
386
+ #
387
+ # Line Splitting options
388
+ #
389
+
390
+ # ls_func_split_full = True # Whether to fully split long function protos/calls at commas
391
+
392
+ #
393
+ # Comment modifications
394
+ #
395
+
396
+ cmt_star_cont = False # Whether to put a star on subsequent comment lines
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crusty
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - David Wagner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-30 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Run uncrustify on all source files in your Xcode project
14
+ email: hello@robinchou.com
15
+ executables:
16
+ - crusty
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/crusty
21
+ homepage: http://github.com/chourobin/crusty
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.0.6
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: Crusty
45
+ test_files: []