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 case 'p':
83 type = sel_parent;
84 break;
85 default:
86 W(F("unknown selector type: %c") % sel[0]);
87 break;
88 }
89 sel.erase(0,2);
90
91 /* a selector date-related should be validated */
92 if (sel_date==type || sel_later==type || sel_earlier==type)
93 {
94 if (app.lua.hook_exists("expand_date"))
95 {
96 N(app.lua.hook_expand_date(sel, tmp),
97 F("selector '%s' is not a valid date\n") % sel);
98 }
99 else
100 {
101 // if expand_date is not available, start with something
102 tmp = sel;
103 }
104
105 // if we still have a too short datetime string, expand it with
106 // default values, but only if the type is earlier or later;
107 // for searching a specific date cert this makes no sense
108 // FIXME: this is highly speculative if expand_date wasn't called
109 // beforehand - tmp could be _anything_ but a partial date string
110 if (tmp.size()<8 && (sel_later==type || sel_earlier==type))
111 tmp += "-01T00:00:00";
112 else if (tmp.size()<11 && (sel_later==type || sel_earlier==type))
113 tmp += "T00:00:00";
114 N(tmp.size()==19 || sel_date==type,
115 F("selector '%s' is not a valid date (%s)") % sel % tmp);
116
117 if (sel != tmp)
118 {
119 P (F ("expanded date '%s' -> '%s'\n") % sel % tmp);
120 sel = tmp;
121 }
122 }
123 }
124 }
125
126 void
127 complete_selector(string const & orig_sel,
128 vector<pair<selector_type, string> > const & limit,
129 selector_type & type,
130 set<string> & completions,
131 app_state & app)
132 {
133 string sel;
134 decode_selector(orig_sel, type, sel, app);
135 app.db.complete(type, sel, limit, completions);
136 }
137
138 vector<pair<selector_type, string> >
139 parse_selector(string const & str,
140 app_state & app)
141 {
142 vector<pair<selector_type, string> > sels;
143
144 // this rule should always be enabled, even if the user specifies
145 // --norc: if you provide a revision id, you get a revision id.
146 if (str.find_first_not_of(constants::legal_id_bytes) == string::npos
147 && str.size() == constants::idlen)
148 {
149 sels.push_back(make_pair(sel_ident, str));
150 }
151 else
152 {
153 typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizer;
154 boost::escaped_list_separator<char> slash("\\", "/", "");
155 tokenizer tokens(str, slash);
156
157 vector<string> selector_strings;
158 copy(tokens.begin(), tokens.end(), back_inserter(selector_strings));
159
160 for (vector<string>::const_iterator i = selector_strings.begin();
161 i != selector_strings.end(); ++i)
162 {
163 string sel;
164 selector_type type = sel_unknown;
165
166 decode_selector(*i, type, sel, app);
167 sels.push_back(make_pair(type, sel));
168 }
169 }
170
171 return sels;
172 }
173
174}; // namespace selectors
175
176// Local Variables:
177// mode: C++
178// fill-column: 76
179// c-file-style: "gnu"
180// indent-tabs-mode: nil
181// End:
182// 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