-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathpattern.cpp
67 lines (56 loc) · 1.94 KB
/
pattern.cpp
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
#include <string>
#include <stdexcept>
#include "set_base.h"
#include "mass_tag.h"
#include "sedit.h"
#include "pattern.h"
/*
copyright (c) 2005 squell <info@squell.net>
use, modification, copying and distribution of this software is permitted
under the conditions described in the file 'COPYING'.
*/
using namespace tag;
using fileexp::mass_tag;
using std::string;
using std::wstring;
using charset::conv;
// "inside out" way of specifying what you want.
// - kind of lazy. but hey long live code reuse :)
// - assumes sedit() processes variables left-to-right
namespace {
struct counter : stredit::format {
handler* tag; // Borland doesn't like ref's in aggr's?
mutable unsigned w;
mutable ptr mod;
counter(handler* h) : tag(h), w(0) { }
virtual result var (ptr& p, ptr end) const;
virtual result code (ptr& p, ptr end) const
{ mod = p; return stredit::format::code(p, end); }
};
counter::result counter::var(ptr& p, ptr) const
{
if(++w == 10) // limit reached
throw std::out_of_range("too many variables in pattern");
ID3field field = mass_tag::field(*p);
if(field < tag::FIELD_MAX) {
const string& pre = conv<wchar_t>(wstring(mod,p)).str<char>();
tag->set(field, pre + char('0'+w));
} else if(*p == 'x') {
; // pass over in silence
} else {
static const char error[] = "illegal variable: %";
throw std::out_of_range(error+conv<wchar_t>(&*p, 1).str<char>());
}
return ++p, "*";
}
}
pattern::pattern(handler& tag, std::string mask)
{
string::size_type pos(0); // replace '*' with stubs
while((pos = mask.find('*',pos)) != string::npos) {
mask.replace(pos, 1, "%x");
}
counter var(&tag);
this->assign( var(mask) );
num = var.w;
}