gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Allow lgf file without Arc maps (#382) A single '-' character in the @arcs sectio header indicates that there is no arc map.
0 4 1
default
5 files changed with 204 insertions and 7 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2011
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#include <lemon/list_graph.h>
20
#include <lemon/lgf_reader.h>
21
#include "test_tools.h"
22

	
23
using namespace lemon;
24

	
25
char test_lgf[] =
26
  "@nodes\n"
27
  "label\n"
28
  "0\n"
29
  "1\n"
30
  "@arcs\n"
31
  "     label\n"
32
  "0 1  0\n"
33
  "1 0  1\n"
34
  "@attributes\n"
35
  "source 0\n"
36
  "target 1\n";
37

	
38
char test_lgf_nomap[] =
39
  "@nodes\n"
40
  "label\n"
41
  "0\n"
42
  "1\n"
43
  "@arcs\n"
44
  "     -\n"
45
  "0 1\n";
46

	
47
char test_lgf_bad1[] =
48
  "@nodes\n"
49
  "label\n"
50
  "0\n"
51
  "1\n"
52
  "@arcs\n"
53
  "     - another\n"
54
  "0 1\n";
55

	
56
char test_lgf_bad2[] =
57
  "@nodes\n"
58
  "label\n"
59
  "0\n"
60
  "1\n"
61
  "@arcs\n"
62
  "     label -\n"
63
  "0 1\n";
64

	
65

	
66
int main() 
67
{
68
  {
69
    ListDigraph d; 
70
    ListDigraph::Node s,t;
71
    ListDigraph::ArcMap<int> label(d);
72
    std::istringstream input(test_lgf);
73
    digraphReader(d, input).
74
      node("source", s).
75
      node("target", t).
76
      arcMap("label", label).
77
      run();
78
    check(countNodes(d) == 2,"There should be 2 nodes");
79
    check(countArcs(d) == 2,"There should be 2 arcs");
80
  }
81
  {
82
    ListGraph g;
83
    ListGraph::Node s,t;
84
    ListGraph::EdgeMap<int> label(g);
85
    std::istringstream input(test_lgf);
86
    graphReader(g, input).
87
      node("source", s).
88
      node("target", t).
89
      edgeMap("label", label).
90
      run();
91
    check(countNodes(g) == 2,"There should be 2 nodes");
92
    check(countEdges(g) == 2,"There should be 2 arcs");
93
  }
94

	
95
  {
96
    ListDigraph d; 
97
    std::istringstream input(test_lgf_nomap);
98
    digraphReader(d, input).
99
      run();
100
    check(countNodes(d) == 2,"There should be 2 nodes");
101
    check(countArcs(d) == 1,"There should be 1 arc");
102
  }
103
  {
104
    ListGraph g;
105
    std::istringstream input(test_lgf_nomap);
106
    graphReader(g, input).
107
      run();
108
    check(countNodes(g) == 2,"There should be 2 nodes");
109
    check(countEdges(g) == 1,"There should be 1 edge");
110
  }
111

	
112
  {
113
    ListDigraph d; 
114
    std::istringstream input(test_lgf_bad1);
115
    bool ok=false;
116
    try {
117
      digraphReader(d, input).
118
        run();
119
    }
120
    catch (FormatError& error) 
121
      {
122
        ok = true;
123
      }
124
    check(ok,"FormatError exception should have occured");
125
  }
126
  {
127
    ListGraph g;
128
    std::istringstream input(test_lgf_bad1);
129
    bool ok=false;
130
    try {
131
      graphReader(g, input).
132
        run();
133
    }
134
    catch (FormatError& error)
135
      {
136
        ok = true;
137
      }
138
    check(ok,"FormatError exception should have occured");
139
  }
140

	
141
  {
142
    ListDigraph d; 
143
    std::istringstream input(test_lgf_bad2);
144
    bool ok=false;
145
    try {
146
      digraphReader(d, input).
147
        run();
148
    }
149
    catch (FormatError& error)
150
      {
151
        ok = true;
152
      }
153
    check(ok,"FormatError exception should have occured");
154
  }
155
  {
156
    ListGraph g;
157
    std::istringstream input(test_lgf_bad2);
158
    bool ok=false;
159
    try {
160
      graphReader(g, input).
161
        run();
162
    }
163
    catch (FormatError& error)
164
      {
165
        ok = true;
166
      }
167
    check(ok,"FormatError exception should have occured");
168
  }
169
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
namespace lemon {
20 20
/*!
21 21

	
22 22

	
23 23

	
24 24
\page lgf-format LEMON Graph Format (LGF)
25 25

	
26 26
The \e LGF is a <em>column oriented</em>
27 27
file format for storing graphs and associated data like
28 28
node and edge maps.
29 29

	
30 30
Each line with \c '#' first non-whitespace
31 31
character is considered as a comment line.
32 32

	
33 33
Otherwise the file consists of sections starting with
34 34
a header line. The header lines starts with an \c '@' character followed by the
35 35
type of section. The standard section types are \c \@nodes, \c
36 36
\@arcs and \c \@edges
37 37
and \@attributes. Each header line may also have an optional
38 38
\e name, which can be use to distinguish the sections of the same
39 39
type.
40 40

	
41 41
The standard sections are column oriented, each line consists of
42 42
<em>token</em>s separated by whitespaces. A token can be \e plain or
43 43
\e quoted. A plain token is just a sequence of non-whitespace characters,
44 44
while a quoted token is a
45 45
character sequence surrounded by double quotes, and it can also
46 46
contain whitespaces and escape sequences.
47 47

	
48 48
The \c \@nodes section describes a set of nodes and associated
49 49
maps. The first is a header line, its columns are the names of the
50 50
maps appearing in the following lines.
51 51
One of the maps must be called \c
52 52
"label", which plays special role in the file.
53 53
The following
54 54
non-empty lines until the next section describes nodes of the
55 55
graph. Each line contains the values of the node maps
56 56
associated to the current node.
57 57

	
58 58
\code
59 59
 @nodes
60 60
 label  coordinates  size    title
61 61
 1      (10,20)      10      "First node"
62 62
 2      (80,80)      8       "Second node"
63 63
 3      (40,10)      10      "Third node"
64 64
\endcode
65 65

	
66
The \c \@arcs section is very similar to the \c \@nodes section,
67
it again starts with a header line describing the names of the maps,
68
but the \c "label" map is not obligatory here. The following lines
69
describe the arcs. The first two tokens of each line are
70
the source and the target node of the arc, respectively, then come the map
66
The \c \@arcs section is very similar to the \c \@nodes section, it
67
again starts with a header line describing the names of the maps, but
68
the \c "label" map is not obligatory here. The following lines
69
describe the arcs. The first two tokens of each line are the source
70
and the target node of the arc, respectively, then come the map
71 71
values. The source and target tokens must be node labels.
72 72

	
73 73
\code
74 74
 @arcs
75 75
         capacity
76 76
 1   2   16
77 77
 1   3   12
78 78
 2   3   18
79 79
\endcode
80 80

	
81
If there is no map in the \c \@arcs section at all, then it must be
82
indicated by a sole '-' sign in the first line.
83

	
84
\code
85
 @arcs
86
         -
87
 1   2
88
 1   3
89
 2   3
90
\endcode
91

	
81 92
The \c \@edges is just a synonym of \c \@arcs. The \@arcs section can
82 93
also store the edge set of an undirected graph. In such case there is
83 94
a conventional method for store arc maps in the file, if two columns
84
has the same caption with \c '+' and \c '-' prefix, then these columns
95
have the same caption with \c '+' and \c '-' prefix, then these columns
85 96
can be regarded as the values of an arc map.
86 97

	
87 98
The \c \@attributes section contains key-value pairs, each line
88 99
consists of two tokens, an attribute name, and then an attribute
89 100
value. The value of the attribute could be also a label value of a
90 101
node or an edge, or even an edge label prefixed with \c '+' or \c '-',
91 102
which regards to the forward or backward directed arc of the
92 103
corresponding edge.
93 104

	
94 105
\code
95 106
 @attributes
96 107
 source 1
97 108
 target 3
98 109
 caption "LEMON test digraph"
99 110
\endcode
100 111

	
101 112
The \e LGF can contain extra sections, but there is no restriction on
102 113
the format of such sections.
103 114

	
104 115
*/
105 116
}
106 117

	
107 118
//  LocalWords:  whitespace whitespaces
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\ingroup lemon_io
20 20
///\file
21 21
///\brief \ref lgf-format "LEMON Graph Format" reader.
22 22

	
23 23

	
24 24
#ifndef LEMON_LGF_READER_H
25 25
#define LEMON_LGF_READER_H
26 26

	
27 27
#include <iostream>
28 28
#include <fstream>
29 29
#include <sstream>
30 30

	
31 31
#include <set>
32 32
#include <map>
33 33

	
34 34
#include <lemon/core.h>
35 35

	
36 36
#include <lemon/lgf_writer.h>
37 37

	
38 38
#include <lemon/concept_check.h>
39 39
#include <lemon/concepts/maps.h>
40 40

	
41 41
namespace lemon {
42 42

	
43 43
  namespace _reader_bits {
44 44

	
45 45
    template <typename Value>
46 46
    struct DefaultConverter {
47 47
      Value operator()(const std::string& str) {
48 48
        std::istringstream is(str);
49 49
        Value value;
50 50
        if (!(is >> value)) {
51 51
          throw FormatError("Cannot read token");
52 52
        }
53 53

	
54 54
        char c;
55 55
        if (is >> std::ws >> c) {
56 56
          throw FormatError("Remaining characters in token");
57 57
        }
58 58
        return value;
59 59
      }
60 60
    };
61 61

	
62 62
    template <>
63 63
    struct DefaultConverter<std::string> {
64 64
      std::string operator()(const std::string& str) {
65 65
        return str;
66 66
      }
67 67
    };
68 68

	
69 69
    template <typename _Item>
70 70
    class MapStorageBase {
71 71
    public:
72 72
      typedef _Item Item;
73 73

	
74 74
    public:
75 75
      MapStorageBase() {}
76 76
      virtual ~MapStorageBase() {}
77 77

	
78 78
      virtual void set(const Item& item, const std::string& value) = 0;
79 79

	
80 80
    };
81 81

	
82 82
    template <typename _Item, typename _Map,
83 83
              typename _Converter = DefaultConverter<typename _Map::Value> >
84 84
    class MapStorage : public MapStorageBase<_Item> {
85 85
    public:
86 86
      typedef _Map Map;
87 87
      typedef _Converter Converter;
88 88
      typedef _Item Item;
89 89

	
90 90
    private:
91 91
      Map& _map;
92 92
      Converter _converter;
93 93

	
94 94
    public:
95 95
      MapStorage(Map& map, const Converter& converter = Converter())
96 96
        : _map(map), _converter(converter) {}
97 97
      virtual ~MapStorage() {}
98 98

	
99 99
      virtual void set(const Item& item ,const std::string& value) {
100 100
        _map.set(item, _converter(value));
101 101
      }
102 102
    };
103 103

	
104 104
    template <typename _Graph, bool _dir, typename _Map,
105 105
              typename _Converter = DefaultConverter<typename _Map::Value> >
106 106
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
107 107
    public:
108 108
      typedef _Map Map;
109 109
      typedef _Converter Converter;
110 110
      typedef _Graph Graph;
111 111
      typedef typename Graph::Edge Item;
112 112
      static const bool dir = _dir;
113 113

	
114 114
    private:
115 115
      const Graph& _graph;
116 116
      Map& _map;
117 117
      Converter _converter;
118 118

	
119 119
    public:
120 120
      GraphArcMapStorage(const Graph& graph, Map& map,
121 121
                         const Converter& converter = Converter())
122 122
        : _graph(graph), _map(map), _converter(converter) {}
123 123
      virtual ~GraphArcMapStorage() {}
124 124

	
125 125
      virtual void set(const Item& item ,const std::string& value) {
126 126
        _map.set(_graph.direct(item, dir), _converter(value));
127 127
      }
128 128
    };
129 129

	
130 130
    class ValueStorageBase {
131 131
    public:
132 132
      ValueStorageBase() {}
133 133
      virtual ~ValueStorageBase() {}
134 134

	
135 135
      virtual void set(const std::string&) = 0;
136 136
    };
137 137

	
138 138
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
139 139
    class ValueStorage : public ValueStorageBase {
140 140
    public:
141 141
      typedef _Value Value;
142 142
      typedef _Converter Converter;
143 143

	
144 144
    private:
145 145
      Value& _value;
146 146
      Converter _converter;
147 147

	
148 148
    public:
149 149
      ValueStorage(Value& value, const Converter& converter = Converter())
150 150
        : _value(value), _converter(converter) {}
151 151

	
152 152
      virtual void set(const std::string& value) {
153 153
        _value = _converter(value);
154 154
      }
155 155
    };
156 156

	
157 157
    template <typename Value>
158 158
    struct MapLookUpConverter {
159 159
      const std::map<std::string, Value>& _map;
160 160

	
161 161
      MapLookUpConverter(const std::map<std::string, Value>& map)
162 162
        : _map(map) {}
163 163

	
164 164
      Value operator()(const std::string& str) {
165 165
        typename std::map<std::string, Value>::const_iterator it =
166 166
          _map.find(str);
167 167
        if (it == _map.end()) {
168 168
          std::ostringstream msg;
169 169
          msg << "Item not found: " << str;
170 170
          throw FormatError(msg.str());
171 171
        }
172 172
        return it->second;
173 173
      }
174 174
    };
175 175

	
176 176
    template <typename Graph>
177 177
    struct GraphArcLookUpConverter {
178 178
      const Graph& _graph;
179 179
      const std::map<std::string, typename Graph::Edge>& _map;
180 180

	
181 181
      GraphArcLookUpConverter(const Graph& graph,
182 182
                              const std::map<std::string,
183 183
                                             typename Graph::Edge>& map)
184 184
        : _graph(graph), _map(map) {}
185 185

	
186 186
      typename Graph::Arc operator()(const std::string& str) {
187 187
        if (str.empty() || (str[0] != '+' && str[0] != '-')) {
188 188
          throw FormatError("Item must start with '+' or '-'");
189 189
        }
190 190
        typename std::map<std::string, typename Graph::Edge>
191 191
          ::const_iterator it = _map.find(str.substr(1));
192 192
        if (it == _map.end()) {
193 193
          throw FormatError("Item not found");
194 194
        }
195 195
        return _graph.direct(it->second, str[0] == '+');
196 196
      }
197 197
    };
... ...
@@ -774,384 +774,391 @@
774 774
      _use_arcs = true;
775 775
      _writer_bits::DefaultConverter<typename Map::Value> converter;
776 776
      for (ArcIt a(_digraph); a != INVALID; ++a) {
777 777
        _arc_index.insert(std::make_pair(converter(map[a]), a));
778 778
      }
779 779
      return *this;
780 780
    }
781 781

	
782 782
    /// \brief Use previously constructed arc set
783 783
    ///
784 784
    /// Use previously constructed arc set, and specify the arc
785 785
    /// label map and a functor which converts the label map values to
786 786
    /// \c std::string.
787 787
    template <typename Map, typename Converter>
788 788
    DigraphReader& useArcs(const Map& map,
789 789
                           const Converter& converter = Converter()) {
790 790
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
791 791
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
792 792
      _use_arcs = true;
793 793
      for (ArcIt a(_digraph); a != INVALID; ++a) {
794 794
        _arc_index.insert(std::make_pair(converter(map[a]), a));
795 795
      }
796 796
      return *this;
797 797
    }
798 798

	
799 799
    /// \brief Skips the reading of node section
800 800
    ///
801 801
    /// Omit the reading of the node section. This implies that each node
802 802
    /// map reading rule will be abandoned, and the nodes of the graph
803 803
    /// will not be constructed, which usually cause that the arc set
804 804
    /// could not be read due to lack of node name resolving.
805 805
    /// Therefore \c skipArcs() function should also be used, or
806 806
    /// \c useNodes() should be used to specify the label of the nodes.
807 807
    DigraphReader& skipNodes() {
808 808
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
809 809
      _skip_nodes = true;
810 810
      return *this;
811 811
    }
812 812

	
813 813
    /// \brief Skips the reading of arc section
814 814
    ///
815 815
    /// Omit the reading of the arc section. This implies that each arc
816 816
    /// map reading rule will be abandoned, and the arcs of the graph
817 817
    /// will not be constructed.
818 818
    DigraphReader& skipArcs() {
819 819
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set");
820 820
      _skip_arcs = true;
821 821
      return *this;
822 822
    }
823 823

	
824 824
    /// @}
825 825

	
826 826
  private:
827 827

	
828 828
    bool readLine() {
829 829
      std::string str;
830 830
      while(++line_num, std::getline(*_is, str)) {
831 831
        line.clear(); line.str(str);
832 832
        char c;
833 833
        if (line >> std::ws >> c && c != '#') {
834 834
          line.putback(c);
835 835
          return true;
836 836
        }
837 837
      }
838 838
      return false;
839 839
    }
840 840

	
841 841
    bool readSuccess() {
842 842
      return static_cast<bool>(*_is);
843 843
    }
844 844

	
845 845
    void skipSection() {
846 846
      char c;
847 847
      while (readSuccess() && line >> c && c != '@') {
848 848
        readLine();
849 849
      }
850 850
      line.putback(c);
851 851
    }
852 852

	
853 853
    void readNodes() {
854 854

	
855 855
      std::vector<int> map_index(_node_maps.size());
856 856
      int map_num, label_index;
857 857

	
858 858
      char c;
859 859
      if (!readLine() || !(line >> c) || c == '@') {
860 860
        if (readSuccess() && line) line.putback(c);
861 861
        if (!_node_maps.empty())
862 862
          throw FormatError("Cannot find map names");
863 863
        return;
864 864
      }
865 865
      line.putback(c);
866 866

	
867 867
      {
868 868
        std::map<std::string, int> maps;
869 869

	
870 870
        std::string map;
871 871
        int index = 0;
872 872
        while (_reader_bits::readToken(line, map)) {
873 873
          if (maps.find(map) != maps.end()) {
874 874
            std::ostringstream msg;
875 875
            msg << "Multiple occurence of node map: " << map;
876 876
            throw FormatError(msg.str());
877 877
          }
878 878
          maps.insert(std::make_pair(map, index));
879 879
          ++index;
880 880
        }
881 881

	
882 882
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
883 883
          std::map<std::string, int>::iterator jt =
884 884
            maps.find(_node_maps[i].first);
885 885
          if (jt == maps.end()) {
886 886
            std::ostringstream msg;
887 887
            msg << "Map not found: " << _node_maps[i].first;
888 888
            throw FormatError(msg.str());
889 889
          }
890 890
          map_index[i] = jt->second;
891 891
        }
892 892

	
893 893
        {
894 894
          std::map<std::string, int>::iterator jt = maps.find("label");
895 895
          if (jt != maps.end()) {
896 896
            label_index = jt->second;
897 897
          } else {
898 898
            label_index = -1;
899 899
          }
900 900
        }
901 901
        map_num = maps.size();
902 902
      }
903 903

	
904 904
      while (readLine() && line >> c && c != '@') {
905 905
        line.putback(c);
906 906

	
907 907
        std::vector<std::string> tokens(map_num);
908 908
        for (int i = 0; i < map_num; ++i) {
909 909
          if (!_reader_bits::readToken(line, tokens[i])) {
910 910
            std::ostringstream msg;
911 911
            msg << "Column not found (" << i + 1 << ")";
912 912
            throw FormatError(msg.str());
913 913
          }
914 914
        }
915 915
        if (line >> std::ws >> c)
916 916
          throw FormatError("Extra character at the end of line");
917 917

	
918 918
        Node n;
919 919
        if (!_use_nodes) {
920 920
          n = _digraph.addNode();
921 921
          if (label_index != -1)
922 922
            _node_index.insert(std::make_pair(tokens[label_index], n));
923 923
        } else {
924 924
          if (label_index == -1)
925 925
            throw FormatError("Label map not found");
926 926
          typename std::map<std::string, Node>::iterator it =
927 927
            _node_index.find(tokens[label_index]);
928 928
          if (it == _node_index.end()) {
929 929
            std::ostringstream msg;
930 930
            msg << "Node with label not found: " << tokens[label_index];
931 931
            throw FormatError(msg.str());
932 932
          }
933 933
          n = it->second;
934 934
        }
935 935

	
936 936
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
937 937
          _node_maps[i].second->set(n, tokens[map_index[i]]);
938 938
        }
939 939

	
940 940
      }
941 941
      if (readSuccess()) {
942 942
        line.putback(c);
943 943
      }
944 944
    }
945 945

	
946 946
    void readArcs() {
947 947

	
948 948
      std::vector<int> map_index(_arc_maps.size());
949 949
      int map_num, label_index;
950 950

	
951 951
      char c;
952 952
      if (!readLine() || !(line >> c) || c == '@') {
953 953
        if (readSuccess() && line) line.putback(c);
954 954
        if (!_arc_maps.empty())
955 955
          throw FormatError("Cannot find map names");
956 956
        return;
957 957
      }
958 958
      line.putback(c);
959 959

	
960 960
      {
961 961
        std::map<std::string, int> maps;
962 962

	
963 963
        std::string map;
964 964
        int index = 0;
965 965
        while (_reader_bits::readToken(line, map)) {
966
          if(map == "-") {
967
              if(index!=0)
968
                throw FormatError("'-' is not allowed as a map name");
969
              else if (line >> std::ws >> c)
970
                throw FormatError("Extra character at the end of line");
971
              else break;
972
            }
966 973
          if (maps.find(map) != maps.end()) {
967 974
            std::ostringstream msg;
968 975
            msg << "Multiple occurence of arc map: " << map;
969 976
            throw FormatError(msg.str());
970 977
          }
971 978
          maps.insert(std::make_pair(map, index));
972 979
          ++index;
973 980
        }
974 981

	
975 982
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
976 983
          std::map<std::string, int>::iterator jt =
977 984
            maps.find(_arc_maps[i].first);
978 985
          if (jt == maps.end()) {
979 986
            std::ostringstream msg;
980 987
            msg << "Map not found: " << _arc_maps[i].first;
981 988
            throw FormatError(msg.str());
982 989
          }
983 990
          map_index[i] = jt->second;
984 991
        }
985 992

	
986 993
        {
987 994
          std::map<std::string, int>::iterator jt = maps.find("label");
988 995
          if (jt != maps.end()) {
989 996
            label_index = jt->second;
990 997
          } else {
991 998
            label_index = -1;
992 999
          }
993 1000
        }
994 1001
        map_num = maps.size();
995 1002
      }
996 1003

	
997 1004
      while (readLine() && line >> c && c != '@') {
998 1005
        line.putback(c);
999 1006

	
1000 1007
        std::string source_token;
1001 1008
        std::string target_token;
1002 1009

	
1003 1010
        if (!_reader_bits::readToken(line, source_token))
1004 1011
          throw FormatError("Source not found");
1005 1012

	
1006 1013
        if (!_reader_bits::readToken(line, target_token))
1007 1014
          throw FormatError("Target not found");
1008 1015

	
1009 1016
        std::vector<std::string> tokens(map_num);
1010 1017
        for (int i = 0; i < map_num; ++i) {
1011 1018
          if (!_reader_bits::readToken(line, tokens[i])) {
1012 1019
            std::ostringstream msg;
1013 1020
            msg << "Column not found (" << i + 1 << ")";
1014 1021
            throw FormatError(msg.str());
1015 1022
          }
1016 1023
        }
1017 1024
        if (line >> std::ws >> c)
1018 1025
          throw FormatError("Extra character at the end of line");
1019 1026

	
1020 1027
        Arc a;
1021 1028
        if (!_use_arcs) {
1022 1029

	
1023 1030
          typename NodeIndex::iterator it;
1024 1031

	
1025 1032
          it = _node_index.find(source_token);
1026 1033
          if (it == _node_index.end()) {
1027 1034
            std::ostringstream msg;
1028 1035
            msg << "Item not found: " << source_token;
1029 1036
            throw FormatError(msg.str());
1030 1037
          }
1031 1038
          Node source = it->second;
1032 1039

	
1033 1040
          it = _node_index.find(target_token);
1034 1041
          if (it == _node_index.end()) {
1035 1042
            std::ostringstream msg;
1036 1043
            msg << "Item not found: " << target_token;
1037 1044
            throw FormatError(msg.str());
1038 1045
          }
1039 1046
          Node target = it->second;
1040 1047

	
1041 1048
          a = _digraph.addArc(source, target);
1042 1049
          if (label_index != -1)
1043 1050
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1044 1051
        } else {
1045 1052
          if (label_index == -1)
1046 1053
            throw FormatError("Label map not found");
1047 1054
          typename std::map<std::string, Arc>::iterator it =
1048 1055
            _arc_index.find(tokens[label_index]);
1049 1056
          if (it == _arc_index.end()) {
1050 1057
            std::ostringstream msg;
1051 1058
            msg << "Arc with label not found: " << tokens[label_index];
1052 1059
            throw FormatError(msg.str());
1053 1060
          }
1054 1061
          a = it->second;
1055 1062
        }
1056 1063

	
1057 1064
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1058 1065
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1059 1066
        }
1060 1067

	
1061 1068
      }
1062 1069
      if (readSuccess()) {
1063 1070
        line.putback(c);
1064 1071
      }
1065 1072
    }
1066 1073

	
1067 1074
    void readAttributes() {
1068 1075

	
1069 1076
      std::set<std::string> read_attr;
1070 1077

	
1071 1078
      char c;
1072 1079
      while (readLine() && line >> c && c != '@') {
1073 1080
        line.putback(c);
1074 1081

	
1075 1082
        std::string attr, token;
1076 1083
        if (!_reader_bits::readToken(line, attr))
1077 1084
          throw FormatError("Attribute name not found");
1078 1085
        if (!_reader_bits::readToken(line, token))
1079 1086
          throw FormatError("Attribute value not found");
1080 1087
        if (line >> c)
1081 1088
          throw FormatError("Extra character at the end of line");
1082 1089

	
1083 1090
        {
1084 1091
          std::set<std::string>::iterator it = read_attr.find(attr);
1085 1092
          if (it != read_attr.end()) {
1086 1093
            std::ostringstream msg;
1087 1094
            msg << "Multiple occurence of attribute: " << attr;
1088 1095
            throw FormatError(msg.str());
1089 1096
          }
1090 1097
          read_attr.insert(attr);
1091 1098
        }
1092 1099

	
1093 1100
        {
1094 1101
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1095 1102
          while (it != _attributes.end() && it->first == attr) {
1096 1103
            it->second->set(token);
1097 1104
            ++it;
1098 1105
          }
1099 1106
        }
1100 1107

	
1101 1108
      }
1102 1109
      if (readSuccess()) {
1103 1110
        line.putback(c);
1104 1111
      }
1105 1112
      for (typename Attributes::iterator it = _attributes.begin();
1106 1113
           it != _attributes.end(); ++it) {
1107 1114
        if (read_attr.find(it->first) == read_attr.end()) {
1108 1115
          std::ostringstream msg;
1109 1116
          msg << "Attribute not found: " << it->first;
1110 1117
          throw FormatError(msg.str());
1111 1118
        }
1112 1119
      }
1113 1120
    }
1114 1121

	
1115 1122
  public:
1116 1123

	
1117 1124
    /// \name Execution of the reader
1118 1125
    /// @{
1119 1126

	
1120 1127
    /// \brief Start the batch processing
1121 1128
    ///
1122 1129
    /// This function starts the batch processing
1123 1130
    void run() {
1124 1131
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1125 1132

	
1126 1133
      bool nodes_done = _skip_nodes;
1127 1134
      bool arcs_done = _skip_arcs;
1128 1135
      bool attributes_done = false;
1129 1136

	
1130 1137
      line_num = 0;
1131 1138
      readLine();
1132 1139
      skipSection();
1133 1140

	
1134 1141
      while (readSuccess()) {
1135 1142
        try {
1136 1143
          char c;
1137 1144
          std::string section, caption;
1138 1145
          line >> c;
1139 1146
          _reader_bits::readToken(line, section);
1140 1147
          _reader_bits::readToken(line, caption);
1141 1148

	
1142 1149
          if (line >> c)
1143 1150
            throw FormatError("Extra character at the end of line");
1144 1151

	
1145 1152
          if (section == "nodes" && !nodes_done) {
1146 1153
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1147 1154
              readNodes();
1148 1155
              nodes_done = true;
1149 1156
            }
1150 1157
          } else if ((section == "arcs" || section == "edges") &&
1151 1158
                     !arcs_done) {
1152 1159
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1153 1160
              readArcs();
1154 1161
              arcs_done = true;
1155 1162
            }
1156 1163
          } else if (section == "attributes" && !attributes_done) {
1157 1164
            if (_attributes_caption.empty() || _attributes_caption == caption) {
... ...
@@ -1614,384 +1621,391 @@
1614 1621
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1615 1622
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1616 1623
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1617 1624
      }
1618 1625
      return *this;
1619 1626
    }
1620 1627

	
1621 1628
    /// \brief Use previously constructed edge set
1622 1629
    ///
1623 1630
    /// Use previously constructed edge set, and specify the edge
1624 1631
    /// label map and a functor which converts the label map values to
1625 1632
    /// \c std::string.
1626 1633
    template <typename Map, typename Converter>
1627 1634
    GraphReader& useEdges(const Map& map,
1628 1635
                            const Converter& converter = Converter()) {
1629 1636
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1630 1637
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1631 1638
      _use_edges = true;
1632 1639
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1633 1640
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1634 1641
      }
1635 1642
      return *this;
1636 1643
    }
1637 1644

	
1638 1645
    /// \brief Skip the reading of node section
1639 1646
    ///
1640 1647
    /// Omit the reading of the node section. This implies that each node
1641 1648
    /// map reading rule will be abandoned, and the nodes of the graph
1642 1649
    /// will not be constructed, which usually cause that the edge set
1643 1650
    /// could not be read due to lack of node name
1644 1651
    /// could not be read due to lack of node name resolving.
1645 1652
    /// Therefore \c skipEdges() function should also be used, or
1646 1653
    /// \c useNodes() should be used to specify the label of the nodes.
1647 1654
    GraphReader& skipNodes() {
1648 1655
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
1649 1656
      _skip_nodes = true;
1650 1657
      return *this;
1651 1658
    }
1652 1659

	
1653 1660
    /// \brief Skip the reading of edge section
1654 1661
    ///
1655 1662
    /// Omit the reading of the edge section. This implies that each edge
1656 1663
    /// map reading rule will be abandoned, and the edges of the graph
1657 1664
    /// will not be constructed.
1658 1665
    GraphReader& skipEdges() {
1659 1666
      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1660 1667
      _skip_edges = true;
1661 1668
      return *this;
1662 1669
    }
1663 1670

	
1664 1671
    /// @}
1665 1672

	
1666 1673
  private:
1667 1674

	
1668 1675
    bool readLine() {
1669 1676
      std::string str;
1670 1677
      while(++line_num, std::getline(*_is, str)) {
1671 1678
        line.clear(); line.str(str);
1672 1679
        char c;
1673 1680
        if (line >> std::ws >> c && c != '#') {
1674 1681
          line.putback(c);
1675 1682
          return true;
1676 1683
        }
1677 1684
      }
1678 1685
      return false;
1679 1686
    }
1680 1687

	
1681 1688
    bool readSuccess() {
1682 1689
      return static_cast<bool>(*_is);
1683 1690
    }
1684 1691

	
1685 1692
    void skipSection() {
1686 1693
      char c;
1687 1694
      while (readSuccess() && line >> c && c != '@') {
1688 1695
        readLine();
1689 1696
      }
1690 1697
      line.putback(c);
1691 1698
    }
1692 1699

	
1693 1700
    void readNodes() {
1694 1701

	
1695 1702
      std::vector<int> map_index(_node_maps.size());
1696 1703
      int map_num, label_index;
1697 1704

	
1698 1705
      char c;
1699 1706
      if (!readLine() || !(line >> c) || c == '@') {
1700 1707
        if (readSuccess() && line) line.putback(c);
1701 1708
        if (!_node_maps.empty())
1702 1709
          throw FormatError("Cannot find map names");
1703 1710
        return;
1704 1711
      }
1705 1712
      line.putback(c);
1706 1713

	
1707 1714
      {
1708 1715
        std::map<std::string, int> maps;
1709 1716

	
1710 1717
        std::string map;
1711 1718
        int index = 0;
1712 1719
        while (_reader_bits::readToken(line, map)) {
1713 1720
          if (maps.find(map) != maps.end()) {
1714 1721
            std::ostringstream msg;
1715 1722
            msg << "Multiple occurence of node map: " << map;
1716 1723
            throw FormatError(msg.str());
1717 1724
          }
1718 1725
          maps.insert(std::make_pair(map, index));
1719 1726
          ++index;
1720 1727
        }
1721 1728

	
1722 1729
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1723 1730
          std::map<std::string, int>::iterator jt =
1724 1731
            maps.find(_node_maps[i].first);
1725 1732
          if (jt == maps.end()) {
1726 1733
            std::ostringstream msg;
1727 1734
            msg << "Map not found: " << _node_maps[i].first;
1728 1735
            throw FormatError(msg.str());
1729 1736
          }
1730 1737
          map_index[i] = jt->second;
1731 1738
        }
1732 1739

	
1733 1740
        {
1734 1741
          std::map<std::string, int>::iterator jt = maps.find("label");
1735 1742
          if (jt != maps.end()) {
1736 1743
            label_index = jt->second;
1737 1744
          } else {
1738 1745
            label_index = -1;
1739 1746
          }
1740 1747
        }
1741 1748
        map_num = maps.size();
1742 1749
      }
1743 1750

	
1744 1751
      while (readLine() && line >> c && c != '@') {
1745 1752
        line.putback(c);
1746 1753

	
1747 1754
        std::vector<std::string> tokens(map_num);
1748 1755
        for (int i = 0; i < map_num; ++i) {
1749 1756
          if (!_reader_bits::readToken(line, tokens[i])) {
1750 1757
            std::ostringstream msg;
1751 1758
            msg << "Column not found (" << i + 1 << ")";
1752 1759
            throw FormatError(msg.str());
1753 1760
          }
1754 1761
        }
1755 1762
        if (line >> std::ws >> c)
1756 1763
          throw FormatError("Extra character at the end of line");
1757 1764

	
1758 1765
        Node n;
1759 1766
        if (!_use_nodes) {
1760 1767
          n = _graph.addNode();
1761 1768
          if (label_index != -1)
1762 1769
            _node_index.insert(std::make_pair(tokens[label_index], n));
1763 1770
        } else {
1764 1771
          if (label_index == -1)
1765 1772
            throw FormatError("Label map not found");
1766 1773
          typename std::map<std::string, Node>::iterator it =
1767 1774
            _node_index.find(tokens[label_index]);
1768 1775
          if (it == _node_index.end()) {
1769 1776
            std::ostringstream msg;
1770 1777
            msg << "Node with label not found: " << tokens[label_index];
1771 1778
            throw FormatError(msg.str());
1772 1779
          }
1773 1780
          n = it->second;
1774 1781
        }
1775 1782

	
1776 1783
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1777 1784
          _node_maps[i].second->set(n, tokens[map_index[i]]);
1778 1785
        }
1779 1786

	
1780 1787
      }
1781 1788
      if (readSuccess()) {
1782 1789
        line.putback(c);
1783 1790
      }
1784 1791
    }
1785 1792

	
1786 1793
    void readEdges() {
1787 1794

	
1788 1795
      std::vector<int> map_index(_edge_maps.size());
1789 1796
      int map_num, label_index;
1790 1797

	
1791 1798
      char c;
1792 1799
      if (!readLine() || !(line >> c) || c == '@') {
1793 1800
        if (readSuccess() && line) line.putback(c);
1794 1801
        if (!_edge_maps.empty())
1795 1802
          throw FormatError("Cannot find map names");
1796 1803
        return;
1797 1804
      }
1798 1805
      line.putback(c);
1799 1806

	
1800 1807
      {
1801 1808
        std::map<std::string, int> maps;
1802 1809

	
1803 1810
        std::string map;
1804 1811
        int index = 0;
1805 1812
        while (_reader_bits::readToken(line, map)) {
1813
          if(map == "-") {
1814
              if(index!=0)
1815
                throw FormatError("'-' is not allowed as a map name");
1816
              else if (line >> std::ws >> c)
1817
                throw FormatError("Extra character at the end of line");
1818
              else break;
1819
            }
1806 1820
          if (maps.find(map) != maps.end()) {
1807 1821
            std::ostringstream msg;
1808 1822
            msg << "Multiple occurence of edge map: " << map;
1809 1823
            throw FormatError(msg.str());
1810 1824
          }
1811 1825
          maps.insert(std::make_pair(map, index));
1812 1826
          ++index;
1813 1827
        }
1814 1828

	
1815 1829
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1816 1830
          std::map<std::string, int>::iterator jt =
1817 1831
            maps.find(_edge_maps[i].first);
1818 1832
          if (jt == maps.end()) {
1819 1833
            std::ostringstream msg;
1820 1834
            msg << "Map not found: " << _edge_maps[i].first;
1821 1835
            throw FormatError(msg.str());
1822 1836
          }
1823 1837
          map_index[i] = jt->second;
1824 1838
        }
1825 1839

	
1826 1840
        {
1827 1841
          std::map<std::string, int>::iterator jt = maps.find("label");
1828 1842
          if (jt != maps.end()) {
1829 1843
            label_index = jt->second;
1830 1844
          } else {
1831 1845
            label_index = -1;
1832 1846
          }
1833 1847
        }
1834 1848
        map_num = maps.size();
1835 1849
      }
1836 1850

	
1837 1851
      while (readLine() && line >> c && c != '@') {
1838 1852
        line.putback(c);
1839 1853

	
1840 1854
        std::string source_token;
1841 1855
        std::string target_token;
1842 1856

	
1843 1857
        if (!_reader_bits::readToken(line, source_token))
1844 1858
          throw FormatError("Node u not found");
1845 1859

	
1846 1860
        if (!_reader_bits::readToken(line, target_token))
1847 1861
          throw FormatError("Node v not found");
1848 1862

	
1849 1863
        std::vector<std::string> tokens(map_num);
1850 1864
        for (int i = 0; i < map_num; ++i) {
1851 1865
          if (!_reader_bits::readToken(line, tokens[i])) {
1852 1866
            std::ostringstream msg;
1853 1867
            msg << "Column not found (" << i + 1 << ")";
1854 1868
            throw FormatError(msg.str());
1855 1869
          }
1856 1870
        }
1857 1871
        if (line >> std::ws >> c)
1858 1872
          throw FormatError("Extra character at the end of line");
1859 1873

	
1860 1874
        Edge e;
1861 1875
        if (!_use_edges) {
1862 1876

	
1863 1877
          typename NodeIndex::iterator it;
1864 1878

	
1865 1879
          it = _node_index.find(source_token);
1866 1880
          if (it == _node_index.end()) {
1867 1881
            std::ostringstream msg;
1868 1882
            msg << "Item not found: " << source_token;
1869 1883
            throw FormatError(msg.str());
1870 1884
          }
1871 1885
          Node source = it->second;
1872 1886

	
1873 1887
          it = _node_index.find(target_token);
1874 1888
          if (it == _node_index.end()) {
1875 1889
            std::ostringstream msg;
1876 1890
            msg << "Item not found: " << target_token;
1877 1891
            throw FormatError(msg.str());
1878 1892
          }
1879 1893
          Node target = it->second;
1880 1894

	
1881 1895
          e = _graph.addEdge(source, target);
1882 1896
          if (label_index != -1)
1883 1897
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1884 1898
        } else {
1885 1899
          if (label_index == -1)
1886 1900
            throw FormatError("Label map not found");
1887 1901
          typename std::map<std::string, Edge>::iterator it =
1888 1902
            _edge_index.find(tokens[label_index]);
1889 1903
          if (it == _edge_index.end()) {
1890 1904
            std::ostringstream msg;
1891 1905
            msg << "Edge with label not found: " << tokens[label_index];
1892 1906
            throw FormatError(msg.str());
1893 1907
          }
1894 1908
          e = it->second;
1895 1909
        }
1896 1910

	
1897 1911
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1898 1912
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1899 1913
        }
1900 1914

	
1901 1915
      }
1902 1916
      if (readSuccess()) {
1903 1917
        line.putback(c);
1904 1918
      }
1905 1919
    }
1906 1920

	
1907 1921
    void readAttributes() {
1908 1922

	
1909 1923
      std::set<std::string> read_attr;
1910 1924

	
1911 1925
      char c;
1912 1926
      while (readLine() && line >> c && c != '@') {
1913 1927
        line.putback(c);
1914 1928

	
1915 1929
        std::string attr, token;
1916 1930
        if (!_reader_bits::readToken(line, attr))
1917 1931
          throw FormatError("Attribute name not found");
1918 1932
        if (!_reader_bits::readToken(line, token))
1919 1933
          throw FormatError("Attribute value not found");
1920 1934
        if (line >> c)
1921 1935
          throw FormatError("Extra character at the end of line");
1922 1936

	
1923 1937
        {
1924 1938
          std::set<std::string>::iterator it = read_attr.find(attr);
1925 1939
          if (it != read_attr.end()) {
1926 1940
            std::ostringstream msg;
1927 1941
            msg << "Multiple occurence of attribute: " << attr;
1928 1942
            throw FormatError(msg.str());
1929 1943
          }
1930 1944
          read_attr.insert(attr);
1931 1945
        }
1932 1946

	
1933 1947
        {
1934 1948
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1935 1949
          while (it != _attributes.end() && it->first == attr) {
1936 1950
            it->second->set(token);
1937 1951
            ++it;
1938 1952
          }
1939 1953
        }
1940 1954

	
1941 1955
      }
1942 1956
      if (readSuccess()) {
1943 1957
        line.putback(c);
1944 1958
      }
1945 1959
      for (typename Attributes::iterator it = _attributes.begin();
1946 1960
           it != _attributes.end(); ++it) {
1947 1961
        if (read_attr.find(it->first) == read_attr.end()) {
1948 1962
          std::ostringstream msg;
1949 1963
          msg << "Attribute not found: " << it->first;
1950 1964
          throw FormatError(msg.str());
1951 1965
        }
1952 1966
      }
1953 1967
    }
1954 1968

	
1955 1969
  public:
1956 1970

	
1957 1971
    /// \name Execution of the reader
1958 1972
    /// @{
1959 1973

	
1960 1974
    /// \brief Start the batch processing
1961 1975
    ///
1962 1976
    /// This function starts the batch processing
1963 1977
    void run() {
1964 1978

	
1965 1979
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1966 1980

	
1967 1981
      bool nodes_done = _skip_nodes;
1968 1982
      bool edges_done = _skip_edges;
1969 1983
      bool attributes_done = false;
1970 1984

	
1971 1985
      line_num = 0;
1972 1986
      readLine();
1973 1987
      skipSection();
1974 1988

	
1975 1989
      while (readSuccess()) {
1976 1990
        try {
1977 1991
          char c;
1978 1992
          std::string section, caption;
1979 1993
          line >> c;
1980 1994
          _reader_bits::readToken(line, section);
1981 1995
          _reader_bits::readToken(line, caption);
1982 1996

	
1983 1997
          if (line >> c)
1984 1998
            throw FormatError("Extra character at the end of line");
1985 1999

	
1986 2000
          if (section == "nodes" && !nodes_done) {
1987 2001
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1988 2002
              readNodes();
1989 2003
              nodes_done = true;
1990 2004
            }
1991 2005
          } else if ((section == "edges" || section == "arcs") &&
1992 2006
                     !edges_done) {
1993 2007
            if (_edges_caption.empty() || _edges_caption == caption) {
1994 2008
              readEdges();
1995 2009
              edges_done = true;
1996 2010
            }
1997 2011
          } else if (section == "attributes" && !attributes_done) {
Ignore white space 6 line context
1 1
INCLUDE_DIRECTORIES(
2 2
  ${CMAKE_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6 6
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
7 7

	
8 8
SET(TESTS
9 9
  bfs_test
10 10
  counter_test
11 11
  dfs_test
12 12
  digraph_test
13 13
  dijkstra_test
14 14
  dim_test
15 15
  error_test
16 16
  graph_copy_test
17 17
  graph_test
18 18
  graph_utils_test
19 19
  heap_test
20 20
  kruskal_test
21
  lgf_test
21 22
  maps_test
22 23
  random_test
23 24
  path_test
24 25
  time_measure_test
25 26
  unionfind_test)
26 27

	
27 28
FOREACH(TEST_NAME ${TESTS})
28 29
  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
29 30
  TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
30 31
  ADD_TEST(${TEST_NAME} ${TEST_NAME})
31 32
ENDFOREACH(TEST_NAME)
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	test/CMakeLists.txt
3 3

	
4 4
noinst_HEADERS += \
5 5
	test/graph_test.h \
6 6
        test/test_tools.h
7 7

	
8 8
check_PROGRAMS += \
9 9
	test/bfs_test \
10 10
        test/counter_test \
11 11
	test/dfs_test \
12 12
	test/digraph_test \
13 13
	test/dijkstra_test \
14 14
        test/dim_test \
15 15
	test/error_test \
16 16
	test/graph_copy_test \
17 17
	test/graph_test \
18 18
	test/graph_utils_test \
19 19
	test/heap_test \
20 20
	test/kruskal_test \
21
	test/lgf_test \
21 22
        test/maps_test \
22 23
        test/random_test \
23 24
        test/path_test \
24 25
        test/test_tools_fail \
25 26
        test/test_tools_pass \
26 27
        test/time_measure_test \
27 28
	test/unionfind_test
28 29

	
29 30
TESTS += $(check_PROGRAMS)
30 31
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
31 32

	
32 33
test_bfs_test_SOURCES = test/bfs_test.cc
33 34
test_counter_test_SOURCES = test/counter_test.cc
34 35
test_dfs_test_SOURCES = test/dfs_test.cc
35 36
test_digraph_test_SOURCES = test/digraph_test.cc
36 37
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
37 38
test_dim_test_SOURCES = test/dim_test.cc
38 39
test_error_test_SOURCES = test/error_test.cc
39 40
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
40 41
test_graph_test_SOURCES = test/graph_test.cc
41 42
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
42 43
test_heap_test_SOURCES = test/heap_test.cc
43 44
test_kruskal_test_SOURCES = test/kruskal_test.cc
45
test_lgf_test_SOURCES = test/lgf_test.cc
44 46
test_maps_test_SOURCES = test/maps_test.cc
45 47
test_path_test_SOURCES = test/path_test.cc
46 48
test_random_test_SOURCES = test/random_test.cc
47 49
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
48 50
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
49 51
test_time_measure_test_SOURCES = test/time_measure_test.cc
50 52
test_unionfind_test_SOURCES = test/unionfind_test.cc
0 comments (0 inline)