p4ruby 2015.2.1265122-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,239 @@
1
+ /*******************************************************************************
2
+
3
+ Copyright (c) 2001-2008, Perforce Software, Inc. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+
26
+ *******************************************************************************/
27
+
28
+ /*******************************************************************************
29
+ * Name : p4clientapi.h
30
+ *
31
+ * Author : Tony Smith <tony@perforce.com> or <tony@smee.org>
32
+ *
33
+ * Description : Ruby bindings for the Perforce API. Definitions of our
34
+ * main interface to Perforce
35
+ *
36
+ ******************************************************************************/
37
+
38
+
39
+ /*******************************************************************************
40
+ * P4ClientApi class - where we register our Ruby classes and plumb together
41
+ * the components
42
+ ******************************************************************************/
43
+
44
+ class Enviro;
45
+ class P4ClientApi
46
+ {
47
+ public:
48
+ P4ClientApi();
49
+ ~P4ClientApi();
50
+
51
+ // Tagged mode - can be enabled/disabled on a per-command basis
52
+ void Tagged( int enable );
53
+ int IsTagged() { return IsTag(); }
54
+
55
+ // Set track mode - track usage of this command on the server
56
+ int SetTrack( int enable );
57
+ int GetTrack() { return IsTrackMode() != 0; }
58
+
59
+ // Set streams mode
60
+
61
+ void SetStreams( int enable );
62
+ int IsStreams() { return IsStreamsMode() != 0; };
63
+
64
+ // Returns bool, but may raise exception
65
+ int SetCharset( const char *c );
66
+
67
+ // Set API level for backwards compatibility
68
+ void SetApiLevel( int level );
69
+
70
+ void SetClient( const char *c ) { client.SetClient( c ); }
71
+ void SetCwd( const char *c );
72
+ void SetEnviroFile( const char *c );
73
+ void SetHost( const char *h ) { client.SetHost( h ); }
74
+ void SetIgnoreFile( const char *f ) { client.SetIgnoreFile( f ); }
75
+ void SetMaxResults( int v ) { maxResults = v; }
76
+ void SetMaxScanRows( int v ) { maxScanRows = v; }
77
+ void SetMaxLockTime( int v ) { maxLockTime = v; }
78
+ VALUE SetEnv( const char *var, const char *val );
79
+ void SetLanguage( const char *l ) { client.SetLanguage( l ); }
80
+ void SetPassword( const char *p ) { client.SetPassword( p ); }
81
+ void SetPort( const char *p ) { client.SetPort( p ); }
82
+ void SetProg( const char *p ) { prog = p; }
83
+ void SetProtocol( const char *var, const char *val );
84
+ void SetTicketFile( const char *p );
85
+ void SetUser( const char *u ) { client.SetUser( u ); }
86
+ void SetVersion( const char *v ) { version = v; }
87
+
88
+ int GetApiLevel() { return apiLevel; }
89
+ const StrPtr &GetCharset() { return client.GetCharset(); }
90
+ const StrPtr &GetClient() { return client.GetClient(); }
91
+ const StrPtr &GetConfig() { return client.GetConfig(); }
92
+ const StrPtr &GetCwd() { return client.GetCwd(); }
93
+ const char * GetEnv( const char *v);
94
+ const StrPtr *GetEnviroFile();
95
+ const StrPtr &GetHost() { return client.GetHost(); }
96
+ const StrPtr &GetIgnoreFile() { return client.GetIgnoreFile();}
97
+ const StrPtr &GetLanguage() { return client.GetLanguage(); }
98
+ const StrPtr &GetPassword() { return client.GetPassword(); }
99
+ const StrPtr &GetPort() { return client.GetPort(); }
100
+ const StrPtr &GetProg() { return prog; }
101
+ const StrPtr &GetTicketFile() { return ticketFile; }
102
+ const StrPtr &GetUser() { return client.GetUser(); }
103
+ const StrPtr &GetVersion() { return version; }
104
+
105
+ int IsIgnored( const char *path );
106
+
107
+ int GetMaxResults() { return maxResults; }
108
+ int GetMaxScanRows() { return maxScanRows; }
109
+ int GetMaxLockTime() { return maxLockTime; }
110
+ int GetServerLevel();
111
+ int ServerCaseSensitive();
112
+ int ServerUnicode();
113
+
114
+
115
+ // Session management
116
+ VALUE Connect(); // P4Exception on error
117
+ VALUE Connected(); // Return true if connected and not dropped.
118
+ VALUE Disconnect();
119
+
120
+ // Executing commands.
121
+ VALUE Run( const char *cmd, int argc, char * const *argv );
122
+ VALUE SetInput( VALUE input );
123
+
124
+ // Result handling
125
+ VALUE GetErrors() { return ui.GetResults().GetErrors();}
126
+ VALUE GetWarnings() { return ui.GetResults().GetWarnings();}
127
+ VALUE GetMessages() { return ui.GetResults().GetMessages();}
128
+ VALUE GetTrackOutput() { return ui.GetResults().GetTrack();}
129
+
130
+ // Spec parsing
131
+ VALUE ParseSpec( const char * type, const char *form );
132
+ VALUE FormatSpec( const char *type, VALUE hash );
133
+ VALUE SpecFields( const char * type );
134
+
135
+ // Exception levels:
136
+ //
137
+ // 0 - No exceptions raised
138
+ // 1 - Exceptions raised for errors
139
+ // 2 - Exceptions raised for errors and warnings
140
+ //
141
+ void ExceptionLevel( int i ) { exceptionLevel = i; }
142
+ int ExceptionLevel() { return exceptionLevel; }
143
+
144
+ void Except( const char *func, Error *e );
145
+ void Except( const char *func, const char *msg );
146
+ void Except( const char *func, const char *msg, const char *cmd );
147
+
148
+ //
149
+ // Debugging support. Debug levels are:
150
+ //
151
+ // 1: Debugs commands being executed
152
+ // 2: Debug UI method calls
153
+ // 3: Show garbage collection
154
+ //
155
+ int GetDebug() { return debug; }
156
+ void SetDebug( int d );
157
+
158
+ // Handler support
159
+
160
+ VALUE SetHandler( VALUE handler );
161
+ VALUE GetHandler() { return ui.GetHandler(); }
162
+
163
+ // Progress API support
164
+ VALUE SetProgress( VALUE progress );
165
+ VALUE GetProgress() { return ui.GetProgress(); }
166
+
167
+ // Ruby garbage collection
168
+ void GCMark();
169
+
170
+
171
+ private:
172
+
173
+ void RunCmd(const char *cmd, ClientUser *ui, int argc, char * const *argv);
174
+
175
+ VALUE ConnectOrReconnect(); // internal connect method
176
+
177
+ enum {
178
+ S_TAGGED = 0x0001,
179
+ S_CONNECTED = 0x0002,
180
+ S_CMDRUN = 0x0004,
181
+ S_UNICODE = 0x0008,
182
+ S_CASEFOLDING = 0x0010,
183
+ S_TRACK = 0x0020,
184
+ S_STREAMS = 0x0040,
185
+
186
+ S_INITIAL_STATE = 0x0041,
187
+ S_RESET_MASK = 0x001E,
188
+ };
189
+
190
+ void InitFlags() { flags = S_INITIAL_STATE; }
191
+ void ResetFlags() { flags &= ~S_RESET_MASK; }
192
+
193
+ void SetTag() { flags |= S_TAGGED; }
194
+ void ClearTag() { flags &= ~S_TAGGED; }
195
+ int IsTag() { return flags & S_TAGGED; }
196
+
197
+ void SetConnected() { flags |= S_CONNECTED; }
198
+ void ClearConnected() { flags &= ~S_CONNECTED; }
199
+ int IsConnected() { return flags & S_CONNECTED; }
200
+
201
+ void SetCmdRun() { flags |= S_CMDRUN; }
202
+ void ClearCmdRun() { flags &= ~S_CMDRUN; }
203
+ int IsCmdRun() { return flags & S_CMDRUN; }
204
+
205
+ void SetUnicode() { flags |= S_UNICODE; }
206
+ void ClearUnicode() { flags &= ~S_UNICODE; }
207
+ int IsUnicode() { return flags & S_UNICODE; }
208
+
209
+ void SetCaseFold() { flags |= S_CASEFOLDING; }
210
+ void ClearCaseFold() { flags &= ~S_CASEFOLDING; }
211
+ int IsCaseFold() { return flags & S_CASEFOLDING; }
212
+
213
+ void SetTrackMode() { flags |= S_TRACK; }
214
+ void ClearTrackMode() { flags &= ~S_TRACK; }
215
+ int IsTrackMode() { return flags & S_TRACK; }
216
+
217
+ void SetStreamsMode() { flags |= S_STREAMS; }
218
+ void ClearStreamsMode() { flags &= ~S_STREAMS; }
219
+ int IsStreamsMode() { return flags & S_STREAMS; }
220
+
221
+ private:
222
+ ClientApi client;
223
+ ClientUserRuby ui;
224
+ Enviro * enviro;
225
+ SpecMgr specMgr;
226
+ StrBuf prog;
227
+ StrBuf version;
228
+ StrBuf ticketFile;
229
+ int depth;
230
+ int debug;
231
+ int exceptionLevel;
232
+ int apiLevel;
233
+ int server2;
234
+ int flags;
235
+ int maxResults;
236
+ int maxScanRows;
237
+ int maxLockTime;
238
+ };
239
+
@@ -0,0 +1,122 @@
1
+ /*******************************************************************************
2
+
3
+ Copyright (c) 2010, Perforce Software, Inc. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+
26
+ *******************************************************************************/
27
+
28
+ /*******************************************************************************
29
+ * Name : p4error.cc
30
+ *
31
+ * Author : Tony Smith <tony@perforce.com> or <tony@smee.org>
32
+ *
33
+ * Description : Class for bridging Perforce's Error class to Ruby
34
+ *
35
+ ******************************************************************************/
36
+ #include <ruby.h>
37
+ #include "undefdups.h"
38
+ #include <p4/clientapi.h>
39
+ #include "p4rubydebug.h"
40
+ #include "p4utils.h"
41
+ #include "p4error.h"
42
+
43
+
44
+ static void error_free( P4Error *e )
45
+ {
46
+ delete e;
47
+ }
48
+
49
+ static void error_mark( P4Error *e )
50
+ {
51
+ e->GCMark();
52
+ }
53
+
54
+
55
+ P4Error::P4Error( const Error &other )
56
+ {
57
+ this->debug = 0;
58
+
59
+ error = other;
60
+ }
61
+
62
+ VALUE
63
+ P4Error::GetId()
64
+ {
65
+ ErrorId *id = error.GetId( 0 );
66
+ if( !id )
67
+ return INT2NUM( 0 );
68
+ return INT2NUM( id->UniqueCode() );
69
+ }
70
+
71
+ VALUE
72
+ P4Error::GetGeneric()
73
+ {
74
+ return INT2NUM( error.GetGeneric() );
75
+ }
76
+
77
+ VALUE
78
+ P4Error::GetSeverity()
79
+ {
80
+ return INT2NUM( error.GetSeverity() );
81
+ }
82
+
83
+ VALUE
84
+ P4Error::GetText()
85
+ {
86
+ StrBuf t;
87
+ error.Fmt( t, EF_PLAIN );
88
+ return P4Utils::ruby_string( t.Text(), t.Length() );
89
+ }
90
+
91
+ VALUE
92
+ P4Error::Inspect()
93
+ {
94
+ StrBuf a;
95
+ StrBuf b;
96
+
97
+ error.Fmt( a, EF_PLAIN );
98
+ b << "[";
99
+ b << "Gen:" << error.GetGeneric();
100
+ b << "/Sev:" << error.GetSeverity();
101
+ b << "]: ";
102
+ b << a;
103
+ return P4Utils::ruby_string( b.Text(), b.Length() );
104
+ }
105
+
106
+ VALUE
107
+ P4Error::Wrap( VALUE pClass )
108
+ {
109
+ VALUE e;
110
+ VALUE argv[ 1 ];
111
+
112
+ e = Data_Wrap_Struct( pClass, error_mark, error_free, this );
113
+ rb_obj_call_init( e, 0, argv );
114
+ return e;
115
+ }
116
+
117
+ void
118
+ P4Error::GCMark()
119
+ {
120
+ // We don't hold Ruby objects
121
+ }
122
+
data/ext/P4/p4error.h ADDED
@@ -0,0 +1,61 @@
1
+ /*******************************************************************************
2
+
3
+ Copyright (c) 2010, Perforce Software, Inc. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+
26
+ *******************************************************************************/
27
+
28
+ /*******************************************************************************
29
+ * Name : p4error.h
30
+ *
31
+ * Author : Tony Smith <tony@perforce.com> or <tony@smee.org>
32
+ *
33
+ * Description : Class for bridging Perforce's Error class to Ruby
34
+ *
35
+ ******************************************************************************/
36
+
37
+ class P4Error
38
+ {
39
+ public:
40
+ // Construct by copying another error object
41
+ P4Error( const Error &other );
42
+
43
+ void SetDebug( int d ) { debug = d; }
44
+
45
+ VALUE GetId();
46
+ VALUE GetGeneric();
47
+ VALUE GetSeverity();
48
+ VALUE GetText();
49
+ VALUE Inspect();
50
+
51
+ // Wrap as Ruby object of class pClass
52
+ VALUE Wrap( VALUE pClass );
53
+
54
+ // Ruby garbage collection
55
+ void GCMark();
56
+
57
+ private:
58
+ Error error;
59
+ int debug;
60
+ };
61
+
@@ -0,0 +1,459 @@
1
+ /*******************************************************************************
2
+
3
+ Copyright (c) 2008, Perforce Software, Inc. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+
26
+ *******************************************************************************/
27
+
28
+ /*******************************************************************************
29
+ * Name : p4mapmaker.cpp
30
+ *
31
+ * Author : Tony Smith <tony@perforce.com>
32
+ *
33
+ * Description : Class to encapsulate Perforce map manipulation from Ruby
34
+ *
35
+ ******************************************************************************/
36
+ #include <ruby.h>
37
+ #include "undefdups.h"
38
+ #include <p4/clientapi.h>
39
+ #include <p4/mapapi.h>
40
+ #include <p4/debug.h>
41
+ #include "p4rubydebug.h"
42
+ #include "p4utils.h"
43
+ #include "p4mapmaker.h"
44
+
45
+
46
+ P4MapMaker::P4MapMaker()
47
+ {
48
+ map = new MapApi;
49
+ }
50
+
51
+ P4MapMaker::~P4MapMaker()
52
+ {
53
+ delete map;
54
+ }
55
+
56
+ P4MapMaker::P4MapMaker( const P4MapMaker &m )
57
+ {
58
+ StrBuf l, r;
59
+ const StrPtr *s;
60
+ MapType t;
61
+ int i;
62
+
63
+ map = new MapApi;
64
+ for( i = 0; i < m.map->Count(); i++ )
65
+ {
66
+ s = m.map->GetLeft( i );
67
+ if( !s ) break;
68
+ l = *s;
69
+
70
+ s = m.map->GetRight( i );
71
+ if( !s ) break;
72
+ r = *s;
73
+
74
+ t = m.map->GetType( i );
75
+
76
+ map->Insert( l, r, t );
77
+ }
78
+ }
79
+
80
+
81
+ P4MapMaker *
82
+ P4MapMaker::Join( P4MapMaker *l, P4MapMaker *r)
83
+ {
84
+ P4MapMaker *m = new P4MapMaker();
85
+ delete m->map;
86
+
87
+ m->map = MapApi::Join( l->map, r->map );
88
+ return m;
89
+ }
90
+
91
+ void
92
+ P4MapMaker::Insert( VALUE m )
93
+ {
94
+ StrBuf in;
95
+ StrBuf lbuf;
96
+ StrBuf r;
97
+ StrRef l;
98
+ MapType t = MapInclude;
99
+
100
+ in = StringValuePtr( m );
101
+ SplitMapping( in, lbuf, r );
102
+
103
+ l = lbuf.Text();
104
+
105
+ // Look for mapType in lhs only.
106
+ if( l[ 0 ] == '-' )
107
+ {
108
+ l += 1;
109
+ t = MapExclude;
110
+ }
111
+ else if( l[ 0 ] == '+' )
112
+ {
113
+ l += 1;
114
+ t = MapOverlay;
115
+ }
116
+
117
+ map->Insert( l, r, t );
118
+ }
119
+
120
+
121
+ void
122
+ P4MapMaker::Insert( VALUE l, VALUE r )
123
+ {
124
+ StrBuf left;
125
+ StrBuf right;
126
+ StrBuf * dest = &left;
127
+ int quoted = 0;
128
+ int index = 0;
129
+
130
+ const char *p;
131
+ MapType t = MapInclude;
132
+
133
+ p = StringValuePtr( l );
134
+ for( ; ; )
135
+ {
136
+ for( index = 0; *p; p++ )
137
+ {
138
+ switch( *p )
139
+ {
140
+ case '"':
141
+ quoted = !quoted;
142
+ break;
143
+
144
+ case ' ':
145
+ case '\t':
146
+ // Embedded whitespace ok; leading not.
147
+ if( quoted || index )
148
+ {
149
+ dest->Extend( *p );
150
+ index++;
151
+ }
152
+ break;
153
+
154
+ case '-':
155
+ if( !index )
156
+ t = MapExclude;
157
+ else
158
+ dest->Extend( *p );
159
+ index++;
160
+ break;
161
+
162
+ case '+':
163
+ if( !index )
164
+ t = MapOverlay;
165
+ else
166
+ dest->Extend( *p );
167
+ index++;
168
+ break;
169
+
170
+ default:
171
+ dest->Extend( *p );
172
+ index++;
173
+ }
174
+ }
175
+
176
+ if( dest == &right )
177
+ break;
178
+
179
+ dest = &right;
180
+ p = StringValuePtr( r );
181
+ quoted = 0;
182
+ }
183
+ left.Terminate();
184
+ right.Terminate();
185
+
186
+ map->Insert( left, right, t );
187
+ }
188
+
189
+ int
190
+ P4MapMaker::Count()
191
+ {
192
+ return map->Count();
193
+ }
194
+
195
+ void
196
+ P4MapMaker::Clear()
197
+ {
198
+ map->Clear();
199
+ }
200
+
201
+ void
202
+ P4MapMaker::Reverse()
203
+ {
204
+ MapApi * nmap = new MapApi;
205
+ const StrPtr * l;
206
+ const StrPtr * r;
207
+ MapType t;
208
+
209
+ for( int i = 0; i < map->Count(); i++ )
210
+ {
211
+ l = map->GetLeft( i );
212
+ r = map->GetRight( i );
213
+ t = map->GetType( i );
214
+
215
+ nmap->Insert( *r, *l, t );
216
+ }
217
+
218
+ delete map;
219
+ map = nmap;
220
+ }
221
+
222
+ VALUE
223
+ P4MapMaker::Translate( VALUE p, int fwd )
224
+ {
225
+ StrBuf from;
226
+ StrBuf to;
227
+ MapDir dir = MapLeftRight;
228
+
229
+ if( !fwd )
230
+ dir = MapRightLeft;
231
+
232
+ from = StringValuePtr( p );
233
+ if( map->Translate( from, to, dir ) )
234
+ return P4Utils::ruby_string( to.Text(), to.Length() );
235
+ return Qnil;
236
+ }
237
+
238
+ VALUE
239
+ P4MapMaker::Lhs()
240
+ {
241
+ VALUE a = rb_ary_new();
242
+ StrBuf s;
243
+ const StrPtr * l;
244
+ MapType t;
245
+ int quote;
246
+
247
+ for( int i = 0; i < map->Count(); i++ )
248
+ {
249
+ s.Clear();
250
+ quote = 0;
251
+
252
+ l = map->GetLeft( i );
253
+ t = map->GetType( i );
254
+
255
+ if( l->Contains( StrRef( " " ) ) )
256
+ {
257
+ quote++;
258
+ s << "\"";
259
+ }
260
+
261
+ switch( t )
262
+ {
263
+ case MapInclude:
264
+ break;
265
+ case MapExclude:
266
+ s << "-";
267
+ break;
268
+ case MapOverlay:
269
+ s << "+";
270
+ };
271
+
272
+ s << l->Text();
273
+ if( quote ) s << "\"";
274
+
275
+ rb_ary_push( a, P4Utils::ruby_string( s.Text(), s.Length() ) );
276
+ }
277
+ return a;
278
+ }
279
+
280
+ VALUE
281
+ P4MapMaker::Rhs()
282
+ {
283
+ VALUE a = rb_ary_new();
284
+ StrBuf s;
285
+ const StrPtr * r;
286
+ int quote;
287
+
288
+ for( int i = 0; i < map->Count(); i++ )
289
+ {
290
+ s.Clear();
291
+ quote = 0;
292
+
293
+ r = map->GetRight( i );
294
+
295
+ if( r->Contains( StrRef( " " ) ) )
296
+ {
297
+ quote++;
298
+ s << "\"";
299
+ }
300
+
301
+ s << r->Text();
302
+ if( quote ) s << "\"";
303
+
304
+ rb_ary_push( a, P4Utils::ruby_string( s.Text(), s.Length() ) );
305
+ }
306
+ return a;
307
+ }
308
+
309
+ VALUE
310
+ P4MapMaker::ToA()
311
+ {
312
+ VALUE a = rb_ary_new();
313
+ StrBuf s;
314
+ const StrPtr * l;
315
+ const StrPtr * r;
316
+ MapType t;
317
+ int quote;
318
+
319
+ for( int i = 0; i < map->Count(); i++ )
320
+ {
321
+ s.Clear();
322
+ quote = 0;
323
+
324
+ l = map->GetLeft( i );
325
+ r = map->GetRight( i );
326
+ t = map->GetType( i );
327
+
328
+ if( l->Contains( StrRef( " " ) ) ||
329
+ r->Contains( StrRef( " " ) ) )
330
+ {
331
+ quote++;
332
+ s << "\"";
333
+ }
334
+
335
+ switch( t )
336
+ {
337
+ case MapInclude:
338
+ break;
339
+ case MapExclude:
340
+ s << "-";
341
+ break;
342
+ case MapOverlay:
343
+ s << "+";
344
+ };
345
+
346
+ s << l->Text();
347
+
348
+ if( quote ) s << "\" \"";
349
+ else s << " ";
350
+
351
+ s << r->Text();
352
+ if( quote ) s << "\"";
353
+
354
+ rb_ary_push( a, P4Utils::ruby_string( s.Text(), s.Length() ) );
355
+ }
356
+ return a;
357
+ }
358
+
359
+ void
360
+ P4MapMaker::Inspect( StrBuf &b )
361
+ {
362
+ if( !map->Count() )
363
+ {
364
+ b << "(empty)";
365
+ return;
366
+ }
367
+
368
+ const StrPtr *l, *r;
369
+ int t;
370
+
371
+ b << "\n";
372
+
373
+ for( int i = 0; i < map->Count(); i++ )
374
+ {
375
+
376
+ l = map->GetLeft( i );
377
+ r = map->GetRight( i );
378
+ t = map->GetType( i );
379
+
380
+ b << "\t";
381
+ switch( t )
382
+ {
383
+ case MapExclude:
384
+ b << "-";
385
+ break;
386
+
387
+ case MapOverlay:
388
+ b << "+";
389
+ break;
390
+
391
+ case MapInclude:
392
+ break;
393
+ }
394
+
395
+ b << l->Text();
396
+ b << " ";
397
+ b << r->Text();
398
+ b << "\n";
399
+ }
400
+ }
401
+
402
+ //
403
+ // Take a single string containing either a half-map, or both halves of
404
+ // a mapping and split it in two. If there's only one half of a mapping in
405
+ // the input, then l, and r are set to the same value as 'in'. If 'in'
406
+ // contains two halves, then they are split.
407
+ //
408
+ void
409
+ P4MapMaker::SplitMapping( const StrPtr &in, StrBuf &l, StrBuf &r )
410
+ {
411
+ char * pos;
412
+ int quoted = 0;
413
+ int split = 0;
414
+ StrBuf * dest = &l;
415
+
416
+ pos = in.Text();
417
+
418
+ l.Clear();
419
+ r.Clear();
420
+
421
+ while( *pos )
422
+ {
423
+ switch( *pos )
424
+ {
425
+ case '"':
426
+ quoted = !quoted;
427
+ break;
428
+
429
+ case ' ':
430
+ if( !quoted && !split )
431
+ {
432
+ // whitespace in the middle. skip it, and start updating
433
+ // the destination
434
+ split = 1;
435
+ dest->Terminate();
436
+ dest = &r;
437
+ }
438
+ else if( !quoted )
439
+ {
440
+ // Trailing space on rhs. ignore
441
+ }
442
+ else
443
+ {
444
+ // Embedded space
445
+ dest->Extend( *pos );
446
+ }
447
+ break;
448
+
449
+ default:
450
+ dest->Extend( *pos );
451
+ }
452
+ pos++;
453
+ }
454
+ l.Terminate();
455
+ r.Terminate();
456
+
457
+ if( !r.Length() )
458
+ r = l;
459
+ }