annotate interps/clc-intercal/CLC-INTERCAL-Base-1.-94.-2/INTERCAL/Generate.pm @ 9288:2bb3ea90aa0c

<oerjan> slwd scow//s/[.].*/./
author HackBot
date Sat, 15 Oct 2016 15:06:04 +0000
parents 859f9b4339e6
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
996
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
1 package Language::INTERCAL::Generate;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
2
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
3 # Creates automatically generated files (ByteCode, Splats) from descriptions
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
4
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
5 # This file is part of CLC-INTERCAL
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
6
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
7 # Copyright (c) 2007-2008 Claudio Calvelli, all rights reserved.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
8
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
9 # CLC-INTERCAL is copyrighted software. However, permission to use, modify,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
10 # and distribute it is granted provided that the conditions set out in the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
11 # licence agreement are met. See files README and COPYING in the distribution.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
12
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
13 # Usage: perl -MLanguage::INTERCAL::Generate -e 'Generate()' [INPUT [OUTPUT]]
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
14
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
15 # If a file contains the string @@SKIPME@@ this module just copies it unchanged,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
16 # this allows it to process itself.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
17
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
18 # INPUT (or standard input) can contain the following commands to generate
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
19 # data-dependent lines:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
20
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
21 # @@DATA filename@@
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
22 # loads filename as a data SPEC (see below)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
23
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
24 # (prefix)@@FILL GROUP PRE FIELD POST SIZE SEP@@(suffix)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
25 # fills a line with as many elements from GROUP as possible, then repeats
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
26 # with another line until all elements of GROUP have been listed; each
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
27 # element will be taken from the given FIELD and the line lenght will
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
28 # not exceed SIZE. (prefix) and (suffix) are added at the start and
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
29 # the end of each line generated; PRE and POST are added before and
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
30 # after each element; SEP is added between elements in the same line.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
31 # The data is sorted by the given FIELD. For example:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
32 # [@@FILL SPLATS 'SP_' NAME '' 76 '/'@@]
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
33 # may generate:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
34 # [SP_BCMATCH/SP_CHARSET/SP_CIRCULAR/SP_COMMENT/SP_CREATION/SP_DIGITS]
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
35 # [SP_INVALID/SP_IOTYPE/SP_JUNK/SP_NONUMBER/SP_NOSUCHCHAR/SP_ROMAN/SP_SPOTS]
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
36 # [SP_THREESPOT/SP_TODO]
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
37
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
38 # (prefix)@@ALL GROUP FIELD@@(suffix)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
39 # generates as many lines as there are elements of GROUP; each line is
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
40 # generated by replacing any @@FIELD@@ in (prefix) and (suffix) with
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
41 # the corresponding data, and replacing the @@ALL...@@ with the
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
42 # value of FIELD. The data is sorted by the FIELD. For example:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
43 # [@@NUMBER@@ SP_@@ALL SPLATS NAME@@]
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
44 # may generate:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
45 # [578 SP_BCMATCH]
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
46 # ...
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
47 # [1 SP_TODO]
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
48 # to insert a literal whirlpool where this can cause confusion use
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
49 # @@WHIRLPOOL@@. Note that if your GROUP has a field named WHIRLPOOL
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
50 # this will not be accessible.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
51
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
52 # @@MULTI GROUP FIELD@@
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
53 # (content)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
54 # @@MULTI@@
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
55 # is a multiline version of @@ALL...@@: produces a block for each
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
56 # element of group, sorted by FIELD, in which each line of (content)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
57 # is subject to the same substitution rules as @@ALL@@. Does not
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
58 # automatically insert the FIELD in the output, use @@FIELD@@ for
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
59 # that. A special syntax @@FIELD SIZE@@ allows to "fold" FIELD:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
60 # for a multiline field containing blank lines, each block is
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
61 # folded separately.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
62
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
63 # SPEC contains data specification in the form:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
64 # @GROUP NAME FIELD...
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
65 # DATA
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
66 # @END [NAME]
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
67
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
68 # Each FIELD definition has the form NAME=TYPE where TYPE is m (multiline),
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
69 # 'd' (digits), 's' (string), 'w' (word) or '@TYPE' (array - cannot be
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
70 # used for multiline).
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
71
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
72 # Each line of DATA is one record followed by the contents of a multiline
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
73 # field, if present; alternatively the special line @SOURCE GROUP will
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
74 # include the whole of another group. The contents of the multiline field
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
75 # must be more indented than the record they refer to and than the record
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
76 # that follows, for example:
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
77 # DATA
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
78 # multiline 1
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
79 # multiline 2
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
80 # muitiline 3
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
81 # NEXT RECORD
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
82 # if a line in a multiline field starts with # it will be interpreted as
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
83 # a comment and ignored; if it starts with @ it will be interpreted as
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
84 # an escape (e.g. @END). These can be escaped with a backslash, which
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
85 # will be removed from the beginning of line. Note that backslashes
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
86 # anywhere else in the multiline fields are not touched.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
87 # All lines in a multiline field will be joined together, separated by
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
88 # a single space (the above sequence produces "multiline 1 multiline 2
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
89 # multiline 3"), except a blank line which produces a double newline
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
90 # in the field.
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
91
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
92 use strict;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
93
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
94 use Carp;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
95 use File::Spec;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
96
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
97 use vars qw($VERSION $PERVERSION);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
98 ($VERSION) = ($PERVERSION = "CLC-INTERCAL/Base INTERCAL/Generate.pm 1.-94.-2") =~ /\s(\S+)$/;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
99
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
100 my $data_suffix = '.Data';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
101 my %groups;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
102
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
103 sub Generate {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
104 @ARGV >= 0 && @ARGV <= 2 or croak "Usage: Generate [INPUT [OUTPUT]]";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
105 my ($input, $output) = @ARGV;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
106
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
107 %groups = ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
108
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
109 # translate INPUT into OUTPUT
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
110 @ARGV = defined $input ? ($input) : ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
111 if (defined $output) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
112 open(STDOUT, '>', $output)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
113 or die "$output: $!";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
114 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
115 my $skipme = 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
116 while (<>) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
117 my $orig = $_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
118 if (/\@\@SKIPME\@\@/) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
119 $skipme = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
120 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
121 if ($skipme) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
122 print;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
123 next;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
124 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
125 if (/^\s*\@\@DATA\s+(.*?)\@\@$/) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
126 load_spec($1 . $data_suffix);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
127 next;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
128 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
129 if (s/^(.*)\@\@FILL\s*//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
130 my $line_pre = $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
131 my $group = get_field($orig, \$_, 'w');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
132 exists $groups{$group}
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
133 or die "Unknown group $group";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
134 my $gp = $groups{$group};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
135 my $item_pre = get_field($orig, \$_, 's');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
136 my $item_name = get_field($orig, \$_, 'w');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
137 exists $gp->{fpos}{$item_name}
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
138 or die "Unknown field $item_name in group $group";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
139 my $item_pos = $gp->{fpos}{$item_name};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
140 my $item_post = get_field($orig, \$_, 's');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
141 my $line_size = get_field($orig, \$_, 'd');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
142 my $item_sep = get_field($orig, \$_, 's');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
143 s/^\@\@// or die "Missing \@\@ after \@\@FILL";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
144 my $line_post = $_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
145 my @il = map { $_->[$item_pos] } @{$gp->{data}};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
146 @il = sort_items(@il);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
147 my $line = $line_pre;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
148 for my $item (@il) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
149 my $nl = $line;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
150 $nl .= $item_sep if $nl ne $line_pre;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
151 $nl .= $item_pre . $item . $item_post;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
152 if (sizeof($nl . $line_post) > $line_size) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
153 print $line, $line_post if $line ne $line_pre;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
154 $nl = $line_pre . $item_pre . $item . $item_post;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
155 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
156 $line = $nl;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
157 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
158 print $line, $line_post if $line ne $line_pre;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
159 next;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
160 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
161 if (s/^(.*)\@\@ALL\s*//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
162 my $line_pre = $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
163 my $group = get_field($orig, \$_, 'w');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
164 exists $groups{$group}
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
165 or die "Unknown group $group";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
166 my $gp = $groups{$group};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
167 my $item_name = get_field($orig, \$_, 'w');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
168 exists $gp->{fpos}{$item_name}
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
169 or die "Unknown field $item_name in group $group";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
170 my $item_pos = $gp->{fpos}{$item_name};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
171 s/^\@\@// or die "Missing \@\@ after \@\@ALL";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
172 my $line_post = $_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
173 my @il = map { $_->[$item_pos] } @{$gp->{data}};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
174 @il = sort_items(@il);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
175 my $p = $gp->{fpos};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
176 check_escapes($gp, $p, $line_pre);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
177 check_escapes($gp, $p, $line_post);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
178 for my $il (@il) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
179 for my $item (@{$gp->{data}}) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
180 next if $item->[$item_pos] ne $il;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
181 my @line = ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
182 for my $ol ($line_pre, $line_post) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
183 my $line = $ol;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
184 my $trans = '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
185 while ($line =~ s/^(.*?)\@\@//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
186 $trans .= $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
187 $line =~ s/^(.*?)\@\@//
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
188 or die "Missing \@\@ closing $line";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
189 my $gn = $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
190 my $quote = $gn =~ s/^(['"]?)(\w+)\1$/$2/ ? $1 : '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
191 my $f;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
192 if ($gn eq 'WHIRLPOOL') {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
193 $f = '@';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
194 } elsif ($gn =~ /^(.*?):(\w+)$/) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
195 $f = $item->[$p->{$1}];
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
196 my @a = @{$item->[$p->{$2}]};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
197 $f =~ s/%/shift @a || '???'/ge;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
198 } else {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
199 $f = $item->[$p->{$gn}];
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
200 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
201 $f =~ s/([\\$quote])/\\$1/g if $quote ne '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
202 $trans .= $f;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
203 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
204 push @line, $trans . $line;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
205 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
206 print $line[0], $il, $line[1];
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
207 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
208 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
209 next;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
210 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
211 if (s/^\s*\@\@MULTI\s*//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
212 my $group = get_field($orig, \$_, 'w');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
213 exists $groups{$group}
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
214 or die "Unknown group $group";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
215 my $gp = $groups{$group};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
216 my $item_name = get_field($orig, \$_, 'w');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
217 exists $gp->{fpos}{$item_name}
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
218 or die "Unknown field $item_name in group $group";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
219 my $item_pos = $gp->{fpos}{$item_name};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
220 s/^\@\@\s*$// or die "Missing \@\@ after \@\@MULTI";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
221 my @il = map { $_->[$item_pos] } @{$gp->{data}};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
222 @il = sort_items(@il);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
223 my $p = $gp->{fpos};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
224 my @line = ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
225 my $found = 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
226 while (<>) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
227 if (/^\s*\@\@MULTI\@\@\s*$/) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
228 $found = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
229 last;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
230 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
231 push @line, $_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
232 check_escapes($gp, $p, $_);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
233 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
234 $found or die "Missing \@\@MULTI\@\@";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
235 for my $il (@il) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
236 for my $item (@{$gp->{data}}) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
237 next if $item->[$item_pos] ne $il;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
238 print translate_escapes($gp, $p, $item, $_) for @line;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
239 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
240 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
241 next;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
242 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
243 if (/\@\@/) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
244 chomp;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
245 die "Invalid \@\@-escape: $_";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
246 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
247 print;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
248 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
249 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
250
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
251 sub get_field {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
252 my ($orig, $line, $type) = @_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
253 if ($type =~ s/^\@//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
254 $$line =~ s/^\[\s*//
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
255 or die "Invalid array: missing [";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
256 my @data = ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
257 while ($$line ne '' && $$line !~ s/^\]\s*//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
258 push @data, get_field($orig, $line, $type);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
259 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
260 return \@data;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
261 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
262 if ($type eq 'd') {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
263 $$line =~ s/^0x([[:xdigit:]]+)\s*//
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
264 and return hex($1);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
265 $$line =~ s/^(\d+)\s*//
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
266 and return $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
267 die "Invalid number: $_";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
268 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
269 if ($type eq 'w') {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
270 $$line =~ s/^(\w+)\s*//
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
271 or die "Invalid symbol: $_";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
272 return $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
273 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
274 if ($type eq 's') {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
275 if ($$line =~ s/^(['"])//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
276 # quoted string
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
277 my $quote = $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
278 my $data = '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
279 while ($$line =~ s/^(.*?)([$quote\\])//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
280 $data .= $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
281 last if $2 eq $quote;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
282 die "Invalid data: \\ at end of line" if $$line eq '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
283 $data .= substr($$line, 0, 1, '');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
284 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
285 $$line =~ s/^\s+//;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
286 return $data;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
287 } else {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
288 # bareword
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
289 $$line =~ s/^(\S+)\s*//
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
290 or die "Invalid string: $_";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
291 return $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
292 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
293 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
294 die "Internal error: type is '$type'";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
295 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
296
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
297 sub sizeof {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
298 my ($s) = @_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
299 my $l = 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
300 while ($s ne '') {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
301 my $x = substr($s, 0, 1, '');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
302 if ($x eq "\t") {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
303 $l = 8 * (1 + int($l / 8));
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
304 } else {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
305 $l++;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
306 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
307 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
308 $l;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
309 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
310
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
311 sub sort_items {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
312 sort {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
313 return $a <=> $b if $a =~ /^\d+$/ && $b =~ /^\d+$/;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
314 return -1 if $a =~ /^\d+$/;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
315 return 1 if $b =~ /^\d+$/;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
316 return $a cmp $b;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
317 } @_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
318 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
319
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
320 sub field_map {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
321 my ($a, $b) = @_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
322 # we are trying to append $b's data to $a...
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
323 my @map = ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
324 for my $n (@{$b->{fnames}}) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
325 # $a must have this field
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
326 return () if ! exists $a->{fpos}{$n};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
327 # the fields must have the same type
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
328 return () if $a->{ftypes}{$n} ne $b->{ftypes}{$n};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
329 my $p = $a->{fpos}{$n};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
330 push @map, $p;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
331 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
332 @map;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
333 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
334
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
335 sub check_escapes {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
336 my ($gp, $p, $line) = @_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
337 while ($line =~ s/^.*?\@\@//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
338 $line =~ s/^(.*?)\@\@//
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
339 or die "Missing \@\@ closing $line";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
340 my $gn = $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
341 $gn =~ s/\s+HTML$//i;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
342 $gn =~ s/\s+\d+$//;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
343 next if $gn eq 'WHIRLPOOL';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
344 my $ogn = $gn;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
345 if ($gn =~ s/^(\w+):(\w+)\s*//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
346 my $next = $gn;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
347 $gn = $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
348 exists $p->{$2}
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
349 or die "Invalid field name $2";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
350 substr($gp->{ftypes}{$2}, 0, 1) eq '@'
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
351 or die "Field $2 is not an array";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
352 my $mapfrom = get_field($ogn, \$next, 's');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
353 my $prefix = get_field($ogn, \$next, 's');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
354 my $suffix = get_field($ogn, \$next, 's');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
355 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
356 $gn =~ s/^(['"])(.*)\1$/$2/;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
357 exists $p->{$gn}
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
358 or die "Invalid field name $gn";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
359 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
360 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
361
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
362 sub translate_escapes {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
363 my ($gp, $p, $item, $line) = @_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
364 my $trans = '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
365 while ($line =~ s/^(.*?)\@\@//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
366 $trans .= $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
367 $line =~ s/^(.*?)\@\@//;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
368 my $gn = $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
369 if ($gn eq 'WHIRLPOOL') {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
370 $trans .= '@';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
371 next;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
372 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
373 my $html = $gn =~ s/\s+HTML$//i;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
374 my $fold = $gn =~ s/\s+(\d+)$// ? $1 : undef;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
375 my ($mapfrom, $prefix, $suffix, $mapto);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
376 my $ogn = $gn;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
377 if ($gn =~ s/^(\w+):(\w+)\s*//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
378 my $next = $gn;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
379 $gn = $1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
380 $mapto = $2;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
381 $mapfrom = get_field($ogn, \$next, 's');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
382 $prefix = get_field($ogn, \$next, 's');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
383 $suffix = get_field($ogn, \$next, 's');
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
384 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
385 my $quote = $gn =~ s/^(['"]?)(\w+)\1$/$2/ ? $1 : '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
386 my $f = $item->[$p->{$gn}];
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
387 if (defined $mapto) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
388 my @a = @{$item->[$p->{$mapto}]};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
389 $f =~ s/$mapfrom/$prefix . (shift @a || '???'). $suffix/ge;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
390 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
391 if ($html) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
392 $f =~ s/&/&amp;/gi;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
393 $f =~ s/</&lt;/gi;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
394 $f =~ s/>/&gt;/gi;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
395 $f =~ s/"/&quot;/gi;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
396 $f =~ s/I&lt;(.*?)&gt;/<I>$1<\/I>/gi;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
397 $f =~ s/L&lt;Language::INTERCAL::Charset&gt;/<A HREF="charset.html">the chapter on character sets<\/A>/gi;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
398 $f =~ s/L&lt;Language::INTERCAL::(?:ArrayIO|ReadNumber|WriteNumber)&gt;/<A HREF="input_output.html">the chapter on Input\/Output<\/A>/gi;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
399 $f =~ s/L&lt;(.*?)&gt;/<CODE>$1<\/CODE>/gi;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
400 $f =~ s/C&lt;(.*?)&gt;/<CODE>$1<\/CODE>/gi;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
401 $f =~ s/\n\n+/<BR>/g;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
402 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
403 if (defined $fold) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
404 my $u = $f;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
405 $f = '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
406 for my $o (split(/\n\n/, $u)) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
407 while (sizeof($o) > $fold) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
408 my $g = '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
409 while ($o =~ s/^(\S*)(\s+)//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
410 my ($n, $s) = ($1, $2);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
411 if (sizeof($g . $n) > $fold) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
412 $o = $n . $s . $o;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
413 last;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
414 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
415 $g .= $n . $s;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
416 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
417 $g =~ s/\s+$//;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
418 $f .= $g . "\n";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
419 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
420 $f .= $o . "\n\n";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
421 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
422 $f =~ s/\n\n$//;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
423 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
424 $f =~ s/([\\$quote])/\\$1/g if $quote ne '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
425 $trans .= $f;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
426 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
427 $trans .= $line;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
428 $trans;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
429 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
430
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
431 sub load_spec {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
432 my ($dataname) = @_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
433 my @gpath = $ENV{CLC_INTERCAL_PATH} ? ($ENV{CLC_INTERCAL_PATH}) : ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
434 my $dataspec = File::Spec->catfile(@gpath, qw(INTERCAL Generate), $dataname);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
435 unless (open(DATASPEC, '<', $dataspec)) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
436 $dataspec = undef;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
437 for my $path (@INC) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
438 my $d = File::Spec->catfile($path, qw(Language INTERCAL Generate), $dataname);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
439 open(DATASPEC, '<', $d) or next;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
440 $dataspec = $d;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
441 last;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
442 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
443 defined $dataspec
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
444 or die "$0: $dataname: $!";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
445 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
446 print STDERR " ($dataspec)\n";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
447 my $in_group = undef;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
448 my $item_indent = undef;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
449 my $last_multi = undef;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
450 my $blank_line = 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
451 while (<DATASPEC>) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
452 chomp;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
453 last if /^\s*\@\__END__/;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
454 if (/^\s*#|^\s*$/) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
455 $blank_line = 1;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
456 next;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
457 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
458 my $bl = $blank_line;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
459 $blank_line = 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
460 if (defined $in_group) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
461 if (s/^\s*\@END\s*//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
462 die "group $in_group->{name} ended by \@END $_"
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
463 if $in_group->{name} ne $_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
464 if ($in_group->{has_m}) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
465 $_->[-1] = ${$_->[-1]} for @{$in_group->{data}};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
466 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
467 $in_group = undef;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
468 next;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
469 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
470 if (s/^\s*\@SOURCE\s+//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
471 push @{$in_group->{sources}}, $_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
472 next;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
473 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
474 die "$0: Invalid \@ escape ($_)" if /^\s*\@/;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
475 my $indent = s/^([ \t]+)// ? sizeof($1) : 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
476 if ($in_group->{has_m} &&
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
477 defined $item_indent &&
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
478 $item_indent < $indent)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
479 {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
480 s/^\\//;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
481 if ($bl) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
482 $$last_multi .= "\n\n" if $bl;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
483 } elsif ($$last_multi ne '') {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
484 $$last_multi .= ' ';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
485 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
486 $$last_multi .= $_;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
487 } else {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
488 $item_indent = $indent;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
489 # process group line
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
490 my @line = ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
491 for my $fname (@{$in_group->{fnames}}) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
492 my $ftype = $in_group->{ftypes}{$fname};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
493 next if $ftype eq 'm';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
494 push @line, get_field($_, \$_, $ftype);
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
495 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
496 die "Extra data at end of line ($_)" if $_ ne '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
497 if ($in_group->{has_m}) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
498 my $x = '';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
499 $last_multi = \$x;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
500 push @line, $last_multi;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
501 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
502 push @{$in_group->{data}}, \@line;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
503 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
504 } elsif (s/^\s*\@GROUP\s+//) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
505 my ($group, @fspec) = split;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
506 die "$0: duplicate group $group" if exists $groups{$group};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
507 die "$0: group $group has no fields!" unless @fspec;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
508 my @fnames = ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
509 my %ftypes = ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
510 my %fpos = ();
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
511 my $has_m = 0;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
512 for my $fs (@fspec) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
513 $fs =~ /^(\w+)=(.*)$/ or die "Invalid field definition ($fs)";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
514 my ($name, $type) = ($1, lc($2));
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
515 exists $ftypes{$type} and die "Duplicate field name ($name)";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
516 $type =~ /^(?:\@*[dws]|m)$/ or die "Invalid field type ($fs)";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
517 die "Sorry, multiline fields must be last" if $has_m;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
518 $has_m = 1 if $type eq 'm';
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
519 $fpos{$name} = scalar @fnames;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
520 push @fnames, $name;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
521 $ftypes{$name} = $type;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
522 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
523 $in_group = {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
524 fnames => \@fnames,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
525 ftypes => \%ftypes,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
526 fpos => \%fpos,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
527 data => [],
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
528 sources => [],
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
529 name => $group,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
530 has_m => $has_m,
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
531 };
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
532 $groups{$group} = $in_group;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
533 } else {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
534 die "Invalid line ($_)";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
535 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
536 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
537 close DATASPEC;
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
538
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
539 # process SOURCE
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
540 for my $g (values %groups) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
541 for my $s (@{$g->{sources}}) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
542 $s ne $g && exists $groups{$s}
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
543 or die "Invalid source $s for $g->{name}";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
544 my $d = $groups{$s};
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
545 @{$d->{sources}}
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
546 and die "Sourcing from a group containing sources ($s) not implemented";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
547 my @map = field_map($g, $d)
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
548 or die "$g->{name} cannot source from $s: incompatible fields";
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
549 for my $d (@{$d->{data}}) {
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
550 push @{$g->{data}}, [map { $d->[$_] } @map];
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
551 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
552 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
553 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
554 }
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
555
859f9b4339e6 <Gregor> tar xf egobot.tar.xz
HackBot
parents:
diff changeset
556 1;