File: mbl_parse_block.cxx

package info (click to toggle)
vxl 1.17.0.dfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 153,280 kB
  • ctags: 105,123
  • sloc: cpp: 747,420; ansic: 209,130; fortran: 34,230; lisp: 14,915; sh: 6,187; python: 5,856; makefile: 340; perl: 294; xml: 160
file content (130 lines) | stat: -rw-r--r-- 3,779 bytes parent folder | download
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
// This is mul/mbl/mbl_parse_block.cxx
#include "mbl_parse_block.h"
//:
// \file
// \author Ian Scott
// \date  25-Feb-2003
// \brief Load a block of text from a file.

#include <vcl_cctype.h>
#include <vcl_cstring.h>
#include <vcl_iostream.h>
#include <mbl/mbl_exception.h>

//: Read a block of text from a stream.
// This function will read through a stream, and store the text found to a string.
// The function terminates when it finds the closing brace.
//
// The stream's fail bit will be set on error. Comment lines beginning with //
// will be stripped.
// \param open_already should be true if the client has already
// read the opening brace. If set to false and the first non-whitespace character is
// not an opening brace then that character will be left in the stream and "{} will be returned.
// \return the text including the opening and closing braces.
// \param comment Lines beginning with white space followed by this string will be ignored.
// \throws mbl_exception_parse_block_parse_error if unrecoverable parse error.
// Set to empty for no comment stripping.

vcl_string mbl_parse_block(vcl_istream &afs, bool open_already /*= false*/, const char * comment /*= "//"*/)
{
  if (!afs) return "{}";
  //: The last character to be read from the stream
  char c;

  // length of the comment token;
  const unsigned comment_length = vcl_strlen(comment);

  if (!open_already)
  {
    if (afs.eof())
      return "{}";
    afs >> c;

    if (!afs) return "{}";
    while (comment && comment_length && c == *comment)
    {
      for (unsigned comment_pos=1; comment_pos < comment_length; ++comment_pos)
      {
        if (afs.eof())
          return "{}";
        afs >> c;
        if (c != comment[comment_pos])
        {
          afs.putback(c); // push c back into stream.
          return "{}";
        }
      }
      vcl_string dummy;
      vcl_getline(afs, dummy);
      if (afs.eof())
        return "{}";
      afs >> vcl_ws >> c;
    }
    if (c != '{')
    {
      afs.putback(c); // push c back into stream.
      return "{}";
    }
  }
  // The stored string.
  vcl_string s="{";
  // The current line is stored separately
  // before being added to s, in case it turns out to be a comment.
  vcl_string s2="";
  // The number of open braces.
  unsigned level=1;
  // The current position in a comment token.
  unsigned comment_position=0;
  // true if we are currently in the whitespace at the beginning of a line
  bool newline=true;

  while (!(!afs))
  {
    // read in one line at a time, to make decisions about comments
    while (!(!afs))
    {
      afs.get(c);
      s2 += c;
      if (c=='\n')
      {
        s+=s2;
        s2="";
        newline = true;
        comment_position = 0;
      }
      else if (vcl_isspace(c))
        comment_position = 0;
      else if (newline && comment_position < comment_length
               &&  c==comment[comment_position])
      {
        if (++comment_position == 2)
        {
          vcl_string dummy;
          vcl_getline(afs, dummy);
          s2 = "";
          newline = true; //false;
          comment_position = 0;
        }
      }
      else
      {
        newline = false;
        comment_position = 0;
        if (c=='{') ++level;
        else if (c=='}')
          if (--level==0) // Found final closing brace
          {
            s+=s2;
            for (unsigned i = 1; i+1 < s.size(); ++i)
              if (!vcl_isspace(s[i])) return s;
            // Contents between braces is just empty space
            return "{}";
          }
      }
    }
  }
  mbl_exception_warning(mbl_exception_parse_block_parse_error(
    "Read problem (possibly end-of-file) before closing '}'\n",s));
  afs.clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
  return "{}";
}