File: MultiFileReader.cxx

package info (click to toggle)
arb 6.0.6-8
  • links: PTS, VCS
  • area: non-free
  • in suites: sid, trixie
  • size: 66,204 kB
  • sloc: ansic: 394,911; cpp: 250,290; makefile: 19,644; sh: 15,879; perl: 10,473; fortran: 6,019; ruby: 683; xml: 503; python: 53; awk: 32
file content (139 lines) | stat: -rw-r--r-- 4,154 bytes parent folder | download | duplicates (6)
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// ============================================================= //
//                                                               //
//   File      : MultiFileReader.cxx                             //
//   Purpose   : Read multiple files like one concatenated file  //
//                                                               //
//   Coded by Ralf Westram (coder@reallysoft.de) in March 2014   //
//   http://www.arb-home.de/                                     //
//                                                               //
// ============================================================= //

#include "MultiFileReader.h"
#include "arb_msg.h"

const string& MultiFileReader::getFilename() const {
    if (!reader) {
        if (last_reader) return last_reader->getFilename();
        arb_assert(0);
        static string nf = "unknown-source";
        return nf;
    }
    return reader->getFilename();
}
bool MultiFileReader::getLine_intern(string& line) {
    bool gotLine = false;
    if (reader) {
        gotLine = reader->getLine(line);
        if (!gotLine) {
            nextReader();
            gotLine = getLine_intern(line);
            if (gotLine) setLineNumber(reader->getLineNumber());
        }
    }
    return gotLine;
}

FILE *MultiFileReader::open(int i) {
    FILE *in       = fopen(files[i], "rt");
    if (!in) error = new string(GB_IO_error("reading", files[i]));
    return in;
}

void MultiFileReader::nextReader() {
    if (reader) {
        if (last_reader) {
            delete last_reader;
            last_reader = NULL;
        }
        last_reader = reader;
        reader      = NULL;
    }
    ++at;
    if (at<files.size()) {
        FILE *in = open(at);
        if (in) {
            reader = new BufferedFileReader(files[at], in);
        }
    }
}

MultiFileReader::MultiFileReader(const CharPtrArray& files_)
    : files(files_),
      reader(NULL),
      last_reader(NULL),
      error(NULL),
      at(-1)
{
    for (size_t i = 0; i<files.size() && !error; ++i) {
        // test open all files
        FILE *in = open(i);
        if (in) fclose(in);
    }
    if (!error) nextReader();
}

MultiFileReader::~MultiFileReader() {
    delete reader;
    delete last_reader;
    delete error;
}

// --------------------------------------------------------------------------------

#ifdef UNIT_TESTS
#ifndef TEST_UNIT_H
#include <test_unit.h>
#endif

void TEST_MultiFileReader() {
    ConstStrArray files;
    files.put("general/broken_LF.input"); // 6 lines
    files.put("general/dos.input");       // 6 lines
    files.put("general/mac.input");       // 6 lines
    files.put("general/empty.input");     // 1 line
    files.put("general/text.input");      // 6 lines

    {
        MultiFileReader reader(files);

        TEST_EXPECT_NO_ERROR(reader.get_error());

        string line;
        string emptyLineError;
        string db_found_msgs;
        int    lineCount      = 0;
        int    emptyLineCount = 0;

        while (reader.getLine(line)) {
            lineCount++;
            if (line.empty()) {
                emptyLineCount++;
                emptyLineError = reader.lineError("seen empty line");
            }
            else if (strstr(line.c_str(), "database") != 0) {
                db_found_msgs += reader.lineError("DB") + "\n";
            }
        }

        TEST_EXPECT_NO_ERROR(reader.get_error());
        TEST_EXPECT_EQUAL(lineCount, 25);
        TEST_EXPECT_EQUAL(emptyLineCount, 1);
        TEST_EXPECT_EQUAL(emptyLineError, "general/empty.input:1: seen empty line");
        TEST_EXPECT_EQUAL(db_found_msgs,
                          "general/broken_LF.input:2: DB\n"
                          "general/dos.input:2: DB\n"
                          "general/mac.input:2: DB\n"
                          "general/text.input:2: DB\n");
    }

    files.put("general/nosuch.input");
    {
        MultiFileReader reader(files);
        TEST_EXPECT_EQUAL(reader.get_error(), "While reading 'general/nosuch.input': No such file or directory");
    }
}

#endif // UNIT_TESTS

// --------------------------------------------------------------------------------