File: automate_reader.cc

package info (click to toggle)
monotone 0.48-3
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 20,096 kB
  • ctags: 8,077
  • sloc: cpp: 81,000; sh: 6,402; perl: 1,241; lisp: 1,045; makefile: 655; python: 566; sql: 112; ansic: 52
file content (138 lines) | stat: -rw-r--r-- 3,069 bytes parent folder | download | duplicates (2)
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
// Copyright (C) 2005 and later by various people
// see monotone commit logs for details and authors
//
// This program is made available under the GNU GPL version 2.0 or
// greater. See the accompanying file COPYING for details.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE.


#include "base.hh"
#include "automate_reader.hh"

#include <iostream>

#include "sanity.hh"

using std::istream;
using std::pair;
using std::streamsize;
using std::string;
using std::vector;

bool automate_reader::get_string(string & out)
{
  out.clear();
  if (loc == none || loc == eof)
    {
      return false;
    }
  size_t size(0);
  char c;
  read(&c, 1);
  if (c == 'e')
    {
      loc = none;
      return false;
    }
  while(c <= '9' && c >= '0')
    {
      size = (size*10)+(c-'0');
      read(&c, 1);
    }
  E(c == ':', origin::user,
    F("Bad input to automate stdio: expected ':' after string size"));
  char *str = new char[size];
  size_t got = 0;
  while(got < size)
    {
      int n = read(str+got, size-got);
      got += n;
    }
  out = string(str, size);
  delete[] str;
  L(FL("Got string '%s'") % out);
  return true;
}
streamsize automate_reader::read(char *buf, size_t nbytes, bool eof_ok)
{
  streamsize rv;

  rv = in.rdbuf()->sgetn(buf, nbytes);

  E(eof_ok || rv > 0, origin::user,
    F("Bad input to automate stdio: unexpected EOF"));
  return rv;
}
void automate_reader::go_to_next_item()
{
  if (loc == eof)
    return;
  string starters("ol");
  string whitespace(" \r\n\t");
  string foo;
  while (loc != none)
    get_string(foo);
  char c('e');
  do
    {
      if (read(&c, 1, true) == 0)
        {
          loc = eof;
          return;
        }
    }
  while (whitespace.find(c) != string::npos);
  switch (c)
    {
    case 'o': loc = opt; break;
    case 'l': loc = cmd; break;
    default:
      E(false, origin::user,
        F("Bad input to automate stdio: unknown start token '%c'") % c);
    }
}
automate_reader::automate_reader(istream & is) : in(is), loc(none)
{}
bool automate_reader::get_command(vector<pair<string, string> > & params,
                                  vector<string> & cmdline)
{
  params.clear();
  cmdline.clear();
  if (loc == none)
    go_to_next_item();
  if (loc == eof)
    return false;
  else if (loc == opt)
    {
      string key, val;
      while(get_string(key) && get_string(val))
        params.push_back(make_pair(key, val));
      go_to_next_item();
    }
  E(loc == cmd, origin::user,
    F("Bad input to automate stdio: expected '%c' token") % cmd);
  string item;
  while (get_string(item))
    {
      cmdline.push_back(item);
    }
  E(cmdline.size() > 0, origin::user,
    F("Bad input to automate stdio: command name is missing"));
  return true;
}
void automate_reader::reset()
{
  loc = none;
}


// Local Variables:
// mode: C++
// fill-column: 76
// c-file-style: "gnu"
// indent-tabs-mode: nil
// End:
// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: