File: suck_table.pl

package info (click to toggle)
tct 1.07-9
  • links: PTS
  • area: main
  • in suites: woody
  • size: 1,828 kB
  • ctags: 1,128
  • sloc: perl: 9,604; ansic: 4,861; makefile: 516; sh: 77
file content (72 lines) | stat: -rw-r--r-- 1,846 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#
# Suck a self-describing table into memory.
#
# Usage: $table = &suck_table(pathname)
#
# Each table has the following components:
#
# - 'origin' is a hash table with host and time information.
#
# - 'labels' is a hash table that maps data field names to offsets 0..m
#
# - 'data' is an array of (array 0..m with data extracted from file).
#

sub suck_table {
    local($path) = @_;
    local(%table, @labels, @data, $offset, $n, $line, $ref);

    open(TABLE, "<$path") || die "Cannot open $path: $!\n";

    #
    # The file starts with origin information (host, time, etc.).
    #
    chop($line = <TABLE>);
    (@labels = &tm_split($line))
	|| die "$path: No origin dictionary record.\n";
    chop($line = <TABLE>);
    (@data = &tm_split($line))
	|| die "$path: No origin data record.\n";
    ($#labels == $#data)
	|| die "$path: Inconsistent origin field count.\n";
    for $offset (0..$#labels) {
	$table{'origin'}{@labels[$offset]} = @data[$offset];
    }

    #
    # Read the data dictionary.
    #
    chop($line = <TABLE>);
    (@labels = &tm_split($line))
	|| die "$path: No data dictionary record.\n";
    for $offset (0..$#labels) {
	$table{'labels'}{@labels[$offset]} = $offset;
    }

    #
    # Read the actual data. This is done most often so it needs to be fast.
    # Use references to avoid hash table lookups.
    #
    $ref = \@{$table{'data'}};
    for ($n = 0; chop($line = <TABLE>); $n++) {
	@{$ref->[$n]} = &tm_split($line);
	($#labels > $#{$ref->[$n]})
	    && ($#{$ref->[$n]} = $#labels);
	($#labels == $#{$ref->[$n]})
	    || die "$path: Inconsistent data field count $#labels != $#{$ref->[$n]}: $line\n";
    }

    #
    # Cleanup.
    #
    close(TABLE);
    return %table;
}

if (!$running_under_grave_robber) {
    $running_under_grave_robber = 1;
    require "tm_misc.pl";
    &suck_table($ARGV[0]);
}

1;