p4ruby 2014.1 → 2014.2.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,69 @@
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.h
30
+ *
31
+ * Author : Tony Smith <tony@perforce.com>
32
+ *
33
+ * Description : Class to encapsulate Perforce map manipulation from Ruby
34
+ *
35
+ ******************************************************************************/
36
+
37
+ class MapApi;
38
+ class P4MapMaker
39
+ {
40
+ public:
41
+ P4MapMaker();
42
+ P4MapMaker( const P4MapMaker &m );
43
+
44
+ ~P4MapMaker();
45
+
46
+ static P4MapMaker * Join( P4MapMaker *l, P4MapMaker *r);
47
+
48
+ void Insert( VALUE m );
49
+ void Insert( VALUE l, VALUE r );
50
+
51
+ void Reverse();
52
+ void Clear();
53
+ int Count();
54
+ VALUE Translate( VALUE p, int fwd = 1 );
55
+ VALUE Lhs();
56
+ VALUE Rhs();
57
+ VALUE ToA();
58
+
59
+ void Inspect( StrBuf &b );
60
+
61
+ // We hold no references to Ruby objects, so no GC to do...
62
+ void GCMark() {}
63
+
64
+ private:
65
+ void SplitMapping( const StrPtr &in, StrBuf &l, StrBuf &r );
66
+ MapApi * map;
67
+ };
68
+
69
+
@@ -0,0 +1,272 @@
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 : p4mergedata.cc
30
+ *
31
+ * Author : Tony Smith <tony@perforce.com> or <tony@smee.org>
32
+ *
33
+ * Description : Class for holding merge data
34
+ *
35
+ ******************************************************************************/
36
+ #include <ruby.h>
37
+ #include "undefdups.h"
38
+ #include <p4/clientapi.h>
39
+ #include <p4/i18napi.h>
40
+ #include <p4/strtable.h>
41
+ #include <p4/spec.h>
42
+ #include "p4result.h"
43
+ #include "p4rubydebug.h"
44
+ #include "clientuserruby.h"
45
+ #include "p4utils.h"
46
+ #include "p4mergedata.h"
47
+
48
+ static void mergedata_free(P4MergeData *md) {
49
+ delete md;
50
+ }
51
+
52
+ static void mergedata_mark(P4MergeData *md) {
53
+ md->GCMark();
54
+ }
55
+
56
+ P4MergeData::P4MergeData(ClientUser *ui, ClientMerge *m, StrPtr &hint,
57
+ VALUE info) {
58
+ this->debug = 0;
59
+ this->actionmerger = 0;
60
+ this->ui = ui;
61
+ this->merger = m;
62
+ this->hint = hint;
63
+ this->info = info;
64
+
65
+ // Extract (forcibly) the paths from the RPC buffer.
66
+ StrPtr *t;
67
+ if ((t = ui->varList->GetVar("baseName"))) base = t->Text();
68
+ if ((t = ui->varList->GetVar("yourName"))) yours = t->Text();
69
+ if ((t = ui->varList->GetVar("theirName"))) theirs = t->Text();
70
+
71
+ }
72
+
73
+ P4MergeData::P4MergeData(ClientUser *ui, ClientResolveA *m, StrPtr &hint,
74
+ VALUE info) {
75
+ this->debug = 0;
76
+ this->merger = 0;
77
+ this->ui = ui;
78
+ this->hint = hint;
79
+ this->actionmerger = m;
80
+ this->info = info;
81
+
82
+ }
83
+
84
+ VALUE P4MergeData::GetYourName() {
85
+ if (merger && yours.Length())
86
+ return P4Utils::ruby_string(yours.Text());
87
+ else
88
+ return Qnil;
89
+ }
90
+
91
+ VALUE P4MergeData::GetTheirName() {
92
+ if (merger && theirs.Length())
93
+ return P4Utils::ruby_string(theirs.Text());
94
+ else
95
+ return Qnil;
96
+ }
97
+
98
+ VALUE P4MergeData::GetBaseName() {
99
+ if (merger && base.Length())
100
+ return P4Utils::ruby_string(base.Text());
101
+ else
102
+ return Qnil;
103
+ }
104
+
105
+ VALUE P4MergeData::GetYourPath() {
106
+ if (merger && merger->GetYourFile())
107
+ return P4Utils::ruby_string(merger->GetYourFile()->Name());
108
+ else
109
+ return Qnil;
110
+ }
111
+
112
+ VALUE P4MergeData::GetTheirPath() {
113
+ if (merger && merger->GetTheirFile())
114
+ return P4Utils::ruby_string(merger->GetTheirFile()->Name());
115
+ else
116
+ return Qnil;
117
+ }
118
+
119
+ VALUE P4MergeData::GetBasePath() {
120
+ if (merger && merger->GetBaseFile())
121
+ return P4Utils::ruby_string(merger->GetBaseFile()->Name());
122
+ else
123
+ return Qnil;
124
+ }
125
+
126
+ VALUE P4MergeData::GetResultPath() {
127
+ if (merger && merger->GetResultFile())
128
+ return P4Utils::ruby_string(merger->GetResultFile()->Name());
129
+ else
130
+ return Qnil;
131
+ }
132
+
133
+ VALUE P4MergeData::GetMergeHint() {
134
+ if (hint.Length())
135
+ return P4Utils::ruby_string(hint.Text());
136
+ else
137
+ return Qnil;
138
+ }
139
+
140
+ VALUE P4MergeData::RunMergeTool() {
141
+ Error e;
142
+ if (merger) {
143
+ ui->Merge(merger->GetBaseFile(), merger->GetTheirFile(),
144
+ merger->GetYourFile(), merger->GetResultFile(), &e);
145
+
146
+ if (e.Test()) return Qfalse;
147
+ return Qtrue;
148
+ }
149
+ return Qfalse;
150
+ }
151
+
152
+ VALUE P4MergeData::GetActionResolveStatus() {
153
+ return actionmerger ? Qtrue : Qfalse;
154
+ }
155
+
156
+ VALUE P4MergeData::GetContentResolveStatus() {
157
+ return merger ? Qtrue : Qfalse;
158
+ }
159
+
160
+ VALUE P4MergeData::GetMergeInfo() {
161
+ return this->info;
162
+ }
163
+
164
+ VALUE P4MergeData::GetMergeAction() {
165
+ // If we don't have an actionMerger then return nil
166
+ if (actionmerger) {
167
+ StrBuf buf;
168
+ actionmerger->GetMergeAction().Fmt(&buf, EF_PLAIN);
169
+ if (buf.Length())
170
+ return P4Utils::ruby_string(buf.Text());
171
+ else
172
+ return Qnil;
173
+ }
174
+ return Qnil;
175
+ }
176
+
177
+ VALUE P4MergeData::GetYoursAction() {
178
+ if (actionmerger) {
179
+ StrBuf buf;
180
+ actionmerger->GetYoursAction().Fmt(&buf, EF_PLAIN);
181
+ if (buf.Length())
182
+ return P4Utils::ruby_string(buf.Text());
183
+ else
184
+ return Qnil;
185
+ }
186
+ return Qnil;
187
+ }
188
+
189
+ VALUE P4MergeData::GetTheirAction() {
190
+ if (actionmerger) {
191
+ StrBuf buf;
192
+ actionmerger->GetTheirAction().Fmt(&buf, EF_PLAIN);
193
+ if (buf.Length())
194
+ return P4Utils::ruby_string(buf.Text());
195
+ else
196
+ return Qnil;
197
+ }
198
+ return Qnil;
199
+ }
200
+
201
+ VALUE P4MergeData::GetType() {
202
+ if (actionmerger) {
203
+ StrBuf buf;
204
+ actionmerger->GetType().Fmt(&buf, EF_PLAIN);
205
+ if (buf.Length())
206
+ return P4Utils::ruby_string(buf.Text());
207
+ else
208
+ return Qnil;
209
+ }
210
+ return Qnil;
211
+ }
212
+
213
+ void P4MergeData::Invalidate() {
214
+ actionmerger = NULL;
215
+ merger = NULL;
216
+ }
217
+
218
+ VALUE P4MergeData::GetString() {
219
+ StrBuf result;
220
+ StrBuf buffer;
221
+
222
+ if (actionmerger) {
223
+ result << "P4MergeData - Action\n";
224
+ actionmerger->GetMergeAction().Fmt(&buffer, EF_INDENT);
225
+ result << "\tmergeAction: " << buffer << "\n";
226
+ buffer.Clear();
227
+
228
+ actionmerger->GetTheirAction().Fmt(&buffer, EF_INDENT);
229
+ result << "\ttheirAction: " << buffer << "\n";
230
+ buffer.Clear();
231
+
232
+ actionmerger->GetYoursAction().Fmt(&buffer, EF_INDENT);
233
+ result << "\tyoursAction: " << buffer << "\n";
234
+ buffer.Clear();
235
+
236
+ actionmerger->GetType().Fmt(&buffer, EF_INDENT);
237
+ result << "\ttype: " << buffer << "\n";
238
+ buffer.Clear();
239
+
240
+ result << "\thint: " << hint << "\n";
241
+ return P4Utils::ruby_string(result.Text());
242
+ } else {
243
+ result << "P4MergeData - Content\n";
244
+ if (yours.Length()) result << "yourName: " << yours << "\n";
245
+ if (theirs.Length()) result << "thierName: " << theirs << "\n";
246
+ if (base.Length()) result << "baseName: " << base << "\n";
247
+
248
+ if ( merger && merger->GetYourFile())
249
+ result << "\tyourFile: " << merger->GetYourFile()->Name() << "\n";
250
+ if ( merger && merger->GetTheirFile())
251
+ result << "\ttheirFile: " << merger->GetTheirFile()->Name() << "\n";
252
+ if ( merger && merger->GetBaseFile())
253
+ result << "\tbaseFile: " << merger->GetBaseFile()->Name() << "\n";
254
+
255
+ return P4Utils::ruby_string(result.Text());
256
+ }
257
+ return Qnil;
258
+ }
259
+
260
+ VALUE P4MergeData::Wrap(VALUE pClass) {
261
+ VALUE md;
262
+ VALUE argv[1];
263
+
264
+ md = Data_Wrap_Struct(pClass, mergedata_mark, mergedata_free, this);
265
+ rb_obj_call_init(md, 0, argv);
266
+ return md;
267
+ }
268
+
269
+ void P4MergeData::GCMark() {
270
+ // We don't hold Ruby objects
271
+ }
272
+
@@ -0,0 +1,97 @@
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 : p4mergedata.h
30
+ *
31
+ * Author : Tony Smith <tony@perforce.com> or <tony@smee.org>
32
+ *
33
+ * Description : Class for holding merge data
34
+ *
35
+ ******************************************************************************/
36
+
37
+ class P4MergeData
38
+ {
39
+ public:
40
+ P4MergeData( ClientUser *ui, ClientMerge *m, StrPtr &hint, VALUE info );
41
+ P4MergeData( ClientUser *ui, ClientResolveA *m, StrPtr &hint, VALUE info );
42
+
43
+ void SetDebug( int d ) { debug = d; }
44
+
45
+ // Content resolve
46
+ VALUE GetYourName();
47
+ VALUE GetTheirName();
48
+ VALUE GetBaseName();
49
+
50
+ VALUE GetYourPath();
51
+ VALUE GetTheirPath();
52
+ VALUE GetBasePath();
53
+ VALUE GetResultPath();
54
+
55
+ VALUE RunMergeTool();
56
+
57
+ // What type of resolve is it?
58
+ VALUE GetActionResolveStatus();
59
+ VALUE GetContentResolveStatus();
60
+
61
+ // Action Resolve
62
+ VALUE GetMergeInfo();
63
+
64
+ VALUE GetMergeAction();
65
+ VALUE GetYoursAction();
66
+ VALUE GetTheirAction();
67
+ VALUE GetType();
68
+
69
+
70
+ VALUE GetString();
71
+ VALUE GetMergeHint();
72
+
73
+ // Wrap as Ruby object of class pClass
74
+ VALUE Wrap( VALUE pClass );
75
+
76
+ // Invalidate our merger and actionMerger objects as they do not survive
77
+ // beyond the life of a resolve while this object itself might well do so,
78
+ // particularly in the case of an exception raised from within the block.
79
+ void Invalidate();
80
+
81
+ // Ruby garbage collection
82
+ void GCMark();
83
+
84
+ private:
85
+ int debug;
86
+ ClientUser * ui;
87
+ StrBuf hint;
88
+ ClientMerge * merger;
89
+ ClientResolveA* actionmerger;
90
+ StrBuf yours;
91
+ StrBuf theirs;
92
+ StrBuf base;
93
+
94
+ VALUE info;
95
+
96
+ };
97
+
@@ -0,0 +1,259 @@
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
+ /*******************************************************************************
30
+ * Name : p4result.cc
31
+ *
32
+ * Author : Tony Smith <tony@perforce.com> or <tony@smee.org>
33
+ *
34
+ * Description : Ruby class for holding results of Perforce commands
35
+ *
36
+ ******************************************************************************/
37
+
38
+ #include <ruby.h>
39
+ #include "undefdups.h"
40
+ #include <p4/clientapi.h>
41
+ #include "gc_hack.h"
42
+ #include "p4error.h"
43
+ #include "p4utils.h"
44
+ #include "p4result.h"
45
+
46
+ P4Result::P4Result()
47
+ {
48
+ output = rb_ary_new();
49
+ warnings = rb_ary_new();
50
+ errors = rb_ary_new();
51
+ messages = rb_ary_new();
52
+ track = rb_ary_new();
53
+ apiLevel = atoi( P4Tag::l_client );
54
+ ID idP4 = rb_intern( "P4" );
55
+ ID idP4Msg = rb_intern( "Message" );
56
+
57
+ VALUE cP4 = rb_const_get_at( rb_cObject, idP4 );
58
+ cP4Msg = rb_const_get_at( cP4, idP4Msg );
59
+
60
+ }
61
+
62
+
63
+ void
64
+ P4Result::Reset()
65
+ {
66
+ output = rb_ary_new();
67
+ warnings = rb_ary_new();
68
+ errors = rb_ary_new();
69
+ messages = rb_ary_new();
70
+ track = rb_ary_new();
71
+ }
72
+
73
+ //
74
+ // Direct output - not via a message of any kind. For example,
75
+ // binary output.
76
+ //
77
+ void
78
+ P4Result::AddOutput( VALUE v )
79
+ {
80
+ rb_ary_push( output, v );
81
+
82
+ //
83
+ // Call the ruby thread scheduler to allow another thread to run
84
+ // now. We should perhaps only call this every 'n' times, but I've
85
+ // no idea what a good value for n might be; so for now at least, n=1
86
+ //
87
+ rb_thread_schedule();
88
+ }
89
+
90
+ /*
91
+ * Main distribution of output to the user. This method sorts the
92
+ * output into groups: output, warnings, errors, and sends all output
93
+ * (regardless of severity) to the messages array.
94
+ */
95
+ void
96
+ P4Result::AddMessage( Error *e )
97
+ {
98
+
99
+ int s;
100
+ s = e->GetSeverity();
101
+
102
+ //
103
+ // Empty and informational messages are pushed out as output as nothing
104
+ // worthy of error handling has occurred. Warnings go into the warnings
105
+ // list and the rest are lumped together as errors.
106
+ //
107
+
108
+ if ( s == E_EMPTY || s == E_INFO )
109
+ rb_ary_push( output, FmtMessage( e ) );
110
+ else if ( s == E_WARN )
111
+ rb_ary_push( warnings, FmtMessage( e ) );
112
+ else
113
+ rb_ary_push( errors, FmtMessage( e ) );
114
+
115
+ //
116
+ // Whatever severity, format the message into the messages array, wrapped
117
+ // up in a P4::Message object.
118
+ //
119
+ rb_ary_push( messages, WrapMessage( e ) );
120
+
121
+ //
122
+ // Call the ruby thread scheduler to allow another thread to run
123
+ // now. We should perhaps only call this every 'n' times, but I've
124
+ // no idea what a good value for n might be; so for now at least, n=1
125
+ //
126
+ rb_thread_schedule();
127
+ }
128
+
129
+ void
130
+ P4Result::AddTrack( const char *msg )
131
+ {
132
+ rb_ary_push( track, P4Utils::ruby_string( msg ) );
133
+
134
+ //
135
+ // Call the ruby thread scheduler to allow another thread to run
136
+ // now. We should perhaps only call this every 'n' times, but I've
137
+ // no idea what a good value for n might be; so for now at least, n=1
138
+ //
139
+ rb_thread_schedule();
140
+ }
141
+
142
+ void
143
+ P4Result::DeleteTrack()
144
+ {
145
+ rb_ary_clear( track );
146
+
147
+ //
148
+ // Call the ruby thread scheduler to allow another thread to run
149
+ // now. We should perhaps only call this every 'n' times, but I've
150
+ // no idea what a good value for n might be; so for now at least, n=1
151
+ //
152
+ rb_thread_schedule();
153
+ }
154
+
155
+ void
156
+ P4Result::AddTrack( VALUE t )
157
+ {
158
+ rb_ary_push( track, t );
159
+
160
+ //
161
+ // Call the ruby thread scheduler to allow another thread to run
162
+ // now. We should perhaps only call this every 'n' times, but I've
163
+ // no idea what a good value for n might be; so for now at least, n=1
164
+ //
165
+ rb_thread_schedule();
166
+ }
167
+
168
+ int
169
+ P4Result::ErrorCount()
170
+ {
171
+ return Length( errors );
172
+ }
173
+
174
+ int
175
+ P4Result::WarningCount()
176
+ {
177
+ return Length( warnings );
178
+ }
179
+
180
+ void
181
+ P4Result::FmtErrors( StrBuf &buf )
182
+ {
183
+ Fmt( "[Error]: ", errors, buf );
184
+ }
185
+
186
+ void
187
+ P4Result::FmtWarnings( StrBuf &buf )
188
+ {
189
+ Fmt( "[Warning]: ", warnings, buf );
190
+ }
191
+
192
+
193
+ int
194
+ P4Result::Length( VALUE ary )
195
+ {
196
+ ID iLength;
197
+ VALUE len;
198
+
199
+ iLength = rb_intern( "length" );
200
+
201
+ len = rb_funcall( ary, iLength, 0 );
202
+ return NUM2INT( len );
203
+ }
204
+
205
+ void
206
+ P4Result::GCMark()
207
+ {
208
+ rb_gc_mark( output );
209
+ rb_gc_mark( errors );
210
+ rb_gc_mark( warnings );
211
+ rb_gc_mark( messages );
212
+ rb_gc_mark( track );
213
+ }
214
+
215
+
216
+ void
217
+ P4Result::Fmt( const char *label, VALUE ary, StrBuf &buf )
218
+ {
219
+ ID idJoin;
220
+ VALUE s1;
221
+ StrBuf csep;
222
+ VALUE rsep;
223
+
224
+ buf.Clear();
225
+ // If the array is empty, then we just return
226
+ if( ! Length( ary ) ) return;
227
+
228
+ // Not empty, so we'll format it.
229
+ idJoin = rb_intern( "join" );
230
+
231
+ // This is the string we'll use to prefix each entry in the array
232
+ csep << "\n\t" << label;
233
+ rsep = P4Utils::ruby_string( csep.Text() );
234
+
235
+ // Since Array#join() won't prefix the first element with the separator
236
+ // we'll have to do it manually.
237
+ buf << csep;
238
+
239
+ // Join the array elements together, and append the result to the buffer
240
+ s1 = rb_funcall( ary, idJoin, 1, rsep );
241
+ buf << StringValuePtr( s1 );
242
+
243
+ return;
244
+ }
245
+
246
+ VALUE
247
+ P4Result::FmtMessage( Error *e )
248
+ {
249
+ StrBuf t;
250
+ e->Fmt( t, EF_PLAIN );
251
+ return P4Utils::ruby_string( t.Text(), t.Length() );
252
+ }
253
+
254
+ VALUE
255
+ P4Result::WrapMessage( Error *e )
256
+ {
257
+ P4Error *pe = new P4Error( *e );
258
+ return pe->Wrap( cP4Msg );
259
+ }