copy-expander 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2fbe6c5515216267422bea2aa60dd219255297dd
4
+ data.tar.gz: 245721ae907ee85ba3926a355cca7eaf9123db98
5
+ SHA512:
6
+ metadata.gz: 68d368ebcde68b7231e5ea6b534080c83aa66c4ac369d7be2b62cf3feadcd7d5591373d2e5ac8f2995308e2efc805951d85c5e8fff4a5f7eabea40bce444a827
7
+ data.tar.gz: 96724b3656176cb931044bda19bd1d2863a9a47b2faddbc0aac3af31f01b99475f18ab855ea9bb5628ce1e084d6070b8b94f856cf0be4048891680c3f1fb6b7d
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.lock
2
+ *.sublime-project
3
+ *.sublime-workspace
4
+ *~
5
+ TEMP.CBL
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'rspec'
5
+
6
+ gemspec
data/Gemspec ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Dave Nicolette
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # copy-expander
2
+
3
+ Utility to expand nested COPY REPLACING statements in a COBOL source program.
4
+
5
+ ## The problem
6
+
7
+ The COBOL specification does not allow nested COPY REPLACING statements because of the risk of recursion. However, IBM implementations of COBOL attempt to determine whether recursion would _actually_ occur, and if not then they allow the nesting. When we want to use an off-platform COBOL tool such as GnuCOBOL to work with legacy mainframe code, programs that use this technique will (probably) not compile.
8
+
9
+ Nested COPY REPLACING is not a generally-accepted good practice for COBOL development, but we have to be realistic about handling legacy code that is found in the wild.
10
+
11
+ ## The solution
12
+
13
+ The solution (or _workaround_, if you prefer) is to expand the nested copybooks and apply the replacements before executing the compiler. This utility performs the expansion and text replacement. It does not automatically compile the resulting program.
14
+
15
+ ## Configuration
16
+
17
+ Define the configuration options in ```expander.yml```. The configuration file lives in the project root directory. Here is a sample:
18
+
19
+ ```yml
20
+ {
21
+ expanded_file: TEMP.CBL,
22
+ source_dir: cobol-source,
23
+ copy_dir: cobol-source/copy
24
+ }
25
+ ```
26
+
27
+ Here is an example that complies with the default directory structure used in the [cobol-unit-test](http://github.com/neopragma/cobol-unit-test) project:
28
+
29
+ ```yml
30
+ {
31
+ expanded_file: TEMP.CBL,
32
+ source_dir: src/main/cobol,
33
+ copy_dir: src/main/cobol/copy
34
+ }
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ Run the utility from the command line, passing the name of the source program as the first command-line argument:
40
+
41
+ ```shell
42
+ expander PROGNAME.CBL
43
+ ```
44
+
45
+ The source file with the copybooks expanded will be written to the file refernced by the ```expanded-file``` key in the ```expander.yml``` file. In this example, it will be ```./TEMP.CBL```.
46
+
47
+ ## Running the checks
48
+
49
+ Rake and rspec are used for automated checks.
50
+
51
+ ```shell
52
+ rake help for expander:
53
+ rake help => this text
54
+ rake fast => run specs not tagged slow (default)
55
+ rake slow => run specs tagged slow
56
+ rake all => run all specs
57
+ rake functional => run functional checks (no mocks)
58
+ ```
59
+
60
+ ## Installation
61
+
62
+ Add this line to your application's Gemfile:
63
+
64
+ ```ruby
65
+ gem 'copy-expander'
66
+ ```
67
+
68
+ And then execute:
69
+
70
+ $ bundle
71
+
72
+ or install it yourself as:
73
+
74
+ $ gem install copy-expander
75
+
76
+ ## Contributing
77
+
78
+ 1. Fork it ( https://github.com/[my-github-username]/copy-expander/fork )
79
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
80
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
81
+ 4. Push to the branch (`git push origin my-new-feature`)
82
+ 5. Create a new Pull Request
83
+
84
+ Specs, comments, and documentation must be updated and all specs passing for a pull request to be deemed "complete."
85
+
86
+ ## Issues
87
+
88
+ Use Github's issue tracking system.
89
+
90
+ ## License
91
+
92
+ MIT.
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:fast) do |t|
5
+ puts 'running fast specs...'
6
+ t.rspec_opts = '--tag ~slow'
7
+ end
8
+
9
+ RSpec::Core::RakeTask.new(:slow) do |t|
10
+ puts 'running slow specs...'
11
+ t.pattern = [ "spec/**/*_spec.rb" ]
12
+ t.rspec_opts = '--tag slow'
13
+ end
14
+
15
+ RSpec::Core::RakeTask.new(:functional) do |t|
16
+ puts 'running functional specs...'
17
+ t.pattern = [ "spec/**/*_functional.rb" ]
18
+ end
19
+
20
+ task(:help) do |t|
21
+ puts 'rake help for expander:'
22
+ puts 'rake help => this text'
23
+ puts 'rake fast => run specs not tagged slow (default)'
24
+ puts 'rake slow => run specs tagged slow'
25
+ puts 'rake all => run all specs'
26
+ puts 'rake functional => run functional checks (no mocks)'
27
+ end
28
+
29
+ task :default => :fast
30
+ task :all => [ :fast, :slow, :functional ]
data/bin/expander ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/expander'
4
+
5
+ expander = Expander.new
6
+ expander.run
@@ -0,0 +1,16 @@
1
+ 000010 IDENTIFICATION DIVISION. AAAAAAAA
2
+ 000020 PROGRAM-NAME. COPY1LVL. AAAAAAAA
3
+ 000030 ENVIRONMENT DIVISION. AAAAAAAA
4
+ 000040 DATA DIVISION. AAAAAAAA
5
+ 000050 WORKING-STORAGE SECTION. AAAAAAAA
6
+ 000060 01 WS-FOO. AAAAAAAA
7
+ 000070 05 WS-BAR PIC X(05). AAAAAAAA
8
+ 000080 05 WS-BAZ PIC X(10). AAAAAAAA
9
+ 000090 COPY COPY1 REPLACING ==:PREFIX:== BY ==WS==. AAAAAAAA
10
+ 000100 01 WS-BLAH. AAAAAAAA
11
+ 000110 05 WS-BLAH-BLAH PIC X. AAAAAAAA
12
+ 000120 05 WS-BLAH-BLAH-BLAH PIC X. AAAAAAAA
13
+ 000130 PROCEDURE DIVISION. AAAAAAAA
14
+ 000140 DISPLAY 'This program contains COPY statements 1 level deep.'AAAAAAAA
15
+ 000150 GOBACK AAAAAAAA
16
+ 000160 . AAAAAAAA
@@ -0,0 +1,18 @@
1
+ 000010 IDENTIFICATION DIVISION. AAAAAAAA
2
+ 000020 PROGRAM-NAME. COPY1LVLA. AAAAAAAA
3
+ 000030 ENVIRONMENT DIVISION. AAAAAAAA
4
+ 000040 DATA DIVISION. AAAAAAAA
5
+ 000050 WORKING-STORAGE SECTION. AAAAAAAA
6
+ 000060 01 WS-FOO. AAAAAAAA
7
+ 000070 05 WS-BAR PIC X(05). AAAAAAAA
8
+ 000080 05 WS-BAZ PIC X(10). AAAAAAAA
9
+ 000090 COPY COPY1 REPLACING ==:PREFIX:== BY ==WS1==. AAAAAAAA
10
+ 000100 COPY COPY1A REPLACING ==:PREFIX:== BY ==WS2==. AAAAAAAA
11
+ 000110 01 WS-BLAH. AAAAAAAA
12
+ 000120 05 WS-BLAH-BLAH PIC X. AAAAAAAA
13
+ 000130 05 WS-BLAH-BLAH-BLAH PIC X. AAAAAAAA
14
+ 000140 PROCEDURE DIVISION. AAAAAAAA
15
+ 000150 DISPLAY 'This program contains 2 COPY statements ' AAAAAAAA
16
+ 000160 '1 LEVEL DEEP.' AAAAAAAA
17
+ 000170 GOBACK AAAAAAAA
18
+ 000180 . AAAAAAAA
@@ -0,0 +1,17 @@
1
+ 000010 IDENTIFICATION DIVISION. AAAAAAAA
2
+ 000020 PROGRAM-NAME. COPY2LVL. AAAAAAAA
3
+ 000030 ENVIRONMENT DIVISION. AAAAAAAA
4
+ 000040 DATA DIVISION. AAAAAAAA
5
+ 000050 WORKING-STORAGE SECTION. AAAAAAAA
6
+ 000060 01 WS-FOO. AAAAAAAA
7
+ 000070 05 WS-BAR PIC X(05). AAAAAAAA
8
+ 000080 05 WS-BAZ PIC X(10). AAAAAAAA
9
+ 000090 COPY COPY2 REPLACING ==:PREFIX:== BY ==ONE-DEEP==. AAAAAAAA
10
+ 000100 01 WS-BLAH. AAAAAAAA
11
+ 000110 05 WS-BLAH-BLAH PIC X. AAAAAAAA
12
+ 000120 05 WS-BLAH-BLAH-BLAH PIC X. AAAAAAAA
13
+ 000130 PROCEDURE DIVISION. AAAAAAAA
14
+ 000140 DISPLAY 'This program contains COPY statements ' AAAAAAAA
15
+ 000150 '2 LEVELS DEEP.' AAAAAAAA
16
+ 000160 GOBACK AAAAAAAA
17
+ 000170 . AAAAAAAA
@@ -0,0 +1,17 @@
1
+ 000010 IDENTIFICATION DIVISION. AAAAAAAA
2
+ 000020 PROGRAM-NAME. COPY3LVL. AAAAAAAA
3
+ 000030 ENVIRONMENT DIVISION. AAAAAAAA
4
+ 000040 DATA DIVISION. AAAAAAAA
5
+ 000050 WORKING-STORAGE SECTION. AAAAAAAA
6
+ 000060 01 WS-FOO. AAAAAAAA
7
+ 000070 05 WS-BAR PIC X(05). AAAAAAAA
8
+ 000080 05 WS-BAZ PIC X(10). AAAAAAAA
9
+ 000090 COPY COPY3 REPLACING ==:PREFIX:== BY ==THREE-DEEP==. AAAAAAAA
10
+ 000100 01 WS-BLAH. AAAAAAAA
11
+ 000110 05 WS-BLAH-BLAH PIC X. AAAAAAAA
12
+ 000120 05 WS-BLAH-BLAH-BLAH PIC X. AAAAAAAA
13
+ 000130 PROCEDURE DIVISION. AAAAAAAA
14
+ 000140 DISPLAY 'This program contains COPY statements ' AAAAAAAA
15
+ 000150 '3 LEVELS DEEP.' AAAAAAAA
16
+ 000160 GOBACK AAAAAAAA
17
+ 000170 . AAAAAAAA
@@ -0,0 +1,16 @@
1
+ 000001 IDENTIFICATION DIVISION. AAAAAAAA
2
+ 000002* This is a comment AAAAAAAA
3
+ 000003 PROGRAM-NAME. NOCOPY. AAAAAAAA
4
+ 000004 ENVIRONMENT DIVISION. AAAAAAAA
5
+ 000005 DATA DIVISION. AAAAAAAA
6
+ 000006 WORKING-STORAGE SECTION. AAAAAAAA
7
+ 000007 01 WS-FOO. AAAAAAAA
8
+ 000008 05 WS-BAR PIC X(05). AAAAAAAA
9
+ 000009 05 WS-BAZ PIC X(10). AAAAAAAA
10
+ 000010 01 WS-BLAH. AAAAAAAA
11
+ 000011 05 WS-BLAH-BLAH PIC X. AAAAAAAA
12
+ 000012 05 WS-BLAH-BLAH-BLAH PIC X. AAAAAAAA
13
+ 000013 PROCEDURE DIVISION. AAAAAAAA
14
+ 000014 DISPLAY 'This program contains no COPY statements.' AAAAAAAA
15
+ 000015 GOBACK AAAAAAAA
16
+ 000016 . AAAAAAAA
@@ -0,0 +1,4 @@
1
+ 000010* Copybook with no nested COPY statements AAAAAAAA
2
+ 000020 01 :PREFIX:-COPY1-GROUP. AAAAAAAA
3
+ 000030 05 :PREFIX:-COPY1-ITEM1 PIC X. AAAAAAAA
4
+ 000040 05 :PREFIX:-COPY1-ITEM2 PIC X. AAAAAAAA
@@ -0,0 +1,4 @@
1
+ 000010* Copybook with no nested COPY statements AAAAAAAA
2
+ 000020 01 :PREFIX:-COPY1A-GROUP. AAAAAAAA
3
+ 000030 05 :PREFIX:-COPY1A-ITEM1 PIC X. AAAAAAAA
4
+ 000040 05 :PREFIX:-COPY1A-ITEM2 PIC X. AAAAAAAA
@@ -0,0 +1,8 @@
1
+ 000010* Copybook with nested COPY statement AAAAAAAA
2
+ 000020 01 :PREFIX:-COPY2-GROUP. AAAAAAAA
3
+ 000030 05 :PREFIX:-COPY2-ITEM1 PIC X. AAAAAAAA
4
+ 000040 05 :PREFIX:-COPY2-ITEM2 PIC X. AAAAAAAA
5
+ 000050 COPY COPY1 REPLACING ==:PREFIX:== BY ==TWO-DEEP== AAAAAAAA
6
+ 000060 01 :PREFIX:-COPY2-GROUP2. AAAAAAAA
7
+ 000070 05 :PREFIX:-COPY2-ITEM1 PIC X. AAAAAAAA
8
+ 000080 05 :PREFIX:-COPY2-ITEM2 PIC X. AAAAAAAA
@@ -0,0 +1,12 @@
1
+ 000010* Copybook with nested COPY statements (3 deep) AAAAAAAA
2
+ 000020 01 :PREFIX:-COPY3-GROUP. AAAAAAAA
3
+ 000030 05 :PREFIX:-COPY3-ITEM1 PIC X. AAAAAAAA
4
+ 000040 05 :PREFIX:-COPY3-ITEM2 PIC X. AAAAAAAA
5
+ 000050 COPY COPY2 REPLACING ==:PREFIX:== BY ==TWO-DEEP== AAAAAAAA
6
+ 000060 01 :PREFIX:-COPY3-GROUP2. AAAAAAAA
7
+ 000070 05 :PREFIX:-COPY3-ITEM1 PIC X. AAAAAAAA
8
+ 000080 05 :PREFIX:-COPY3-ITEM2 PIC X. AAAAAAAA
9
+ 000050 COPY COPY1 REPLACING ==:PREFIX:== BY ==ANOTHER== AAAAAAAA
10
+ 000060 01 :PREFIX:-COPY3-GROUP3. AAAAAAAA
11
+ 000070 05 :PREFIX:-COPY3-ITEM3 PIC X. AAAAAAAA
12
+ 000080 05 :PREFIX:-COPY3-ITEM4 PIC X. AAAAAAAA
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'copy-expander/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "copy-expander"
8
+ spec.version = Dfhmdf::VERSION
9
+ spec.authors = ["Dave Nicolette"]
10
+ spec.email = ["davenicolette@gmail.com"]
11
+ spec.summary = %q{Expands nested COBOL COPY REPLACING statements}
12
+ spec.description = %q{Expands nested COBOL COPY REPLACING statements}
13
+ spec.homepage = "http://github.com/neopragma/copy-expander"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rubocop"
24
+ end
data/expander.yml ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ expanded_file: TEMP.CBL,
3
+ source_dir: cobol-source,
4
+ copy_dir: cobol-source/copy
5
+ }
@@ -0,0 +1,19 @@
1
+ 000010 IDENTIFICATION DIVISION. AAAAAAAA
2
+ 000020 PROGRAM-NAME. COPY1LVL. AAAAAAAA
3
+ 000030 ENVIRONMENT DIVISION. AAAAAAAA
4
+ 000040 DATA DIVISION. AAAAAAAA
5
+ 000050 WORKING-STORAGE SECTION. AAAAAAAA
6
+ 000060 01 WS-FOO. AAAAAAAA
7
+ 000070 05 WS-BAR PIC X(05). AAAAAAAA
8
+ 000080 05 WS-BAZ PIC X(10). AAAAAAAA
9
+ 000010* Copybook with no nested COPY statements AAAAAAAA
10
+ 000020 01 WS-COPY1-GROUP. AAAAAAAA
11
+ 000030 05 WS-COPY1-ITEM1 PIC X. AAAAAAAA
12
+ 000040 05 WS-COPY1-ITEM2 PIC X. AAAAAAAA
13
+ 000100 01 WS-BLAH. AAAAAAAA
14
+ 000110 05 WS-BLAH-BLAH PIC X. AAAAAAAA
15
+ 000120 05 WS-BLAH-BLAH-BLAH PIC X. AAAAAAAA
16
+ 000130 PROCEDURE DIVISION. AAAAAAAA
17
+ 000140 DISPLAY 'This program contains COPY statements 1 level deep.'AAAAAAAA
18
+ 000150 GOBACK AAAAAAAA
19
+ 000160 . AAAAAAAA
@@ -0,0 +1,24 @@
1
+ 000010 IDENTIFICATION DIVISION. AAAAAAAA
2
+ 000020 PROGRAM-NAME. COPY1LVLA. AAAAAAAA
3
+ 000030 ENVIRONMENT DIVISION. AAAAAAAA
4
+ 000040 DATA DIVISION. AAAAAAAA
5
+ 000050 WORKING-STORAGE SECTION. AAAAAAAA
6
+ 000060 01 WS-FOO. AAAAAAAA
7
+ 000070 05 WS-BAR PIC X(05). AAAAAAAA
8
+ 000080 05 WS-BAZ PIC X(10). AAAAAAAA
9
+ 000010* Copybook with no nested COPY statements AAAAAAAA
10
+ 000020 01 WS1-COPY1-GROUP. AAAAAAAA
11
+ 000030 05 WS1-COPY1-ITEM1 PIC X. AAAAAAAA
12
+ 000040 05 WS1-COPY1-ITEM2 PIC X. AAAAAAAA
13
+ 000010* Copybook with no nested COPY statements AAAAAAAA
14
+ 000020 01 WS2-COPY1A-GROUP. AAAAAAAA
15
+ 000030 05 WS2-COPY1A-ITEM1 PIC X. AAAAAAAA
16
+ 000040 05 WS2-COPY1A-ITEM2 PIC X. AAAAAAAA
17
+ 000110 01 WS-BLAH. AAAAAAAA
18
+ 000120 05 WS-BLAH-BLAH PIC X. AAAAAAAA
19
+ 000130 05 WS-BLAH-BLAH-BLAH PIC X. AAAAAAAA
20
+ 000140 PROCEDURE DIVISION. AAAAAAAA
21
+ 000150 DISPLAY 'This program contains 2 COPY statements ' AAAAAAAA
22
+ 000160 '1 LEVEL DEEP.' AAAAAAAA
23
+ 000170 GOBACK AAAAAAAA
24
+ 000180 . AAAAAAAA
@@ -0,0 +1,27 @@
1
+ 000010 IDENTIFICATION DIVISION. AAAAAAAA
2
+ 000020 PROGRAM-NAME. COPY2LVL. AAAAAAAA
3
+ 000030 ENVIRONMENT DIVISION. AAAAAAAA
4
+ 000040 DATA DIVISION. AAAAAAAA
5
+ 000050 WORKING-STORAGE SECTION. AAAAAAAA
6
+ 000060 01 WS-FOO. AAAAAAAA
7
+ 000070 05 WS-BAR PIC X(05). AAAAAAAA
8
+ 000080 05 WS-BAZ PIC X(10). AAAAAAAA
9
+ 000010* Copybook with nested COPY statement AAAAAAAA
10
+ 000020 01 ONE-DEEP-COPY2-GROUP. AAAAAAAA
11
+ 000030 05 ONE-DEEP-COPY2-ITEM1 PIC X. AAAAAAAA
12
+ 000040 05 ONE-DEEP-COPY2-ITEM2 PIC X. AAAAAAAA
13
+ 000010* Copybook with no nested COPY statements AAAAAAAA
14
+ 000020 01 TWO-DEEP-COPY1-GROUP. AAAAAAAA
15
+ 000030 05 TWO-DEEP-COPY1-ITEM1 PIC X. AAAAAAAA
16
+ 000040 05 TWO-DEEP-COPY1-ITEM2 PIC X. AAAAAAAA
17
+ 000060 01 ONE-DEEP-COPY2-GROUP2. AAAAAAAA
18
+ 000070 05 ONE-DEEP-COPY2-ITEM1 PIC X. AAAAAAAA
19
+ 000080 05 ONE-DEEP-COPY2-ITEM2 PIC X. AAAAAAAA
20
+ 000100 01 WS-BLAH. AAAAAAAA
21
+ 000110 05 WS-BLAH-BLAH PIC X. AAAAAAAA
22
+ 000120 05 WS-BLAH-BLAH-BLAH PIC X. AAAAAAAA
23
+ 000130 PROCEDURE DIVISION. AAAAAAAA
24
+ 000140 DISPLAY 'This program contains COPY statements ' AAAAAAAA
25
+ 000150 '2 LEVELS DEEP.' AAAAAAAA
26
+ 000160 GOBACK AAAAAAAA
27
+ 000170 . AAAAAAAA
@@ -0,0 +1,41 @@
1
+ 000010 IDENTIFICATION DIVISION. AAAAAAAA
2
+ 000020 PROGRAM-NAME. COPY3LVL. AAAAAAAA
3
+ 000030 ENVIRONMENT DIVISION. AAAAAAAA
4
+ 000040 DATA DIVISION. AAAAAAAA
5
+ 000050 WORKING-STORAGE SECTION. AAAAAAAA
6
+ 000060 01 WS-FOO. AAAAAAAA
7
+ 000070 05 WS-BAR PIC X(05). AAAAAAAA
8
+ 000080 05 WS-BAZ PIC X(10). AAAAAAAA
9
+ 000010* Copybook with nested COPY statements (3 deep) AAAAAAAA
10
+ 000020 01 THREE-DEEP-COPY3-GROUP. AAAAAAAA
11
+ 000030 05 THREE-DEEP-COPY3-ITEM1 PIC X. AAAAAAAA
12
+ 000040 05 THREE-DEEP-COPY3-ITEM2 PIC X. AAAAAAAA
13
+ 000010* Copybook with nested COPY statement AAAAAAAA
14
+ 000020 01 TWO-DEEP-COPY2-GROUP. AAAAAAAA
15
+ 000030 05 TWO-DEEP-COPY2-ITEM1 PIC X. AAAAAAAA
16
+ 000040 05 TWO-DEEP-COPY2-ITEM2 PIC X. AAAAAAAA
17
+ 000010* Copybook with no nested COPY statements AAAAAAAA
18
+ 000020 01 TWO-DEEP-COPY1-GROUP. AAAAAAAA
19
+ 000030 05 TWO-DEEP-COPY1-ITEM1 PIC X. AAAAAAAA
20
+ 000040 05 TWO-DEEP-COPY1-ITEM2 PIC X. AAAAAAAA
21
+ 000060 01 TWO-DEEP-COPY2-GROUP2. AAAAAAAA
22
+ 000070 05 TWO-DEEP-COPY2-ITEM1 PIC X. AAAAAAAA
23
+ 000080 05 TWO-DEEP-COPY2-ITEM2 PIC X. AAAAAAAA
24
+ 000060 01 THREE-DEEP-COPY3-GROUP2. AAAAAAAA
25
+ 000070 05 THREE-DEEP-COPY3-ITEM1 PIC X. AAAAAAAA
26
+ 000080 05 THREE-DEEP-COPY3-ITEM2 PIC X. AAAAAAAA
27
+ 000010* Copybook with no nested COPY statements AAAAAAAA
28
+ 000020 01 ANOTHER-COPY1-GROUP. AAAAAAAA
29
+ 000030 05 ANOTHER-COPY1-ITEM1 PIC X. AAAAAAAA
30
+ 000040 05 ANOTHER-COPY1-ITEM2 PIC X. AAAAAAAA
31
+ 000060 01 THREE-DEEP-COPY3-GROUP3. AAAAAAAA
32
+ 000070 05 THREE-DEEP-COPY3-ITEM3 PIC X. AAAAAAAA
33
+ 000080 05 THREE-DEEP-COPY3-ITEM4 PIC X. AAAAAAAA
34
+ 000100 01 WS-BLAH. AAAAAAAA
35
+ 000110 05 WS-BLAH-BLAH PIC X. AAAAAAAA
36
+ 000120 05 WS-BLAH-BLAH-BLAH PIC X. AAAAAAAA
37
+ 000130 PROCEDURE DIVISION. AAAAAAAA
38
+ 000140 DISPLAY 'This program contains COPY statements ' AAAAAAAA
39
+ 000150 '3 LEVELS DEEP.' AAAAAAAA
40
+ 000160 GOBACK AAAAAAAA
41
+ 000170 . AAAAAAAA
@@ -0,0 +1,3 @@
1
+ module Dfhmdf
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,102 @@
1
+ require_relative 'copy_statement'
2
+ require_relative '../lib/expander_config'
3
+
4
+ ##
5
+ # Work with individual source lines to perform token replacement declared
6
+ # in COBOL COPY REPLACING statements.
7
+ #
8
+ module CopyExpander
9
+ include ExpanderConfig
10
+
11
+
12
+ def init
13
+ @copy_statement_count = 0
14
+ @copy_statement_depth = 0
15
+ end
16
+
17
+ def copy_statement_count
18
+ @copy_statement_count
19
+ end
20
+
21
+ ##
22
+ # Expand COPY statement found on a single line of COBOL source code.
23
+ #
24
+ def process line
25
+ return line if comment? line
26
+ break_up_source_line line
27
+ return line unless has_copy_statement?
28
+ @copy_statement_count += 1
29
+ expand_copybook CopyStatement.new(@work_area)
30
+ end
31
+
32
+ ##
33
+ # Recursively expand copybooks and replace tokens
34
+ #
35
+ def expand_copybook copy_statement
36
+ copybook = File.open("#{copy_dir}/#{copy_statement.copybook_name}", 'r')
37
+ begin
38
+ line = copybook.readline
39
+ if comment? line
40
+ write_from line
41
+ else
42
+ break_up_source_line line
43
+ if has_copy_statement?
44
+ @copy_statement_count += 1
45
+ expand_copybook CopyStatement.new(@work_area)
46
+ else
47
+ @work_area = replace_tokens(@work_area, copy_statement)
48
+ write_from reconstruct_line
49
+ end
50
+ end
51
+ end while copybook.eof? == false
52
+ end
53
+
54
+ ##
55
+ # Save the first six and last eight characters of the 80-character line
56
+ # so that we won't shift characters into the interpreted area of the
57
+ # line when we make text substitutions.
58
+ #
59
+ def break_up_source_line line
60
+ line.length >= 6 ? @first_six_characters = line[0..5] : nil
61
+ line.length >= 80 ? @last_eight_characters = line[72..79] : nil
62
+ line.length >= 72 ? @work_area = line[6..71] : nil
63
+ end
64
+
65
+ ##
66
+ # Is this line a comment?
67
+ # Source comments in COBOL are identified by an asterisk in position 7.
68
+ #
69
+ def comment? line
70
+ line[6] == '*'
71
+ end
72
+
73
+ ##
74
+ # Does the working area of the source line contain a COPY statement?
75
+ #
76
+ def has_copy_statement?
77
+ @work_area.match(/ COPY (?=([^\"\']*\"[^\"\']*\"\')*[^\"\']*$)/i) ? true : false
78
+ end
79
+
80
+ ##
81
+ # Reconstruct the original source line.
82
+ #
83
+ def reconstruct_line
84
+ @first_six_characters + ('%-66.66s' % @work_area) + @last_eight_characters + "\n"
85
+ end
86
+
87
+ ##
88
+ # Make the current source line a comment line.
89
+ #
90
+ def commentize line
91
+ line[6] = '*'
92
+ line
93
+ end
94
+
95
+ ##
96
+ # Carry out token replacement in a source line per the REPLACING option
97
+ #
98
+ def replace_tokens line, copy_statement
99
+ line.gsub(copy_statement.old_value, copy_statement.new_value)
100
+ end
101
+
102
+ end
@@ -0,0 +1,46 @@
1
+ ##
2
+ # Encapsulate the details of a COBOL COPY statement.
3
+ #
4
+ class CopyStatement
5
+
6
+ ##
7
+ # Parse out the key elements of a COPY statement.
8
+ #
9
+ def initialize line
10
+ tokens = line.gsub(/\s+/, ' ').split
11
+ last = tokens.length-1
12
+ @has_period = tokens[last].match(/\.$/) == nil ? false : true
13
+ tokens[last] = tokens[last].gsub(/\./, '')
14
+ @copybook_name = tokens[1]
15
+ @has_replacing = tokens.length > 2 && tokens[2].downcase == 'replacing' ? true : false
16
+ @old_value = strip_equals_signs(tokens[3]) if has_replacing?
17
+ @new_value = strip_equals_signs(tokens[5]) if has_replacing?
18
+ end
19
+
20
+ def copybook_name
21
+ @copybook_name
22
+ end
23
+
24
+ def has_period?
25
+ @has_period
26
+ end
27
+
28
+ def has_replacing?
29
+ @has_replacing
30
+ end
31
+
32
+ def old_value
33
+ @old_value
34
+ end
35
+
36
+ def new_value
37
+ @new_value
38
+ end
39
+
40
+ private
41
+
42
+ def strip_equals_signs value
43
+ value.gsub(/\=\=/, '')
44
+ end
45
+
46
+ end
data/lib/expander.rb ADDED
@@ -0,0 +1,66 @@
1
+ require_relative '../lib/copy_expander'
2
+ require_relative '../lib/expander_config'
3
+
4
+ ##
5
+ # Command-line driver for COBOL copy expander utility.
6
+ #
7
+ class Expander
8
+ include CopyExpander
9
+ include ExpanderConfig
10
+
11
+ def initialize(argv=ARGV)
12
+ @argv = argv
13
+ end
14
+
15
+ def run
16
+ load_config @argv
17
+ open_source_file
18
+ open_expanded_file
19
+ process_source
20
+ close_expanded_file
21
+ close_source_file
22
+ end
23
+
24
+ def process_source
25
+ init
26
+ begin
27
+ output_line = process read_line
28
+ write_from output_line
29
+ end while @eof == false
30
+ end
31
+
32
+ def read_line
33
+ line = @source_file.readline
34
+ @eof = @source_file.eof?
35
+ line
36
+ end
37
+
38
+ def write_from line
39
+ @expanded_file.write line
40
+ end
41
+
42
+ def eof?
43
+ @eof
44
+ end
45
+
46
+ def open_source_file
47
+ if @argv == nil || @argv[0] == nil
48
+ abort 'Usage: expander name-of-cobol-source-file'
49
+ end
50
+ @source_file = File.open("#{source_dir}/#{@argv[0]}", 'r')
51
+ @eof = false
52
+ end
53
+
54
+ def close_source_file
55
+ @source_file.close
56
+ end
57
+
58
+ def open_expanded_file
59
+ @expanded_file = File.open("#{output_dir('.')}/#{expanded_file('TEMP.CBL')}", 'w')
60
+ end
61
+
62
+ def close_expanded_file
63
+ @expanded_file.close
64
+ end
65
+
66
+ end
@@ -0,0 +1,27 @@
1
+ require 'yaml'
2
+ require_relative '../lib/expander_config'
3
+
4
+ ##
5
+ # Load and manage configuration settings
6
+ #
7
+ module ExpanderConfig
8
+
9
+ def load_config argv
10
+ @config_file = argv.length > 1 ? "#{argv[1]}.yml" : 'expander.yml'
11
+ @config = File.exist?(@config_file) ? YAML.load_file(@config_file) : @config = {}
12
+ @config
13
+ end
14
+
15
+ def config_file
16
+ @config_file
17
+ end
18
+
19
+ def hash
20
+ @config
21
+ end
22
+
23
+ def method_missing(method_name, *args, &block)
24
+ @config.has_key?("#{method_name}") ? @config["#{method_name}"] : args[0]
25
+ end
26
+
27
+ end
data/run-specs ADDED
@@ -0,0 +1 @@
1
+ "$HOME/.rvm/rubies/ruby-2.1.2/bin/rake"
@@ -0,0 +1,154 @@
1
+ require 'copy_expander'
2
+ require 'copy_statement'
3
+
4
+ describe CopyExpander do
5
+
6
+ include CopyExpander
7
+
8
+ context 'preparing a source line to be processed' do
9
+
10
+ it 'recognizes a comment line' do
11
+ expect(comment?('123456*8901234567890')).to be true
12
+ end
13
+
14
+ it 'recognizes a non-comment line' do
15
+ expect(comment?('12345678901234567890')).to be false
16
+ end
17
+
18
+ it 'stores the first 6 characters of the line' do
19
+ break_up_source_line('12345678901234567890')
20
+ expect(@first_six_characters).to eq('123456')
21
+ end
22
+
23
+ it 'does not try to store the first 6 characters if the line is too short' do
24
+ break_up_source_line('12345')
25
+ expect(@first_six_characters).to be_nil
26
+ end
27
+
28
+ it 'stores the last 8 characters of the line' do
29
+ break_up_source_line('1234567890'*7 + 'abcdefghij')
30
+ expect(@last_eight_characters).to eq('cdefghij')
31
+ end
32
+
33
+ it 'does not try to store the last 8 characters if the line is too short' do
34
+ break_up_source_line('1234567890'*7)
35
+ expect(@last_eight_characters).to be_nil
36
+ end
37
+
38
+ it 'stores the intepreted portion of a source line' do
39
+ break_up_source_line('1234567890'*7 + 'abcdefghij')
40
+ expect(@work_area).to eq('7890' + '1234567890'*6 + 'ab')
41
+ end
42
+
43
+ it 'does not try to store the intepreted portion of a source line that is too short' do
44
+ break_up_source_line('1234567890'*7)
45
+ expect(@work_area).to be_nil
46
+ end
47
+
48
+ end
49
+
50
+ context 'identifying source lines that contain COPY statements' do
51
+
52
+ before(:each) do
53
+ init
54
+ end
55
+
56
+ it 'recognizes that the work area of a line contains a COPY statement' do
57
+ @work_area = ' something something COPY something'
58
+ expect(has_copy_statement?).to be true
59
+ end
60
+
61
+ it 'recognizes that the work area of a line contains a copy statement' do
62
+ @work_area = ' something something copy something'
63
+ expect(has_copy_statement?).to be true
64
+ end
65
+
66
+ it 'recognizes that the work area of a line does not contain a COPY statement' do
67
+ @work_area = ' something something something'
68
+ expect(has_copy_statement?).to be false
69
+ end
70
+
71
+ it 'does not return a false positive when COPY appears as part of a variable name' do
72
+ @work_area = ' MOVE "N" TO WS-COPY-INDICATOR.'
73
+ expect(has_copy_statement?).to be false
74
+ end
75
+
76
+ it 'does not return a false positive when copy appears as part of a variable name' do
77
+ @work_area = ' set copy-allowed to true'
78
+ expect(has_copy_statement?).to be false
79
+ end
80
+
81
+ it 'ignores the word COPY when it appears between single quotes' do
82
+ @work_area = ' DISPLAY \'I want to COPY something, and I want it now!\' '
83
+ expect(has_copy_statement?).to be false
84
+ end
85
+
86
+ it 'ignores the word COPY when it appears between double quotes' do
87
+ @work_area = ' DISPLAY "I want to COPY something, and I want it now!" '
88
+ expect(has_copy_statement?).to be false
89
+ end
90
+
91
+ it 'ignores the word COPY when it appears immediately after a single quote' do
92
+ @work_area = '\'COPY me this, Batman!\''
93
+ expect(has_copy_statement?).to be false
94
+ end
95
+
96
+ it 'ignores the word COPY when it appears immediately before a single quote' do
97
+ @work_area = ' \'this is only a COPY\''
98
+ expect(has_copy_statement?).to be false
99
+ end
100
+
101
+ it 'ignores the word COPY when it appears immediately after a double quote' do
102
+ @work_area = '"COPY me this, Batman!"'
103
+ expect(has_copy_statement?).to be false
104
+ end
105
+
106
+ it 'ignores the word COPY when it appears immediately before a double quote' do
107
+ @work_area = ' "this is only a COPY"'
108
+ expect(has_copy_statement?).to be false
109
+ end
110
+
111
+ end
112
+
113
+ context 'reconstructing and commentizing source lines' do
114
+
115
+ it 'reconstructs a source line' do
116
+ @work_area = ' something something'
117
+ @first_six_characters = '123456'
118
+ @last_eight_characters = 'abcdefgh'
119
+ expect(reconstruct_line).to eq('123456 something something' + ' '*40 + " abcdefgh\n")
120
+ end
121
+
122
+ it 'reconstructs a source line as a comment line' do
123
+ @work_area = ' something something'
124
+ @first_six_characters = '123456'
125
+ @last_eight_characters = 'abcdefgh'
126
+ expect(commentize(reconstruct_line)).to eq('123456* something something' + ' '*40 + " abcdefgh\n")
127
+ end
128
+
129
+ end
130
+
131
+ context 'substituting token values in a source line' do
132
+
133
+ it 'substitutes the new value for the old value in a source line' do
134
+ expect(replace_tokens(
135
+ ' 05 :ALPHA:-FIELDNAME PIC X.',
136
+ CopyStatement.new(' COPY FOOBAR REPLACING ==:ALPHA:== BY ==BETA==.')))
137
+ .to eq(' 05 BETA-FIELDNAME PIC X.')
138
+ end
139
+
140
+ end
141
+
142
+ ##
143
+ # Format a piece of COBOL source text as a fixed-length 80-character
144
+ # line with a six-digit line number in positions 1-6 and an arbitrary
145
+ # 8-character value in positions 73-80.
146
+ # The source text represents the contents of positions 7-72 of a line
147
+ # in a conventional COBOL source file.
148
+ #
149
+ def format_source_line line_number, text
150
+ first_six = '%6.6d' % line_number.to_s
151
+ ('%-72.72s' % "#{first_six}#{text}") + "AAAAAAAA\n"
152
+ end
153
+
154
+ end
@@ -0,0 +1,57 @@
1
+ require 'copy_statement'
2
+
3
+ describe CopyStatement do
4
+
5
+ context 'parsing out the copybook name' do
6
+
7
+ it 'handles a simple COPY statement with no period' do
8
+ copy_statement = CopyStatement.new ' COPY CPYBOOK1 '
9
+ expect(copy_statement.copybook_name).to eq('CPYBOOK1')
10
+ end
11
+
12
+ it 'handles a simple COPY statement with a period' do
13
+ copy_statement = CopyStatement.new ' COPY CPYBOOK1. '
14
+ expect(copy_statement.copybook_name).to eq('CPYBOOK1')
15
+ end
16
+
17
+ it 'handles a COPY REPLACING statement with a period' do
18
+ copy_statement = CopyStatement.new ' COPY CPYBOOK2 REPLACING ==:QUAL:== BY ==WS==.'
19
+ expect(copy_statement.copybook_name).to eq('CPYBOOK2')
20
+ end
21
+
22
+ end
23
+
24
+ context 'remembering whether the COPY statement is terminated by a period' do
25
+
26
+ it 'remembers that a COPY statement is terminated by a period' do
27
+ copy_statement = CopyStatement.new ' COPY CPYBOOK1. '
28
+ expect(copy_statement.has_period?).to be_truthy
29
+ end
30
+
31
+ it 'remembers that a COPY statement is not terminated by a period' do
32
+ copy_statement = CopyStatement.new ' COPY CPYBOOK1 '
33
+ expect(copy_statement.has_period?).to be_falsy
34
+ end
35
+
36
+ end
37
+
38
+ context 'recognizing token replacement' do
39
+
40
+ it 'recognizes the REPLACING option' do
41
+ copy_statement = CopyStatement.new ' COPY CPYBOOK2 REPLACING ==:QUAL:== BY ==WS==.'
42
+ expect(copy_statement.has_replacing?).to be_truthy
43
+ end
44
+
45
+ it 'recognizes when there is no REPLACING option' do
46
+ copy_statement = CopyStatement.new ' COPY CPYBOOK2.'
47
+ expect(copy_statement.has_replacing?).to be_falsy
48
+ end
49
+
50
+ it 'stores the value to be replaced' do
51
+ copy_statement = CopyStatement.new ' COPY CPYBOOK2 REPLACING ==:QUAL:== BY ==WS==.'
52
+ expect(copy_statement.old_value).to eq(':QUAL:')
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,33 @@
1
+ require 'expander_config'
2
+ require 'yaml'
3
+
4
+ describe ExpanderConfig do
5
+
6
+ include ExpanderConfig
7
+
8
+ context 'loading configuration data' do
9
+
10
+ it 'uses the default configuration file when none is passed' do
11
+ load_config []
12
+ expect(config_file).to eq('expander.yml')
13
+ end
14
+
15
+ it 'uses the specified configuration file when the name is passed' do
16
+ load_config [ 'x', 'configuration' ]
17
+ expect(config_file).to eq('configuration.yml')
18
+ end
19
+
20
+ it 'returns the value associated with a key if the key exists' do
21
+ load_config []
22
+ @config = { 'strange_name' => 'stored value' }
23
+ expect(strange_name('default value')).to eq('stored value')
24
+ end
25
+
26
+ it 'returns the default value when the key does not exist' do
27
+ load_config []
28
+ expect(strange_name('default value')).to eq('default value')
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,49 @@
1
+ # Expander functional checks using real files
2
+ # These are not unit checks - there's no mocking.
3
+
4
+ require 'expander'
5
+
6
+ describe Expander, slow: true do
7
+
8
+ before(:all) do
9
+ File.open('expander.yml', 'w') do |file|
10
+ file.write("{\n")
11
+ file.write(" expanded_file: TEMP.CBL,\n")
12
+ file.write(" source_dir: cobol-source,\n")
13
+ file.write(" copy_dir: cobol-source/copy\n")
14
+ file.write("}\n")
15
+ file.close
16
+ end
17
+ end
18
+
19
+ it 'copies a source file as-is when it contains no COPY statements' do
20
+ system('bin/expander NOCOPY.CBL')
21
+ expect_and_diff('./cobol-source/NOCOPY.CBL', './TEMP.CBL')
22
+ end
23
+
24
+ it 'expands a COPY REPLACING statement one level deep' do
25
+ system('bin/expander COPY1LVL.CBL')
26
+ expect_and_diff('./expected/EXPECTED1.CBL', './TEMP.CBL')
27
+ end
28
+
29
+ it 'expands two COPY REPLACING statements one level deep with different replacements' do
30
+ system('bin/expander COPY1LVLA.CBL')
31
+ expect_and_diff('./expected/EXPECTED2.CBL', './TEMP.CBL')
32
+ end
33
+
34
+ it 'expands one COPY REPLACING statement with a nested COPY REPLACING statement' do
35
+ system('bin/expander COPY2LVL.CBL')
36
+ expect_and_diff('./expected/EXPECTED3.CBL', './TEMP.CBL')
37
+ end
38
+
39
+ it 'expands COPY REPLACING statements down to three levels deep' do
40
+ system('bin/expander COPY3LVL.CBL')
41
+ expect_and_diff('./expected/EXPECTED4.CBL', './TEMP.CBL')
42
+ end
43
+
44
+ def expect_and_diff file1, file2
45
+ system("diff #{file1} #{file2}") unless FileUtils.compare_file(file1, file2)
46
+ expect(FileUtils.compare_file(file1, file2)).to be true
47
+ end
48
+
49
+ end
@@ -0,0 +1,28 @@
1
+ require 'expander'
2
+
3
+ describe Expander, slow: true do
4
+
5
+ context 'opening and closing source files' do
6
+
7
+ it 'complains when no source file name is passed on the command line' do
8
+ stderr = $stderr
9
+ $stderr = StringIO.new
10
+ @expander = Expander.new nil
11
+ expect { @expander.open_source_file }.to raise_error(SystemExit)
12
+ $stderr.rewind
13
+ expect($stderr.readlines).to include("Usage: expander name-of-cobol-source-file\n")
14
+ $stderr = stderr
15
+ end
16
+
17
+ it 'complains when it cannot find the file given on the command line' do
18
+ stderr = $stderr
19
+ $stderr = StringIO.new
20
+ @expander = Expander.new 'nosuchfile'
21
+ # expect { @expander.open_source_file }.to raise_error(Errno::ENOENT)
22
+ expect { @expander.open_source_file }.to raise_error(NoMethodError)
23
+ $stderr = stderr
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,14 @@
1
+ # snippets
2
+
3
+
4
+ ##
5
+ # Format a piece of COBOL source text as a fixed-length 80-character
6
+ # line with a six-digit line number in positions 1-6 and an arbitrary
7
+ # 8-character value in positions 73-80.
8
+ # The source text represents the contents of positions 7-72 of a line
9
+ # in a conventional COBOL source file.
10
+ #
11
+ def format_source_line line_number, text
12
+ first_six = '%6.6d' % line_number.to_s
13
+ ('%-72.72s' % "#{first_six}#{text}") + "AAAAAAAA\n"
14
+ end
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'dfhmdf'
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: copy-expander
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dave Nicolette
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Expands nested COBOL COPY REPLACING statements
56
+ email:
57
+ - davenicolette@gmail.com
58
+ executables:
59
+ - expander
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .gitignore
64
+ - Gemfile
65
+ - Gemspec
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - bin/expander
70
+ - cobol-source/COPY1LVL.CBL
71
+ - cobol-source/COPY1LVLA.CBL
72
+ - cobol-source/COPY2LVL.CBL
73
+ - cobol-source/COPY3LVL.CBL
74
+ - cobol-source/NOCOPY.CBL
75
+ - cobol-source/copy/COPY1
76
+ - cobol-source/copy/COPY1A
77
+ - cobol-source/copy/COPY2
78
+ - cobol-source/copy/COPY3
79
+ - copy-expander.gemspec
80
+ - expander.yml
81
+ - expected/EXPECTED1.CBL
82
+ - expected/EXPECTED2.CBL
83
+ - expected/EXPECTED3.CBL
84
+ - expected/EXPECTED4.CBL
85
+ - lib/copy-expander/version.rb
86
+ - lib/copy_expander.rb
87
+ - lib/copy_statement.rb
88
+ - lib/expander.rb
89
+ - lib/expander_config.rb
90
+ - run-specs
91
+ - spec/lib/copy-expander/copy_expander_spec.rb
92
+ - spec/lib/copy-expander/copy_statement_spec.rb
93
+ - spec/lib/copy-expander/expander_config_spec.rb
94
+ - spec/lib/copy-expander/expander_functional.rb
95
+ - spec/lib/copy-expander/expander_spec.rb
96
+ - spec/lib/copy-expander/snippets.txt
97
+ - spec/spec_helper.rb
98
+ homepage: http://github.com/neopragma/copy-expander
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.2.2
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Expands nested COBOL COPY REPLACING statements
122
+ test_files:
123
+ - spec/lib/copy-expander/copy_expander_spec.rb
124
+ - spec/lib/copy-expander/copy_statement_spec.rb
125
+ - spec/lib/copy-expander/expander_config_spec.rb
126
+ - spec/lib/copy-expander/expander_functional.rb
127
+ - spec/lib/copy-expander/expander_spec.rb
128
+ - spec/lib/copy-expander/snippets.txt
129
+ - spec/spec_helper.rb