p4ruby 2015.2.1265122-x64-mingw32

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,1338 @@
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
+
301
+ static VALUE p4_get_enviro_file( VALUE self )
302
+ {
303
+ P4ClientApi *p4;
304
+ Data_Get_Struct( self, P4ClientApi, p4 );
305
+ const StrPtr *enviro_file = p4->GetEnviroFile();
306
+ return P4Utils::ruby_string( enviro_file->Text() );
307
+ }
308
+
309
+ static VALUE p4_set_enviro_file( VALUE self, VALUE rbstr )
310
+ {
311
+ P4ClientApi *p4;
312
+ Data_Get_Struct( self, P4ClientApi, p4 );
313
+ p4->SetEnviroFile( StringValuePtr(rbstr) );
314
+ return Qtrue;
315
+ }
316
+
317
+ static VALUE p4_get_host( VALUE self )
318
+ {
319
+ P4ClientApi *p4;
320
+ Data_Get_Struct( self, P4ClientApi, p4 );
321
+ StrPtr host = p4->GetHost();
322
+ return P4Utils::ruby_string( host.Text() );
323
+ }
324
+
325
+ static VALUE p4_set_host( VALUE self, VALUE host )
326
+ {
327
+ P4ClientApi *p4;
328
+ Data_Get_Struct( self, P4ClientApi, p4 );
329
+ p4->SetHost( StringValuePtr( host ) );
330
+ return Qtrue;
331
+ }
332
+
333
+ static VALUE p4_get_ignore( VALUE self )
334
+ {
335
+ P4ClientApi *p4;
336
+ Data_Get_Struct( self, P4ClientApi, p4 );
337
+ StrPtr ignore = p4->GetIgnoreFile();
338
+ return P4Utils::ruby_string( ignore.Text() );
339
+ }
340
+
341
+ static VALUE p4_set_ignore( VALUE self, VALUE file )
342
+ {
343
+ P4ClientApi *p4;
344
+ Data_Get_Struct( self, P4ClientApi, p4 );
345
+ p4->SetIgnoreFile( StringValuePtr( file ) );
346
+ return Qtrue;
347
+ }
348
+
349
+ static VALUE p4_is_ignored( VALUE self, VALUE path )
350
+ {
351
+ P4ClientApi *p4;
352
+ Data_Get_Struct( self, P4ClientApi, p4 );
353
+ if( p4->IsIgnored( StringValuePtr( path ) ) )
354
+ return Qtrue;
355
+ return Qfalse;
356
+ }
357
+
358
+ static VALUE p4_get_language( VALUE self )
359
+ {
360
+ P4ClientApi *p4;
361
+ Data_Get_Struct( self, P4ClientApi, p4 );
362
+ StrPtr lang = p4->GetLanguage();
363
+ return P4Utils::ruby_string( lang.Text() );
364
+ }
365
+
366
+ static VALUE p4_set_language( VALUE self, VALUE lang )
367
+ {
368
+ P4ClientApi *p4;
369
+ Data_Get_Struct( self, P4ClientApi, p4 );
370
+ p4->SetLanguage( StringValuePtr( lang ) );
371
+ return Qtrue;
372
+ }
373
+
374
+ static VALUE p4_get_maxresults( VALUE self )
375
+ {
376
+ P4ClientApi *p4;
377
+ Data_Get_Struct( self, P4ClientApi, p4 );
378
+ return INT2NUM( p4->GetMaxResults() );
379
+ }
380
+
381
+ static VALUE p4_set_maxresults( VALUE self, VALUE val )
382
+ {
383
+ P4ClientApi *p4;
384
+ Data_Get_Struct( self, P4ClientApi, p4 );
385
+ p4->SetMaxResults( NUM2INT( val ) );
386
+ return Qtrue;
387
+ }
388
+
389
+ static VALUE p4_get_maxscanrows( VALUE self )
390
+ {
391
+ P4ClientApi *p4;
392
+ Data_Get_Struct( self, P4ClientApi, p4 );
393
+ return INT2NUM( p4->GetMaxScanRows() );
394
+ }
395
+
396
+ static VALUE p4_set_maxscanrows( VALUE self, VALUE val )
397
+ {
398
+ P4ClientApi *p4;
399
+ Data_Get_Struct( self, P4ClientApi, p4 );
400
+ p4->SetMaxScanRows( NUM2INT( val ) );
401
+ return Qtrue;
402
+ }
403
+
404
+ static VALUE p4_get_maxlocktime( VALUE self )
405
+ {
406
+ P4ClientApi *p4;
407
+ Data_Get_Struct( self, P4ClientApi, p4 );
408
+ return INT2NUM( p4->GetMaxLockTime() );
409
+ }
410
+
411
+ static VALUE p4_set_maxlocktime( VALUE self, VALUE val )
412
+ {
413
+ P4ClientApi *p4;
414
+ Data_Get_Struct( self, P4ClientApi, p4 );
415
+ p4->SetMaxLockTime( NUM2INT( val ) );
416
+ return Qtrue;
417
+ }
418
+
419
+ static VALUE p4_get_password( VALUE self )
420
+ {
421
+ P4ClientApi *p4;
422
+ Data_Get_Struct( self, P4ClientApi, p4 );
423
+ StrPtr passwd = p4->GetPassword();
424
+ return P4Utils::ruby_string( passwd.Text() );
425
+ }
426
+
427
+ static VALUE p4_set_password( VALUE self, VALUE passwd )
428
+ {
429
+ P4ClientApi *p4;
430
+ Data_Get_Struct( self, P4ClientApi, p4 );
431
+ p4->SetPassword( StringValuePtr( passwd ) );
432
+ return Qtrue;
433
+ }
434
+
435
+ static VALUE p4_get_port( VALUE self )
436
+ {
437
+ P4ClientApi *p4;
438
+ Data_Get_Struct( self, P4ClientApi, p4 );
439
+ StrPtr port = p4->GetPort();
440
+ return P4Utils::ruby_string( port.Text() );
441
+ }
442
+
443
+ static VALUE p4_set_port( VALUE self, VALUE port )
444
+ {
445
+ P4ClientApi *p4;
446
+ Data_Get_Struct( self, P4ClientApi, p4 );
447
+ if( p4->Connected() )
448
+ rb_raise( eP4, "Can't change port once you've connected." );
449
+
450
+ p4->SetPort( StringValuePtr( port ) );
451
+ return Qtrue;
452
+ }
453
+
454
+ static VALUE p4_get_prog( VALUE self )
455
+ {
456
+ P4ClientApi *p4;
457
+ Data_Get_Struct( self, P4ClientApi, p4 );
458
+ return P4Utils::ruby_string( p4->GetProg().Text() );
459
+ }
460
+
461
+ static VALUE p4_set_prog( VALUE self, VALUE prog )
462
+ {
463
+ P4ClientApi *p4;
464
+ Data_Get_Struct( self, P4ClientApi, p4 );
465
+ p4->SetProg( StringValuePtr( prog ) );
466
+ return Qtrue;
467
+ }
468
+
469
+ static VALUE p4_set_protocol( VALUE self, VALUE var, VALUE val )
470
+ {
471
+ P4ClientApi *p4;
472
+ Data_Get_Struct( self, P4ClientApi, p4 );
473
+ p4->SetProtocol( StringValuePtr( var ), StringValuePtr( val ) );
474
+ return Qtrue;
475
+ }
476
+
477
+ static VALUE p4_get_ticket_file( VALUE self )
478
+ {
479
+ P4ClientApi *p4;
480
+ Data_Get_Struct( self, P4ClientApi, p4 );
481
+ return P4Utils::ruby_string( p4->GetTicketFile().Text() );
482
+ }
483
+
484
+ static VALUE p4_set_ticket_file( VALUE self, VALUE path )
485
+ {
486
+ P4ClientApi *p4;
487
+ Data_Get_Struct( self, P4ClientApi, p4 );
488
+ p4->SetTicketFile( StringValuePtr( path ) );
489
+ return Qtrue;
490
+ }
491
+
492
+ static VALUE p4_get_user( VALUE self )
493
+ {
494
+ P4ClientApi *p4;
495
+ Data_Get_Struct( self, P4ClientApi, p4 );
496
+ StrPtr user = p4->GetUser();
497
+ return P4Utils::ruby_string( user.Text() );
498
+ }
499
+
500
+ static VALUE p4_set_user( VALUE self, VALUE user )
501
+ {
502
+ P4ClientApi *p4;
503
+ Data_Get_Struct( self, P4ClientApi, p4 );
504
+ p4->SetUser( StringValuePtr( user ) );
505
+ return Qtrue;
506
+ }
507
+
508
+ static VALUE p4_get_version( VALUE self )
509
+ {
510
+ P4ClientApi *p4;
511
+ Data_Get_Struct( self, P4ClientApi, p4 );
512
+ return P4Utils::ruby_string( p4->GetVersion().Text() );
513
+ }
514
+
515
+ static VALUE p4_set_version( VALUE self, VALUE version )
516
+ {
517
+ P4ClientApi *p4;
518
+ Data_Get_Struct( self, P4ClientApi, p4 );
519
+ p4->SetVersion( StringValuePtr( version ) );
520
+ return Qtrue;
521
+ }
522
+
523
+ static VALUE p4_get_track( VALUE self )
524
+ {
525
+ P4ClientApi *p4;
526
+ Data_Get_Struct( self, P4ClientApi, p4 );
527
+ return p4->GetTrack() ? Qtrue : Qfalse;
528
+ }
529
+
530
+ static VALUE p4_set_track( VALUE self, VALUE toggle )
531
+ {
532
+ P4ClientApi *p4;
533
+ Data_Get_Struct( self, P4ClientApi, p4 );
534
+
535
+ // The user might have passed an integer, or it might be a boolean,
536
+ // we convert to int for consistency.
537
+ int flag = 0;
538
+ if( toggle == Qtrue )
539
+ flag = 1;
540
+ else if( toggle == Qfalse )
541
+ flag = 0;
542
+ else
543
+ flag = NUM2INT( toggle ) ? 1 : 0;
544
+
545
+ p4->SetTrack( flag );
546
+ return flag ? Qtrue : Qfalse; // Seems to be ignored...
547
+ }
548
+
549
+ static VALUE p4_get_streams( VALUE self )
550
+ {
551
+ P4ClientApi *p4;
552
+ Data_Get_Struct( self, P4ClientApi, p4 );
553
+ return p4->IsStreams() ? Qtrue : Qfalse;
554
+ }
555
+
556
+ static VALUE p4_set_streams( VALUE self, VALUE toggle )
557
+ {
558
+ P4ClientApi *p4;
559
+ Data_Get_Struct( self, P4ClientApi, p4 );
560
+
561
+ // The user might have passed an integer, or it might be a boolean,
562
+ // we convert to int for consistency.
563
+ int flag = 0;
564
+ if( toggle == Qtrue )
565
+ flag = 1;
566
+ else if( toggle == Qfalse )
567
+ flag = 0;
568
+ else
569
+ flag = NUM2INT( toggle ) ? 1 : 0;
570
+
571
+ p4->SetStreams( flag );
572
+ return flag ? Qtrue : Qfalse; // Seems to be ignored...
573
+ }
574
+
575
+ /*******************************************************************************
576
+ * Running commands. General purpose Run method and method for supplying
577
+ * input to "p4 xxx -i" commands
578
+ ******************************************************************************/
579
+
580
+ static VALUE p4_run( VALUE self, VALUE args )
581
+ {
582
+ int i;
583
+ int argc = 0;
584
+ ID idFlatten = rb_intern( "flatten" );
585
+ ID idLength = rb_intern( "length" );
586
+ ID idTo_S = rb_intern( "to_s" );
587
+
588
+ P4ClientApi *p4;
589
+ Data_Get_Struct( self, P4ClientApi, p4 );
590
+
591
+ // Flatten the args array, and extract the Perforce command leaving
592
+ // the remaining args in the array.
593
+ VALUE flatArgs = rb_funcall( args, idFlatten, 0 );
594
+
595
+ if ( ! NUM2INT( rb_funcall( flatArgs, idLength, 0 ) ) )
596
+ rb_raise( eP4, "P4#run requires an argument" );
597
+
598
+ VALUE v = rb_funcall( flatArgs, rb_intern( "shift" ), 0 );
599
+ char *cmd = StringValuePtr( v );
600
+ argc = NUM2INT( rb_funcall( flatArgs, idLength, 0 ) );
601
+
602
+ // Allocate storage on the stack so it's automatically reclaimed
603
+ // when we exit.
604
+ char **p4args = ALLOCA_N( char *, argc + 1 );
605
+
606
+ // Copy the args across
607
+ for ( i = 0; i < argc; i++ )
608
+ {
609
+ VALUE entry = rb_ary_entry( flatArgs, i );
610
+ VALUE v = rb_funcall( entry, idTo_S, 0 );
611
+ p4args[ i ] = StringValuePtr( v );
612
+ }
613
+ p4args[ i ] = 0;
614
+
615
+ // Run the command
616
+ VALUE res = p4->Run( cmd, argc, p4args );
617
+ return res;
618
+ }
619
+
620
+ static VALUE p4_set_input( VALUE self, VALUE input )
621
+ {
622
+ P4ClientApi *p4;
623
+ Data_Get_Struct( self, P4ClientApi, p4 );
624
+ return p4->SetInput( input );
625
+ }
626
+
627
+ static VALUE p4_get_errors( VALUE self )
628
+ {
629
+ P4ClientApi *p4;
630
+ Data_Get_Struct( self, P4ClientApi, p4 );
631
+ return p4->GetErrors();
632
+ }
633
+
634
+ static VALUE p4_get_messages( VALUE self )
635
+ {
636
+ P4ClientApi *p4;
637
+ Data_Get_Struct( self, P4ClientApi, p4 );
638
+ return p4->GetMessages();
639
+ }
640
+
641
+ static VALUE p4_get_warnings( VALUE self )
642
+ {
643
+ P4ClientApi *p4;
644
+ Data_Get_Struct( self, P4ClientApi, p4 );
645
+ return p4->GetWarnings();
646
+ }
647
+
648
+ static VALUE p4_set_except_level( VALUE self, VALUE level )
649
+ {
650
+ P4ClientApi *p4;
651
+ Data_Get_Struct( self, P4ClientApi, p4 );
652
+ p4->ExceptionLevel( NUM2INT(level) );
653
+ return level;
654
+ }
655
+
656
+ static VALUE p4_get_except_level( VALUE self )
657
+ {
658
+ P4ClientApi *p4;
659
+ Data_Get_Struct( self, P4ClientApi, p4 );
660
+ return INT2NUM( p4->ExceptionLevel() );
661
+ }
662
+
663
+ static VALUE p4_get_server_level( VALUE self )
664
+ {
665
+ P4ClientApi *p4;
666
+ Data_Get_Struct( self, P4ClientApi, p4 );
667
+ int level = p4->GetServerLevel();
668
+ return INT2NUM( level );
669
+ }
670
+
671
+ static VALUE p4_parse_spec( VALUE self, VALUE type, VALUE form )
672
+ {
673
+ P4ClientApi *p4;
674
+
675
+ Check_Type( form, T_STRING );
676
+ Check_Type( type, T_STRING );
677
+
678
+ Data_Get_Struct( self, P4ClientApi, p4 );
679
+ return p4->ParseSpec( StringValuePtr(type), StringValuePtr(form) );
680
+ }
681
+
682
+ static VALUE p4_format_spec( VALUE self, VALUE type, VALUE hash )
683
+ {
684
+ P4ClientApi *p4;
685
+
686
+ Check_Type( type, T_STRING );
687
+ Check_Type( hash, T_HASH );
688
+
689
+ Data_Get_Struct( self, P4ClientApi, p4 );
690
+ return p4->FormatSpec( StringValuePtr(type), hash );
691
+ }
692
+
693
+ static VALUE p4_track_output( VALUE self )
694
+ {
695
+ P4ClientApi *p4;
696
+ Data_Get_Struct( self, P4ClientApi, p4 );
697
+ return p4->GetTrackOutput();
698
+ }
699
+
700
+ /*******************************************************************************
701
+ * Self identification
702
+ ******************************************************************************/
703
+ static VALUE p4_identify( VALUE self )
704
+ {
705
+ StrBuf s;
706
+ s.Append("P4RUBY ");
707
+ s.Append(P4RUBY_VERSION);
708
+ s.Append(" P4API ");
709
+ s.Append(P4APIVER_STRING);
710
+ s.Append(" PATCHLEVEL ");
711
+ s.Append(P4API_PATCHLEVEL_STRING);
712
+ s.Append(" WITH_LIBS ");
713
+ s.Append(WITH_LIBS);
714
+ return P4Utils::ruby_string( s.Text() );
715
+ }
716
+
717
+ /*******************************************************************************
718
+ * Debugging support
719
+ ******************************************************************************/
720
+ static VALUE p4_get_debug( VALUE self)
721
+ {
722
+ P4ClientApi *p4;
723
+ Data_Get_Struct( self, P4ClientApi, p4);
724
+ return INT2NUM( p4->GetDebug() );
725
+ }
726
+
727
+ static VALUE p4_set_debug( VALUE self, VALUE debug )
728
+ {
729
+ P4ClientApi *p4;
730
+ Data_Get_Struct( self, P4ClientApi, p4 );
731
+ p4->SetDebug( NUM2INT(debug) );
732
+ return Qtrue;
733
+ }
734
+
735
+ /*******************************************************************************
736
+ * Handler support
737
+ ******************************************************************************/
738
+ static VALUE p4_get_handler( VALUE self )
739
+ {
740
+ P4ClientApi *p4;
741
+ Data_Get_Struct( self, P4ClientApi, p4 );
742
+ return p4->GetHandler();
743
+ }
744
+
745
+ static VALUE p4_set_handler( VALUE self, VALUE handler )
746
+ {
747
+ P4ClientApi *p4;
748
+ Data_Get_Struct( self, P4ClientApi, p4 );
749
+ p4->SetHandler( handler );
750
+ return Qtrue;
751
+ }
752
+
753
+ /*******************************************************************************
754
+ * Progress support
755
+ ******************************************************************************/
756
+ static VALUE p4_get_progress( VALUE self )
757
+ {
758
+ P4ClientApi *p4;
759
+ Data_Get_Struct( self, P4ClientApi, p4 );
760
+ return p4->GetProgress();
761
+ }
762
+
763
+ static VALUE p4_set_progress( VALUE self, VALUE progress )
764
+ {
765
+ P4ClientApi *p4;
766
+ Data_Get_Struct( self, P4ClientApi, p4 );
767
+ return p4->SetProgress( progress );
768
+ }
769
+
770
+ /*******************************************************************************
771
+ * P4::MergeData methods. Construction/destruction defined elsewhere
772
+ ******************************************************************************/
773
+
774
+ static VALUE p4md_getyourname( VALUE self )
775
+ {
776
+ P4MergeData *md = 0;
777
+ Data_Get_Struct( self, P4MergeData, md );
778
+ return md->GetYourName();
779
+ }
780
+
781
+ static VALUE p4md_gettheirname( VALUE self )
782
+ {
783
+ P4MergeData *md = 0;
784
+ Data_Get_Struct( self, P4MergeData, md );
785
+ return md->GetTheirName();
786
+ }
787
+
788
+ static VALUE p4md_getbasename( VALUE self )
789
+ {
790
+ P4MergeData *md = 0;
791
+ Data_Get_Struct( self, P4MergeData, md );
792
+ return md->GetBaseName();
793
+ }
794
+
795
+ static VALUE p4md_getyourpath( VALUE self )
796
+ {
797
+ P4MergeData *md = 0;
798
+ Data_Get_Struct( self, P4MergeData, md );
799
+ return md->GetYourPath();
800
+ }
801
+
802
+ static VALUE p4md_gettheirpath( VALUE self )
803
+ {
804
+ P4MergeData *md = 0;
805
+ Data_Get_Struct( self, P4MergeData, md );
806
+ return md->GetTheirPath();
807
+ }
808
+
809
+ static VALUE p4md_getbasepath( VALUE self )
810
+ {
811
+ P4MergeData *md = 0;
812
+ Data_Get_Struct( self, P4MergeData, md );
813
+ return md->GetBasePath();
814
+ }
815
+
816
+ static VALUE p4md_getresultpath( VALUE self )
817
+ {
818
+ P4MergeData *md = 0;
819
+ Data_Get_Struct( self, P4MergeData, md );
820
+ return md->GetResultPath();
821
+ }
822
+
823
+ static VALUE p4md_getmergehint( VALUE self )
824
+ {
825
+ P4MergeData *md = 0;
826
+ Data_Get_Struct( self, P4MergeData, md );
827
+ return md->GetMergeHint();
828
+ }
829
+
830
+ static VALUE p4md_runmerge( VALUE self )
831
+ {
832
+ P4MergeData *md = 0;
833
+ Data_Get_Struct( self, P4MergeData, md );
834
+ return md->RunMergeTool();
835
+ }
836
+
837
+ static VALUE p4md_getcontentresolve( VALUE self )
838
+ {
839
+ P4MergeData *md = 0;
840
+ Data_Get_Struct( self, P4MergeData, md );
841
+ return md->GetContentResolveStatus();
842
+ }
843
+
844
+ //
845
+ // Additional methods added for action resolve
846
+ //
847
+ static VALUE p4md_getactionresolve( VALUE self )
848
+ {
849
+ P4MergeData *md = 0;
850
+ Data_Get_Struct( self, P4MergeData, md );
851
+ return md->GetActionResolveStatus();
852
+ }
853
+
854
+ static VALUE p4md_getyoursaction( VALUE self )
855
+ {
856
+ P4MergeData *md = 0;
857
+ Data_Get_Struct( self, P4MergeData, md );
858
+ return md->GetYoursAction();
859
+ }
860
+
861
+ static VALUE p4md_gettheiraction( VALUE self )
862
+ {
863
+ P4MergeData *md = 0;
864
+ Data_Get_Struct( self, P4MergeData, md );
865
+ return md->GetTheirAction();
866
+ }
867
+
868
+ static VALUE p4md_getmergeaction( VALUE self )
869
+ {
870
+ P4MergeData *md = 0;
871
+ Data_Get_Struct( self, P4MergeData, md );
872
+ return md->GetMergeAction();
873
+ }
874
+
875
+ static VALUE p4md_getactiontype( VALUE self )
876
+ {
877
+ P4MergeData *md = 0;
878
+ Data_Get_Struct( self, P4MergeData, md );
879
+ return md->GetType();
880
+ }
881
+
882
+ static VALUE p4md_getinfo( VALUE self )
883
+ {
884
+ P4MergeData *md = 0;
885
+ Data_Get_Struct( self, P4MergeData, md );
886
+ return md->GetMergeInfo();
887
+ }
888
+
889
+ static VALUE p4md_invalidate( VALUE self )
890
+ {
891
+ P4MergeData *md = 0;
892
+ Data_Get_Struct( self, P4MergeData, md );
893
+ md->Invalidate();
894
+ return self;
895
+ }
896
+
897
+ static VALUE p4md_tos( VALUE self )
898
+ {
899
+ P4MergeData *md = 0;
900
+ Data_Get_Struct( self, P4MergeData, md );
901
+ return md->GetString();
902
+ }
903
+ /******************************************************************************
904
+ * P4::Map class
905
+ ******************************************************************************/
906
+ static void p4map_free( P4MapMaker *m )
907
+ {
908
+ delete m;
909
+ }
910
+
911
+ static VALUE p4map_new( int argc, VALUE *argv, VALUE pClass )
912
+ {
913
+ //VALUE pClass;
914
+ VALUE array;
915
+ VALUE self;
916
+ P4MapMaker *m = new P4MapMaker;
917
+
918
+ // First arg is the class
919
+ // pClass = argv[ 0 ];
920
+
921
+ // Now instantiate the new object.
922
+ self = Data_Wrap_Struct( pClass, 0, p4map_free, m );
923
+ rb_obj_call_init( self, 0, argv );
924
+
925
+ if( argc )
926
+ {
927
+ array = argv[ 0 ];
928
+ if( !rb_obj_is_kind_of( array, rb_cArray ) )
929
+ rb_raise( rb_eRuntimeError, "Not an array" );
930
+
931
+ StrBuf t;
932
+ ID idLen = rb_intern( "length" );
933
+ int len;
934
+ VALUE entry;
935
+
936
+ // Now iterate over the array, inserting the mappings
937
+ len = NUM2INT( rb_funcall( array, idLen, 0 ) );
938
+ for( int i = 0; i < len; i++ )
939
+ {
940
+ entry = rb_ary_entry( array, i );
941
+ m->Insert( entry );
942
+ }
943
+ }
944
+ return self;
945
+ }
946
+
947
+ //
948
+ // Joins the RHS of the first mapping with the LHS of the second, and
949
+ // returns a new P4::Map object made up of the LHS of the first and the
950
+ // RHS of the second where the joins match up.
951
+ //
952
+ static VALUE p4map_join( VALUE pClass, VALUE left, VALUE right )
953
+ {
954
+ P4MapMaker * l = 0;
955
+ P4MapMaker * r = 0;
956
+ P4MapMaker * j = 0;
957
+ VALUE m;
958
+ VALUE argv[ 1 ];
959
+
960
+ Data_Get_Struct( left, P4MapMaker, l );
961
+ Data_Get_Struct( right, P4MapMaker, r );
962
+
963
+ j = P4MapMaker::Join( l, r );
964
+ if( !j ) return Qnil;
965
+
966
+ m = Data_Wrap_Struct( pClass, 0, p4map_free, j );
967
+ rb_obj_call_init( m, 0, argv );
968
+ return m;
969
+ }
970
+
971
+ //
972
+ // Debugging support
973
+ //
974
+ static VALUE p4map_inspect( VALUE self )
975
+ {
976
+ P4MapMaker * m = 0;
977
+ StrBuf b;
978
+ StrBuf tb;
979
+
980
+ tb.Alloc( 32 );
981
+ sprintf( tb.Text(), "%p", (void*) self );
982
+ tb.SetLength();
983
+
984
+ Data_Get_Struct( self, P4MapMaker, m );
985
+
986
+ b << "#<P4::Map:" << tb << "> ";
987
+
988
+ m->Inspect( b );
989
+ return P4Utils::ruby_string( b.Text(), b.Length() );
990
+ }
991
+
992
+ //
993
+ // Insert a mapping into a P4::Map object. Can be called with either
994
+ // one, or two arguments. If one, it's assumed to be a string containing
995
+ // either a half-map, or both halves of the mapping.
996
+ //
997
+ static VALUE p4map_insert( int argc, VALUE *argv, VALUE self )
998
+ {
999
+ P4MapMaker * m = 0;
1000
+ StrBuf t;
1001
+
1002
+ Data_Get_Struct( self, P4MapMaker, m );
1003
+
1004
+ if( argc < 1 || argc > 2 )
1005
+ rb_raise( rb_eArgError, "P4::Map#insert takes 1, or 2 arguments" );
1006
+
1007
+
1008
+ if( argc == 1 )
1009
+ {
1010
+ // A mapping with only a left hand side.
1011
+ m->Insert( *argv );
1012
+ return self;
1013
+ }
1014
+
1015
+ if( argc == 2 )
1016
+ {
1017
+ // Separate left- and right-hand strings.
1018
+ VALUE left;
1019
+ VALUE right;
1020
+
1021
+ left = *argv++;
1022
+ right = *argv;
1023
+
1024
+ m->Insert( left, right );
1025
+ }
1026
+ return self;
1027
+ }
1028
+ static VALUE p4map_clear( VALUE self )
1029
+ {
1030
+ P4MapMaker * m = 0;
1031
+
1032
+ Data_Get_Struct( self, P4MapMaker, m );
1033
+ m->Clear();
1034
+ return Qtrue;
1035
+ }
1036
+
1037
+ static VALUE p4map_count( VALUE self )
1038
+ {
1039
+ P4MapMaker * m = 0;
1040
+
1041
+ Data_Get_Struct( self, P4MapMaker, m );
1042
+ return INT2NUM( m->Count() );
1043
+ }
1044
+
1045
+ static VALUE p4map_empty( VALUE self )
1046
+ {
1047
+ P4MapMaker * m = 0;
1048
+
1049
+ Data_Get_Struct( self, P4MapMaker, m );
1050
+ return m->Count() ? Qfalse : Qtrue;
1051
+ }
1052
+
1053
+ static VALUE p4map_reverse( VALUE self )
1054
+ {
1055
+ P4MapMaker * m = 0;
1056
+ P4MapMaker * m2 = 0;
1057
+ VALUE rval;
1058
+ VALUE argv[ 1 ];
1059
+
1060
+ Data_Get_Struct( self, P4MapMaker, m );
1061
+ m2 = new P4MapMaker( *m );
1062
+ m2->Reverse();
1063
+
1064
+ rval = Data_Wrap_Struct( cP4Map, 0, p4map_free, m2 );
1065
+ rb_obj_call_init( rval, 0, argv );
1066
+ return rval;
1067
+ }
1068
+
1069
+ //
1070
+ // P4::Map#translate( string, fwd=true )
1071
+ //
1072
+ static VALUE p4map_trans( int argc, VALUE *argv, VALUE self )
1073
+ {
1074
+ P4MapMaker * m = 0;
1075
+ int fwd = 1;
1076
+ VALUE string;
1077
+
1078
+ if( argc < 1 || argc > 2 )
1079
+ rb_raise( rb_eArgError,
1080
+ "Invalid arguments to P4::Map#translate. "
1081
+ "Pass the string you wish to translate, and an optional "
1082
+ "boolean to indicate whether translation should be in "
1083
+ "the forward direction." );
1084
+
1085
+ argc--;
1086
+ string = *argv++;
1087
+
1088
+ if( argc && *argv == Qfalse )
1089
+ fwd = 0;
1090
+
1091
+ Data_Get_Struct( self, P4MapMaker, m );
1092
+ return m->Translate( string, fwd );
1093
+ }
1094
+
1095
+ static VALUE p4map_includes( VALUE self, VALUE string )
1096
+ {
1097
+ P4MapMaker * m = 0;
1098
+
1099
+ Data_Get_Struct( self, P4MapMaker, m );
1100
+ if( m->Translate( string, 1 ) != Qnil )
1101
+ return Qtrue;
1102
+ if( m->Translate( string, 0 ) != Qnil )
1103
+ return Qtrue;
1104
+ return Qfalse;
1105
+ }
1106
+
1107
+ static VALUE p4map_lhs( VALUE self )
1108
+ {
1109
+ P4MapMaker * m = 0;
1110
+
1111
+ Data_Get_Struct( self, P4MapMaker, m );
1112
+ return m->Lhs();
1113
+ }
1114
+
1115
+ static VALUE p4map_rhs( VALUE self )
1116
+ {
1117
+ P4MapMaker * m = 0;
1118
+
1119
+ Data_Get_Struct( self, P4MapMaker, m );
1120
+ return m->Rhs();
1121
+ }
1122
+
1123
+ static VALUE p4map_to_a( VALUE self )
1124
+ {
1125
+ P4MapMaker * m = 0;
1126
+
1127
+ Data_Get_Struct( self, P4MapMaker, m );
1128
+ return m->ToA();
1129
+ }
1130
+
1131
+ /*******************************************************************************
1132
+ * P4::Message methods. Construction/destruction defined elsewhere
1133
+ ******************************************************************************/
1134
+ static VALUE p4msg_get_severity( VALUE self )
1135
+ {
1136
+ P4Error * e = 0;
1137
+
1138
+ Data_Get_Struct( self, P4Error, e );
1139
+ return e->GetSeverity();
1140
+ }
1141
+
1142
+ static VALUE p4msg_get_generic( VALUE self )
1143
+ {
1144
+ P4Error * e = 0;
1145
+
1146
+ Data_Get_Struct( self, P4Error, e );
1147
+ return e->GetGeneric();
1148
+ }
1149
+
1150
+ static VALUE p4msg_get_text( VALUE self )
1151
+ {
1152
+ P4Error * e = 0;
1153
+
1154
+ Data_Get_Struct( self, P4Error, e );
1155
+ return e->GetText();
1156
+ }
1157
+
1158
+ static VALUE p4msg_get_id( VALUE self )
1159
+ {
1160
+ P4Error * e = 0;
1161
+
1162
+ Data_Get_Struct( self, P4Error, e );
1163
+ return e->GetId();
1164
+ }
1165
+ static VALUE p4msg_inspect( VALUE self )
1166
+ {
1167
+ P4Error * e = 0;
1168
+
1169
+ Data_Get_Struct( self, P4Error, e );
1170
+ return e->Inspect();
1171
+ }
1172
+
1173
+
1174
+ /******************************************************************************
1175
+ * Extension initialisation
1176
+ ******************************************************************************/
1177
+
1178
+ void Init_P4()
1179
+ {
1180
+ // Ruby instantiation
1181
+ eP4 = rb_define_class( "P4Exception", rb_eRuntimeError );
1182
+
1183
+ // We ensure this class already exists by loading the version file in P4.rb.
1184
+ // If we don't do this, calling things via rake might change the load order
1185
+ // in "interesting" ways.
1186
+ cP4 = rb_path2class("P4");
1187
+
1188
+ rb_define_singleton_method( cP4, "new", RUBY_METHOD_FUNC(p4_new), 0 );
1189
+
1190
+ // Protocol options
1191
+ rb_define_method( cP4, "api_level", RUBY_METHOD_FUNC(p4_get_api_level), 0);
1192
+ rb_define_method( cP4, "api_level=", RUBY_METHOD_FUNC(p4_set_api_level), 1);
1193
+ rb_define_method( cP4, "streams?", RUBY_METHOD_FUNC(p4_get_streams) , 0 );
1194
+ rb_define_method( cP4, "streams=", RUBY_METHOD_FUNC(p4_set_streams) , 1 );
1195
+ rb_define_method( cP4, "tagged", RUBY_METHOD_FUNC(p4_run_tagged), 1 );
1196
+ rb_define_method( cP4, "tagged?", RUBY_METHOD_FUNC(p4_get_tagged), 0 );
1197
+ rb_define_method( cP4, "tagged=", RUBY_METHOD_FUNC(p4_set_tagged), 1 );
1198
+ rb_define_method( cP4, "track?", RUBY_METHOD_FUNC(p4_get_track) , 0 );
1199
+ rb_define_method( cP4, "track=", RUBY_METHOD_FUNC(p4_set_track) , 1 );
1200
+
1201
+
1202
+ // Perforce client settings.
1203
+ //
1204
+ rb_define_method( cP4, "charset", RUBY_METHOD_FUNC(p4_get_charset) , 0 );
1205
+ rb_define_method( cP4, "charset=", RUBY_METHOD_FUNC(p4_set_charset) , 1 );
1206
+ rb_define_method( cP4, "cwd", RUBY_METHOD_FUNC(p4_get_cwd) , 0 );
1207
+ rb_define_method( cP4, "cwd=", RUBY_METHOD_FUNC(p4_set_cwd) , 1 );
1208
+ rb_define_method( cP4, "client", RUBY_METHOD_FUNC(p4_get_client) , 0 );
1209
+ rb_define_method( cP4, "client=", RUBY_METHOD_FUNC(p4_set_client) , 1 );
1210
+ rb_define_method( cP4, "env", RUBY_METHOD_FUNC(p4_get_env) , 1 );
1211
+ rb_define_method( cP4, "set_env", RUBY_METHOD_FUNC(p4_set_env) , 2 );
1212
+ rb_define_method( cP4, "enviro_file", RUBY_METHOD_FUNC(p4_get_enviro_file), 0);
1213
+ rb_define_method( cP4, "enviro_file=", RUBY_METHOD_FUNC(p4_set_enviro_file), 1);
1214
+ rb_define_method( cP4, "host", RUBY_METHOD_FUNC(p4_get_host) , 0 );
1215
+ rb_define_method( cP4, "host=", RUBY_METHOD_FUNC(p4_set_host) , 1 );
1216
+ rb_define_method( cP4, "ignore_file",RUBY_METHOD_FUNC(p4_get_ignore) , 0 );
1217
+ rb_define_method( cP4, "ignore_file=",RUBY_METHOD_FUNC(p4_set_ignore), 1 );
1218
+ rb_define_method( cP4, "ignored?", RUBY_METHOD_FUNC(p4_is_ignored) , 1 );
1219
+ rb_define_method( cP4, "language", RUBY_METHOD_FUNC(p4_get_language), 0 );
1220
+ rb_define_method( cP4, "language=", RUBY_METHOD_FUNC(p4_set_language), 1 );
1221
+ rb_define_method( cP4, "p4config_file",RUBY_METHOD_FUNC(p4_get_p4config),0);
1222
+ rb_define_method( cP4, "password", RUBY_METHOD_FUNC(p4_get_password), 0 );
1223
+ rb_define_method( cP4, "password=", RUBY_METHOD_FUNC(p4_set_password), 1 );
1224
+ rb_define_method( cP4, "port", RUBY_METHOD_FUNC(p4_get_port) , 0 );
1225
+ rb_define_method( cP4, "port=", RUBY_METHOD_FUNC(p4_set_port) , 1 );
1226
+ rb_define_method( cP4, "prog", RUBY_METHOD_FUNC(p4_get_prog) , 0 );
1227
+ rb_define_method( cP4, "prog=", RUBY_METHOD_FUNC(p4_set_prog) , 1 );
1228
+ rb_define_method( cP4, "protocol", RUBY_METHOD_FUNC(p4_set_protocol), 2 );
1229
+ rb_define_method( cP4, "ticket_file", RUBY_METHOD_FUNC(p4_get_ticket_file), 0 );
1230
+ rb_define_method( cP4, "ticket_file=", RUBY_METHOD_FUNC(p4_set_ticket_file), 1 );
1231
+ rb_define_method( cP4, "user", RUBY_METHOD_FUNC(p4_get_user) , 0 );
1232
+ rb_define_method( cP4, "user=", RUBY_METHOD_FUNC(p4_set_user) , 1 );
1233
+ rb_define_method( cP4, "version", RUBY_METHOD_FUNC(p4_get_version) , 0 );
1234
+ rb_define_method( cP4, "version=", RUBY_METHOD_FUNC(p4_set_version) , 1 );
1235
+
1236
+
1237
+ rb_define_method( cP4, "maxresults", RUBY_METHOD_FUNC(p4_get_maxresults),0);
1238
+ rb_define_method( cP4, "maxresults=",RUBY_METHOD_FUNC(p4_set_maxresults),1);
1239
+ rb_define_method( cP4, "maxscanrows", RUBY_METHOD_FUNC(p4_get_maxscanrows),0);
1240
+ rb_define_method( cP4, "maxscanrows=",RUBY_METHOD_FUNC(p4_set_maxscanrows), 1 );
1241
+ rb_define_method( cP4, "maxlocktime", RUBY_METHOD_FUNC(p4_get_maxlocktime), 0 );
1242
+ rb_define_method( cP4, "maxlocktime=", RUBY_METHOD_FUNC(p4_set_maxlocktime), 1 );
1243
+
1244
+ // Session Connect/Disconnect
1245
+ rb_define_method( cP4, "connect", RUBY_METHOD_FUNC(p4_connect) , 0 );
1246
+ rb_define_method( cP4, "connected?",RUBY_METHOD_FUNC(p4_connected) , 0 );
1247
+ rb_define_method( cP4, "disconnect", RUBY_METHOD_FUNC(p4_disconnect) , 0 );
1248
+
1249
+ // Running commands - general purpose commands
1250
+ rb_define_method( cP4, "run", RUBY_METHOD_FUNC(p4_run) ,-2 );
1251
+ rb_define_method( cP4, "input=", RUBY_METHOD_FUNC(p4_set_input) , 1 );
1252
+ rb_define_method( cP4, "errors", RUBY_METHOD_FUNC(p4_get_errors) , 0 );
1253
+ rb_define_method( cP4, "messages", RUBY_METHOD_FUNC(p4_get_messages), 0 );
1254
+ rb_define_method( cP4, "warnings", RUBY_METHOD_FUNC(p4_get_warnings), 0 );
1255
+ rb_define_method( cP4, "exception_level", RUBY_METHOD_FUNC(p4_get_except_level), 0 );
1256
+ rb_define_method( cP4, "exception_level=", RUBY_METHOD_FUNC(p4_set_except_level), 1 );
1257
+ rb_define_method( cP4, "server_level", RUBY_METHOD_FUNC(p4_get_server_level), 0 );
1258
+ rb_define_method( cP4, "server_case_sensitive?", RUBY_METHOD_FUNC(p4_server_case_sensitive), 0 );
1259
+ rb_define_method( cP4, "track_output", RUBY_METHOD_FUNC(p4_track_output), 0 );
1260
+
1261
+ rb_define_method( cP4, "server_unicode?", RUBY_METHOD_FUNC(p4_server_unicode), 0 );
1262
+
1263
+ // Spec parsing
1264
+ rb_define_method( cP4, "parse_spec", RUBY_METHOD_FUNC(p4_parse_spec), 2 );
1265
+ rb_define_method( cP4, "format_spec", RUBY_METHOD_FUNC(p4_format_spec), 2 );
1266
+
1267
+ // Identification
1268
+ rb_define_const( cP4, "P4API_VERSION", P4Utils::ruby_string(P4APIVER_STRING));
1269
+ rb_define_const( cP4, "P4API_PATCHLEVEL", INT2NUM(P4API_PATCHLEVEL));
1270
+ rb_define_const( cP4, "P4RUBY_VERSION", P4Utils::ruby_string(P4RUBY_VERSION) );
1271
+ rb_define_singleton_method( cP4, "identify", RUBY_METHOD_FUNC(p4_identify), 0 );
1272
+
1273
+ // Debugging support
1274
+ rb_define_method( cP4, "debug", RUBY_METHOD_FUNC(p4_get_debug), 0);
1275
+ rb_define_method( cP4, "debug=", RUBY_METHOD_FUNC(p4_set_debug), 1 );
1276
+
1277
+ // Support for OutputHandler
1278
+ rb_define_method( cP4, "handler", RUBY_METHOD_FUNC(p4_get_handler), 0);
1279
+ rb_define_method( cP4, "handler=", RUBY_METHOD_FUNC(p4_set_handler), 1);
1280
+
1281
+ // Support for Progress API
1282
+ rb_define_method( cP4, "progress", RUBY_METHOD_FUNC(p4_get_progress), 0);
1283
+ rb_define_method( cP4, "progress=", RUBY_METHOD_FUNC(p4_set_progress), 1);
1284
+
1285
+ // P4::MergeData class
1286
+ cP4MD = rb_define_class_under( cP4, "MergeData", rb_cObject );
1287
+
1288
+ rb_define_method( cP4MD, "your_name", RUBY_METHOD_FUNC(p4md_getyourname),0);
1289
+ rb_define_method( cP4MD, "their_name", RUBY_METHOD_FUNC(p4md_gettheirname),0);
1290
+ rb_define_method( cP4MD, "base_name", RUBY_METHOD_FUNC(p4md_getbasename),0);
1291
+ rb_define_method( cP4MD, "your_path", RUBY_METHOD_FUNC(p4md_getyourpath),0);
1292
+ rb_define_method( cP4MD, "their_path", RUBY_METHOD_FUNC(p4md_gettheirpath),0);
1293
+ rb_define_method( cP4MD, "base_path", RUBY_METHOD_FUNC(p4md_getbasepath),0);
1294
+ rb_define_method( cP4MD, "result_path", RUBY_METHOD_FUNC(p4md_getresultpath),0);
1295
+ rb_define_method( cP4MD, "merge_hint", RUBY_METHOD_FUNC(p4md_getmergehint),0);
1296
+ rb_define_method( cP4MD, "run_merge", RUBY_METHOD_FUNC(p4md_runmerge),0);
1297
+
1298
+ rb_define_method(cP4MD, "action_resolve?", RUBY_METHOD_FUNC(p4md_getactionresolve), 0);
1299
+ rb_define_method(cP4MD, "action_type", RUBY_METHOD_FUNC(p4md_getactiontype), 0);
1300
+ rb_define_method(cP4MD, "content_resolve?", RUBY_METHOD_FUNC(p4md_getcontentresolve), 0);
1301
+ rb_define_method(cP4MD, "info", RUBY_METHOD_FUNC(p4md_getinfo), 0);
1302
+ rb_define_method(cP4MD, "invalidate", RUBY_METHOD_FUNC(p4md_invalidate), 0);
1303
+ rb_define_method(cP4MD, "merge_action", RUBY_METHOD_FUNC(p4md_getmergeaction), 0);
1304
+ rb_define_method(cP4MD, "their_action", RUBY_METHOD_FUNC(p4md_gettheiraction), 0);
1305
+ rb_define_method(cP4MD, "to_s", RUBY_METHOD_FUNC(p4md_tos), 0);
1306
+ rb_define_method(cP4MD, "yours_action", RUBY_METHOD_FUNC(p4md_getyoursaction), 0);
1307
+
1308
+ // P4::Map class
1309
+ cP4Map = rb_define_class_under( cP4, "Map", rb_cObject );
1310
+ rb_define_singleton_method( cP4Map, "new", RUBY_METHOD_FUNC(p4map_new), -1);
1311
+ rb_define_singleton_method( cP4Map, "join", RUBY_METHOD_FUNC(p4map_join), 2 );
1312
+ rb_define_method( cP4Map, "insert", RUBY_METHOD_FUNC(p4map_insert),-1);
1313
+ rb_define_method( cP4Map, "inspect", RUBY_METHOD_FUNC(p4map_inspect),0);
1314
+ rb_define_method( cP4Map, "clear", RUBY_METHOD_FUNC(p4map_clear),0);
1315
+ rb_define_method( cP4Map, "count", RUBY_METHOD_FUNC(p4map_count),0);
1316
+ rb_define_method( cP4Map, "empty?", RUBY_METHOD_FUNC(p4map_empty),0);
1317
+ rb_define_method( cP4Map, "translate", RUBY_METHOD_FUNC(p4map_trans),-1);
1318
+ rb_define_method( cP4Map, "reverse", RUBY_METHOD_FUNC(p4map_reverse),0);
1319
+ rb_define_method( cP4Map, "includes?", RUBY_METHOD_FUNC(p4map_includes),1);
1320
+ rb_define_method( cP4Map, "lhs", RUBY_METHOD_FUNC(p4map_lhs),0);
1321
+ rb_define_method( cP4Map, "rhs", RUBY_METHOD_FUNC(p4map_rhs),0);
1322
+ rb_define_method( cP4Map, "to_a", RUBY_METHOD_FUNC(p4map_to_a),0);
1323
+
1324
+ // P4::Message class.
1325
+ cP4Msg = rb_define_class_under( cP4, "Message", rb_cObject );
1326
+ rb_define_method( cP4Msg, "inspect", RUBY_METHOD_FUNC(p4msg_inspect),0);
1327
+ rb_define_method( cP4Msg, "msgid", RUBY_METHOD_FUNC(p4msg_get_id), 0);
1328
+ rb_define_method( cP4Msg, "severity", RUBY_METHOD_FUNC(p4msg_get_severity), 0);
1329
+ rb_define_method( cP4Msg, "generic", RUBY_METHOD_FUNC(p4msg_get_generic), 0);
1330
+ rb_define_method( cP4Msg, "to_s", RUBY_METHOD_FUNC(p4msg_get_text), 0);
1331
+
1332
+ // P4::Progress class.
1333
+ cP4Prog = rb_define_class_under( cP4, "Progress", rb_cObject );
1334
+
1335
+ };
1336
+
1337
+
1338
+ } // Extern C