This file is indexed.

/usr/share/perl5/Prima/internals.pod is in libprima-perl 1.28-1.1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
=for rcs $Id: internals.pod,v 1.10 2007/09/13 15:12:25 dk Exp $

=head1 NAME

Prima::internals - Prima internal architecture

=head1 DESCRIPTION

This documents elucidates the internal structures
of the Prima toolkit, its loading considerations,
object and class representation and C coding style.

=head1 Bootstrap

=head2 Initializing

For a perl script, Prima is no more but an average module
that uses DynaLoader. As 'use Prima' code gets executed, a bootstrap
procedure boot_Prima() is called. This procedure initializes
all internal structures and built-in Prima classes. It also
initializes all system-dependent structures, calling
window_subsystem_init(). After that point Prima module
is ready to use. All wrapping code for built-in functionality 
that can be seen from perl is located into two modules -
Prima::Const and Prima::Classes.

=head2 Constants

Prima defines lot of constants for different purposes 
( e.g. colors, font styles etc). Prima does not
follow perl naming conventions here, on the reason of simplicity.
It is ( arguably ) easier to write cl::White rather than Prima::cl::White.
As perl constants are functions to be called once ( that means that a constant's
value is not defined until it used first ), Prima registers these functions
during boot_Prima stage. As soon as perl code tries to get a constant's value,
an AUTOLOAD function is called, which is binded inside Prima::Const.
Constants are widely used both in C and perl code, and are defined in apricot.h
in that way so perl constant definition comes along with C one.
As an example file event constants set is described here.

 apricot.h:
   #define FE(const_name) CONSTANT(fe,const_name)
   START_TABLE(fe,UV)
   #define feRead      1
   FE(Read)
   #define feWrite     2
   FE(Write)
   #define feException 4
   FE(Exception)
   END_TABLE(fe,UV)
   #undef FE

 Const.pm:
   package fe; *AUTOLOAD = \&Prima::Const::AUTOLOAD;

This code creates a structure of UV's ( unsigned integers ) and
a register_fe_constants() function, which should be called at
boot_Prima stage. This way feRead becomes C analog to
fe::Read in perl.

=head1 Classes and methods

=head2 Virtual method tables

Prima implementation of classes uses virtual method tables, or VMTs, in order to
make the classes inheritable and their methods overrideable. The VMTs are
usual C structs, that contain pointers to functions.
Set of these functions represents a class. This chapter is not about OO 
programming, you have to find a good book on it if you are not familiar with 
the OO concepts, but in short, because Prima is written in C, not in C++,
it uses its own classes and objects implementation, so all object syntax
is devised from scratch.

Built-in classes already contain all information needed for method 
overloading, but when a new class is derived from existing one, 
new VMT is have to be created as well. The actual sub-classing
is performed inside build_dynamic_vmt() and build_static_vmt(). 
gimme_the_vmt() function creates new VMT instance on the fly and 
caches the result for every new class that is derived from Prima class.


=head2 C to Perl and Perl to C calling routines

Majority of Prima methods is written in C using XS perl 
routines, which represent a natural ( from a perl programmer's view ) way 
of C to Perl communication.
L<perlguts> manpage describes these functions and macros.

NB - Do not mix XS calls to xs language ( L<perlxs> manpage) - the latter
is a meta-language for simplification of coding tasks and is not used
in Prima implementation.

It was decided not to code every function with XS calls, but instead
use special wrapper functions ( also called "thunks") for every function 
that is called from within perl. Thunks are generated automatically
by gencls tool ( L<gencls> manpage ), and typical Prima method
consists of three functions, two of which are thunks.

First function, say Class_init(char*), would initialize a class ( for example).
It is written fully in C, so in order to be called from perl code 
a registration step must be taken for a second function,
Class_init_FROMPERL(), that would look like

   newXS( "Prima::Class::init", Class_init_FROMPERL, "Prima::Class");

Class_init_FROMPERL() is a first thunk, that translates the parameters
passed from perl to C and the result back from C function to perl.
This step is almost fully automatized, so one never bothers about writing
XS code, the gencls utility creates the thunks code automatically.

Many C methods are called from within Prima C code using VMTs, but
it is possible to override these methods from perl code. The
actions for such a situation when a function is called from C but is
an overridden method therefore must be taken. On that occasion the third function
Class_init_REDEFINED() is declared. Its task is a reverse from Class_init_FROMPERL() -
it conveys all C parameters to perl and return values from a perl function
back to C. This thunk is also generated automatically by gencls tool.

As one can notice, only basic data types can be converted between C and perl,
and at some point automated routines do not help. In such a situation
data conversion code is written manually and is included into core C files.
In the class declaration files these methods are prepended with 'public' or 'weird'
modifiers, when methods with no special data handling needs use 'method' or
'static' modifiers. 

NB - functions that are not allowed to be seen from perl have 'c_only' modifier,
and therefore do not need thunk wrapping. These functions can nevertheless 
be overridden from C.

=head2 Built-in classes

Prima defines the following built-in classes: (in hierarchy order)

    Object
        Component
                AbstractMenu
                        AccelTable
                        Menu
                        Popup
                Clipboard
                Drawable
                        DeviceBitmap
                        Printer
                        Image
                                Icon
                File
                Timer
                Widget
                        Application
                        Window

These classes can be seen from perl with Prima:: prefix.
Along with these, Utils class is defined. Its only 
difference is that it cannot be used as a prototype for an
object, and used merely as a package that binds functions.
Classes that are not intended to be an object prototype
marked with 'package' prefix, when others are marked with 'object'
(see prima-gencls manpage).

=head1 Objects

This chapter deals only with Prima::Object descendants, pure
perl objects are not of interest here, so the 'object' term is
thereafter referenced to Prima::Object descendant object.
Prima employs blessed hashes for its objects.

=head2 Creation

All built-in object classes and their descendants can be used for
creating objects with perl semantics. Perl objects are created
by calling bless(), but it is not enough to create
Prima objects. Every Prima::Object descendant class therefore is 
equipped with create() method, that allocates object instance 
and calls bless() itself. Parameters that come with create() call
are formed into a hash and passed to init() method, that is also
present on every object. Note the fact that although perl-coded init()
returns the hash, it not seen in C code. This is a special 
consideration for the methods that have 'HV * profile' as a last 
parameter in their class declaration. The corresponding thunk 
copies the hash content back to perl stack, using parse_hv() 
and push_hv() functions. 

Objects can be created from perl by using following code example:

   $obj = Prima::SampleObject-> create( 
       name  => "Sample",
       index => 10,
   );

and from C:

   Handle obj;
   HV * profile = newHV();
   pset_c( name, "Sample");
   pset_i( index, 10);
   obj = Object_create("SampleObject", profile);
   sv_free(( SV*) profile);


Convenience pset_XX macros assign a value of XX type to 
the hash key given as a first parameter, to a hash variable
named profile. C<pset_i> works with integers, C<pset_c> - with strings, etc.

=head2 Destruction

As well as create() method, every object class has destroy() method.
Object can be destroyed either from perl 

   $obj-> destroy

or from C

   Object_destroy( obj);

An object can be automatically destroyed when its reference count
reaches 0. Note that the auto destruction would never happen
if the object's reference count is not lowered after its
creation. The code

   --SvREFCNT( SvRV( PAnyObject(object)-> mate)); 

is required if the object is to be returned to perl.
If that code is not called, the object still could be 
destroyed explicitly, but its reference would still live, 
resulting in memory leak problem.

For user code it is sufficient to overload done() and/or cleanup()
methods, or just onDestroy notifications. It is highly recommended
to avoid overloading destroy method, since it can be called 
in re-entrant fashion. When overloading done(), be prepared that
it may be called inside init(), and deal with the 
semi-initialized object.

=head2 Data instance

All object data after their creation represent an object instance.
All Prima objects are blessed hashes, and the hash key
__CMATE__ holds a C pointer to a memory which is occupied
by C data instance, or a "mate". It keeps all object variables
and a pointer to VMT. Every object has its own copy of data instance,
but the VMTs can be shared. In order to reach to C data instance
gimme_the_mate() function is used. As a first parameter it accepts
a scalar (SV*), which is expected to be a reference to a hash, and 
returns the C data instance if the scalar is a Prima object.

=head2 Object life stages

It was decided to divide object life stage in several steps.
Every stage is mirrored into PObject(self)-> stage integer variable,
which can be one of csXXX constants.
Currently it has six: 

=over

=item csConstructing

Initial stage, is set until create() is finished.
Right after init() is completed, setup() method 
is called. 

=item csNormal

After create() is finished and before destroy() started.
If an object is csNormal and csConstructing stage,
Object_alive() result would be non-zero.

=item csDestroying

destroy() started. This stage includes calling of cleanup()
and done() routines.

=item csFrozen

cleanup() started.

=item csFinalizing

done() started

=item csDead

Destroy finished

=back 


=head1 Coding techniques

=head2 Accessing object data

C coding has no specific conventions, except
when a code is an object method. Object syntax
for accessing object instance data is also fairly standard.
For example, accessing component's field called 'name'
can be done in several ways:

 ((PComponent) self)-> name; // classic C
 PComponent(self)-> name;    // using PComponent() macro from apricot.h
 var-> name;                 // using local var() macro

Object code could to be called also in several ways:

 (((PComponent) self)-> self)-> get_name( self); // classic C
 CComponent(self)-> get_name( self);             // using CComponent() macro from apricot.h
 my-> get_name( self);                           // using local my() macro

This calling is preferred, comparing to direct call
of Component_get_name(), primarily because get_name() is
a method and can be overridden from user code.

=head2 Calling perl code

call_perl_indirect() function accepts object, its method name
and parameters list with parameter format string. It has several
wrappers for easier use, which are:

   call_perl( Handle self, char * method, char * format, ...)
   sv_call_perl( SV * object, char * method, char * format, ...)
   cv_call_perl( SV * object, SV * code_reference, char * format, ...)

each character of format string represents a parameters type,
and characters can be:

   'i' - integer
   's' - char *
   'n' - float
   'H' - Handle
   'S' - SV *
   'P' - Point
   'R' - Rect

The format string can be prepended with '<' character, in which
case SV * scalar ( always scalar, even if code returns nothing
or array ) value is returned. The caller is responsible for
freeing the return value.

=head2 Exceptions

As descriped in L<perlguts> manpage, G_EVAL flag is used
in perl_call_sv() and perl_call_method() to indicate that
an eventual exception should never be propagated automatically.
The caller checks if the exception was taken place by
evaluating

        SvTRUE( GvSV( PL_errgv))

statement. It is guaranteed to be false if there was no
exception condition. But in some situations, namely,
when no perl_call_* functions are called or error value
is already assigned before calling code, there is a wrapping
technique that keeps previous error message and looks like:

    dG_EVAL_ARGS;                       // define arguments
    ....
    OPEN_G_EVAL;                        // open brackets
    // call code
    perl_call_method( ... | G_EVAL);    // G_EVAL is necessary
    if ( SvTRUE( GvSV( PL_errgv)) {
        CLOSE_G_EVAL;                   // close brackets
        croak( SvPV_nolen( GvSV( PL_errgv)));// propagate exception
        // no code is executed after croak
    }
    CLOSE_G_EVAL;                       // close brackets
    ...

This technique provides workaround to a "false alarm" situation, if
SvTRUE( GvSV( PL_errgv)) is true before perl_call_method().

=head2 Object protection

After the object destroy stage is completed, it is possible 
that object's data instance is gone,
and even simple stage check might cause segmentation fault.
To avoid this, bracketing functions called C<protect_object()> 
and C<unprotect_object()> are used.
protect_object() increments reference count to the object instance,
thus delaying its freeing until decrementing unprotect_object() is called.

All C code that references to an object must check for its stage
after every routine that switches to perl code, because the object might 
be destroyed inside the call. Typical code example would be like:

   function( Handle object) {
        int stage;
        protect_object( object);

        // call some perl code
        perl_call_method( object, "test", ...);

        stage = PObject(object)-> stage;
        unprotect_object( object);
        if ( stage == csDead) return;

        // proceed with the object
   }


Usual C code never checks for object stage before
the call, because gimme_the_mate() function returns NULL
if object's stage is csDead, and majority of Prima C code
is prepended with this call, thus rejecting invalid references 
on early stage. If it is desired to get the
C mate for objects that are in csDead stage, use C<gimme_the_real_mate()>
function instead.

=head2 init

Object's method init() is responsible for setting all its initial properties to 
the object, but all code that is executed inside init must be aware that
the object's stage is csConstructing. init() consists of two parts:
calling of ancestor's init() and setting properties. Examples are
many in both C and perl code, but in short it looks like:

   void
   Class_init( Handle self, HV * profile)
   {
      inherited init( self, profile);
      my-> set_index( pget_i( index));
      my-> set_name( pget_c( name));
   }

pget_XX macros call croak() if the profile key is not
present into profile, but the mechanism guarantees that
all keys that are listed in profile_default() are conveyed to
init(). For explicit checking of key presence pexists() macro
is used, and pdelete() is used for key deletion, although is it not
recommended to use pdelete() inside init().

=head2 Object creation and returning

As described is previous sections, there are some
precautions to be taken into account when an object is created inside C code.
A piece of real code from DeviceBitmap.c would serve as an example:

   static 
   Handle xdup( Handle self, char * className)
   {
      Handle h;
      Point s;
      PDrawable i;

      // allocate a parameters hash
      HV * profile = newHV();

      // set all necessary arguments
      pset_H( owner,        var-> owner);
      pset_i( width,        var-> w);
      pset_i( height,       var-> h);
      pset_i( type,         var-> monochrome ? imBW : imRGB);

      // create object
      h = Object_create( className, profile);

      // free profile, do not need it anymore
      sv_free(( SV *) profile);

      i = ( PDrawable) h;
      s = i-> self-> get_size( h);
      i-> self-> begin_paint( h);
      i-> self-> put_image_indirect( h, self, 0, 0, 0, 0, s.x, s.y, s.x, s.y, ropCopyPut);
      i-> self-> end_paint( h);

      // decrement reference count
      --SvREFCNT( SvRV( i-> mate));
      return h;
   }


Note that all code that would use this xdup(), have to
increase and decrease object's reference count if some perl
functions are to be executed before returning object to perl,
otherwise it might be destroyed before its time.

       Handle x = xdup( self, "Prima::Image");
       ++SvREFCNT( SvRV( PAnyObject(x)-> mate)); // Code without these
       CImage( x)-> type( x, imbpp1);
       --SvREFCNT( SvRV( PAnyObject(x)-> mate)); // brackets is unsafe
       return x;


=head2 Attaching objects

The newly created object returned from C would be destroyed
due perl's garbage cleaning mechanism right away, unless the
object value would be assigned to a scalar, for example.

Thus

    $c = Prima::Object-> create();

and
    Prima::Object-> create;

have different results. But for some classes, namely Widget
ant its descendants, and also for Timer, AbstractMenu, Printer
and Clipboard the code above would have same result - the 
objects would not be killed. That is because these objects
call Component_attach() during init-stage, automatically
increasing their reference count. Component_attach() and 
its reverse Component_detach() account list of objects, 
attributed to each other. Object can be attached to multiple
objects, but cannot be attached more that once to another object.

=head2 Notifications

All Prima::Component descendants are equipped with the mechanism 
that allows multiple user callbacks routines to be called on 
different events. This mechanism is used heavily in event-driven
programming. Component_notify() is used to call user notifications,
and its format string has same format as accepted by perl_call_indirect().
The only difference that it always has to be prepended with '<s', - 
this way the call success flag is set, and first parameter have to 
be the name of the notification.

    Component_notify( self, "<sH", "Paint", self);
    Component_notify( self, "<sPii", "MouseDown", self, point, int, int);

Notifications mechanism accounts the reference list, similar
to attach-detach mechanism, because all notifications can
be attributed to different objects. The membership in this
list does not affect the reference counting.

=head2 Multiple property setting

Prima::Object method set() is designed to assign
several properties at one time. Sometimes it is
more convenient to write

   $c-> set( index => 10, name  => "Sample" );

than to invoke several methods one by one. set()
performs this calling itself, but for performance reasons
it is possible to overload this method and code special 
conditions for multiple assignment. As an example, Prima::Image
type conversion code is exemplified:

   void
   Image_set( Handle self, HV * profile)
   {
      ...
      if ( pexist( type))
      {
         int newType = pget_i( type);
         if ( !itype_supported( newType))
            warn("RTC0100: Invalid image type requested (%08x) in Image::set_type", 
               newType);
         else 
            if ( !opt_InPaint)
               my-> reset( self, newType, pexist( palette) ? 
                  pget_sv( palette) : my->get_palette( self));
         pdelete( palette);
         pdelete( type);
      }
      ...
      inherited set ( self, profile);
   }

If type conversion is performed along with palette change, some efficiency
is gained by supplying both 'type' and 'palette' parameters at a time.
Moreover, because ordering of the fields is not determined by default
( although that be done by supplying '__ORDER__' hash key to set() }, it
can easily be discovered that

    $image-> type( $a);
    $image-> palette( $b);

and 

    $image-> palette( $b);
    $image-> type( $a);

produce different results. Therefore it might be only solution to
code Class_set() explicitly.

If it is desired to specify exact order how atomic properties have to be called,
__ORDER__ anonymous array have to be added to set() parameters.

   $image-> set(
      owner => $xxx,
      type  => 24,
      __ORDER__ => [qw( type owner)],
   );


=head1 API reference

=head2 Variables

=over

=item primaObjects, PHash

Hash with all prima objects, where keys are their data instances

=item application, Handle

Pointer to an application. There can be only one Application
instance at a time, or none at all.

=back

=head2 Macros and functions

=over

=item dG_EVAL_ARGS

Defines variable for $@ value storage 

=item OPEN_G_EVAL, CLOSE_G_EVAL

Brackets for exception catching

=item build_static_vmt 

 Bool(void * vmt)

Caches pre-built VMT for further use

=item build_dynamic_vmt

 Bool( void * vmt, char * ancestorName, int ancestorVmtSize)

Creates a subclass from vmt and caches result under ancestorName key

=item gimme_the_vmt

 PVMT( const char *className);

Returns VMT pointer associated with class by name.

=item gimme_the_mate

 Handle( SV * perlObject)

Returns a C pointer to an object, if perlObject is a reference to a
Prima object. returns nilHandle if object's stage is csDead

=item gimme_the_real_mate

 Handle( SV * perlObject)

Returns a C pointer to an object, if perlObject is a reference to a
Prima object. Same as C<gimme_the_mate>, but does not check for
the object stage.

=item alloc1

 alloc1(type)

To be used instead (type*)(malloc(sizeof(type))

=item allocn

 allocn(type,n)

To be used instead (type*)(malloc((n)*sizeof(type))

=item alloc1z

Same as C<alloc1> but fills the allocated memory with zeros

=item allocnz

Same as C<allocn> but fills the allocated memory with zeros

=item prima_mallocz

Same as malloc() but fills the allocated memory with zeros

=item prima_hash_create

 PHash(void)

Creates an empty hash

=item prima_hash_destroy

 void(PHash self, Bool killAll);

Destroys a hash. If killAll is true, assumes that
every value in the hash is a dynamic memory pointer
and calls free() on each.

=item prima_hash_fetch

 void*( PHash self, const void *key, int keyLen);

Returns pointer to a value, if found, nil otherwise

=item prima_hash_delete

 void*( PHash self, const void *key, int keyLen, Bool kill);

Deletes hash key and returns associated value.
if kill is true, calls free() on the value and returns nil.


=item prima_hash_store

 void( PHash self, const void *key, int keyLen, void *val);

Stores new value into hash. If the key is already present, old
value is overwritten. 

=item  prima_hash_count

 int(PHash self)

Returns number of keys in the hash

=item prima_hash_first_that

 void * ( PHash self, void *action, void *params, int *pKeyLen, void **pKey);

Enumerates all hash entries, calling action procedure on each.
If the action procedure returns true, enumeration stops and the last processed
value is returned. Otherwise nil is returned. action have to be function declared as

 Bool action_callback( void * value, int keyLen, void * key, void * params);

params is a pointer to an arbitrary user data

=item kind_of

 Bool( Handle object, void *cls);

Returns true, if the object is an exemplar of class cls or its descendant

=item PERL_CALL_METHOD, PERL_CALL_PV

To be used instead of perl_call_method and perl_call_pv, 
described in perlguts manpage. These functions aliased to a code 
with the workaround of perl bug which emerges when
G_EVAL flag is combined with G_SCALAR.

=item eval

 SV *( char *string)

Simplified perl_eval_pv() call.

=item  sv_query_method

 CV * ( SV * object, char *methodName, Bool cacheIt);

Returns perl pointer to a method searched by a scalar and a name
If cacheIt true, caches the hierarchy traverse result for a speedup.


=item  query_method

 CV * ( Handle object, char *methodName, Bool cacheIt);

Returns perl pointer to a method searched by an object and a name
If cacheIt true, caches the hierarchy traverse result for a speedup.

=item call_perl_indirect

 SV * ( Handle self, char *subName, const char *format, Bool cdecl, 
        Bool coderef, va_list params);

Core function for calling Prima methods. Is used by the following three 
functions, but is never called directly. Format is described in C<Calling perl code>
section.

=item call_perl

 SV * ( Handle self, char *subName, const char *format, ...); 

Calls method of an object pointer by a Handle

=item sv_call_perl

 SV * ( SV * mate, char *subName, const char *format, ...); 

Calls method of an object pointed by a SV*

=item cv_call_perl

 SV * ( SV * mate, Sv * coderef, const char *format, ...); 

Calls arbitrary perl code with mate as first parameter.
Used in notifications mechanism.

=item Object_create

 Handle( char * className, HV * profile); 

Creates an exemplar of className class with parameters 
in profile. Never returns nilHandle, throws an exception
instead.

=item create_object

 void*( const char *objClass, const char *format, ...);

Convenience wrapper to Object_create. Uses format 
specification that is described in C<Calling perl code>.

=item create_instance

 Handle( const char * className)

Convenience call to C<Object_create> with parameters in hash 'profile'.

=item Object_destroy

 void( Handle self);

Destroys object. One of few Prima function that can be called in 
re-entrant fashion.

=item Object_alive

 void( Handle self);

Returns non-zero is object is alive, 0 otherwise.
In particular, current implementation returns 1 if
object's stage is csNormal and 2 if it is csConstructing.
Has virtually no use in C, only used in perl code.

=item protect_object 

 void( Handle obj);

restricts object pointer from deletion after Object_destroy().
Can be called several times on an object. 
Increments Object. protectCount.

=item unprotect_object 

 void( Handle obj);

Frees object pointer after Object. protectCount hits zero.
Can be called several times on an object.

=item parse_hv

 HV *( I32 ax, SV **sp, I32 items, SV **mark, int expected, const char *methodName);

Transfers arguments in perl stack to a newly created HV and returns it.

=item push_hv

 void ( I32 ax, SV **sp, I32 items, SV **mark, int callerReturns, HV *hv);

Puts all hv contents back to perl stack.

=item push_hv_for_REDEFINED

 SV **( SV **sp, HV *hv);

Puts hv content as arguments to perl code to be called

=item pop_hv_for_REDEFINED

 int ( SV **sp, int count, HV *hv, int shouldBe);

Reads result of executed perl code and stores them into hv.

=item pexist

 Bool(char*key)

Return true if a key is present into hash 'profile'

=item pdelete

 void(char*key)

Deletes a key in hash 'profile'

=item pget_sv, pget_i, pget_f, pget_c, pget_H, pget_B

 TYPE(char*key)

Returns value of ( SV*, int, float, char*, Handle or Bool)
that is associated to a key in hash 'profile'. Calls croak()
if the key is not present.

=item pset_sv, pset_i, pset_f, pset_c, pset_H

 void( char*key, TYPE value)

Assigns a value to a key in hash 'profile' and increments
reference count to a newly created scalar.

=item pset_b

 void( char*key, void* data, int length)

Assigns binary data to a key in hash 'profile' and increments
reference count to a newly created scalar.


=item pset_sv_noinc

 void(char* key, SV * sv)

Assigns scalar value to a key  in hash 'profile' without
reference count increment.

=item duplicate_string

 char*( const char *)

Returns copy of a string

=item list_create

 void ( PList self, int size, int delta);

Creates a list instance with a static List structure.

=item plist_create

 PList( int size, int delta);

Created list instance and returns newly allocated List structure.


=item list_destroy

 void( PList self);

Destroys list data.

=item plist_destroy

 void ( PList self);

Destroys list data and frees list instance.

=item list_add

 int( PList self, Handle item);

Adds new item into a list, returns its index or -1
on error.

=item list_insert_at

 int ( PList self, Handle item, int pos);

Inserts new item into a list at a given position, returns
its position or -1 on error.

=item list_at

 Handle ( PList self, int index);

Returns items that is located at given index or nilHandle 
if the index is out of range.

=item list_delete

 void( PList self, Handle item);

Removes the item from list.

=item list_delete_at

 void( PList self, int index);

Removes the item located at given index from a list.

=item list_delete_all

 void ( PList self, Bool kill);

Removes all items from the list. If kill is true,
calls free() on every item before.

=item list_first_that

 int( PList self, void * action, void * params);

Enumerates all list entries, calling action procedure on each.
If action returns true, enumeration stops and the index is returned.
Otherwise -1 is returned. action have to be a function declared as

 Bool action_callback( Handle item, void * params);

params is a pointer to an arbitrary user data

=item list_index_of

 int( PList self, Handle item);

Returns index of an item, or -1 if the item is not in the list.

=back

=head1 AUTHOR

Dmitry Karasik, E<lt>dmitry@karasik.eu.orgE<gt>.

=head1 SEE ALSO

L<Prima>