coderunner 0.12.19 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.12.19
1
+ 0.13.0
data/coderunner.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "coderunner"
8
- s.version = "0.12.19"
8
+ s.version = "0.13.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Edmund Highcock"]
12
- s.date = "2013-08-07"
12
+ s.date = "2013-08-09"
13
13
  s.description = "CodeRunner is a framework for the automated running and analysis of simulations. It automatically generates any necessary input files, organises the output data and analyses it. Because it is a modular system, it can easily be customised to work with any system and any simulation code. One of its greatest strengths is that it is independent of any one simulation code; thus it can easily plot and compare the data from different codes."
14
14
  s.email = "edmundhighcock@sourceforge.net"
15
15
  s.executables = ["coderunner"]
@@ -39,6 +39,7 @@ Gem::Specification.new do |s|
39
39
  "lib/coderunner/class_methods.rb",
40
40
  "lib/coderunner/feedback.rb",
41
41
  "lib/coderunner/fortran_namelist.rb",
42
+ "lib/coderunner/fortran_namelist_c.rb",
42
43
  "lib/coderunner/graphs_and_films.rb",
43
44
  "lib/coderunner/heuristic_run_methods.rb",
44
45
  "lib/coderunner/instance_methods.rb",
@@ -69,8 +70,13 @@ Gem::Specification.new do |s|
69
70
  "lib/cubecalccrmod/default_modlets/empty_defaults.rb",
70
71
  "lib/cubecalccrmod/defaults_files/cubecalc_defaults.rb",
71
72
  "lib/cubecalccrmod/defaults_files/sleep_defaults.rb",
73
+ "lib/cubecalccrmod/deleted_variables.rb",
72
74
  "lib/cubecalccrmod/empty.rb",
75
+ "lib/cubecalccrmod/namelists.rb",
73
76
  "lib/cubecalccrmod/sleep.rb",
77
+ "lib/cubecalccrmod/with_namelist.rb",
78
+ "test/cubecalc.in",
79
+ "test/cubecalc_namelist.cc",
74
80
  "test/fortran_namelist.in",
75
81
  "test/helper.rb",
76
82
  "test/old_test.rb",
data/lib/coderunner.rb CHANGED
@@ -110,6 +110,8 @@ eprint '.' unless $has_put_startup_message_for_code_runner
110
110
  #eprint '.' unless $has_put_startup_message_for_code_runner
111
111
  load CodeRunner::SCRIPT_FOLDER + "/fortran_namelist.rb"
112
112
  eprint '.' unless $has_put_startup_message_for_code_runner
113
+ load CodeRunner::SCRIPT_FOLDER + "/fortran_namelist_c.rb"
114
+ eprint '.' unless $has_put_startup_message_for_code_runner
113
115
 
114
116
  CodeRunner::CODE_RUNNER_VERSION = Version.new(Gem.loaded_specs['coderunner'].version.to_s) rescue "test"
115
117
 
@@ -37,7 +37,11 @@ class Run
37
37
  # folder = File.dirname(__FILE__)
38
38
 
39
39
 
40
- @namelists = eval(File.read(folder + '/namelists.rb'), binding, folder + '/namelists.rb')
40
+ namelist_file = folder + '/namelists.rb'
41
+ unless FileTest.exist?(namelist_file)
42
+ File.open(namelist_file, 'w'){|file| file.puts '{}'}
43
+ end
44
+ @namelists = eval(File.read(folder + '/namelists.rb'), binding, folder + '/namelists.rb')
41
45
 
42
46
  @variables_with_help = (@namelists.inject({}) do |hash, (namelist, namelist_hash)|
43
47
  namelist_hash[:variables].each{|var, var_hash| hash[var] = var_hash[:help] if var_hash[:help]}
@@ -543,7 +547,7 @@ def self.parse_input_file(input_file, strict=true)
543
547
  namelist_hash = {}
544
548
  regex = Regexp.new("#{rcp.matching_regex.to_s}\\s*(?:\\!(?<comment>.*))?\\n")
545
549
  #ep input_file
546
- text.scan(/(?:^\s*\!\s*(?<namelist_comment>[^\n]+))?\n^\&(?<namelist>\S+).*?^\//m) do
550
+ text.scan(/(?:(?:^|\A)\s*\!\s*(?<namelist_comment>[^\n]+)\n)?(?:^|\A)\&(?<namelist>\S+).*?^\//m) do
547
551
  namelist = $~[:namelist].to_sym
548
552
  hash = namelist_hash[namelist] = {}
549
553
  #p $~
@@ -553,7 +557,7 @@ def self.parse_input_file(input_file, strict=true)
553
557
  hash[var] = val
554
558
  end
555
559
  end
556
- # pp namelist_hash
560
+ pp 'inputfile', namelist_hash
557
561
  namelist_hash
558
562
  end
559
563
 
@@ -1017,13 +1021,15 @@ end
1017
1021
 
1018
1022
  # Given the folder where the source code resides, return a single string containing all the code
1019
1023
 
1024
+ @fortran_namelist_source_file_match = /((\.f9[05])|(\.fpp))$/
1025
+
1020
1026
  def self.get_aggregated_source_code_text(source_code_folder)
1021
1027
  #p 'source_code_folder', source_code_folder
1022
1028
  string = ""
1023
1029
  (rcp.source_code_subfolders.map{|f| '/' + f} + [""]).map{|f| source_code_folder + f}.each do |folder|
1024
1030
  Dir.chdir(folder) do
1025
1031
  Dir.entries.each do |file|
1026
- next unless file =~ /((\.f9[05])|(\.fpp))$/
1032
+ next unless file =~ rcp.fortran_namelist_source_file_match
1027
1033
  next if file =~ /ingen/
1028
1034
  ep file
1029
1035
  text = File.read(file) + "\n"
@@ -1035,12 +1041,9 @@ def self.get_aggregated_source_code_text(source_code_folder)
1035
1041
  string
1036
1042
  end
1037
1043
 
1038
- # Find unknown input variables in the source code and add them to the database of namelists
1039
- # Delete input variables which are no longer present in the source code
1040
-
1041
- def self.synchronise_variables(source_code_folder = ARGV[2])
1042
- source = get_aggregated_source_code_text(source_code_folder)
1043
- # ep source.size
1044
+ # Find all input namelists and variables by scanning the source code
1045
+ #
1046
+ def self.get_namelists_and_variables_from_source_code(source)
1044
1047
  nms = {}
1045
1048
  all_variables_in_source = {}
1046
1049
  namelist_declarations = {}
@@ -1066,6 +1069,54 @@ def self.synchronise_variables(source_code_folder = ARGV[2])
1066
1069
  nms[namelist].uniq!
1067
1070
  all_variables_in_source[namelist].uniq!
1068
1071
  end
1072
+ return [nms, all_variables_in_source, namelist_declarations]
1073
+ end
1074
+
1075
+ # Try to get a sample value of the
1076
+ def self.get_sample_value(source, var)
1077
+ ep var
1078
+ values_text = source.scan(Regexp.new("\\W#{var}\\s*=\\s*.+")).join("\n")
1079
+ ep values_text
1080
+ values = scan_text_for_variables(values_text).map{|(v,val)| val}
1081
+ values.uniq!
1082
+ # ep values if var == :nbeta
1083
+ values.delete_if{|val| val.kind_of? String} if values.find{|val| val.kind_of? Numeric}
1084
+ values.delete_if{|val| val.kind_of? String and not String::FORTRAN_BOOLS.include? val} if values.find{|val| val.kind_of? String and String::FORTRAN_BOOLS.include? val}
1085
+ # values.sort!
1086
+ # ep var
1087
+ # ep values
1088
+ sample_val = values[0]
1089
+ if not values[0] or ( values[0].kind_of? String and not String::FORTRAN_BOOLS.include? values[0])
1090
+ p source.scan(Regexp.new("^\s*(?<type>integer|float|character|logical|real|double|complex)(?:&[\\n\\r]|.)*\\W#{var}\\W", Regexp::IGNORECASE)).uniq
1091
+ p var unless $~
1092
+
1093
+ case $~[:type]
1094
+ when /logical/
1095
+ sample_val = '.false.'
1096
+ when /int/
1097
+ sample_val = 0
1098
+ when 'real', 'float', 'double'
1099
+ sample_val = 0.0
1100
+ when /character/
1101
+ sample_val = ""
1102
+ when /complex/
1103
+ sample_val = Complex(0.0, 0.0)
1104
+ end
1105
+ # type = Feedback.get_choice("Found the following possible values for '#{var}' in namelist '#{namelist}': #{values.inspect} but cannot determine its type. Please choose its type", ['Float', 'Integer', 'String', 'Unknown' ])
1106
+ # ep type
1107
+ n +=1
1108
+
1109
+ end
1110
+ return sample_val
1111
+ end
1112
+
1113
+ # Find unknown input variables in the source code and add them to the database of namelists
1114
+ # Delete input variables which are no longer present in the source code
1115
+
1116
+ def self.synchronise_variables(source_code_folder = ARGV[2])
1117
+ source = get_aggregated_source_code_text(source_code_folder)
1118
+ nms, all_variables_in_source, namelist_declarations = get_namelists_and_variables_from_source_code(source)
1119
+ # ep source.size
1069
1120
  variables_to_delete = {}
1070
1121
  #pp 'namelists', rcp.namelists
1071
1122
  rcp.namelists.each do |namelist, namelist_hash|
@@ -1094,53 +1145,22 @@ def self.synchronise_variables(source_code_folder = ARGV[2])
1094
1145
  end
1095
1146
  end
1096
1147
 
1148
+ raise "No namelists found" if nms.size == 0
1097
1149
  eputs nms.keys.zip(nms.values.map{|vs| vs.size})
1098
- eputs "Namelists to be added to. (Press Enter)"; STDIN.gets
1150
+ eputs "Namelists to be added to. (Press Enter)"; STDIN.gets unless ENV['CR_NON_INTERACTIVE']
1099
1151
  n = 0
1100
1152
  ep nms
1101
1153
  # ep nms.values.sum
1102
1154
  nms.values.sum.each do |var|
1103
1155
  eputs var if variable_exists? var
1104
1156
  end
1105
- eputs "Conflicting Variables. (Press Enter)";; STDIN.gets
1157
+ eputs "Conflicting Variables. (Press Enter)";; STDIN.gets unless ENV['CR_NON_INTERACTIVE']
1106
1158
  nms.each do |namelist, vars|
1107
1159
  ep namelist
1108
1160
  ep vars
1109
1161
  vars.each do |var|
1110
1162
  # next unless var == :w_antenna
1111
- ep var
1112
- values_text = source.scan(Regexp.new("\\W#{var}\\s*=\\s*.+")).join("\n")
1113
- ep values_text
1114
- values = scan_text_for_variables(values_text).map{|(v,val)| val}
1115
- values.uniq!
1116
- # ep values if var == :nbeta
1117
- values.delete_if{|val| val.kind_of? String} if values.find{|val| val.kind_of? Numeric}
1118
- values.delete_if{|val| val.kind_of? String and not String::FORTRAN_BOOLS.include? val} if values.find{|val| val.kind_of? String and String::FORTRAN_BOOLS.include? val}
1119
- # values.sort!
1120
- # ep var
1121
- # ep values
1122
- sample_val = values[0]
1123
- if not values[0] or ( values[0].kind_of? String and not String::FORTRAN_BOOLS.include? values[0])
1124
- p source.scan(Regexp.new("^\s*(?<type>integer|float|character|logical|real|double|complex)(?:&[\\n\\r]|.)*\\W#{var}\\W", Regexp::IGNORECASE)).uniq
1125
- p var unless $~
1126
-
1127
- case $~[:type]
1128
- when /logical/
1129
- sample_val = '.false.'
1130
- when /int/
1131
- sample_val = 0
1132
- when 'real', 'float', 'double'
1133
- sample_val = 0.0
1134
- when /character/
1135
- sample_val = ""
1136
- when /complex/
1137
- sample_val = Complex(0.0, 0.0)
1138
- end
1139
- # type = Feedback.get_choice("Found the following possible values for '#{var}' in namelist '#{namelist}': #{values.inspect} but cannot determine its type. Please choose its type", ['Float', 'Integer', 'String', 'Unknown' ])
1140
- # ep type
1141
- n +=1
1142
-
1143
- end
1163
+ sample_val = get_sample_value(source, var)
1144
1164
  p namelist, var, sample_val
1145
1165
  add_code_variable_to_namelist(namelist, var, sample_val)
1146
1166
  end
@@ -0,0 +1,53 @@
1
+ class CodeRunner::Run
2
+ class FortranNamelistC < FortranNamelist
3
+ # Given the folder where the source code resides, return a single string containing all the code
4
+
5
+ @fortran_namelist_source_file_match = /(\.c|\.cpp|\.cu|\.cc)$/
6
+
7
+ @fortran_namelist_variable_match_regex = /^[^\/]*?fnr_get_(?<type>\w+)\(\&?[\w\s]+\s*,\s*["'](?<namelist>\w+)[\d()]*?['"]\s*,\s*['"](?<variable>\w+)['"],[^)]+\)\)\s*[\w\[\]\d]+\s*=\s*(?<default>\S+)\s*;/
8
+ #
9
+ # Find all input namelists and variables by scanning the source code
10
+ #
11
+ def self.get_namelists_and_variables_from_source_code(source)
12
+ nms = {}
13
+ all_variables_in_source = {}
14
+ namelist_declarations = {}
15
+ #source.scan(/^\s*namelist\s*\/(?<namelist>\w+)\/(?<variables>(?:(?:&\s*[\n\r]+)|[^!\n\r])*)/) do
16
+ #source.scan(Regexp.new("#{/^\s*namelist\s*\/\s*(?<namelist>\w+)\s*\//}(?<variables>#{FORTRAN_SINGLE_LINE})")) do
17
+ source.scan(rcp.fortran_namelist_variable_match_regex) do
18
+ #p $~
19
+ namelist = $~[:namelist].to_s.downcase.to_sym
20
+ #variables = $~[:variables].gsub(/!.*/, '')
21
+ #eputs namelist, variables
22
+ #namelist_declarations[namelist] = variables
23
+ #gets # if namelist == :collisions_knobs
24
+
25
+ #next if [:stuff, :ingen_knobs].include? namelist
26
+ nms[namelist] ||= []
27
+ all_variables_in_source[namelist] ||= []
28
+ # puts variables
29
+ #variables.scan(/\w+/) do
30
+ var = $~[:variable].to_sym
31
+ # (p variables, namelist; exit) if var == :following or var == :sou
32
+ all_variables_in_source[namelist].push var
33
+ next if known_code_variable?(namelist, var)
34
+ nms[namelist].push var
35
+ #end
36
+ nms[namelist].uniq!
37
+ all_variables_in_source[namelist].uniq!
38
+ end
39
+ return [nms, all_variables_in_source, namelist_declarations]
40
+ end
41
+ def self.get_sample_value(source, var)
42
+ sample_val = nil
43
+ source.scan(rcp.fortran_namelist_variable_match_regex) do
44
+
45
+ next unless var == $~[:variable].to_sym
46
+ sample_val = eval($~[:default])
47
+ end
48
+ raise "Couldn't get a sample value for #{var.inspect}" unless sample_val
49
+ return sample_val
50
+ end
51
+
52
+ end
53
+ end
@@ -1,13 +1,13 @@
1
1
  class CodeRunner
2
- class Cubecalc < Run
2
+ class Cubecalc < Run::FortranNamelistC
3
3
 
4
4
  # @code = 'cubecalc'
5
5
 
6
- @variables = [:calculate_sides, :width, :height, :depth, :area]
6
+ @variables = [:calculate_sides, :width, :height, :depth]
7
7
 
8
8
  @naming_pars = [:width]
9
9
 
10
- @results = [:volume, :sides]
10
+ @results = [:volume, :sides, :area]
11
11
 
12
12
  # e.g. number of iterations
13
13
 
@@ -0,0 +1,30 @@
1
+ {:edges_1=>
2
+ {:should_include=>"true",
3
+ :description=>nil,
4
+ :help=>nil,
5
+ :code_name=>:edges_1,
6
+ :must_pass=>
7
+ [{:test=>"kind_of? Numeric",
8
+ :explanation=>
9
+ "This variable must be a floating point number (an integer is also acceptable: it will be converted into a floating point number)."}],
10
+ :type=>:Float},
11
+ :edges_2=>
12
+ {:should_include=>"true",
13
+ :description=>nil,
14
+ :help=>nil,
15
+ :code_name=>:edges_2,
16
+ :must_pass=>
17
+ [{:test=>"kind_of? Numeric",
18
+ :explanation=>
19
+ "This variable must be a floating point number (an integer is also acceptable: it will be converted into a floating point number)."}],
20
+ :type=>:Float},
21
+ :edges_3=>
22
+ {:should_include=>"true",
23
+ :description=>nil,
24
+ :help=>nil,
25
+ :code_name=>:edges_3,
26
+ :must_pass=>
27
+ [{:test=>"kind_of? Numeric",
28
+ :explanation=>
29
+ "This variable must be a floating point number (an integer is also acceptable: it will be converted into a floating point number)."}],
30
+ :type=>:Float}}
@@ -0,0 +1,52 @@
1
+ {:cubecalc=>
2
+ {:description=>"",
3
+ :should_include=>"true",
4
+ :variables=>
5
+ {:calculate_sides=>
6
+ {:should_include=>"true",
7
+ :description=>nil,
8
+ :help=>nil,
9
+ :code_name=>:calculate_sides,
10
+ :must_pass=>
11
+ [{:test=>"kind_of? Integer",
12
+ :explanation=>"This variable must be an integer."}],
13
+ :type=>:Integer},
14
+ :must_sleep=>
15
+ {:should_include=>"true",
16
+ :description=>nil,
17
+ :help=>nil,
18
+ :code_name=>:must_sleep,
19
+ :must_pass=>
20
+ [{:test=>"kind_of? Integer",
21
+ :explanation=>"This variable must be an integer."}],
22
+ :type=>:Integer},
23
+ :width=>
24
+ {:should_include=>"true",
25
+ :description=>nil,
26
+ :help=>nil,
27
+ :code_name=>:width,
28
+ :must_pass=>
29
+ [{:test=>"kind_of? Numeric",
30
+ :explanation=>
31
+ "This variable must be a floating point number (an integer is also acceptable: it will be converted into a floating point number)."}],
32
+ :type=>:Float},
33
+ :depth=>
34
+ {:should_include=>"true",
35
+ :description=>nil,
36
+ :help=>nil,
37
+ :code_name=>:depth,
38
+ :must_pass=>
39
+ [{:test=>"kind_of? Numeric",
40
+ :explanation=>
41
+ "This variable must be a floating point number (an integer is also acceptable: it will be converted into a floating point number)."}],
42
+ :type=>:Float},
43
+ :height=>
44
+ {:should_include=>"true",
45
+ :description=>nil,
46
+ :help=>nil,
47
+ :code_name=>:height,
48
+ :must_pass=>
49
+ [{:test=>"kind_of? Numeric",
50
+ :explanation=>
51
+ "This variable must be a floating point number (an integer is also acceptable: it will be converted into a floating point number)."}],
52
+ :type=>:Float}}}}
@@ -0,0 +1,43 @@
1
+ class CodeRunner
2
+ class Cubecalc
3
+ class WithNamelist < Cubecalc
4
+ @source_code_subfolders = []
5
+ setup_namelists(rcp.code_module_folder)
6
+
7
+ def parameter_string
8
+ 'input_file.in'
9
+ end
10
+
11
+ def generate_input_file
12
+ File.open('input_file.in', 'w'){|file| file.puts input_file_text}
13
+ end
14
+
15
+ def input_file_header
16
+ <<EOF
17
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
18
+ !
19
+ ! Input file for the test program cubecalc_namelist
20
+ !
21
+ !
22
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
23
+
24
+ ! #@defaults_file_description
25
+
26
+ EOF
27
+ end
28
+
29
+ def self.defaults_file_header
30
+ <<EOF
31
+ #############################################################
32
+ #
33
+ # Defaults for the test program cubecalc_namelist
34
+ #
35
+ #############################################################
36
+
37
+ @defaults_file_description = "Basic defaults"
38
+ EOF
39
+ end
40
+ end
41
+ end
42
+ end
43
+
data/test/cubecalc.in ADDED
@@ -0,0 +1,7 @@
1
+ &cubecalc
2
+ calculate_sides = 1
3
+ must_sleep = 1
4
+ width = 2.7
5
+ depth = 3.9
6
+ height = 8.2
7
+ /
@@ -0,0 +1,759 @@
1
+
2
+ #include <stdio.h>
3
+ #include <iostream>
4
+ #include <cstdlib>
5
+ #include <fstream>
6
+ #include <cstring>
7
+ #include <ctime>
8
+ #include <regex.h>
9
+ using namespace std;
10
+
11
+ /* Fortran Namelist Reader for C
12
+ * Written by Edmund Highcock
13
+ * edmundhighcock@sourceforge.net
14
+ *
15
+ * This is free software released
16
+ * under the GPL v3 */
17
+
18
+
19
+
20
+ int FNR_DEBUG=0;
21
+
22
+ void fnr_error_message(char * message, int exit)
23
+ {
24
+ printf("%s\n", message);
25
+ if (exit) abort();
26
+ }
27
+
28
+ void fnr_debug_write(char * message)
29
+ {
30
+ if (FNR_DEBUG) printf("%s\n", message);
31
+ }
32
+
33
+ struct fnr_struct
34
+ {
35
+ int n_namelists;
36
+ char ** namelist_names;
37
+ int * namelist_sizes;
38
+ char *** variable_names;
39
+ char *** variable_values;
40
+ /*void * template_ptr;*/
41
+ /*int check_template;*/
42
+ };
43
+
44
+ int fnr_file_size(FILE * fp)
45
+ {
46
+ /*Get file size*/
47
+ int sz;
48
+ if (FNR_DEBUG) printf("Seeking end\n");
49
+ fseek(fp, 0L, SEEK_END);
50
+ if (FNR_DEBUG) printf("Sought end\n");
51
+ sz = ftell(fp);
52
+
53
+ /*Seek back to the beginning:*/
54
+ fseek(fp, 0L, SEEK_SET);
55
+ return sz;
56
+ }
57
+ void fnr_read_file(char * fname, char ** text_ptr)
58
+ {
59
+ /*FILE * fp=fopen("my_file.txt", "r");*/
60
+
61
+ FILE * fp=fopen(fname, "r");
62
+
63
+ if (FNR_DEBUG) printf("Opened file\n");
64
+
65
+ int sz = fnr_file_size(fp); /* File size*/
66
+
67
+ if (FNR_DEBUG) printf("Size was %d\n", sz);
68
+
69
+ *text_ptr = (char *)malloc((sz+1)*sizeof(char));
70
+
71
+ char *text = *text_ptr;
72
+
73
+
74
+ int i=0;
75
+ while(!feof(fp)) {
76
+ /*printf("I is %d\n", i);*/
77
+ text[i++] = fgetc(fp);
78
+ /*printf("reading");*/
79
+ }
80
+ text[i-1]='\0';
81
+ fclose(fp);
82
+ if (FNR_DEBUG) printf("Read file into memory\n");
83
+ }
84
+ int fnr_count_matches(char * text, regex_t regex){
85
+
86
+ int reti;
87
+ if (FNR_DEBUG) printf("Marker A4\n");
88
+
89
+ int location = 0;
90
+ int text_length = strlen(text);
91
+ int nmatches=0;
92
+ if (FNR_DEBUG) printf("Marker D1\n");
93
+
94
+ size_t nmatch = 1;
95
+ regmatch_t length_match[1];
96
+ while (location < text_length - 1){
97
+ if (FNR_DEBUG) printf("Location %d\n", location);
98
+ reti = regexec(&regex, &text[location], nmatch, length_match, 0);
99
+ if (!reti)
100
+ {
101
+ /*printf("First letter %s", &text[location + length_match[0].rm_so + 4]);*/
102
+ location = location + length_match[0].rm_eo ;
103
+ nmatches += 1;
104
+ }
105
+ if (reti) break;
106
+ }
107
+ if (FNR_DEBUG) printf("Matches was %d\n", nmatches);
108
+ return nmatches;
109
+ }
110
+
111
+
112
+ int fnr_count_namelists(char * text)
113
+ {
114
+
115
+ if (FNR_DEBUG) printf("void fnr_count_namelists; string is %s\n", text);
116
+ regex_t regex;
117
+ int reti;
118
+ int nmatches;
119
+
120
+
121
+ /* Compile regular expression */
122
+ /*reti = regcomp(&regex, "&[_[:alnum:]]\\+\\?\n", 0);*/
123
+ /*reti = regcomp(&regex, "&[_[:alnum:]]+[[:blank:]]", REG_EXTENDED);*/
124
+ reti = regcomp(&regex, "^&[_[:alnum:]]+[\n\r[:blank:]]", REG_EXTENDED|REG_NEWLINE);
125
+ if( reti ){ fprintf(stderr, "Could not compile regex\n"); exit(1); }
126
+ nmatches = fnr_count_matches(text, regex);
127
+ regfree(&regex);
128
+ if (FNR_DEBUG) printf("Marker A6\n");
129
+ return nmatches;
130
+
131
+ }
132
+
133
+ int fnr_count_variables(char * text)
134
+ {
135
+
136
+ if (FNR_DEBUG) printf("void fnr_count_variables; string is %s\n", text);
137
+ regex_t regex;
138
+ int reti;
139
+ int nmatches;
140
+
141
+
142
+ /* Compile regular expression */
143
+ reti = regcomp(&regex, "^[[:space:]]*[_[:alnum:]()]+([[:blank:]]|=)", REG_EXTENDED|REG_NEWLINE);
144
+ if( reti ){ fprintf(stderr, "Could not compile regex\n"); exit(1); }
145
+ nmatches = fnr_count_matches(text, regex);
146
+ regfree(&regex);
147
+ if (FNR_DEBUG) printf("Marker A8\n");
148
+ return nmatches;
149
+
150
+ }
151
+
152
+ void fnr_match_namelists(char * text, char ** namelist_names, char ** namelist_texts)
153
+ {
154
+
155
+ if (FNR_DEBUG) printf("void fnr_match_namelists\n");
156
+ regex_t regex;
157
+ int reti;
158
+ int location = 0;
159
+ int text_length = strlen(text);
160
+ // int nmatches=0;
161
+ size_t nmatch = 3;
162
+ regmatch_t length_match[3];
163
+ int name_size, ntext_size;
164
+
165
+
166
+ /* Compile regular expression */
167
+ // reti = regcomp(&regex, "^&([_[:alnum:]]+)([[:blank:]\n\r](!.*/.*(\r|\n)|[^/]|(\r|\n))+)^/", REG_EXTENDED|REG_NEWLINE);
168
+ //reti = regcomp(&regex, "[\n\r][[:blank:]]*&([_[:alnum:]]+)([[:blank:]\n\r](!.*[\r\n]|[^/]|[\r\n])+)^/", REG_EXTENDED|REG_NEWLINE);
169
+ //reti = regcomp(&regex, "^[[:blank:]]*&([_[:alnum:]]+)([[:blank:]\n\r](!.*|[^/\r\n]|[\r\n]+([^/\n\r]|[\n\r][^/]))+)[\r\n]/", REG_EXTENDED|REG_NEWLINE);
170
+ /*reti = regcomp(&regex, "^[[:blank:]]*&([_[:alnum:]]+)([[:blank:]\n\r]([^\n\r]/|(\n|\r\n)[^/\n\r]|[^\n\r/])+)(\n|\r\n)/", REG_EXTENDED|REG_NEWLINE);*/
171
+ reti = regcomp(&regex, "^[[:blank:]]*&([_[:alnum:]]+)([[:blank:]\n\r]([^\n\r]/|(\n|\r\n)|[^\n\r/])+)^/", REG_EXTENDED|REG_NEWLINE);
172
+ /*reti = regcomp(&regex, "^[[:blank:]]*&([_[:alnum:]]+)([[:blank:]\n\r]([^\n\r]/|[^/])+)(\n|\r\n)/", REG_EXTENDED|REG_NEWLINE);*/
173
+ // reti = regcomp(&regex, "[\n\r][[:blank:]]*&([_[:alnum:]]+)([[:blank:]\n\r](.|[\r\n])+)^/", REG_EXTENDED|REG_NEWLINE);
174
+ /*reti = regcomp(&regex, "&[_[:alnum:]]\\+\\?\n", 0);*/
175
+ if( reti ){ fprintf(stderr, "Could not compile regex for matching namelist names and texts\n"); exit(1); }
176
+ int i = 0;
177
+
178
+ while (location < text_length - 1){
179
+ if (FNR_DEBUG) printf("Location %d\n", location);
180
+ reti = regexec(&regex, &text[location], nmatch, length_match, 0);
181
+ char ** ntexts = namelist_texts;
182
+ char ** nnames = namelist_names;
183
+ if (!reti)
184
+ {
185
+
186
+ /*Assign namelist name*/
187
+ name_size = length_match[1].rm_eo - length_match[1].rm_so + 1;
188
+ nnames[i] = (char *)malloc(name_size*sizeof(char));
189
+ strncpy(nnames[i], &text[location+length_match[1].rm_so], name_size-1);
190
+ nnames[i][name_size - 1 ] = '\0';
191
+
192
+ /*Assign namelist text*/
193
+ ntext_size = length_match[2].rm_eo - length_match[2].rm_so + 1;
194
+ ntexts[i] = (char *)malloc(ntext_size*sizeof(char));
195
+ strncpy(ntexts[i], &text[location+length_match[2].rm_so], ntext_size-1);
196
+ ntexts[i][ntext_size - 1] = '\0';
197
+
198
+ /*variable_text_size = length_match[2].rm_eo - length_match[2].rm_so;*/
199
+
200
+ if (FNR_DEBUG) printf("begin %d, end %d, Size %d, Name %s\n", length_match[1].rm_so, length_match[1].rm_eo, name_size, nnames[i]);
201
+ if (FNR_DEBUG) printf("begin %d, end %d, Size %d, Name %s\n", length_match[2].rm_so, length_match[2].rm_eo, ntext_size, ntexts[i]);
202
+ /*nmatches++;*/
203
+ i++;
204
+
205
+ location = location + length_match[0].rm_eo;
206
+ }
207
+ if (reti) {
208
+ if (FNR_DEBUG) printf("Finished matching namelists\n");
209
+ break;
210
+ }
211
+ }
212
+ /*printf("F*/
213
+
214
+ regfree(&regex);
215
+ }
216
+
217
+ void fnr_match_variables(char * text, char ** variable_names, char ** variable_values)
218
+ {
219
+
220
+ if (FNR_DEBUG) printf("void fnr_match_variables\n");
221
+ regex_t regex;
222
+ int reti;
223
+ int location = 0;
224
+ int text_length = strlen(text);
225
+ // int nmatches=0;
226
+ size_t nmatch = 6;
227
+ regmatch_t length_match[6];
228
+ int name_size, value_size;
229
+
230
+
231
+ /* Compile regular expression */
232
+ /*reti = regcomp(&regex, "(^|\n)[[:space:]]*([_[:alnum:]]+)([[:blank:]]|=)[[:space:]]*=[[:space:]]*(\"([^\"]|\\\\|\\\")+\"|'([[^']|\\\\|\\')+'|[[:alnum:].+-]+)([[:blank:]\r\n]|!)", REG_EXTENDED|REG_NEWLINE);*/
233
+ reti = regcomp(&regex, "(^|\n|\r)[[:space:]]*([_[:alnum:]()]+)([[:blank:]]+=|=)[[:blank:]]*(\"([^\"]|\\\\|\\\")+\"|'([^']|\\\\|\\')+'|[[:alnum:].+-]+)([[:blank:]\r\n]|!)", REG_EXTENDED|REG_NEWLINE);
234
+ if( reti ){ fprintf(stderr, "Could not compile regex for matching namelist names and texts\n"); exit(1); }
235
+ int i = 0;
236
+
237
+ if (FNR_DEBUG) printf ("Finished making regex; MARKER D1\n");
238
+ if (FNR_DEBUG) printf ("location, %d, text_length, %d, text %s\n", location, text_length, text);
239
+ while (location < text_length - 1){
240
+ if (FNR_DEBUG) printf("Location %d\n", location);
241
+ reti = regexec(&regex, &text[location], nmatch, length_match, 0);
242
+ char ** vnames = variable_names;
243
+ char ** vvalues = variable_values;
244
+ if (!reti)
245
+ {
246
+
247
+ /*Assign variable name*/
248
+ int a = 2;
249
+ int b = 4;
250
+ name_size = length_match[a].rm_eo - length_match[a].rm_so + 1;
251
+ vnames[i] = (char *)malloc(name_size*sizeof(char));
252
+ strncpy(vnames[i], &text[location+length_match[a].rm_so], name_size-1);
253
+ vnames[i][name_size - 1 ] = '\0';
254
+
255
+ /*Assign variable value*/
256
+ value_size = length_match[b].rm_eo - length_match[b].rm_so + 1;
257
+ vvalues[i] = (char *)malloc(value_size*sizeof(char));
258
+ strncpy(vvalues[i], &text[location+length_match[b].rm_so], value_size-1);
259
+ vvalues[i][value_size - 1] = '\0';
260
+
261
+ /*variable_text_size = length_match[2].rm_eo - length_match[2].rm_so;*/
262
+
263
+ if (FNR_DEBUG) printf("begin %d, end %d, Size %d, Name %s\n", length_match[2].rm_so, length_match[2].rm_eo, name_size, vnames[i]);
264
+ if (FNR_DEBUG) printf("begin %d, end %d, Size %d, Name %s\n", length_match[3].rm_so, length_match[3].rm_eo, value_size, vvalues[i]);
265
+ /*nmatches++;*/
266
+ i++;
267
+
268
+ location = location + length_match[0].rm_eo;
269
+ }
270
+ if (reti) {
271
+ if (FNR_DEBUG) printf("Finished matching variables\n");
272
+ break;
273
+ }
274
+ }
275
+ regfree(&regex);
276
+ }
277
+
278
+ struct fnr_struct fnr_read_namelist_string(char * file_string)
279
+ {
280
+ struct fnr_struct namelist_struct;
281
+ char ** namelist_texts;
282
+ if (FNR_DEBUG) printf("The string to be read is %s\n\n", file_string);
283
+ /*fnr_match_namelists(file_string, namelist_struct.namelist_names, &namelist_texts);*/
284
+
285
+ /* Count the namelists and allocate the namelists arrays accordingly */
286
+ namelist_struct.n_namelists = fnr_count_namelists(file_string);
287
+
288
+ namelist_struct.namelist_names = (char **)malloc(namelist_struct.n_namelists*sizeof(char *));
289
+ namelist_struct.namelist_sizes = (int *)malloc(namelist_struct.n_namelists*sizeof(int));
290
+ namelist_struct.variable_names = (char ***)malloc(namelist_struct.n_namelists*sizeof(char **));
291
+ namelist_struct.variable_values = (char ***)malloc(namelist_struct.n_namelists*sizeof(char **));
292
+ namelist_texts = (char **)malloc(namelist_struct.n_namelists*sizeof(char *));
293
+
294
+ /* Match all the namelists, put their names into namelist names and
295
+ * their content into namelist_texts*/
296
+ fnr_match_namelists(file_string, namelist_struct.namelist_names, namelist_texts);
297
+ int i;
298
+ int nvars;
299
+ for (i=0; i < namelist_struct.n_namelists; i++)
300
+ {
301
+ if (FNR_DEBUG) printf("Analysing namelist %d, called %s\n", i, namelist_struct.namelist_names[i]);
302
+ nvars = namelist_struct.namelist_sizes[i] = fnr_count_variables(namelist_texts[i]);
303
+ namelist_struct.variable_names[i] = (char **)malloc(nvars*sizeof(char *));
304
+ namelist_struct.variable_values[i] = (char **)malloc(nvars*sizeof(char *));
305
+ fnr_match_variables(namelist_texts[i], namelist_struct.variable_names[i], namelist_struct.variable_values[i]);
306
+ free(namelist_texts[i]);
307
+
308
+ }
309
+
310
+
311
+ free(namelist_texts);
312
+
313
+ return namelist_struct;
314
+ };
315
+ struct fnr_struct fnr_read_namelist_file(char * file_name)
316
+ {
317
+ char * file_string;
318
+ /*printf("Marker A1\n");*/
319
+ printf("Reading file %s\n", file_name);
320
+ if (FNR_DEBUG) printf("Reading file\n");
321
+ fnr_read_file(file_name, &file_string);
322
+ if (FNR_DEBUG) printf("The string read was: \n%s\n", file_string);
323
+ struct fnr_struct namelist_struct = fnr_read_namelist_string(file_string);
324
+ return namelist_struct;
325
+ }
326
+
327
+ void fnr_free(struct fnr_struct * namelist_struct){
328
+ int i,j;
329
+ for (i=0; i < namelist_struct->n_namelists; i++)
330
+ {
331
+ for (j=0; j < namelist_struct->namelist_sizes[i];j++){
332
+ free(namelist_struct->variable_names[i][j]);
333
+ free(namelist_struct->variable_values[i][j]);
334
+ }
335
+ free(namelist_struct->variable_names[i]);
336
+ free(namelist_struct->variable_values[i]);
337
+ free(namelist_struct->namelist_names[i]);
338
+ }
339
+ free(namelist_struct->namelist_sizes);
340
+ free(namelist_struct->namelist_names);
341
+ free(namelist_struct->variable_names);
342
+ free(namelist_struct->variable_values);
343
+ }
344
+
345
+
346
+ int FNR_NAMELIST_NOT_FOUND=1;
347
+ int FNR_VARIABLE_NOT_FOUND=2;
348
+ int FNR_VARIABLE_SSCANF_ERROR=3;
349
+ int FNR_NAMELIST_NOT_IN_TEMPLATE=4;
350
+ int FNR_VARIABLE_NOT_IN_TEMPLATE=5;
351
+
352
+ int fnr_abort_on_error;
353
+ int fnr_abort_if_missing;
354
+
355
+ /* Defaults */
356
+ /*fnr_abort_on_error=1;*/
357
+ /*fnr_abort_if_missing=0;*/
358
+
359
+ void fnr_check_rvalue(const char * namelist, const char * variable, int rvalue)
360
+ {
361
+ if (FNR_DEBUG) printf("rvalue, %d, fnr_abort_if_missing, %d\n", rvalue, fnr_abort_if_missing);
362
+ if (!rvalue) return;
363
+ if (fnr_abort_on_error && rvalue == FNR_VARIABLE_SSCANF_ERROR)
364
+ {
365
+ printf("Error in namelist %s, variable %s\n", namelist, variable);
366
+ abort();
367
+ }
368
+ if (fnr_abort_if_missing && rvalue == FNR_NAMELIST_NOT_FOUND)
369
+ {
370
+ printf("Missing namelist %s\n", namelist);
371
+ abort();
372
+ }
373
+ if (fnr_abort_if_missing && rvalue == FNR_VARIABLE_NOT_FOUND)
374
+ {
375
+ printf("Missing variable %s in namelist %s\n", variable, namelist);
376
+ abort();
377
+ }
378
+ if (rvalue == FNR_NAMELIST_NOT_IN_TEMPLATE)
379
+ {
380
+ printf("Namelist %s is not in template (i.e. it is not a valid namelist).\n", namelist);
381
+ abort();
382
+ }
383
+ if (rvalue == FNR_VARIABLE_NOT_IN_TEMPLATE)
384
+ {
385
+ printf("Variable %s in namelist %s is not in template (i.e. it is not a valid variable).\n", variable, namelist);
386
+ abort();
387
+ }
388
+
389
+ if (FNR_DEBUG) printf("Marker E8\n");
390
+
391
+ }
392
+
393
+ int fnr_get_string_no_test(struct fnr_struct * namelist_struct, const char * namelist, const char * variable, char ** value)
394
+ /*{*/
395
+ /*int check_template = 0;*/
396
+ /*struct fnr_struct * dummy;*/
397
+ /*return fnr_get_string(namelist_struct, namelist, variable, value, check_template, dummy);*/
398
+ /*}*/
399
+
400
+ /*int fnr_get_string(struct fnr_struct * namelist_struct, const char * namelist, const char * variable, char ** value, const int check_template, const struct fnr_struct * namelist_template)*/
401
+ {
402
+ int i,j;
403
+ int found_namelist = 0;
404
+ int found_variable = 0;
405
+ int rvalue = 0;
406
+ for (i=0;i<namelist_struct->n_namelists; i++)
407
+ {
408
+ if (!strcmp(namelist_struct->namelist_names[i], namelist) )
409
+ {
410
+ found_namelist = 1;
411
+ break;
412
+ }
413
+ }
414
+ if (!found_namelist){
415
+ rvalue = FNR_NAMELIST_NOT_FOUND;
416
+ }
417
+ if (found_namelist)
418
+ {
419
+ if (FNR_DEBUG) printf("Found namelist %s, size: %d\n", namelist_struct->namelist_names[i], namelist_struct->namelist_sizes[i]);
420
+ for (j=namelist_struct->namelist_sizes[i]-1;j>-1;j--)
421
+ /* Must take the last specification of the variable*/
422
+ {
423
+ if (FNR_DEBUG) printf("Marker C2; %d %s\n", j, namelist_struct->variable_names[i][j]);
424
+ if (!strcmp(namelist_struct->variable_names[i][j], variable))
425
+ {
426
+ found_variable = 1;
427
+ break;
428
+ }
429
+ }
430
+ if (!found_variable) rvalue = FNR_VARIABLE_NOT_FOUND;
431
+ if (FNR_DEBUG) printf("Marker C3\n");
432
+ if (found_variable)
433
+ {
434
+ if (FNR_DEBUG) printf("Found variable %s\n", variable);
435
+ char * v = namelist_struct->variable_values[i][j];
436
+ if (FNR_DEBUG) printf("Found value %s\n", v);
437
+ const char * dq = "\"";
438
+ const char * sq = "'";
439
+ if (v[0] == dq[0] || v[0] == sq[0])
440
+ {
441
+ if (FNR_DEBUG) printf("Value was a string \n");
442
+ *value = (char *)malloc((strlen(v)-1)*sizeof(char));
443
+ char * val = *value;
444
+ if (FNR_DEBUG) printf("Allocated \n");
445
+ strncpy(val, &v[1], strlen(v)-2);
446
+ if (FNR_DEBUG) printf("Copied: %s \n", val);
447
+ val[strlen(v)-2] = '\0';
448
+ if (FNR_DEBUG) printf("Terminated: %s \n", val);
449
+ }
450
+ else
451
+ {
452
+ if (FNR_DEBUG) printf("MARKER D4.5; Length of string %d\n", strlen(variable));
453
+ *value = (char *)malloc((strlen(v)+1)*sizeof(char));
454
+ strcpy(*value, v);
455
+ if (FNR_DEBUG) printf("MARKER D4.6; copied value %s to output: %s\n", *value, v);
456
+ }
457
+ }
458
+ }
459
+ if (!found_namelist || !found_variable){
460
+ if (FNR_DEBUG) printf("MARKER D4; Length of string %d\n", strlen(variable));
461
+ *value = (char *)malloc((strlen(variable)+1)*sizeof(char));
462
+ /*char empty_string = "";*/
463
+ if (FNR_DEBUG) printf("Length of variable was %d\n", strlen(variable));
464
+ if (FNR_DEBUG) printf("MARKER D5\n");
465
+ strcpy(*value, variable);
466
+ if (FNR_DEBUG) printf("MARKER D5.3\n");
467
+ /**value[strlen(variable)] = '\0";*/
468
+ if (FNR_DEBUG) printf("MARKER D5.5\n");
469
+ }
470
+ return rvalue;
471
+ }
472
+
473
+ int fnr_get_string(struct fnr_struct * namelist_struct, const char * namelist, const char * variable, char ** value)
474
+ {
475
+ if (FNR_DEBUG) printf("Getting string no test, namelist %s, variable %s\n", namelist, variable);
476
+ int rvalue = fnr_get_string_no_test(namelist_struct, namelist, variable, value);
477
+ fnr_check_rvalue(namelist, variable, rvalue);
478
+ if (FNR_DEBUG) printf("Checked rvalue for %s\n", variable);
479
+ return rvalue;
480
+ }
481
+
482
+ int fnr_get_int(struct fnr_struct * namelist_struct, const char * namelist, const char * variable, int * value)
483
+ {
484
+ char * str_value;
485
+ int scfrvalue=0;
486
+ int rvalue;
487
+ rvalue = fnr_get_string(namelist_struct, namelist, variable, &str_value);
488
+ if (FNR_DEBUG) printf("Got string for int\n");
489
+ /*if (rvalue) return rvalue;*/
490
+ if (FNR_DEBUG) printf("Size of value is %d\n", strlen(str_value));
491
+ if (FNR_DEBUG) printf("Str value was %s\n", str_value);
492
+ if (!rvalue) scfrvalue = sscanf(str_value, "%d", value);
493
+ if (FNR_DEBUG) printf("rvalue was %d\n, int is %d\n", rvalue, *value);
494
+ if (!rvalue && !scfrvalue) rvalue = FNR_VARIABLE_SSCANF_ERROR;
495
+ /*else rvalue = 0;*/
496
+ fnr_check_rvalue(namelist, variable, rvalue);
497
+ return rvalue;
498
+ }
499
+
500
+ int fnr_get_bool(struct fnr_struct * namelist_struct, const char * namelist, const char * variable, int * value)
501
+ {
502
+ char * str_value;
503
+ // int scfrvalue=0;
504
+ int rvalue;
505
+ rvalue = fnr_get_string(namelist_struct, namelist, variable, &str_value);
506
+ /*if (rvalue) return rvalue;*/
507
+ if (FNR_DEBUG) printf("Str value was %s\n", str_value);
508
+ if (!rvalue) {
509
+
510
+ regex_t regex_true, regex_false;
511
+ int reti;
512
+
513
+
514
+ /* Compile regular expression */
515
+ reti = regcomp(&regex_true, "^(t|\\.true\\.)$", REG_ICASE|REG_EXTENDED);
516
+ if( reti ){ fprintf(stderr, "Could not compile regex_true\n"); exit(1); }
517
+ reti = regcomp(&regex_false, "^(f|\\.false\\.)$", REG_ICASE|REG_EXTENDED);
518
+ if( reti ){ fprintf(stderr, "Could not compile regex_false\n"); exit(1); }
519
+ reti = regexec(&regex_true, str_value, 0, NULL, 0);
520
+ if (!reti) *value = 1;
521
+ else
522
+ {
523
+ if (FNR_DEBUG) printf("Not True\n");
524
+ reti = regexec(&regex_false, str_value, 0, NULL, 0);
525
+ if (!reti) *value = 0;
526
+ else rvalue=FNR_VARIABLE_SSCANF_ERROR;
527
+ }
528
+ regfree(&regex_true);
529
+ regfree(&regex_false);
530
+ if (FNR_DEBUG) printf("Marker A6\n");
531
+ }
532
+ if (FNR_DEBUG) printf("rvalue was %d\n, int is %d\n", rvalue, *value);
533
+ fnr_check_rvalue(namelist, variable, rvalue);
534
+ return rvalue;
535
+ }
536
+
537
+ int fnr_get_float(struct fnr_struct * namelist_struct, const char * namelist, const char * variable, float * value)
538
+ {
539
+ char * str_value;
540
+ int rvalue;
541
+ int scfrvalue=0;
542
+ rvalue = fnr_get_string(namelist_struct, namelist, variable, &str_value);
543
+ /*if (rvalue) return rvalue;*/
544
+ if (FNR_DEBUG) printf("Str value was %s\n", str_value);
545
+ if (!rvalue) scfrvalue = sscanf(str_value, "%f", value);
546
+ if (FNR_DEBUG) printf("rvalue was %d\n, float is %f\n", rvalue, *value);
547
+ if (!rvalue && !scfrvalue) rvalue = FNR_VARIABLE_SSCANF_ERROR;
548
+ /*else rvalue = 0;*/
549
+ fnr_check_rvalue(namelist, variable, rvalue);
550
+ if (FNR_DEBUG) printf("Marker E9\n");
551
+ return rvalue;
552
+ }
553
+
554
+
555
+ int fnr_get_double(struct fnr_struct * namelist_struct, const char * namelist, const char * variable, double * value)
556
+ {
557
+ char * str_value;
558
+ int rvalue;
559
+ int scfrvalue=0;
560
+ rvalue = fnr_get_string(namelist_struct, namelist, variable, &str_value);
561
+ /*if (rvalue) return rvalue;*/
562
+ if (FNR_DEBUG) printf("Marker E1\n");
563
+ if (FNR_DEBUG) printf("Str value was %s\n, rvalue %d", str_value, rvalue);
564
+ if (!rvalue) scfrvalue = sscanf(str_value, "%lf", value);
565
+ if (FNR_DEBUG) printf("scrvalue was %d\n, double is %f\n", rvalue, *value);
566
+ if (!rvalue && !scfrvalue) rvalue = FNR_VARIABLE_SSCANF_ERROR;
567
+ /*else rvalue = 0;*/
568
+ fnr_check_rvalue(namelist, variable, rvalue);
569
+ return rvalue;
570
+ }
571
+
572
+ void fnr_check_namelist_against_template(struct fnr_struct * namelist_struct, struct fnr_struct * template_struct)
573
+ {
574
+ int i,j;
575
+ for (i=0; i < namelist_struct->n_namelists; i++)
576
+ {
577
+ for (j=0; j < namelist_struct->namelist_sizes[i];j++)
578
+ {
579
+ char * dummy;
580
+ int template_rvalue = fnr_get_string_no_test(template_struct, namelist_struct->namelist_names[i], namelist_struct->variable_names[i][j], &dummy);
581
+ if (FNR_DEBUG) printf("Template return value was %d\n", template_rvalue);
582
+ /*int old_abort = fnr_abort_if_missing;*/
583
+ /*fnr_abort_if_missing = 0;*/
584
+ int rvalue = template_rvalue;
585
+ if (template_rvalue == FNR_NAMELIST_NOT_FOUND) rvalue = FNR_NAMELIST_NOT_IN_TEMPLATE;
586
+ if (template_rvalue == FNR_VARIABLE_NOT_FOUND) rvalue = FNR_VARIABLE_NOT_IN_TEMPLATE;
587
+ fnr_check_rvalue(namelist_struct->namelist_names[i], namelist_struct->variable_names[i][j], rvalue);
588
+ }
589
+ }
590
+ }
591
+
592
+
593
+ const char * FNR_TEMPLATE_STRING = "\n\
594
+ \n\
595
+ &my_namelist\n\
596
+ beta = \"This is some help for beta\"\n\
597
+ /\n\
598
+ \n\
599
+ &my_namelist1\n\
600
+ !asd\n\
601
+ beta = 2.7 ! adadfsa\n\
602
+ asdf = \"xxxsdfa\"\n\
603
+ \n\
604
+ /\n\
605
+ ";
606
+
607
+
608
+ // int main (int argc, char ** argv) {
609
+ // if (argc < 2) fnr_error_message("Please pass the first test input file as the first parameter.", 1);
610
+ //
611
+ // int noah = 1;
612
+ //
613
+ // if (noah)
614
+ // {
615
+ // struct fnr_struct namelist_struct = fnr_read_namelist_file(argv[1]);
616
+ // int Nx;
617
+ // fnr_abort_on_error = 1;
618
+ // fnr_abort_if_missing = 1;
619
+ //
620
+ // if(fnr_get_int(&namelist_struct, "kt_grids_box_parameters", "nx", &Nx)) *&Nx=128;
621
+ // printf("Nx was %d\n", Nx);
622
+ // return(0);
623
+ // }
624
+ //
625
+ // if (argc < 3) fnr_error_message("Please pass the second test input file as the second parameter.", 1);
626
+ // if (FNR_DEBUG) printf("Read namelist template???\n");
627
+ //
628
+ // if (!strcmp(argv[1], "help_variable"))
629
+ // {
630
+ // if (argc < 4) fnr_error_message("Please pass the namelist as the second parameter and the variable as the third.", 1);
631
+ // struct fnr_struct template_struct_help = fnr_read_namelist_string(FNR_TEMPLATE_STRING);
632
+ // if (FNR_DEBUG) printf("Read namelist template successful\n");
633
+ // fnr_abort_on_error = 1;
634
+ // fnr_abort_if_missing = 1;
635
+ // char * help;
636
+ // if (fnr_get_string(&template_struct_help, argv[2], argv[3], &help))
637
+ // printf("No help available");
638
+ // else
639
+ // printf("%s\n", help);
640
+ // exit(0);
641
+ // }
642
+ //
643
+ // struct fnr_struct namelist_struct = fnr_read_namelist_file(argv[1]);
644
+ // /*namelist_struct.check_template = 0;*/
645
+ //
646
+ // fnr_abort_on_error = 1;
647
+ // fnr_abort_if_missing = 1;
648
+ //
649
+ // /* String */
650
+ // /* fnr_get returns 0 if successful */
651
+ // char * collision_model;
652
+ // if (fnr_get_string(&namelist_struct, "collisions_knobs", "collision_model", &collision_model))
653
+ // collision_model = "default";
654
+ // printf("Collison model was %s\n", collision_model);
655
+ //
656
+ // /* Integer */
657
+ // int nx;
658
+ // if (fnr_get_int(&namelist_struct, "kt_grids_box_parameters", "nx", &nx)) nx = 0;
659
+ // printf("nx was %d\n", nx);
660
+ //
661
+ // /* Float */
662
+ // float g_exb;
663
+ // if (fnr_get_float(&namelist_struct, "dist_fn_knobs", "g_exb", &g_exb)) g_exb = 4.0;
664
+ // printf("g_exb was %f\n", g_exb);
665
+ //
666
+ // /* Double */
667
+ // double phiinit;
668
+ // if (fnr_get_double(&namelist_struct, "init_g_knobs", "phiinit", &phiinit)) phiinit = 0.0;
669
+ // printf("phiinit was %f\n", phiinit);
670
+ //
671
+ // /*Bool*/
672
+ // int write_phi_over_time;
673
+ // if (fnr_get_bool(&namelist_struct, "gs2_diagnostics_knobs", "write_phi_over_time", &write_phi_over_time)) write_phi_over_time = 0;
674
+ // printf("write_phi_over_time was %d\n", write_phi_over_time);
675
+ //
676
+ //
677
+ // /*Fails*/
678
+ // /*if (fnr_get_double(&namelist_struct, "init_g_knobs", "hiinit", &phiinit)) phiinit = 0.0;*/
679
+ // /*printf("phiinit was %f\n", phiinit);*/
680
+ //
681
+ // printf("Success!\n");
682
+ //
683
+ //
684
+ // struct fnr_struct namelist_struct_with_template = fnr_read_namelist_file(argv[2]);
685
+ // if (FNR_DEBUG) printf("Finished reading second namelist\n\n");
686
+ // struct fnr_struct template_struct = fnr_read_namelist_string(FNR_TEMPLATE_STRING);
687
+ //
688
+ // fnr_abort_on_error = 1;
689
+ // fnr_abort_if_missing = 0;
690
+ //
691
+ // double beta = 1.2;
692
+ // if (fnr_get_double(&namelist_struct_with_template, "my_namelist1", "beta", &beta)) beta = 0.5;
693
+ // printf("beta was %e\n", beta);
694
+ //
695
+ // fnr_check_namelist_against_template(&namelist_struct_with_template, &template_struct);
696
+ //
697
+ // fnr_free(&namelist_struct);
698
+ // fnr_free(&namelist_struct_with_template);
699
+ // fnr_free(&template_struct);
700
+ // }
701
+ //
702
+ //
703
+ //
704
+ //
705
+ //
706
+
707
+ int main(int argc, char* argv[]){
708
+ string line;
709
+ cout << "Starting..." << endl;
710
+
711
+
712
+ char* input_file_name = argv[1]; //Get the input file name from the command line
713
+ cout << input_file_name << endl;
714
+
715
+ struct fnr_struct namelist_file;
716
+
717
+ namelist_file = fnr_read_namelist_file(input_file_name);
718
+
719
+ int calculate_sides; //Should the program calculate the area of the sides of the cube?
720
+
721
+ if (fnr_get_int(&namelist_file, "cubecalc", "calculate_sides", &calculate_sides)) calculate_sides = 0;
722
+ cout << calculate_sides << endl;
723
+
724
+ int must_sleep;
725
+ if (fnr_get_int(&namelist_file, "cubecalc", "must_sleep", &must_sleep)) must_sleep = 0;
726
+
727
+ if (must_sleep){ //It has been told to sleep for a time
728
+ bool cont = true;
729
+ time_t start_t;
730
+ time(&start_t);
731
+ while (cont){
732
+ time_t new_t;
733
+ time(&new_t);
734
+ cont = (new_t < (start_t + must_sleep * 1.0));
735
+ }
736
+ }
737
+
738
+ float* edges = new float[3];
739
+ if (fnr_get_float(&namelist_file, "cubecalc", "width", &edges[0])) edges[0] = 1.0;
740
+ if (fnr_get_float(&namelist_file, "cubecalc", "depth", &edges[1])) edges[1] = 1.0;
741
+ if (fnr_get_float(&namelist_file, "cubecalc", "height", &edges[2])) edges[2] = 1.0;
742
+ printf("edges[0] %f\n", edges[0]);
743
+
744
+
745
+ FILE* output = fopen("results.txt", "w"); //Write the volume to the output file
746
+ fprintf(output, "Volume was %f", edges[0] * edges[1] * edges[2]);
747
+ fclose(output);
748
+
749
+ if (calculate_sides == 1){ //If it has been told to calculate the sides
750
+ cout << "calculating sides" << endl;
751
+ FILE* sides = fopen("sides.txt", "w");
752
+ for(int i=0; i<3; i++){
753
+ cout << "Side " << i << ": " << edges[(i%3)] * edges[((i+1)%3)] << endl;
754
+ fprintf(sides, "The area of side %d is %f\n", i, edges[i%3] * edges[(i+1)%3]);
755
+ }
756
+ fclose(sides);
757
+ }
758
+ }
759
+
@@ -21,6 +21,7 @@ $coderunner_command = "#{$ruby_command} -I lib/ lib/coderunner.rb"
21
21
  #raise "Couldn't build test program using #{string}" unless system string
22
22
  #end
23
23
 
24
+ if true
24
25
  class TestSubmission < Test::Unit::TestCase
25
26
  def setup
26
27
  string = $cpp_command + ' ../cubecalc.cc -o cubecalc'
@@ -349,6 +350,7 @@ EOF
349
350
  end # if ENV['LATEX']
350
351
 
351
352
  end # class TestCodeRunner
353
+ end # if false/true
352
354
 
353
355
  #class TestFortranNamelist < Test::Unit::TestCase
354
356
  ##require 'gs2crmod'
@@ -359,3 +361,33 @@ end # class TestCodeRunner
359
361
  #end
360
362
  #end
361
363
  #end
364
+ #
365
+ #
366
+ ENV['CR_NON_INTERACTIVE'] = 'true'
367
+ class TestFortranNamelistC < Test::Unit::TestCase
368
+ def setup
369
+ end
370
+ def test_synchronise_variables
371
+ #FileUtils.rm('lib/cubecalccrmod/namelists.rb')
372
+ CodeRunner.setup_run_class('cubecalc', modlet: 'with_namelist')
373
+ assert_equal(File.read('test/cubecalc_namelist.cc').size+1, CodeRunner::Cubecalc::WithNamelist.get_aggregated_source_code_text('test').size)
374
+ CodeRunner::Cubecalc::WithNamelist.synchronise_variables('test')
375
+ end
376
+ def tfolder
377
+ 'test/submit_with_namelist'
378
+ end
379
+ def test_submit
380
+ CodeRunner.setup_run_class('cubecalc', modlet: 'with_namelist')
381
+ assert_system("#$cpp_command test/cubecalc_namelist.cc -o test/cubecalc_namelist")
382
+ CodeRunner::Cubecalc::WithNamelist.make_new_defaults_file('cubecalctest', 'test/cubecalc.in')
383
+ FileUtils.mv('cubecalctest_defaults.rb', CodeRunner::Cubecalc::WithNamelist.rcp.user_defaults_location + '/cubecalctest_defaults.rb')
384
+ FileUtils.makedirs(tfolder)
385
+ CodeRunner.submit(C: 'cubecalc', m: 'with_namelist', Y: tfolder, X: Dir.pwd + '/test/cubecalc_namelist', D: 'cubecalctest')
386
+ CodeRunner.status(Y: tfolder)
387
+ runner = CodeRunner.fetch_runner(Y: tfolder)
388
+ assert_equal(86.35, runner.run_list[1].volume.round(2))
389
+ FileUtils.rm_r(tfolder)
390
+ FileUtils.rm(CodeRunner::Cubecalc::WithNamelist.rcp.user_defaults_location + '/cubecalctest_defaults.rb')
391
+ FileUtils.rm('test/cubecalc_namelist')
392
+ end
393
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coderunner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.19
4
+ version: 0.13.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-07 00:00:00.000000000 Z
12
+ date: 2013-08-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: graphkit
@@ -206,6 +206,7 @@ files:
206
206
  - lib/coderunner/class_methods.rb
207
207
  - lib/coderunner/feedback.rb
208
208
  - lib/coderunner/fortran_namelist.rb
209
+ - lib/coderunner/fortran_namelist_c.rb
209
210
  - lib/coderunner/graphs_and_films.rb
210
211
  - lib/coderunner/heuristic_run_methods.rb
211
212
  - lib/coderunner/instance_methods.rb
@@ -236,8 +237,13 @@ files:
236
237
  - lib/cubecalccrmod/default_modlets/empty_defaults.rb
237
238
  - lib/cubecalccrmod/defaults_files/cubecalc_defaults.rb
238
239
  - lib/cubecalccrmod/defaults_files/sleep_defaults.rb
240
+ - lib/cubecalccrmod/deleted_variables.rb
239
241
  - lib/cubecalccrmod/empty.rb
242
+ - lib/cubecalccrmod/namelists.rb
240
243
  - lib/cubecalccrmod/sleep.rb
244
+ - lib/cubecalccrmod/with_namelist.rb
245
+ - test/cubecalc.in
246
+ - test/cubecalc_namelist.cc
241
247
  - test/fortran_namelist.in
242
248
  - test/helper.rb
243
249
  - test/old_test.rb