monotone

monotone Mtn Source Tree

Root/selectors.cc

1// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
2//
3// This program is made available under the GNU GPL version 2.0 or
4// greater. See the accompanying file COPYING for details.
5//
6// This program is distributed WITHOUT ANY WARRANTY; without even the
7// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8// PURPOSE.
9
10#include "base.hh"
11#include "selectors.hh"
12#include "sanity.hh"
13#include "app_state.hh"
14#include "constants.hh"
15
16#include <boost/tokenizer.hpp>
17
18using std::make_pair;
19using std::pair;
20using std::set;
21using std::string;
22using std::vector;
23
24namespace selectors
25{
26
27 static void
28 decode_selector(string const & orig_sel,
29 selector_type & type,
30 string & sel,
31 app_state & app)
32 {
33 sel = orig_sel;
34
35 L(FL("decoding selector '%s'") % sel);
36
37 string tmp;
38 if (sel.size() < 2 || sel[1] != ':')
39 {
40 if (!app.lua.hook_expand_selector(sel, tmp))
41 {
42 L(FL("expansion of selector '%s' failed") % sel);
43 }
44 else
45 {
46 P(F("expanded selector '%s' -> '%s'") % sel % tmp);
47 sel = tmp;
48 }
49 }
50
51 if (sel.size() >= 2 && sel[1] == ':')
52 {
53 switch (sel[0])
54 {
55 case 'a':
56 type = sel_author;
57 break;
58 case 'b':
59 type = sel_branch;
60 break;
61 case 'h':
62 type = sel_head;
63 break;
64 case 'd':
65 type = sel_date;
66 break;
67 case 'i':
68 type = sel_ident;
69 break;
70 case 't':
71 type = sel_tag;
72 break;
73 case 'c':
74 type = sel_cert;
75 break;
76 case 'l':
77 type = sel_later;
78 break;
79 case 'e':
80 type = sel_earlier;
81 break;
82 default:
83 W(F("unknown selector type: %c") % sel[0]);
84 break;
85 }
86 sel.erase(0,2);
87
88 /* a selector date-related should be validated */
89 if (sel_date==type || sel_later==type || sel_earlier==type)
90 {
91 if (app.lua.hook_exists("expand_date"))
92 {
93 N(app.lua.hook_expand_date(sel, tmp),
94 F("selector '%s' is not a valid date\n") % sel);
95 }
96 else
97 {
98 // if expand_date is not available, start with something
99 tmp = sel;
100 }
101
102 // if we still have a too short datetime string, expand it with
103 // default values, but only if the type is earlier or later;
104 // for searching a specific date cert this makes no sense
105 // FIXME: this is highly speculative if expand_date wasn't called
106 // beforehand - tmp could be _anything_ but a partial date string
107 if (tmp.size()<8 && (sel_later==type || sel_earlier==type))
108 tmp += "-01T00:00:00";
109 else if (tmp.size()<11 && (sel_later==type || sel_earlier==type))
110 tmp += "T00:00:00";
111 N(tmp.size()==19 || sel_date==type,
112 F("selector '%s' is not a valid date (%s)") % sel % tmp);
113
114 if (sel != tmp)
115 {
116 P (F ("expanded date '%s' -> '%s'\n") % sel % tmp);
117 sel = tmp;
118 }
119 }
120 }
121 }
122
123 void
124 complete_selector(string const & orig_sel,
125 vector<pair<selector_type, string> > const & limit,
126 selector_type & type,
127 set<string> & completions,
128 app_state & app)
129 {
130 string sel;
131 decode_selector(orig_sel, type, sel, app);
132 app.db.complete(type, sel, limit, completions);
133 }
134
135 vector<pair<selector_type, string> >
136 parse_selector(string const & str,
137 app_state & app)
138 {
139 vector<pair<selector_type, string> > sels;
140
141 // this rule should always be enabled, even if the user specifies
142 // --norc: if you provide a revision id, you get a revision id.
143 if (str.find_first_not_of(constants::legal_id_bytes) == string::npos
144 && str.size() == constants::idlen)
145 {
146 sels.push_back(make_pair(sel_ident, str));
147 }
148 else
149 {
150 typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizer;
151 boost::escaped_list_separator<char> slash("\\", "/", "");
152 tokenizer tokens(str, slash);
153
154 vector<string> selector_strings;
155 copy(tokens.begin(), tokens.end(), back_inserter(selector_strings));
156
157 for (vector<string>::const_iterator i = selector_strings.begin();
158 i != selector_strings.end(); ++i)
159 {
160 string sel;
161 selector_type type = sel_unknown;
162
163 decode_selector(*i, type, sel, app);
164 sels.push_back(make_pair(type, sel));
165 }
166 }
167
168 return sels;
169 }
170
171}; // namespace selectors
172
173// Local Variables:
174// mode: C++
175// fill-column: 76
176// c-file-style: "gnu"
177// indent-tabs-mode: nil
178// End:
179// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status