p4ruby 2014.1 → 2014.2.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/P4/gc_hack.h ADDED
@@ -0,0 +1,10 @@
1
+ /*******************************************************************************
2
+ * Hack to get garbage collection working reliably and portably.
3
+ ******************************************************************************/
4
+
5
+ #ifndef _GC_HACK_INCLUDED
6
+ # define _GC_HACK_INCLUDED
7
+
8
+ # define rb_gc_mark(value) ((void (*)(VALUE))(rb_gc_mark))(value)
9
+
10
+ #endif
data/ext/P4/p4.cpp ADDED
@@ -0,0 +1,1319 @@
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 : p4.cc
30
+ *
31
+ * Author : Tony Smith <tony@perforce.com> or <tony@smee.org>
32
+ *
33
+ * Description : Ruby bindings for the Perforce API.
34
+ *
35
+ * vim:ts=8:sw=4
36
+ ******************************************************************************/
37
+ #include <ruby.h>
38
+ #include "undefdups.h"
39
+ #include <p4/clientapi.h>
40
+ #include <p4/strtable.h>
41
+ #include <p4/spec.h>
42
+ #include <p4/ident.h>
43
+ #include "p4result.h"
44
+ #include "specmgr.h"
45
+ #include "clientuserruby.h"
46
+ #include "p4rubyconf.h"
47
+ #include "p4clientapi.h"
48
+ #include "p4mergedata.h"
49
+ #include "p4mapmaker.h"
50
+ #include "p4error.h"
51
+ #include "p4utils.h"
52
+ #include "extconf.h"
53
+
54
+
55
+ // Our Ident mechanism doesn't really translate to a semantic versioning scheme,
56
+ // So it's been simply replaced by the current version string. We'll see if that
57
+ // needs to change, since a lot of the information this displayed is available
58
+ // via RbConfig locally.
59
+ //static Ident ident = {
60
+ // IdentMagic "P4RUBY " P4RUBY_VERSION
61
+ //};
62
+
63
+
64
+ /*******************************************************************************
65
+ * Our Ruby classes.
66
+ ******************************************************************************/
67
+ VALUE cP4; // Base P4 Class
68
+ VALUE eP4; // Exception class
69
+ VALUE cP4MD; // P4::MergeData class
70
+ VALUE cP4Map; // P4::Map class
71
+ VALUE cP4Msg; // P4::Message class
72
+ VALUE cP4Prog; // P4::Progress class
73
+
74
+
75
+ extern "C"
76
+ {
77
+
78
+ //
79
+ // Construction/destruction
80
+ //
81
+
82
+ static void p4_free( P4ClientApi *p4 )
83
+ {
84
+ delete p4;
85
+ }
86
+
87
+ static void p4_mark( P4ClientApi *p4 )
88
+ {
89
+ p4->GCMark();
90
+ }
91
+
92
+ static VALUE p4_new( VALUE pClass )
93
+ {
94
+ VALUE argv[ 1 ];
95
+ P4ClientApi *p4 = new P4ClientApi();
96
+ VALUE self;
97
+
98
+ self = Data_Wrap_Struct( pClass, p4_mark, p4_free, p4 );
99
+ rb_obj_call_init( self, 0, argv );
100
+ return self;
101
+ }
102
+
103
+
104
+ //
105
+ // Session connect/disconnect
106
+ //
107
+ static VALUE p4_connect( VALUE self )
108
+ {
109
+ P4ClientApi *p4;
110
+ Data_Get_Struct( self, P4ClientApi, p4 );
111
+ return p4->Connect();
112
+ }
113
+
114
+ static VALUE p4_disconnect( VALUE self )
115
+ {
116
+ P4ClientApi *p4;
117
+ Data_Get_Struct( self, P4ClientApi, p4 );
118
+ return p4->Disconnect();
119
+ }
120
+
121
+ static VALUE p4_connected( VALUE self )
122
+ {
123
+ P4ClientApi *p4;
124
+ Data_Get_Struct( self, P4ClientApi, p4 );
125
+ return p4->Connected();
126
+ }
127
+
128
+ static VALUE p4_server_case_sensitive( VALUE self )
129
+ {
130
+ P4ClientApi *p4;
131
+ Data_Get_Struct( self, P4ClientApi, p4 );
132
+ if( p4->ServerCaseSensitive() )
133
+ return Qtrue;
134
+ return Qfalse;
135
+ }
136
+
137
+ static VALUE p4_server_unicode( VALUE self )
138
+ {
139
+ P4ClientApi *p4;
140
+ Data_Get_Struct( self, P4ClientApi, p4 );
141
+ if( p4->ServerUnicode() )
142
+ return Qtrue;
143
+ return Qfalse;
144
+ }
145
+
146
+ static VALUE p4_run_tagged( VALUE self, VALUE tagged )
147
+ {
148
+ P4ClientApi *p4;
149
+ Data_Get_Struct( self, P4ClientApi, p4 );
150
+
151
+ if( ! rb_block_given_p() )
152
+ rb_raise( rb_eArgError, "P4#run_tagged requires a block" );
153
+
154
+ // The user might have passed an integer, or it might be a boolean,
155
+ // we convert to int for consistency.
156
+ int flag = 0;
157
+ if( tagged == Qtrue )
158
+ flag = 1;
159
+ else if( tagged == Qfalse )
160
+ flag = 0;
161
+ else
162
+ flag = NUM2INT( tagged ) ? 1 : 0;
163
+
164
+ int old_value = p4->IsTagged();
165
+ p4->Tagged( flag );
166
+
167
+ VALUE ret_val;
168
+
169
+ //
170
+ // XXX: This should perhaps be protected with rb_ensure()...
171
+ //
172
+ ret_val = rb_yield( self );
173
+
174
+ p4->Tagged( old_value );
175
+ return ret_val;
176
+ }
177
+
178
+ static VALUE p4_get_tagged( VALUE self )
179
+ {
180
+ P4ClientApi *p4;
181
+ Data_Get_Struct( self, P4ClientApi, p4 );
182
+ return p4->IsTagged() ? Qtrue : Qfalse;
183
+ }
184
+
185
+ static VALUE p4_set_tagged( VALUE self, VALUE toggle )
186
+ {
187
+ P4ClientApi *p4;
188
+ Data_Get_Struct( self, P4ClientApi, p4 );
189
+
190
+ // The user might have passed an integer, or it might be a boolean,
191
+ // we convert to int for consistency.
192
+ int flag = 0;
193
+ if( toggle == Qtrue )
194
+ flag = 1;
195
+ else if( toggle == Qfalse )
196
+ flag = 0;
197
+ else
198
+ flag = NUM2INT( toggle ) ? 1 : 0;
199
+
200
+ p4->Tagged( flag );
201
+ return flag ? Qtrue : Qfalse; // Seems to be ignored...
202
+ }
203
+
204
+ static VALUE p4_get_api_level( VALUE self )
205
+ {
206
+ P4ClientApi *p4;
207
+ Data_Get_Struct( self, P4ClientApi, p4 );
208
+ return INT2NUM( p4->GetApiLevel() );
209
+ }
210
+
211
+ static VALUE p4_set_api_level( VALUE self, VALUE level )
212
+ {
213
+ P4ClientApi *p4;
214
+ Data_Get_Struct( self, P4ClientApi, p4 );
215
+ p4->SetApiLevel( NUM2INT( level ) );
216
+ return self;
217
+ }
218
+
219
+ //
220
+ // Getting/Setting Perforce environment
221
+ //
222
+ static VALUE p4_get_charset( VALUE self )
223
+ {
224
+ P4ClientApi *p4;
225
+ Data_Get_Struct( self, P4ClientApi, p4 );
226
+ StrPtr c = p4->GetCharset();
227
+ return P4Utils::ruby_string( c.Text() );
228
+ }
229
+
230
+ static VALUE p4_set_charset( VALUE self, VALUE c )
231
+ {
232
+ P4ClientApi *p4;
233
+ Data_Get_Struct( self, P4ClientApi, p4 );
234
+
235
+ // p4.charset = nil prior to connect can be used to
236
+ // disable automatic charset detection
237
+ if( c == Qnil )
238
+ return p4->SetCharset( 0 );
239
+
240
+ return p4->SetCharset( StringValuePtr( c ) );
241
+ }
242
+
243
+ static VALUE p4_get_p4config( VALUE self )
244
+ {
245
+ P4ClientApi *p4;
246
+ Data_Get_Struct( self, P4ClientApi, p4 );
247
+ StrPtr c = p4->GetConfig();
248
+ return P4Utils::ruby_string( c.Text() );
249
+ }
250
+
251
+ static VALUE p4_get_cwd( VALUE self )
252
+ {
253
+ P4ClientApi *p4;
254
+ Data_Get_Struct( self, P4ClientApi, p4 );
255
+ StrPtr cwd = p4->GetCwd();
256
+ return P4Utils::ruby_string( cwd.Text() );
257
+ }
258
+
259
+ static VALUE p4_set_cwd( VALUE self, VALUE cwd )
260
+ {
261
+ P4ClientApi *p4;
262
+ Data_Get_Struct( self, P4ClientApi, p4 );
263
+ p4->SetCwd( StringValuePtr( cwd ) );
264
+ return Qtrue;
265
+ }
266
+
267
+ static VALUE p4_get_client( VALUE self )
268
+ {
269
+ P4ClientApi *p4;
270
+ Data_Get_Struct( self, P4ClientApi, p4 );
271
+ StrPtr client = p4->GetClient();
272
+ return P4Utils::ruby_string( client.Text() );
273
+ }
274
+
275
+ static VALUE p4_set_client( VALUE self, VALUE client )
276
+ {
277
+ P4ClientApi *p4;
278
+ Data_Get_Struct( self, P4ClientApi, p4 );
279
+ p4->SetClient( StringValuePtr( client ) );
280
+ return Qtrue;
281
+ }
282
+
283
+ static VALUE p4_get_env( VALUE self, VALUE var )
284
+ {
285
+ P4ClientApi *p4;
286
+ const char *val;
287
+ Data_Get_Struct( self, P4ClientApi, p4 );
288
+ val = p4->GetEnv( StringValuePtr( var ) );
289
+ if( !val ) return Qnil;
290
+
291
+ return P4Utils::ruby_string( val );
292
+ }
293
+
294
+ static VALUE p4_set_env( VALUE self, VALUE var, VALUE val )
295
+ {
296
+ P4ClientApi *p4;
297
+ Data_Get_Struct( self, P4ClientApi, p4 );
298
+ return p4->SetEnv( StringValuePtr( var ), StringValuePtr( val ) );
299
+ }
300
+ static VALUE p4_get_host( VALUE self )
301
+ {
302
+ P4ClientApi *p4;
303
+ Data_Get_Struct( self, P4ClientApi, p4 );
304
+ StrPtr host = p4->GetHost();
305
+ return P4Utils::ruby_string( host.Text() );
306
+ }
307
+
308
+ static VALUE p4_set_host( VALUE self, VALUE host )
309
+ {
310
+ P4ClientApi *p4;
311
+ Data_Get_Struct( self, P4ClientApi, p4 );
312
+ p4->SetHost( StringValuePtr( host ) );
313
+ return Qtrue;
314
+ }
315
+
316
+ static VALUE p4_get_ignore( VALUE self )
317
+ {
318
+ P4ClientApi *p4;
319
+ Data_Get_Struct( self, P4ClientApi, p4 );
320
+ StrPtr ignore = p4->GetIgnoreFile();
321
+ return P4Utils::ruby_string( ignore.Text() );
322
+ }
323
+
324
+ static VALUE p4_set_ignore( VALUE self, VALUE file )
325
+ {
326
+ P4ClientApi *p4;
327
+ Data_Get_Struct( self, P4ClientApi, p4 );
328
+ p4->SetIgnoreFile( StringValuePtr( file ) );
329
+ return Qtrue;
330
+ }
331
+
332
+ static VALUE p4_is_ignored( VALUE self, VALUE path )
333
+ {
334
+ P4ClientApi *p4;
335
+ Data_Get_Struct( self, P4ClientApi, p4 );
336
+ if( p4->IsIgnored( StringValuePtr( path ) ) )
337
+ return Qtrue;
338
+ return Qfalse;
339
+ }
340
+
341
+ static VALUE p4_get_language( VALUE self )
342
+ {
343
+ P4ClientApi *p4;
344
+ Data_Get_Struct( self, P4ClientApi, p4 );
345
+ StrPtr lang = p4->GetLanguage();
346
+ return P4Utils::ruby_string( lang.Text() );
347
+ }
348
+
349
+ static VALUE p4_set_language( VALUE self, VALUE lang )
350
+ {
351
+ P4ClientApi *p4;
352
+ Data_Get_Struct( self, P4ClientApi, p4 );
353
+ p4->SetLanguage( StringValuePtr( lang ) );
354
+ return Qtrue;
355
+ }
356
+
357
+ static VALUE p4_get_maxresults( VALUE self )
358
+ {
359
+ P4ClientApi *p4;
360
+ Data_Get_Struct( self, P4ClientApi, p4 );
361
+ return INT2NUM( p4->GetMaxResults() );
362
+ }
363
+
364
+ static VALUE p4_set_maxresults( VALUE self, VALUE val )
365
+ {
366
+ P4ClientApi *p4;
367
+ Data_Get_Struct( self, P4ClientApi, p4 );
368
+ p4->SetMaxResults( NUM2INT( val ) );
369
+ return Qtrue;
370
+ }
371
+
372
+ static VALUE p4_get_maxscanrows( VALUE self )
373
+ {
374
+ P4ClientApi *p4;
375
+ Data_Get_Struct( self, P4ClientApi, p4 );
376
+ return INT2NUM( p4->GetMaxScanRows() );
377
+ }
378
+
379
+ static VALUE p4_set_maxscanrows( VALUE self, VALUE val )
380
+ {
381
+ P4ClientApi *p4;
382
+ Data_Get_Struct( self, P4ClientApi, p4 );
383
+ p4->SetMaxScanRows( NUM2INT( val ) );
384
+ return Qtrue;
385
+ }
386
+
387
+ static VALUE p4_get_maxlocktime( VALUE self )
388
+ {
389
+ P4ClientApi *p4;
390
+ Data_Get_Struct( self, P4ClientApi, p4 );
391
+ return INT2NUM( p4->GetMaxLockTime() );
392
+ }
393
+
394
+ static VALUE p4_set_maxlocktime( VALUE self, VALUE val )
395
+ {
396
+ P4ClientApi *p4;
397
+ Data_Get_Struct( self, P4ClientApi, p4 );
398
+ p4->SetMaxLockTime( NUM2INT( val ) );
399
+ return Qtrue;
400
+ }
401
+
402
+ static VALUE p4_get_password( VALUE self )
403
+ {
404
+ P4ClientApi *p4;
405
+ Data_Get_Struct( self, P4ClientApi, p4 );
406
+ StrPtr passwd = p4->GetPassword();
407
+ return P4Utils::ruby_string( passwd.Text() );
408
+ }
409
+
410
+ static VALUE p4_set_password( VALUE self, VALUE passwd )
411
+ {
412
+ P4ClientApi *p4;
413
+ Data_Get_Struct( self, P4ClientApi, p4 );
414
+ p4->SetPassword( StringValuePtr( passwd ) );
415
+ return Qtrue;
416
+ }
417
+
418
+ static VALUE p4_get_port( VALUE self )
419
+ {
420
+ P4ClientApi *p4;
421
+ Data_Get_Struct( self, P4ClientApi, p4 );
422
+ StrPtr port = p4->GetPort();
423
+ return P4Utils::ruby_string( port.Text() );
424
+ }
425
+
426
+ static VALUE p4_set_port( VALUE self, VALUE port )
427
+ {
428
+ P4ClientApi *p4;
429
+ Data_Get_Struct( self, P4ClientApi, p4 );
430
+ if( p4->Connected() )
431
+ rb_raise( eP4, "Can't change port once you've connected." );
432
+
433
+ p4->SetPort( StringValuePtr( port ) );
434
+ return Qtrue;
435
+ }
436
+
437
+ static VALUE p4_get_prog( VALUE self )
438
+ {
439
+ P4ClientApi *p4;
440
+ Data_Get_Struct( self, P4ClientApi, p4 );
441
+ return P4Utils::ruby_string( p4->GetProg().Text() );
442
+ }
443
+
444
+ static VALUE p4_set_prog( VALUE self, VALUE prog )
445
+ {
446
+ P4ClientApi *p4;
447
+ Data_Get_Struct( self, P4ClientApi, p4 );
448
+ p4->SetProg( StringValuePtr( prog ) );
449
+ return Qtrue;
450
+ }
451
+
452
+ static VALUE p4_set_protocol( VALUE self, VALUE var, VALUE val )
453
+ {
454
+ P4ClientApi *p4;
455
+ Data_Get_Struct( self, P4ClientApi, p4 );
456
+ p4->SetProtocol( StringValuePtr( var ), StringValuePtr( val ) );
457
+ return Qtrue;
458
+ }
459
+
460
+ static VALUE p4_get_ticket_file( VALUE self )
461
+ {
462
+ P4ClientApi *p4;
463
+ Data_Get_Struct( self, P4ClientApi, p4 );
464
+ return P4Utils::ruby_string( p4->GetTicketFile().Text() );
465
+ }
466
+
467
+ static VALUE p4_set_ticket_file( VALUE self, VALUE path )
468
+ {
469
+ P4ClientApi *p4;
470
+ Data_Get_Struct( self, P4ClientApi, p4 );
471
+ p4->SetTicketFile( StringValuePtr( path ) );
472
+ return Qtrue;
473
+ }
474
+
475
+ static VALUE p4_get_user( VALUE self )
476
+ {
477
+ P4ClientApi *p4;
478
+ Data_Get_Struct( self, P4ClientApi, p4 );
479
+ StrPtr user = p4->GetUser();
480
+ return P4Utils::ruby_string( user.Text() );
481
+ }
482
+
483
+ static VALUE p4_set_user( VALUE self, VALUE user )
484
+ {
485
+ P4ClientApi *p4;
486
+ Data_Get_Struct( self, P4ClientApi, p4 );
487
+ p4->SetUser( StringValuePtr( user ) );
488
+ return Qtrue;
489
+ }
490
+
491
+ static VALUE p4_get_version( VALUE self )
492
+ {
493
+ P4ClientApi *p4;
494
+ Data_Get_Struct( self, P4ClientApi, p4 );
495
+ return P4Utils::ruby_string( p4->GetVersion().Text() );
496
+ }
497
+
498
+ static VALUE p4_set_version( VALUE self, VALUE version )
499
+ {
500
+ P4ClientApi *p4;
501
+ Data_Get_Struct( self, P4ClientApi, p4 );
502
+ p4->SetVersion( StringValuePtr( version ) );
503
+ return Qtrue;
504
+ }
505
+
506
+ static VALUE p4_get_track( VALUE self )
507
+ {
508
+ P4ClientApi *p4;
509
+ Data_Get_Struct( self, P4ClientApi, p4 );
510
+ return p4->GetTrack() ? Qtrue : Qfalse;
511
+ }
512
+
513
+ static VALUE p4_set_track( VALUE self, VALUE toggle )
514
+ {
515
+ P4ClientApi *p4;
516
+ Data_Get_Struct( self, P4ClientApi, p4 );
517
+
518
+ // The user might have passed an integer, or it might be a boolean,
519
+ // we convert to int for consistency.
520
+ int flag = 0;
521
+ if( toggle == Qtrue )
522
+ flag = 1;
523
+ else if( toggle == Qfalse )
524
+ flag = 0;
525
+ else
526
+ flag = NUM2INT( toggle ) ? 1 : 0;
527
+
528
+ p4->SetTrack( flag );
529
+ return flag ? Qtrue : Qfalse; // Seems to be ignored...
530
+ }
531
+
532
+ static VALUE p4_get_streams( VALUE self )
533
+ {
534
+ P4ClientApi *p4;
535
+ Data_Get_Struct( self, P4ClientApi, p4 );
536
+ return p4->IsStreams() ? Qtrue : Qfalse;
537
+ }
538
+
539
+ static VALUE p4_set_streams( VALUE self, VALUE toggle )
540
+ {
541
+ P4ClientApi *p4;
542
+ Data_Get_Struct( self, P4ClientApi, p4 );
543
+
544
+ // The user might have passed an integer, or it might be a boolean,
545
+ // we convert to int for consistency.
546
+ int flag = 0;
547
+ if( toggle == Qtrue )
548
+ flag = 1;
549
+ else if( toggle == Qfalse )
550
+ flag = 0;
551
+ else
552
+ flag = NUM2INT( toggle ) ? 1 : 0;
553
+
554
+ p4->SetStreams( flag );
555
+ return flag ? Qtrue : Qfalse; // Seems to be ignored...
556
+ }
557
+
558
+ /*******************************************************************************
559
+ * Running commands. General purpose Run method and method for supplying
560
+ * input to "p4 xxx -i" commands
561
+ ******************************************************************************/
562
+
563
+ static VALUE p4_run( VALUE self, VALUE args )
564
+ {
565
+ int i;
566
+ int argc = 0;
567
+ ID idFlatten = rb_intern( "flatten" );
568
+ ID idLength = rb_intern( "length" );
569
+ ID idTo_S = rb_intern( "to_s" );
570
+
571
+ P4ClientApi *p4;
572
+ Data_Get_Struct( self, P4ClientApi, p4 );
573
+
574
+ // Flatten the args array, and extract the Perforce command leaving
575
+ // the remaining args in the array.
576
+ VALUE flatArgs = rb_funcall( args, idFlatten, 0 );
577
+
578
+ if ( ! NUM2INT( rb_funcall( flatArgs, idLength, 0 ) ) )
579
+ rb_raise( eP4, "P4#run requires an argument" );
580
+
581
+ VALUE v = rb_funcall( flatArgs, rb_intern( "shift" ), 0 );
582
+ char *cmd = StringValuePtr( v );
583
+ argc = NUM2INT( rb_funcall( flatArgs, idLength, 0 ) );
584
+
585
+ // Allocate storage on the stack so it's automatically reclaimed
586
+ // when we exit.
587
+ char **p4args = ALLOCA_N( char *, argc + 1 );
588
+
589
+ // Copy the args across
590
+ for ( i = 0; i < argc; i++ )
591
+ {
592
+ VALUE entry = rb_ary_entry( flatArgs, i );
593
+ VALUE v = rb_funcall( entry, idTo_S, 0 );
594
+ p4args[ i ] = StringValuePtr( v );
595
+ }
596
+ p4args[ i ] = 0;
597
+
598
+ // Run the command
599
+ VALUE res = p4->Run( cmd, argc, p4args );
600
+ return res;
601
+ }
602
+
603
+ static VALUE p4_set_input( VALUE self, VALUE input )
604
+ {
605
+ P4ClientApi *p4;
606
+ Data_Get_Struct( self, P4ClientApi, p4 );
607
+ return p4->SetInput( input );
608
+ }
609
+
610
+ static VALUE p4_get_errors( VALUE self )
611
+ {
612
+ P4ClientApi *p4;
613
+ Data_Get_Struct( self, P4ClientApi, p4 );
614
+ return p4->GetErrors();
615
+ }
616
+
617
+ static VALUE p4_get_messages( VALUE self )
618
+ {
619
+ P4ClientApi *p4;
620
+ Data_Get_Struct( self, P4ClientApi, p4 );
621
+ return p4->GetMessages();
622
+ }
623
+
624
+ static VALUE p4_get_warnings( VALUE self )
625
+ {
626
+ P4ClientApi *p4;
627
+ Data_Get_Struct( self, P4ClientApi, p4 );
628
+ return p4->GetWarnings();
629
+ }
630
+
631
+ static VALUE p4_set_except_level( VALUE self, VALUE level )
632
+ {
633
+ P4ClientApi *p4;
634
+ Data_Get_Struct( self, P4ClientApi, p4 );
635
+ p4->ExceptionLevel( NUM2INT(level) );
636
+ return level;
637
+ }
638
+
639
+ static VALUE p4_get_except_level( VALUE self )
640
+ {
641
+ P4ClientApi *p4;
642
+ Data_Get_Struct( self, P4ClientApi, p4 );
643
+ return INT2NUM( p4->ExceptionLevel() );
644
+ }
645
+
646
+ static VALUE p4_get_server_level( VALUE self )
647
+ {
648
+ P4ClientApi *p4;
649
+ Data_Get_Struct( self, P4ClientApi, p4 );
650
+ int level = p4->GetServerLevel();
651
+ return INT2NUM( level );
652
+ }
653
+
654
+ static VALUE p4_parse_spec( VALUE self, VALUE type, VALUE form )
655
+ {
656
+ P4ClientApi *p4;
657
+
658
+ Check_Type( form, T_STRING );
659
+ Check_Type( type, T_STRING );
660
+
661
+ Data_Get_Struct( self, P4ClientApi, p4 );
662
+ return p4->ParseSpec( StringValuePtr(type), StringValuePtr(form) );
663
+ }
664
+
665
+ static VALUE p4_format_spec( VALUE self, VALUE type, VALUE hash )
666
+ {
667
+ P4ClientApi *p4;
668
+
669
+ Check_Type( type, T_STRING );
670
+ Check_Type( hash, T_HASH );
671
+
672
+ Data_Get_Struct( self, P4ClientApi, p4 );
673
+ return p4->FormatSpec( StringValuePtr(type), hash );
674
+ }
675
+
676
+ static VALUE p4_track_output( VALUE self )
677
+ {
678
+ P4ClientApi *p4;
679
+ Data_Get_Struct( self, P4ClientApi, p4 );
680
+ return p4->GetTrackOutput();
681
+ }
682
+
683
+ /*******************************************************************************
684
+ * Self identification
685
+ ******************************************************************************/
686
+ static VALUE p4_identify( VALUE self )
687
+ {
688
+ StrBuf s;
689
+ s.Append("P4RUBY ");
690
+ s.Append(P4RUBY_VERSION);
691
+ s.Append(" P4API ");
692
+ s.Append(P4APIVER_STRING);
693
+ s.Append(" PATCHLEVEL ");
694
+ s.Append(P4API_PATCHLEVEL_STRING);
695
+ s.Append(" WITH_LIBS ");
696
+ s.Append(WITH_LIBS);
697
+ return P4Utils::ruby_string( s.Text() );
698
+ }
699
+
700
+ /*******************************************************************************
701
+ * Debugging support
702
+ ******************************************************************************/
703
+ static VALUE p4_get_debug( VALUE self)
704
+ {
705
+ P4ClientApi *p4;
706
+ Data_Get_Struct( self, P4ClientApi, p4);
707
+ return INT2NUM( p4->GetDebug() );
708
+ }
709
+
710
+ static VALUE p4_set_debug( VALUE self, VALUE debug )
711
+ {
712
+ P4ClientApi *p4;
713
+ Data_Get_Struct( self, P4ClientApi, p4 );
714
+ p4->SetDebug( NUM2INT(debug) );
715
+ return Qtrue;
716
+ }
717
+
718
+ /*******************************************************************************
719
+ * Handler support
720
+ ******************************************************************************/
721
+ static VALUE p4_get_handler( VALUE self )
722
+ {
723
+ P4ClientApi *p4;
724
+ Data_Get_Struct( self, P4ClientApi, p4 );
725
+ return p4->GetHandler();
726
+ }
727
+
728
+ static VALUE p4_set_handler( VALUE self, VALUE handler )
729
+ {
730
+ P4ClientApi *p4;
731
+ Data_Get_Struct( self, P4ClientApi, p4 );
732
+ p4->SetHandler( handler );
733
+ return Qtrue;
734
+ }
735
+
736
+ /*******************************************************************************
737
+ * Progress support
738
+ ******************************************************************************/
739
+ static VALUE p4_get_progress( VALUE self )
740
+ {
741
+ P4ClientApi *p4;
742
+ Data_Get_Struct( self, P4ClientApi, p4 );
743
+ return p4->GetProgress();
744
+ }
745
+
746
+ static VALUE p4_set_progress( VALUE self, VALUE progress )
747
+ {
748
+ P4ClientApi *p4;
749
+ Data_Get_Struct( self, P4ClientApi, p4 );
750
+ return p4->SetProgress( progress );
751
+ }
752
+
753
+ /*******************************************************************************
754
+ * P4::MergeData methods. Construction/destruction defined elsewhere
755
+ ******************************************************************************/
756
+
757
+ static VALUE p4md_getyourname( VALUE self )
758
+ {
759
+ P4MergeData *md = 0;
760
+ Data_Get_Struct( self, P4MergeData, md );
761
+ return md->GetYourName();
762
+ }
763
+
764
+ static VALUE p4md_gettheirname( VALUE self )
765
+ {
766
+ P4MergeData *md = 0;
767
+ Data_Get_Struct( self, P4MergeData, md );
768
+ return md->GetTheirName();
769
+ }
770
+
771
+ static VALUE p4md_getbasename( VALUE self )
772
+ {
773
+ P4MergeData *md = 0;
774
+ Data_Get_Struct( self, P4MergeData, md );
775
+ return md->GetBaseName();
776
+ }
777
+
778
+ static VALUE p4md_getyourpath( VALUE self )
779
+ {
780
+ P4MergeData *md = 0;
781
+ Data_Get_Struct( self, P4MergeData, md );
782
+ return md->GetYourPath();
783
+ }
784
+
785
+ static VALUE p4md_gettheirpath( VALUE self )
786
+ {
787
+ P4MergeData *md = 0;
788
+ Data_Get_Struct( self, P4MergeData, md );
789
+ return md->GetTheirPath();
790
+ }
791
+
792
+ static VALUE p4md_getbasepath( VALUE self )
793
+ {
794
+ P4MergeData *md = 0;
795
+ Data_Get_Struct( self, P4MergeData, md );
796
+ return md->GetBasePath();
797
+ }
798
+
799
+ static VALUE p4md_getresultpath( VALUE self )
800
+ {
801
+ P4MergeData *md = 0;
802
+ Data_Get_Struct( self, P4MergeData, md );
803
+ return md->GetResultPath();
804
+ }
805
+
806
+ static VALUE p4md_getmergehint( VALUE self )
807
+ {
808
+ P4MergeData *md = 0;
809
+ Data_Get_Struct( self, P4MergeData, md );
810
+ return md->GetMergeHint();
811
+ }
812
+
813
+ static VALUE p4md_runmerge( VALUE self )
814
+ {
815
+ P4MergeData *md = 0;
816
+ Data_Get_Struct( self, P4MergeData, md );
817
+ return md->RunMergeTool();
818
+ }
819
+
820
+ static VALUE p4md_getcontentresolve( VALUE self )
821
+ {
822
+ P4MergeData *md = 0;
823
+ Data_Get_Struct( self, P4MergeData, md );
824
+ return md->GetContentResolveStatus();
825
+ }
826
+
827
+ //
828
+ // Additional methods added for action resolve
829
+ //
830
+ static VALUE p4md_getactionresolve( VALUE self )
831
+ {
832
+ P4MergeData *md = 0;
833
+ Data_Get_Struct( self, P4MergeData, md );
834
+ return md->GetActionResolveStatus();
835
+ }
836
+
837
+ static VALUE p4md_getyoursaction( VALUE self )
838
+ {
839
+ P4MergeData *md = 0;
840
+ Data_Get_Struct( self, P4MergeData, md );
841
+ return md->GetYoursAction();
842
+ }
843
+
844
+ static VALUE p4md_gettheiraction( VALUE self )
845
+ {
846
+ P4MergeData *md = 0;
847
+ Data_Get_Struct( self, P4MergeData, md );
848
+ return md->GetTheirAction();
849
+ }
850
+
851
+ static VALUE p4md_getmergeaction( VALUE self )
852
+ {
853
+ P4MergeData *md = 0;
854
+ Data_Get_Struct( self, P4MergeData, md );
855
+ return md->GetMergeAction();
856
+ }
857
+
858
+ static VALUE p4md_getactiontype( VALUE self )
859
+ {
860
+ P4MergeData *md = 0;
861
+ Data_Get_Struct( self, P4MergeData, md );
862
+ return md->GetType();
863
+ }
864
+
865
+ static VALUE p4md_getinfo( VALUE self )
866
+ {
867
+ P4MergeData *md = 0;
868
+ Data_Get_Struct( self, P4MergeData, md );
869
+ return md->GetMergeInfo();
870
+ }
871
+
872
+ static VALUE p4md_invalidate( VALUE self )
873
+ {
874
+ P4MergeData *md = 0;
875
+ Data_Get_Struct( self, P4MergeData, md );
876
+ md->Invalidate();
877
+ return self;
878
+ }
879
+
880
+ static VALUE p4md_tos( VALUE self )
881
+ {
882
+ P4MergeData *md = 0;
883
+ Data_Get_Struct( self, P4MergeData, md );
884
+ return md->GetString();
885
+ }
886
+ /******************************************************************************
887
+ * P4::Map class
888
+ ******************************************************************************/
889
+ static void p4map_free( P4MapMaker *m )
890
+ {
891
+ delete m;
892
+ }
893
+
894
+ static VALUE p4map_new( int argc, VALUE *argv, VALUE pClass )
895
+ {
896
+ //VALUE pClass;
897
+ VALUE array;
898
+ VALUE self;
899
+ P4MapMaker *m = new P4MapMaker;
900
+
901
+ // First arg is the class
902
+ // pClass = argv[ 0 ];
903
+
904
+ // Now instantiate the new object.
905
+ self = Data_Wrap_Struct( pClass, 0, p4map_free, m );
906
+ rb_obj_call_init( self, 0, argv );
907
+
908
+ if( argc )
909
+ {
910
+ array = argv[ 0 ];
911
+ if( !rb_obj_is_kind_of( array, rb_cArray ) )
912
+ rb_raise( rb_eRuntimeError, "Not an array" );
913
+
914
+ StrBuf t;
915
+ ID idLen = rb_intern( "length" );
916
+ int len;
917
+ VALUE entry;
918
+
919
+ // Now iterate over the array, inserting the mappings
920
+ len = NUM2INT( rb_funcall( array, idLen, 0 ) );
921
+ for( int i = 0; i < len; i++ )
922
+ {
923
+ entry = rb_ary_entry( array, i );
924
+ m->Insert( entry );
925
+ }
926
+ }
927
+ return self;
928
+ }
929
+
930
+ //
931
+ // Joins the RHS of the first mapping with the LHS of the second, and
932
+ // returns a new P4::Map object made up of the LHS of the first and the
933
+ // RHS of the second where the joins match up.
934
+ //
935
+ static VALUE p4map_join( VALUE pClass, VALUE left, VALUE right )
936
+ {
937
+ P4MapMaker * l = 0;
938
+ P4MapMaker * r = 0;
939
+ P4MapMaker * j = 0;
940
+ VALUE m;
941
+ VALUE argv[ 1 ];
942
+
943
+ Data_Get_Struct( left, P4MapMaker, l );
944
+ Data_Get_Struct( right, P4MapMaker, r );
945
+
946
+ j = P4MapMaker::Join( l, r );
947
+ if( !j ) return Qnil;
948
+
949
+ m = Data_Wrap_Struct( pClass, 0, p4map_free, j );
950
+ rb_obj_call_init( m, 0, argv );
951
+ return m;
952
+ }
953
+
954
+ //
955
+ // Debugging support
956
+ //
957
+ static VALUE p4map_inspect( VALUE self )
958
+ {
959
+ P4MapMaker * m = 0;
960
+ StrBuf b;
961
+ StrBuf tb;
962
+
963
+ tb.Alloc( 32 );
964
+ sprintf( tb.Text(), "%p", (void*) self );
965
+ tb.SetLength();
966
+
967
+ Data_Get_Struct( self, P4MapMaker, m );
968
+
969
+ b << "#<P4::Map:" << tb << "> ";
970
+
971
+ m->Inspect( b );
972
+ return P4Utils::ruby_string( b.Text(), b.Length() );
973
+ }
974
+
975
+ //
976
+ // Insert a mapping into a P4::Map object. Can be called with either
977
+ // one, or two arguments. If one, it's assumed to be a string containing
978
+ // either a half-map, or both halves of the mapping.
979
+ //
980
+ static VALUE p4map_insert( int argc, VALUE *argv, VALUE self )
981
+ {
982
+ P4MapMaker * m = 0;
983
+ StrBuf t;
984
+
985
+ Data_Get_Struct( self, P4MapMaker, m );
986
+
987
+ if( argc < 1 || argc > 2 )
988
+ rb_raise( rb_eArgError, "P4::Map#insert takes 1, or 2 arguments" );
989
+
990
+
991
+ if( argc == 1 )
992
+ {
993
+ // A mapping with only a left hand side.
994
+ m->Insert( *argv );
995
+ return self;
996
+ }
997
+
998
+ if( argc == 2 )
999
+ {
1000
+ // Separate left- and right-hand strings.
1001
+ VALUE left;
1002
+ VALUE right;
1003
+
1004
+ left = *argv++;
1005
+ right = *argv;
1006
+
1007
+ m->Insert( left, right );
1008
+ }
1009
+ return self;
1010
+ }
1011
+ static VALUE p4map_clear( VALUE self )
1012
+ {
1013
+ P4MapMaker * m = 0;
1014
+
1015
+ Data_Get_Struct( self, P4MapMaker, m );
1016
+ m->Clear();
1017
+ return Qtrue;
1018
+ }
1019
+
1020
+ static VALUE p4map_count( VALUE self )
1021
+ {
1022
+ P4MapMaker * m = 0;
1023
+
1024
+ Data_Get_Struct( self, P4MapMaker, m );
1025
+ return INT2NUM( m->Count() );
1026
+ }
1027
+
1028
+ static VALUE p4map_empty( VALUE self )
1029
+ {
1030
+ P4MapMaker * m = 0;
1031
+
1032
+ Data_Get_Struct( self, P4MapMaker, m );
1033
+ return m->Count() ? Qfalse : Qtrue;
1034
+ }
1035
+
1036
+ static VALUE p4map_reverse( VALUE self )
1037
+ {
1038
+ P4MapMaker * m = 0;
1039
+ P4MapMaker * m2 = 0;
1040
+ VALUE rval;
1041
+ VALUE argv[ 1 ];
1042
+
1043
+ Data_Get_Struct( self, P4MapMaker, m );
1044
+ m2 = new P4MapMaker( *m );
1045
+ m2->Reverse();
1046
+
1047
+ rval = Data_Wrap_Struct( cP4Map, 0, p4map_free, m2 );
1048
+ rb_obj_call_init( rval, 0, argv );
1049
+ return rval;
1050
+ }
1051
+
1052
+ //
1053
+ // P4::Map#translate( string, fwd=true )
1054
+ //
1055
+ static VALUE p4map_trans( int argc, VALUE *argv, VALUE self )
1056
+ {
1057
+ P4MapMaker * m = 0;
1058
+ int fwd = 1;
1059
+ VALUE string;
1060
+
1061
+ if( argc < 1 || argc > 2 )
1062
+ rb_raise( rb_eArgError,
1063
+ "Invalid arguments to P4::Map#translate. "
1064
+ "Pass the string you wish to translate, and an optional "
1065
+ "boolean to indicate whether translation should be in "
1066
+ "the forward direction." );
1067
+
1068
+ argc--;
1069
+ string = *argv++;
1070
+
1071
+ if( argc && *argv == Qfalse )
1072
+ fwd = 0;
1073
+
1074
+ Data_Get_Struct( self, P4MapMaker, m );
1075
+ return m->Translate( string, fwd );
1076
+ }
1077
+
1078
+ static VALUE p4map_includes( VALUE self, VALUE string )
1079
+ {
1080
+ P4MapMaker * m = 0;
1081
+
1082
+ Data_Get_Struct( self, P4MapMaker, m );
1083
+ if( m->Translate( string, 1 ) != Qnil )
1084
+ return Qtrue;
1085
+ if( m->Translate( string, 0 ) != Qnil )
1086
+ return Qtrue;
1087
+ return Qfalse;
1088
+ }
1089
+
1090
+ static VALUE p4map_lhs( VALUE self )
1091
+ {
1092
+ P4MapMaker * m = 0;
1093
+
1094
+ Data_Get_Struct( self, P4MapMaker, m );
1095
+ return m->Lhs();
1096
+ }
1097
+
1098
+ static VALUE p4map_rhs( VALUE self )
1099
+ {
1100
+ P4MapMaker * m = 0;
1101
+
1102
+ Data_Get_Struct( self, P4MapMaker, m );
1103
+ return m->Rhs();
1104
+ }
1105
+
1106
+ static VALUE p4map_to_a( VALUE self )
1107
+ {
1108
+ P4MapMaker * m = 0;
1109
+
1110
+ Data_Get_Struct( self, P4MapMaker, m );
1111
+ return m->ToA();
1112
+ }
1113
+
1114
+ /*******************************************************************************
1115
+ * P4::Message methods. Construction/destruction defined elsewhere
1116
+ ******************************************************************************/
1117
+ static VALUE p4msg_get_severity( VALUE self )
1118
+ {
1119
+ P4Error * e = 0;
1120
+
1121
+ Data_Get_Struct( self, P4Error, e );
1122
+ return e->GetSeverity();
1123
+ }
1124
+
1125
+ static VALUE p4msg_get_generic( VALUE self )
1126
+ {
1127
+ P4Error * e = 0;
1128
+
1129
+ Data_Get_Struct( self, P4Error, e );
1130
+ return e->GetGeneric();
1131
+ }
1132
+
1133
+ static VALUE p4msg_get_text( VALUE self )
1134
+ {
1135
+ P4Error * e = 0;
1136
+
1137
+ Data_Get_Struct( self, P4Error, e );
1138
+ return e->GetText();
1139
+ }
1140
+
1141
+ static VALUE p4msg_get_id( VALUE self )
1142
+ {
1143
+ P4Error * e = 0;
1144
+
1145
+ Data_Get_Struct( self, P4Error, e );
1146
+ return e->GetId();
1147
+ }
1148
+ static VALUE p4msg_inspect( VALUE self )
1149
+ {
1150
+ P4Error * e = 0;
1151
+
1152
+ Data_Get_Struct( self, P4Error, e );
1153
+ return e->Inspect();
1154
+ }
1155
+
1156
+
1157
+ /******************************************************************************
1158
+ * Extension initialisation
1159
+ ******************************************************************************/
1160
+
1161
+ void Init_P4()
1162
+ {
1163
+ // Ruby instantiation
1164
+ eP4 = rb_define_class( "P4Exception", rb_eRuntimeError );
1165
+
1166
+ // We ensure this class already exists by loading the version file in P4.rb.
1167
+ // If we don't do this, calling things via rake might change the load order
1168
+ // in "interesting" ways.
1169
+ cP4 = rb_path2class("P4");
1170
+
1171
+ rb_define_singleton_method( cP4, "new", RUBY_METHOD_FUNC(p4_new), 0 );
1172
+
1173
+ // Protocol options
1174
+ rb_define_method( cP4, "api_level", RUBY_METHOD_FUNC(p4_get_api_level), 0);
1175
+ rb_define_method( cP4, "api_level=", RUBY_METHOD_FUNC(p4_set_api_level), 1);
1176
+ rb_define_method( cP4, "streams?", RUBY_METHOD_FUNC(p4_get_streams) , 0 );
1177
+ rb_define_method( cP4, "streams=", RUBY_METHOD_FUNC(p4_set_streams) , 1 );
1178
+ rb_define_method( cP4, "tagged", RUBY_METHOD_FUNC(p4_run_tagged), 1 );
1179
+ rb_define_method( cP4, "tagged?", RUBY_METHOD_FUNC(p4_get_tagged), 0 );
1180
+ rb_define_method( cP4, "tagged=", RUBY_METHOD_FUNC(p4_set_tagged), 1 );
1181
+ rb_define_method( cP4, "track?", RUBY_METHOD_FUNC(p4_get_track) , 0 );
1182
+ rb_define_method( cP4, "track=", RUBY_METHOD_FUNC(p4_set_track) , 1 );
1183
+
1184
+
1185
+ // Perforce client settings.
1186
+ //
1187
+ rb_define_method( cP4, "charset", RUBY_METHOD_FUNC(p4_get_charset) , 0 );
1188
+ rb_define_method( cP4, "charset=", RUBY_METHOD_FUNC(p4_set_charset) , 1 );
1189
+ rb_define_method( cP4, "cwd", RUBY_METHOD_FUNC(p4_get_cwd) , 0 );
1190
+ rb_define_method( cP4, "cwd=", RUBY_METHOD_FUNC(p4_set_cwd) , 1 );
1191
+ rb_define_method( cP4, "client", RUBY_METHOD_FUNC(p4_get_client) , 0 );
1192
+ rb_define_method( cP4, "client=", RUBY_METHOD_FUNC(p4_set_client) , 1 );
1193
+ rb_define_method( cP4, "env", RUBY_METHOD_FUNC(p4_get_env) , 1 );
1194
+ rb_define_method( cP4, "set_env", RUBY_METHOD_FUNC(p4_set_env) , 2 );
1195
+ rb_define_method( cP4, "host", RUBY_METHOD_FUNC(p4_get_host) , 0 );
1196
+ rb_define_method( cP4, "host=", RUBY_METHOD_FUNC(p4_set_host) , 1 );
1197
+ rb_define_method( cP4, "ignore_file",RUBY_METHOD_FUNC(p4_get_ignore) , 0 );
1198
+ rb_define_method( cP4, "ignore_file=",RUBY_METHOD_FUNC(p4_set_ignore), 1 );
1199
+ rb_define_method( cP4, "ignored?", RUBY_METHOD_FUNC(p4_is_ignored) , 1 );
1200
+ rb_define_method( cP4, "language", RUBY_METHOD_FUNC(p4_get_language), 0 );
1201
+ rb_define_method( cP4, "language=", RUBY_METHOD_FUNC(p4_set_language), 1 );
1202
+ rb_define_method( cP4, "p4config_file",RUBY_METHOD_FUNC(p4_get_p4config),0);
1203
+ rb_define_method( cP4, "password", RUBY_METHOD_FUNC(p4_get_password), 0 );
1204
+ rb_define_method( cP4, "password=", RUBY_METHOD_FUNC(p4_set_password), 1 );
1205
+ rb_define_method( cP4, "port", RUBY_METHOD_FUNC(p4_get_port) , 0 );
1206
+ rb_define_method( cP4, "port=", RUBY_METHOD_FUNC(p4_set_port) , 1 );
1207
+ rb_define_method( cP4, "prog", RUBY_METHOD_FUNC(p4_get_prog) , 0 );
1208
+ rb_define_method( cP4, "prog=", RUBY_METHOD_FUNC(p4_set_prog) , 1 );
1209
+ rb_define_method( cP4, "protocol", RUBY_METHOD_FUNC(p4_set_protocol), 2 );
1210
+ rb_define_method( cP4, "ticket_file", RUBY_METHOD_FUNC(p4_get_ticket_file), 0 );
1211
+ rb_define_method( cP4, "ticket_file=", RUBY_METHOD_FUNC(p4_set_ticket_file), 1 );
1212
+ rb_define_method( cP4, "user", RUBY_METHOD_FUNC(p4_get_user) , 0 );
1213
+ rb_define_method( cP4, "user=", RUBY_METHOD_FUNC(p4_set_user) , 1 );
1214
+ rb_define_method( cP4, "version", RUBY_METHOD_FUNC(p4_get_version) , 0 );
1215
+ rb_define_method( cP4, "version=", RUBY_METHOD_FUNC(p4_set_version) , 1 );
1216
+
1217
+
1218
+ rb_define_method( cP4, "maxresults", RUBY_METHOD_FUNC(p4_get_maxresults),0);
1219
+ rb_define_method( cP4, "maxresults=",RUBY_METHOD_FUNC(p4_set_maxresults),1);
1220
+ rb_define_method( cP4, "maxscanrows", RUBY_METHOD_FUNC(p4_get_maxscanrows),0);
1221
+ rb_define_method( cP4, "maxscanrows=",RUBY_METHOD_FUNC(p4_set_maxscanrows), 1 );
1222
+ rb_define_method( cP4, "maxlocktime", RUBY_METHOD_FUNC(p4_get_maxlocktime), 0 );
1223
+ rb_define_method( cP4, "maxlocktime=", RUBY_METHOD_FUNC(p4_set_maxlocktime), 1 );
1224
+
1225
+ // Session Connect/Disconnect
1226
+ rb_define_method( cP4, "connect", RUBY_METHOD_FUNC(p4_connect) , 0 );
1227
+ rb_define_method( cP4, "connected?",RUBY_METHOD_FUNC(p4_connected) , 0 );
1228
+ rb_define_method( cP4, "disconnect", RUBY_METHOD_FUNC(p4_disconnect) , 0 );
1229
+
1230
+ // Running commands - general purpose commands
1231
+ rb_define_method( cP4, "run", RUBY_METHOD_FUNC(p4_run) ,-2 );
1232
+ rb_define_method( cP4, "input=", RUBY_METHOD_FUNC(p4_set_input) , 1 );
1233
+ rb_define_method( cP4, "errors", RUBY_METHOD_FUNC(p4_get_errors) , 0 );
1234
+ rb_define_method( cP4, "messages", RUBY_METHOD_FUNC(p4_get_messages), 0 );
1235
+ rb_define_method( cP4, "warnings", RUBY_METHOD_FUNC(p4_get_warnings), 0 );
1236
+ rb_define_method( cP4, "exception_level", RUBY_METHOD_FUNC(p4_get_except_level), 0 );
1237
+ rb_define_method( cP4, "exception_level=", RUBY_METHOD_FUNC(p4_set_except_level), 1 );
1238
+ rb_define_method( cP4, "server_level", RUBY_METHOD_FUNC(p4_get_server_level), 0 );
1239
+ rb_define_method( cP4, "server_case_sensitive?", RUBY_METHOD_FUNC(p4_server_case_sensitive), 0 );
1240
+ rb_define_method( cP4, "track_output", RUBY_METHOD_FUNC(p4_track_output), 0 );
1241
+
1242
+ rb_define_method( cP4, "server_unicode?", RUBY_METHOD_FUNC(p4_server_unicode), 0 );
1243
+
1244
+ // Spec parsing
1245
+ rb_define_method( cP4, "parse_spec", RUBY_METHOD_FUNC(p4_parse_spec), 2 );
1246
+ rb_define_method( cP4, "format_spec", RUBY_METHOD_FUNC(p4_format_spec), 2 );
1247
+
1248
+ // Identification
1249
+ rb_define_const( cP4, "P4API_VERSION", P4Utils::ruby_string(P4APIVER_STRING));
1250
+ rb_define_const( cP4, "P4API_PATCHLEVEL", INT2NUM(P4API_PATCHLEVEL));
1251
+ rb_define_const( cP4, "P4RUBY_VERSION", P4Utils::ruby_string(P4RUBY_VERSION) );
1252
+ rb_define_singleton_method( cP4, "identify", RUBY_METHOD_FUNC(p4_identify), 0 );
1253
+
1254
+ // Debugging support
1255
+ rb_define_method( cP4, "debug", RUBY_METHOD_FUNC(p4_get_debug), 0);
1256
+ rb_define_method( cP4, "debug=", RUBY_METHOD_FUNC(p4_set_debug), 1 );
1257
+
1258
+ // Support for OutputHandler
1259
+ rb_define_method( cP4, "handler", RUBY_METHOD_FUNC(p4_get_handler), 0);
1260
+ rb_define_method( cP4, "handler=", RUBY_METHOD_FUNC(p4_set_handler), 1);
1261
+
1262
+ // Support for Progress API
1263
+ rb_define_method( cP4, "progress", RUBY_METHOD_FUNC(p4_get_progress), 0);
1264
+ rb_define_method( cP4, "progress=", RUBY_METHOD_FUNC(p4_set_progress), 1);
1265
+
1266
+ // P4::MergeData class
1267
+ cP4MD = rb_define_class_under( cP4, "MergeData", rb_cObject );
1268
+
1269
+ rb_define_method( cP4MD, "your_name", RUBY_METHOD_FUNC(p4md_getyourname),0);
1270
+ rb_define_method( cP4MD, "their_name", RUBY_METHOD_FUNC(p4md_gettheirname),0);
1271
+ rb_define_method( cP4MD, "base_name", RUBY_METHOD_FUNC(p4md_getbasename),0);
1272
+ rb_define_method( cP4MD, "your_path", RUBY_METHOD_FUNC(p4md_getyourpath),0);
1273
+ rb_define_method( cP4MD, "their_path", RUBY_METHOD_FUNC(p4md_gettheirpath),0);
1274
+ rb_define_method( cP4MD, "base_path", RUBY_METHOD_FUNC(p4md_getbasepath),0);
1275
+ rb_define_method( cP4MD, "result_path", RUBY_METHOD_FUNC(p4md_getresultpath),0);
1276
+ rb_define_method( cP4MD, "merge_hint", RUBY_METHOD_FUNC(p4md_getmergehint),0);
1277
+ rb_define_method( cP4MD, "run_merge", RUBY_METHOD_FUNC(p4md_runmerge),0);
1278
+
1279
+ rb_define_method(cP4MD, "action_resolve?", RUBY_METHOD_FUNC(p4md_getactionresolve), 0);
1280
+ rb_define_method(cP4MD, "action_type", RUBY_METHOD_FUNC(p4md_getactiontype), 0);
1281
+ rb_define_method(cP4MD, "content_resolve?", RUBY_METHOD_FUNC(p4md_getcontentresolve), 0);
1282
+ rb_define_method(cP4MD, "info", RUBY_METHOD_FUNC(p4md_getinfo), 0);
1283
+ rb_define_method(cP4MD, "invalidate", RUBY_METHOD_FUNC(p4md_invalidate), 0);
1284
+ rb_define_method(cP4MD, "merge_action", RUBY_METHOD_FUNC(p4md_getmergeaction), 0);
1285
+ rb_define_method(cP4MD, "their_action", RUBY_METHOD_FUNC(p4md_gettheiraction), 0);
1286
+ rb_define_method(cP4MD, "to_s", RUBY_METHOD_FUNC(p4md_tos), 0);
1287
+ rb_define_method(cP4MD, "yours_action", RUBY_METHOD_FUNC(p4md_getyoursaction), 0);
1288
+
1289
+ // P4::Map class
1290
+ cP4Map = rb_define_class_under( cP4, "Map", rb_cObject );
1291
+ rb_define_singleton_method( cP4Map, "new", RUBY_METHOD_FUNC(p4map_new), -1);
1292
+ rb_define_singleton_method( cP4Map, "join", RUBY_METHOD_FUNC(p4map_join), 2 );
1293
+ rb_define_method( cP4Map, "insert", RUBY_METHOD_FUNC(p4map_insert),-1);
1294
+ rb_define_method( cP4Map, "inspect", RUBY_METHOD_FUNC(p4map_inspect),0);
1295
+ rb_define_method( cP4Map, "clear", RUBY_METHOD_FUNC(p4map_clear),0);
1296
+ rb_define_method( cP4Map, "count", RUBY_METHOD_FUNC(p4map_count),0);
1297
+ rb_define_method( cP4Map, "empty?", RUBY_METHOD_FUNC(p4map_empty),0);
1298
+ rb_define_method( cP4Map, "translate", RUBY_METHOD_FUNC(p4map_trans),-1);
1299
+ rb_define_method( cP4Map, "reverse", RUBY_METHOD_FUNC(p4map_reverse),0);
1300
+ rb_define_method( cP4Map, "includes?", RUBY_METHOD_FUNC(p4map_includes),1);
1301
+ rb_define_method( cP4Map, "lhs", RUBY_METHOD_FUNC(p4map_lhs),0);
1302
+ rb_define_method( cP4Map, "rhs", RUBY_METHOD_FUNC(p4map_rhs),0);
1303
+ rb_define_method( cP4Map, "to_a", RUBY_METHOD_FUNC(p4map_to_a),0);
1304
+
1305
+ // P4::Message class.
1306
+ cP4Msg = rb_define_class_under( cP4, "Message", rb_cObject );
1307
+ rb_define_method( cP4Msg, "inspect", RUBY_METHOD_FUNC(p4msg_inspect),0);
1308
+ rb_define_method( cP4Msg, "msgid", RUBY_METHOD_FUNC(p4msg_get_id), 0);
1309
+ rb_define_method( cP4Msg, "severity", RUBY_METHOD_FUNC(p4msg_get_severity), 0);
1310
+ rb_define_method( cP4Msg, "generic", RUBY_METHOD_FUNC(p4msg_get_generic), 0);
1311
+ rb_define_method( cP4Msg, "to_s", RUBY_METHOD_FUNC(p4msg_get_text), 0);
1312
+
1313
+ // P4::Progress class.
1314
+ cP4Prog = rb_define_class_under( cP4, "Progress", rb_cObject );
1315
+
1316
+ };
1317
+
1318
+
1319
+ } // Extern C