dgd-tools 0.1.2 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "ChatTheatre Kernellib",
3
+ "git": {
4
+ "url": "https://github.com/ChatTheatre/kernellib.git",
5
+ "branch": "master"
6
+ },
7
+ "paths": {
8
+ "src/include/kernel": "include/kernel",
9
+ "src/include/*.h": "include",
10
+ "src/kernel": "kernel"
11
+ }
12
+ }
@@ -16,7 +16,6 @@ module DGD::Manifest
16
16
  }
17
17
  KERNEL_PATHS = KERNEL_PATH_MAP.values
18
18
  DEFAULT_KERNELLIB_URL = "https://github.com/ChatTheatre/kernellib"
19
-
20
19
  GENERATED_ROOT = ".root"
21
20
 
22
21
  def self.system_call(cmd)
@@ -30,24 +29,26 @@ module DGD::Manifest
30
29
  # This is a repo of everything DGD Manifest saves between runs.
31
30
  # It includes downloaded Git repos, Goods files and more.
32
31
  class Repo
33
- attr_reader :manifest_dir
32
+ attr_reader :shared_dir
34
33
 
35
34
  def initialize
35
+ @no_manifest_file = true
36
36
  @home = ENV["HOME"]
37
- @manifest_dir = "#{@home}/.dgd-tools"
38
- Dir.mkdir(@manifest_dir) unless File.directory?(@manifest_dir)
37
+ @shared_dir = "#{@home}/.dgd-tools"
38
+ Dir.mkdir(@shared_dir) unless File.directory?(@shared_dir)
39
+
39
40
  ["git", "goods"].each do |subdir|
40
- full_subdir = "#{@manifest_dir}/#{subdir}"
41
+ full_subdir = "#{@shared_dir}/#{subdir}"
41
42
  Dir.mkdir(full_subdir) unless File.directory?(full_subdir)
42
43
  end
43
44
 
44
- unless File.exist?("#{@manifest_dir}/dgd/bin/dgd")
45
- dgd_dir = "#{@manifest_dir}/dgd"
45
+ unless File.exist?("#{@shared_dir}/dgd/bin/dgd")
46
+ dgd_dir = "#{@shared_dir}/dgd"
46
47
  if File.directory?(dgd_dir)
47
48
  # Not clear to me what to do here...
48
49
  else
49
50
  DGD::Manifest.system_call("git clone https://github.com/ChatTheatre/dgd.git #{dgd_dir}")
50
- Dir.chdir("#{@manifest_dir}/dgd/src") do
51
+ Dir.chdir("#{@shared_dir}/dgd/src") do
51
52
  DGD::Manifest.system_call(DGD_BUILD_COMMAND)
52
53
  end
53
54
  end
@@ -60,77 +61,120 @@ module DGD::Manifest
60
61
  end
61
62
 
62
63
  def manifest_file(path)
63
- raise "Already have a dgd.manifest file!" if @manifest_file
64
+ raise "Already have a dgd.manifest file!" unless @no_manifest_file
64
65
 
66
+ @no_manifest_file = false
65
67
  @manifest_file ||= AppFile.new(self, path)
66
68
  end
67
69
 
68
- def assemble_app(location)
69
- dgd_root = "#{File.expand_path(location)}/#{GENERATED_ROOT}"
70
- app_path = "#{File.expand_path(location)}/#{@manifest_file.app_root}"
71
- FileUtils.rm_rf(dgd_root)
72
- FileUtils.cp_r(app_path, dgd_root)
70
+ protected
73
71
 
74
- write_config_file("#{location}/dgd.config")
75
- specs = @manifest_file.specs
72
+ # This includes files to assemble... But also subdirectories and commands. This format is
73
+ # unstable and ugly, and should not be exposed to outside parties who might later depend on it.
74
+ def assembly_operations(location)
75
+ operations = []
76
76
 
77
- copies = []
77
+ raise("No manifest file!") if @no_manifest_file
78
78
 
79
- specs.each do |spec|
80
- git_repo = spec.source
81
- git_repo.use_details(spec.source_details)
79
+ @manifest_file.specs.each do |spec|
80
+ spec_git_repo = spec.source
81
+ spec_git_repo.use_details(spec.source_details) # This sets things like checked-out branch
82
82
 
83
83
  spec.paths.each do |from, to|
84
- from_path = "#{git_repo.local_dir}/#{from}"
85
- to_path = "#{dgd_root}/#{to}"
86
- copies << [from_path, to_path]
84
+ # Note: spec_git_repo.local_dir is an absolute path.
85
+ from_path = "#{spec_git_repo.local_dir}/#{from}"
86
+ if File.directory?(from_path)
87
+ files = Dir["#{from_path}/**/*"].to_a + Dir["#{from_path}/**/.*"].to_a
88
+ dirs = files.select { |file| File.directory?(file) }
89
+ non_dirs = files - dirs
90
+ operations << { cmd: "cp", from: from_path, to: to, dirs: dirs, non_dirs: non_dirs, comment: :single_dir }
91
+ elsif from_path["*"] # If from_path contains at least one asterisk
92
+ components = from.split("/")
93
+ first_wild_idx = components.index { |item| item["*"] }
94
+ no_wild_from_path = components[0..(first_wild_idx-1)].join("/")
95
+ wild_path = components[first_wild_idx..-1].join("/")
96
+
97
+ files = Dir["#{spec_git_repo.local_dir}/#{no_wild_from_path}/#{wild_path}"].to_a
98
+ dirs = files.select { |file| File.directory?(file) }
99
+ dirs += files.map { |f| File.dirname(f) }
100
+ dirs.uniq!
101
+
102
+ non_dirs = files - dirs
103
+ operations << { cmd: "cp", from: "#{spec_git_repo.local_dir}/#{no_wild_from_path}", to: to, dirs: dirs, non_dirs: non_dirs, comment: :path_wildcard }
104
+ else
105
+ # A single file
106
+ operations << { cmd: "cp", from: from_path, to: to, dirs: [], non_dirs: [from_path], comment: :single_file }
107
+ end
108
+ end
109
+ end
110
+
111
+ app_path = "#{File.expand_path(location)}/#{@manifest_file.app_root}"
112
+ app_files = Dir["#{app_path}/**/*"].to_a
113
+ app_dirs = app_files.select { |f| File.directory?(f) }
114
+ app_non_dirs = app_files - app_dirs
115
+ unless app_dirs.empty? && app_non_dirs.empty?
116
+ operations << { cmd: "cp", from: app_path, to: ".", dirs: app_dirs, non_dirs: app_non_dirs, comment: :app_files } # No source
117
+ end
118
+
119
+ operations
120
+ end
121
+
122
+ public
123
+
124
+ def dgd_root(location)
125
+ "#{File.expand_path(location)}/#{GENERATED_ROOT}"
126
+ end
127
+
128
+ def assemble_app(location)
129
+ Dir[File.join(dgd_root(location), "*")].each { |dir| FileUtils.rm_rf dir }
130
+
131
+ write_app_files(location)
132
+ end
133
+
134
+ def update_app(location)
135
+ write_app_files(location) # TODO: maybe check files dates? Some way to do update-only
136
+ end
137
+
138
+ protected
139
+
140
+ def write_app_files(location)
141
+ Dir.chdir(location) do
142
+ write_config_file("#{location}/dgd.config")
143
+ FileUtils.mkdir_p("#{location}/state") # Statedir for statedumps, editor files, etc.
144
+
145
+ assembly_operations(location).each do |sd_hash|
146
+ to_path = "#{dgd_root(location)}/#{sd_hash[:to]}"
147
+
148
+ # Make appropriate dirs, including empty ones
149
+ sd_hash[:dirs].each do |dir|
150
+ FileUtils.mkdir_p dir.sub(sd_hash[:from], to_path)
151
+ end
152
+
153
+ # Copy all files
154
+ sd_hash[:non_dirs].each do |from_file|
155
+ to_file = from_file.sub(sd_hash[:from], "#{dgd_root(location)}/#{sd_hash[:to]}")
156
+ to_dir = File.dirname(to_file)
157
+ FileUtils.mkdir_p to_dir
158
+ FileUtils.cp from_file, to_file
159
+ end
87
160
  end
88
161
  end
162
+ end
89
163
 
90
- copies.sort_by { |c| c[1] }.each do |from_path, to_path|
91
- to_dir = to_path.split("/")[0..-2].join("/")
92
- FileUtils.mkdir_p to_dir
93
- STDERR.puts "COPYING #{from_path.inspect} #{to_path.inspect}"
94
- FileUtils.cp_r(from_path, to_path)
164
+ public
165
+
166
+ def precheck(location)
167
+ all_files = assembly_operations(location).flat_map { |sd| sd[:non_dirs] }
168
+
169
+ if all_files.size != all_files.uniq.size
170
+ repeated = all_files.uniq.select { |f| all_files.count(f) > 1 }
171
+ raise "Error in dgd.manifest! Repeated files: #{repeated.inspect} / #{all_files.inspect}"
95
172
  end
96
173
  end
97
174
 
98
175
  def write_config_file(path)
99
176
  File.open(path, "wb") do |f|
100
- f.write <<CONTENTS
101
- /* These are SkotOS limits. They are enormous. They should
102
- be configurable but they are not yet. */
103
- telnet_port = ([
104
- "*":50100 /* telnet port number */
105
- ]);
106
- binary_port = ([
107
- "*":50110 /* Failsafe */
108
- ]); /* binary ports */
109
- directory = "./#{GENERATED_ROOT}";
110
-
111
- users = 100; /* max # of users */
112
- editors = 40; /* max # of editor sessions */
113
- ed_tmpfile = "../state/ed"; /* proto editor tmpfile */
114
- swap_file = "../state/swap"; /* swap file */
115
- swap_size = 1048576; /* # sectors in swap file */
116
- sector_size = 512; /* swap sector size */
117
- swap_fragment = 4096; /* fragment to swap out */
118
- static_chunk = 64512; /* static memory chunk */
119
- dynamic_chunk = 261120; /* dynamic memory chunk */
120
- dump_file = "../state/dump"; /* dump file */
121
- dump_interval = 3600; /* dump interval */
122
-
123
- typechecking = 2; /* highest level of typechecking */
124
- include_file = "/include/std.h"; /* standard include file */
125
- include_dirs = ({ "/include", "~/include" }); /* directories to search */
126
- auto_object = "/kernel/lib/auto"; /* auto inherited object */
127
- driver_object = "/kernel/sys/driver"; /* driver object */
128
- create = "_F_create"; /* name of create function */
129
-
130
- array_size = 16384; /* max array size */
131
- objects = 262144; /* max # of objects */
132
- call_outs = 16384; /* max # of call_outs */
133
- CONTENTS
177
+ f.write @manifest_file.dgd_config.as_file
134
178
  end
135
179
  end
136
180
  end
@@ -145,7 +189,7 @@ CONTENTS
145
189
  @git_url = git_url
146
190
  @repo = repo
147
191
  local_path = git_url.tr("/\\", "_")
148
- @local_dir = "#{@repo.manifest_dir}/git/#{local_path}"
192
+ @local_dir = "#{@repo.shared_dir}/git/#{local_path}"
149
193
 
150
194
  if File.directory?(@local_dir)
151
195
  Dir.chdir(@local_dir) do
@@ -157,19 +201,17 @@ CONTENTS
157
201
  end
158
202
 
159
203
  def default_branch
160
- return @default_branch if @default_branch
161
- output = `git rev-parse --abbrev-ref origin/HEAD`.chomp
162
- @default_branch = output.gsub(/^origin\//, "")
204
+ @default_branch ||= `git rev-parse --abbrev-ref origin/HEAD`.chomp.gsub(/^origin\//, "")
163
205
  end
164
206
 
165
207
  def use_details(details)
166
208
  if details["branch"]
167
209
  Dir.chdir(@local_dir) do
168
- DGD::Manifest.system_call("git checkout #{details["branch"]}")
210
+ DGD::Manifest.system_call("git checkout #{details["branch"]} && git pull")
169
211
  end
170
212
  else
171
213
  Dir.chdir(@local_dir) do
172
- DGD::Manifest.system_call("git checkout #{default_branch}")
214
+ DGD::Manifest.system_call("git checkout #{default_branch} && git pull")
173
215
  end
174
216
  end
175
217
  end
@@ -179,47 +221,64 @@ CONTENTS
179
221
  attr_reader :path
180
222
  attr_reader :repo
181
223
  attr_reader :specs
182
- attr_reader :app_root
224
+ attr_reader :dgd_config
183
225
 
184
226
  def initialize(repo, path)
185
227
  @path = path
186
228
  @repo = repo
187
229
  raise("No such dgd.manifest file as #{path.inspect}!") unless File.exist?(path)
188
- contents = JSON.load(File.read(path))
230
+ contents = AppFile.parse_manifest_file(path)
189
231
 
190
232
  read_manifest_file(contents)
191
233
 
192
- @app_root = contents["app_root"] || "app"
193
-
194
234
  output_paths = @specs.flat_map { |s| s.paths.values }
195
235
  unless output_paths == output_paths.uniq
196
236
  repeated_paths = output_paths.select { |p| output_paths.count(p) > 1 }
197
237
  raise "Repeated (conflicting?) paths in dgd.manifest! #{repeated_paths.inspect}"
198
238
  end
199
239
 
200
- # Make sure the dgd.manifest file overrides either no kernel paths or both/all
201
- if KERNEL_PATHS.any? { |kp| output_paths.include?(kp) }
202
- unless KERNEL_PATHS.all? { |kp| output_paths.include?(kp) }
203
- raise "dgd.manifest file #{path.inspect} includes some Kernel Library paths but not all! All needed: #{KERNEL_PATHS}!"
204
- end
205
- puts "This dgd.manifest file overrides the Kernel Library with its own."
206
- else
207
- puts "This dgd.manifest needs the default Kernel Library."
208
- # This app has specified no kernellib paths -- add them
209
- git_repo = @repo.git_repo(DEFAULT_KERNELLIB_URL)
210
- klib_spec = GoodsSpec.new @repo, name: "default Kernel Library",
211
- source: git_repo, paths: KERNEL_PATH_MAP
212
- specs.unshift klib_spec
213
- end
240
+ ## Make sure the dgd.manifest file overrides either no kernel paths or both/all
241
+ #if KERNEL_PATHS.any? { |kp| output_paths.include?(kp) }
242
+ # unless KERNEL_PATHS.all? { |kp| output_paths.include?(kp) }
243
+ # raise "dgd.manifest file #{path.inspect} includes some Kernel Library paths but not all! All needed: #{KERNEL_PATHS}!"
244
+ # end
245
+ # puts "This dgd.manifest file overrides the Kernel Library with its own."
246
+ #else
247
+ # puts "This dgd.manifest needs the default Kernel Library."
248
+ # # This app has specified no kernellib paths -- add them
249
+ # spec_git_repo = @repo.git_repo(DEFAULT_KERNELLIB_URL)
250
+ # klib_spec = GoodsSpec.new @repo, name: "default Kernel Library",
251
+ # source: spec_git_repo, paths: KERNEL_PATH_MAP
252
+ # specs.unshift klib_spec
253
+ #end
214
254
 
215
255
  nil
216
256
  end
217
257
 
258
+ # Load the JSON and then remove comments
259
+ def self.parse_manifest_file(path)
260
+ contents = JSON.parse(File.read path)
261
+ remove_comments!(contents)
262
+ contents
263
+ end
264
+
265
+ def self.remove_comments!(items)
266
+ if items.is_a?(Hash)
267
+ items.delete_if { |k, v| k[0] == "#" }
268
+ items.values.each { |v| remove_comments!(v) }
269
+ elsif items.is_a?(Array)
270
+ items.delete_if { |i| i.is_a?(String) && i[0] == "#" }
271
+ items.each { |i| remove_comments!(i) }
272
+ end
273
+ end
274
+
218
275
  def read_manifest_file(contents)
219
276
  raise "Expected a top-level JSON object in dgd.manifest!" unless contents.is_a?(Hash)
220
277
 
221
278
  @specs = []
222
279
 
280
+ @dgd_config = DGDRuntimeConfig.new (contents["config"] || {})
281
+
223
282
  if contents["unbundled_goods"]
224
283
  raise "Unbundled_goods must be an array!" unless contents["unbundled_goods"].is_a?(Array)
225
284
 
@@ -241,9 +300,15 @@ CONTENTS
241
300
  end
242
301
  end
243
302
 
303
+ def app_root
304
+ @dgd_config.app_root
305
+ end
306
+
244
307
  def unbundled_json_to_spec(fields)
245
308
  source = nil
246
309
  source_details = nil
310
+ dependencies = []
311
+
247
312
  if fields["git"]
248
313
  raise "A git source requires a git url: #{fields.inspect}!" unless fields["git"]["url"]
249
314
  source = @repo.git_repo(fields["git"]["url"])
@@ -256,7 +321,23 @@ CONTENTS
256
321
  raise "Paths in Goods files must map strings to strings! #{fields["paths"].inspect}"
257
322
  end
258
323
 
259
- spec = GoodsSpec.new(@repo, name: fields["name"], source: source, source_details: source_details, paths: fields["paths"])
324
+ if fields["dependencies"]
325
+ # For now, permit a single string as a dependency.
326
+ fields["dependencies"] = [ fields["dependencies"] ] if fields["dependencies"].is_a?(String)
327
+
328
+ fields["dependencies"].each do |dep|
329
+ if dep.is_a?(String)
330
+ dependencies.push "url" => dep
331
+ elsif dep.is_a?(Hash)
332
+ raise "Currently only URL-based dependencies on Goods files are supported!" unless dep["url"]
333
+ dependencies.push dep
334
+ else
335
+ raise "Unexpected dependency type #{dep.class} when parsing DGD Manifest specs, item: #{dep.inspect}"
336
+ end
337
+ end
338
+ end
339
+
340
+ spec = GoodsSpec.new(@repo, name: fields["name"], source: source, source_details: source_details, paths: fields["paths"], dependencies: dependencies)
260
341
  return spec
261
342
  end
262
343
  end
@@ -267,8 +348,9 @@ CONTENTS
267
348
  attr_reader :source
268
349
  attr_reader :source_details
269
350
  attr_reader :paths
351
+ attr_reader :dependencies
270
352
 
271
- def initialize(repo, name:, source:, source_details: {}, paths:)
353
+ def initialize(repo, name:, source:, source_details: {}, paths:, dependencies:)
272
354
  @repo = repo
273
355
  @name = name
274
356
  @source = source
@@ -281,6 +363,211 @@ CONTENTS
281
363
  end
282
364
 
283
365
  @paths = cleaned_paths
366
+ @dependencies = dependencies
367
+ end
368
+ end
369
+
370
+ class AppDirectory
371
+ attr_reader :location
372
+ attr_accessor :name
373
+
374
+ DEFAULT_FILE_LOCATIONS = {
375
+ "manifest" => "dgd.manifest",
376
+ "gitignore" => ".gitignore",
377
+ "gems_rb" => "gems.rb",
378
+ }
379
+ DEFAULT_EMPTY_DIRS = [ "app", "state" ]
380
+
381
+ def initialize(directory)
382
+ @location = directory
383
+ end
384
+
385
+ def gitignore_contents
386
+ <<~FILE_CONTENTS
387
+ # DGD Manifest files
388
+ .root
389
+ dgd.config
390
+ state/*
391
+ FILE_CONTENTS
392
+ end
393
+
394
+ def manifest_contents
395
+ <<FILE_CONTENTS
396
+ {
397
+ "name": "#{@name}",
398
+ "version": "0.1.0",
399
+ "description": "TODO: put description here",
400
+ "app_root": "app",
401
+ "goods": [
402
+ "# This is an example goods file - substitute your own.",
403
+ "https://raw.githubusercontent.com/noahgibbs/dgd-tools/main/goods/skotos_httpd.goods"
404
+ ],
405
+ "unbundled_goods": [
406
+ {
407
+ "#": "this is an example of unbundled goods - substitute your own",
408
+ "name": "kernellib",
409
+ "git": {
410
+ "url": "https://github.com/ChatTheatre/kernellib.git",
411
+ "branch": "master"
412
+ },
413
+ "paths": {
414
+ "src/doc/kernel": "doc/kernel",
415
+ "src/include/kernel": "include/kernel",
416
+ "src/include/*.h": "include",
417
+ "src/kernel": "kernel"
418
+ }
419
+ }
420
+ ]
421
+ }
422
+ FILE_CONTENTS
423
+ end
424
+
425
+ def gems_rb_contents
426
+ <<~FILE_CONTENTS
427
+ source "https://rubygems.org"
428
+
429
+ gem "dgd-tools", ">= #{DGD::VERSION}"
430
+ FILE_CONTENTS
431
+ end
432
+
433
+ def create!
434
+ if File.exist?(@location) && (!File.directory?(@location) || Dir["#{@location}/**"].size != 0)
435
+ raise "Cannot create a new DGD manifest project over a file or in an existing non-empty directory!"
436
+ end
437
+
438
+ puts "Creating new DGD manifest project at #{@location}..."
439
+ FileUtils.mkdir_p @location
440
+ Dir.chdir @location do
441
+ DEFAULT_FILE_LOCATIONS.each do |file_desc, file_location|
442
+ File.open(file_location, "wb") do |f|
443
+ contents = send("#{file_desc}_contents")
444
+ f.write(contents)
445
+ end
446
+ end
447
+
448
+ DEFAULT_EMPTY_DIRS.each do |dir|
449
+ FileUtils.mkdir dir
450
+ FileUtils.touch File.join(dir, ".keep")
451
+ end
452
+
453
+ result = system "bundle"
454
+ raise("Could not run bundler to install dgd-tools for #{@location}!") unless result
455
+
456
+ result = system "bundle exec dgd-manifest install"
457
+ raise("Error when running dgd-manifest for #{@location}!") unless result
458
+ end
459
+
460
+ puts "Successfully created project at #{@location}."
461
+ end
462
+ end
463
+
464
+ class DGDRuntimeConfig
465
+ attr_reader :app_root
466
+
467
+ DEFAULT_CONFIG = {
468
+ users: 100,
469
+ editors: 40,
470
+ swap_size: 1048576,
471
+ sector_size: 512,
472
+ swap_fragment: 4096,
473
+ static_chunk: 64512,
474
+ dynamic_chunk: 261120,
475
+ dump_interval: 3600,
476
+ typechecking: 2,
477
+ include_file: "/include/std.h",
478
+ include_dirs: ["/include", "~/include"],
479
+ auto_object: "/kernel/lib/auto",
480
+ driver_object: "/kernel/sys/driver",
481
+ create: "_F_create",
482
+ array_size: 16384,
483
+ objects: 262144,
484
+ call_outs: 16384,
485
+ }
486
+ CONFIG_KEYS = DEFAULT_CONFIG.keys.map(&:to_s) + [ "app_root", "ports", "telnet_ports", "dump_file", "statedir" ]
487
+
488
+ def initialize(config_data)
489
+ @app_root = config_data["app_root"] || "app"
490
+ @ports = {
491
+ "*" => 50100,
492
+ }
493
+ @telnet_ports = {
494
+ "*" => 50110,
495
+ }
496
+ @statedir = config_data["statedir"] || "state"
497
+ @dump_file = if config_data["dump_file"]
498
+ "../" + config_data["dump_file"]
499
+ else
500
+ "../#{@statedir}/dump"
501
+ end
502
+ @config = DEFAULT_CONFIG.dup
503
+
504
+ @raw_data = config_data
505
+ @config.keys.each do |prop|
506
+ # For now, assume and require that JSON data is the correct type if present
507
+ @config[prop] = config_data[prop.to_s] if config_data[prop.to_s]
508
+ end
509
+ unexpected_config_keys = config_data.keys - CONFIG_KEYS
510
+ unless unexpected_config_keys.empty?
511
+ raise "Unexpected key names in DGD configuration: #{unexpected_config_keys.inspect}!"
512
+ end
513
+
514
+ if config_data["telnet_ports"]
515
+ @telnet_ports = config_to_ports(config_data["telnet_ports"])
516
+ end
517
+ if config_data["ports"]
518
+ @ports = config_to_ports(config_data["ports"])
519
+ end
520
+ end
521
+
522
+ def config_to_ports(data)
523
+ if data.is_a?(Hash)
524
+ # TODO: verify that keys are IP addr strings and values are legal port numbers
525
+ return data
526
+ elsif data.is_a?(Array)
527
+ # TODO: verify that data is an array of legal integer port numbers
528
+ ports = {}
529
+ data.each { |p| ports["*"] = p }
530
+ return ports
531
+ elsif data.is_a?(Integer)
532
+ return { "*": data }
533
+ else
534
+ raise "dgd-manifest: not sure how to get port data from a #{data.class.name} -- #{data.inspect}!"
535
+ end
536
+ end
537
+
538
+ def as_file
539
+ return <<DGD_CONFIG
540
+ telnet_port = ([
541
+ #{@telnet_ports.map { |ip, p| "#{ip.inspect}:#{p}" }.join(",\n ") }
542
+ ]); /* legacy telnet ports */
543
+ binary_port = ([
544
+ #{@ports.map { |ip, p| "#{ip.inspect}:#{p}" }.join(",\n ") }
545
+ ]); /* binary ports */
546
+ directory = "./#{GENERATED_ROOT}";
547
+
548
+ users = #{@config[:users]}; /* max # of connections */
549
+ editors = #{@config[:editors]}; /* max # of built-in-editor sessions */
550
+ ed_tmpfile = "../#{@statedir}/ed"; /* proto editor tmpfile */
551
+ swap_file = "../#{@statedir}/swap"; /* swap file */
552
+ swap_size = #{@config[:swap_size]}; /* # sectors in swap file */
553
+ sector_size = #{@config[:sector_size]}; /* swap sector size */
554
+ swap_fragment = #{@config[:swap_fragment]}; /* fragment to swap out */
555
+ static_chunk = #{@config[:static_chunk]}; /* static memory chunk */
556
+ dynamic_chunk = #{@config[:dynamic_chunk]}; /* dynamic memory chunk */
557
+ dump_file = #{@dump_file.inspect}; /* dump file */
558
+ dump_interval = #{@config[:dump_interval]}; /* expected statedump interval in seconds */
559
+
560
+ typechecking = #{@config[:typechecking]}; /* level of typechecking (2 is highest) */
561
+ include_file = #{@config[:include_file].inspect}; /* standard include file */
562
+ include_dirs = ({ #{@config[:include_dirs].map(&:inspect).join(", ")} }); /* directories to search */
563
+ auto_object = #{@config[:auto_object].inspect}; /* auto inherited object */
564
+ driver_object = #{@config[:driver_object].inspect}; /* driver object */
565
+ create = #{@config[:create].inspect}; /* name of create function */
566
+
567
+ array_size = #{@config[:array_size]}; /* max array size */
568
+ objects = #{@config[:objects]}; /* max # of objects */
569
+ call_outs = #{@config[:call_outs]}; /* max # of callouts */
570
+ DGD_CONFIG
284
571
  end
285
572
  end
286
573
  end