File: nodifferences.cc

package info (click to toggle)
stealth 1.45-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 716 kB
  • ctags: 175
  • sloc: cpp: 1,612; makefile: 88; sh: 70
file content (125 lines) | stat: -rw-r--r-- 4,226 bytes parent folder | download | duplicates (3)
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
#include "scanner.ih"

/*
    Example of diff-output:

33c33
< 90d8b506d249634c4ff80b9018644567  out
---
> b88d0b77db74cc4a742d7bc26cdd2a1e  out

*/

bool Scanner::noDifferences(std::string const &current,
                                  std::string const &logfile)
{
    Util::debug() << "Scanner::noDifferences(): started " << 
            d_sorter["DIFF"] << " " << current << " " << logfile << endl;

    d_shFork << d_sorter["DIFF"] << " " << current << " " << logfile <<
                                                                endl <<
                        "/bin/echo \"" << d_sentinel << "\"" << endl;

    HashString< pair<string, vector<string> > > status;

    Util::debug() << "Scanner::noDifferences():         " << "/bin/echo " << 
                        d_sentinel << endl;

    //  key is string, case sensitive.
    //
    //  The last element of the lines produced by diff is used as the
    //  key. For the current function to operate sensibly, this should be
    //  a filename or path/file.
    //
    //  If the first character of the line is a < or >, then a modification is
    //  detected: for these lines the following happens:
    //      1. If the key already existed its .first element is set to
    //          "modified". If the key didn't exist yet, it is set to
    //          "added" at at '<', and to "removed" at a '>'
    //      2. The line itself is pushed back to the .second (vector) element
    //          of the pair.
    //
    //  At the end, if the hashtable has any elements, the table is inserted
    //  into the d_reporter and `false' is returned. If the hashtable contains
    //  no elements, 'true' is returned.

    string  s;
//    Pattern split("(\\S+)\\s*$");

    Util::debug() << "Scanner::noDifferences(): starting to read lines" << 
                                                                        endl;

//    if (!d_shFork.available())
//        d_reporter.exit() << "`" << d_sorter["SH"] << "': no output from " <<
//                             d_sorter["DIFF"] << endl;

    while (getline(d_shFork, s))
    {
        Util::debug() << "Scanner::noDifferences():      got: `" << s << 
                                                                    "'\n" <<
            "Scanner::noDifferences(): sentinel: `" << d_sentinel << 
                                                                "'" << endl;
        if (s == d_sentinel)
            break;

        if (!(s_split << s))
            continue;                       // no match at empty lines ?

        string key = s_split[1];            // get the key
        bool exists = status.count(key);

        if (s[0] == '>')                // removal, e.g.,   > b88d0b....  out
                status[key].first = exists ? "MODIFIED" : "REMOVED";
        else if (s[0] == '<')
                status[key].first = exists ? "MODIFIED" : "ADDED";
        else
            continue;

        status[key].second.push_back(s);
    }

    if (!status.size())                 // no elements ?
    {
        Util::debug() << "no differences were observed" << endl;

        rename(current.c_str(), logfile.c_str());   // install `logfile'
        return true;                   // nothing to report
    }

    if (d_label.length())
        d_reporter << d_label << endl;

    for
    (
        HashString< pair<string, vector<string> > >::iterator
        begin = status.begin(), end = status.end();
            begin != end;
                begin++
    )
    {
        d_reporter << begin->second.first  << ": " << begin->first << endl;

        for
        (
            vector<string>::iterator
                sbegin = begin->second.second.begin(),
                send = begin->second.second.end();
                    sbegin != send;
                        sbegin++
        )
            d_reporter << "    " << *sbegin << endl;
    }

    string
        datetime = logfile + "." + Util::datetime();

    rename(logfile.c_str(), datetime.c_str());
    rename(current.c_str(), logfile.c_str());   // install `logfile'

    Util::debug() << "differences were observed: see `" << 
                 d_sorter["REPORT"] << "'  and `" << logfile << "'" << endl;

    return false;
}