# New Ticket Created by  [EMAIL PROTECTED] 
# Please include the string:  [perl #27486]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org:80/rt3/Ticket/Display.html?id=27486 >


2004-Mar-07

Objective:
  The classes/pmc_*.h C API's are supposed to be visible
  via include/parrot/extend.h.

Example:
  A parrot extension might say

    #include "parrot/extend.h"
  [...]
    printf("%d\n", Parrot_Array_elements(interp,array));

Implementation:

  A new generated header include/parrot/pmc_apis.h is created.
  It is #include'd by include/parrot/extern.h .
  It is a target in ./Makefile (aka config/gen/makefiles/root.in),
  which calls a new  build_tools/pmc_apis_h.pl  to create it.

  build_tools/pmc_apis_h.pl creates include/parrot/pmc_apis.h by
  cat'ing together classes/pmc_*.h , while changing the type names
  from internal to public forms.  Eg, PMC * becomes Parrot_PMC.

  A working test is added to  t/src/extend.t .

Comments:

  The make'ing of classes/ gets pulled to earlier in the build process.
  This seems the right thing.  And even works. :)

  I needed public type names for BIGNUM and visit_info.  But these
  do not seem to have been defined yet.  So I created placeholder
  names Parrot__bignum and Parrot__view_info in extern.h.  When official
  names are determined, these temporary ones can be easily changed.

  Parrot C extensions! :)

Files created:
  build_tools/pmc_apis_h.pl
  include/parrot/pmc_apis.h   (generated at build time)

Files modified:
  config/gen/makefiles/root.in
  include/parrot/extend.h
  t/src/extend.t
  MANIFEST

Mitchell

diff -uPr ../parrot_cvs/MANIFEST ./MANIFEST
--- ../parrot_cvs/MANIFEST      Sat Mar  6 20:47:43 2004
+++ ./MANIFEST  Sun Mar  7 00:54:36 2004
@@ -6,6 +6,7 @@
 build_tools/ops2c.pl                              [devel]
 build_tools/ops2pm.pl                             [devel]
 build_tools/pbc2c.pl                              [devel]
+build_tools/pmc_apis_h.pl                         []
 build_tools/vtable_h.pl                           []
 ChangeLog                                         []
 chartypes/unicode.c                               []
diff -uPr ../parrot_cvs/build_tools/pmc_apis_h.pl ./build_tools/pmc_apis_h.pl
--- ../parrot_cvs/build_tools/pmc_apis_h.pl     Wed Dec 31 19:00:00 1969
+++ ./build_tools/pmc_apis_h.pl Sun Mar  7 03:43:13 2004
@@ -0,0 +1,56 @@
+#! perl -w
+################################################################################
+# Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
+# $Id:  $
+################################################################################
+
+=head1 NAME
+
+build_tools/pmc_apis_h.pl - Create include/parrot/pmc_apis.h
+
+=head1 SYNOPSIS
+
+       % perl build_tools/pmc_apis_h.pl
+
+=head1 DESCRIPTION
+
+This script creates F<include/parrot/pmc_apis.h> from F<classes/pmc_*.h>.
+
+=cut
+
+################################################################################
+
+use lib 'lib';
+use Parrot::Configure::Step qw(move_if_diff);
+
+open OUT, ">include/parrot/pmc_apis.h.tmp" or die $!;
+
+print OUT <<'EOF';
+/*
+** !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
+**
+** This file is generated automatically from 'classes/pmc_*.h' by pmc_apis_h.pl
+*/
+
+#if !defined(PARROT_PMC_APIS_H_GUARD)
+#define PARROT_PMC_APIS_H_GUARD
+
+EOF
+
+for(<classes/pmc_*.h>) {
+    my $header = `cat $_`;
+    $header =~ s/\b(PMC|STRING)\s*\*/Parrot_$1 /g;
+    $header =~ s/\b(U?)INTVAL\b/Parrot_${1}Int/g;
+    $header =~ s/\bFLOATVAL\b/Parrot_Float/g;
+    $header =~ s/\bBIGNUM\s*\*/Parrot__bignum /g;
+    $header =~ s/\bvisit_info\s*\*/Parrot__visit_info /g;
+    $header =~ s/^.+?_class_init\s*\(.+//mg;
+    print OUT $header;
+}
+
+print OUT "\n\n#endif  /* PARROT_PMC_APIS_H_GUARD */\n\n";
+
+close OUT;
+
+move_if_diff("include/parrot/pmc_apis.h.tmp","include/parrot/pmc_apis.h");
+
diff -uPr ../parrot_cvs/config/gen/makefiles/root.in ./config/gen/makefiles/root.in
--- ../parrot_cvs/config/gen/makefiles/root.in  Sat Mar  6 14:20:20 2004
+++ ./config/gen/makefiles/root.in      Sun Mar  7 01:07:44 2004
@@ -141,7 +141,8 @@
     $(INC)/vtable.h \
     $(INC)/oplib/core_ops.h \
     $(INC)/oplib/core_ops_prederef.h \
-    $(INC)/oplib/core_ops_switch.h
+    $(INC)/oplib/core_ops_switch.h \
+    $(INC)/pmc_apis.h
 
 GEN_SOURCES = \
     $(SRC)/core_ops.c \
@@ -875,6 +876,10 @@
 $(CLASS_O_FILES) : $(CLASS_PMC_FILES) $(NONGEN_HEADERS)
        $(MAKE_C) classes
 
+$(INC)/pmc_apis.h : $(CLASS_PMC_FILES)
+       $(MAKE_C) classes
+       $(PERL) $(BUILD_TOOL)/pmc_apis_h.pl
+
 
 ${icu_make}
 
diff -uPr ../parrot_cvs/include/parrot/extend.h ./include/parrot/extend.h
--- ../parrot_cvs/include/parrot/extend.h       Mon Feb 23 16:16:35 2004
+++ ./include/parrot/extend.h   Sun Mar  7 03:16:03 2004
@@ -30,6 +30,9 @@
 #define Parrot_PMC PMC *
 #define Parrot_Language Parrot_Int
 
+#define Parrot__visit_info visit_info *
+#define Parrot__bignum BIGNUM *
+
 #else
 
 typedef void * Parrot_INTERP;
@@ -41,8 +44,15 @@
 typedef const void * Parrot_Const_Encoding;
 typedef const void * Parrot_Const_CharType;
 
+typedef void * Parrot__visit_info;
+typedef void * Parrot__bignum;
+
 #endif
 
+
+#include "parrot/pmc_apis.h"    /* give us headers for the pmc classes */
+
+
 Parrot_PMC Parrot_PMC_get_pmc_intkey(Parrot_INTERP, Parrot_PMC, Parrot_Int);
 Parrot_STRING Parrot_PMC_get_string(Parrot_INTERP, Parrot_PMC);
 Parrot_STRING Parrot_PMC_get_string_intkey(Parrot_INTERP, Parrot_PMC, Parrot_Int);
diff -uPr ../parrot_cvs/t/src/extend.t ./t/src/extend.t
--- ../parrot_cvs/t/src/extend.t        Thu Feb 26 03:13:37 2004
+++ ./t/src/extend.t    Sun Mar  7 11:27:06 2004
@@ -17,7 +17,7 @@
 
 =cut
 
-use Parrot::Test tests => 13;
+use Parrot::Test tests => 14;
 use Parrot::Config;
 
 c_output_is(<<'CODE', <<'OUTPUT', "set/get_intreg");
@@ -534,4 +534,31 @@
 unlink "$temp.pasm", "$temp.pbc";
 
 
+c_output_is(<<'CODE', <<'OUTPUT', "basic pmc class api use");
+
+#include <stdio.h>
+#include "parrot/embed.h"
+#include "parrot/extend.h"
+
+int main(int argc, char* argv[]) {
+    Parrot_Interp interpreter;
+    Parrot_PMC a;
+
+    /* Interpreter set-up */
+    interpreter = Parrot_new(NULL);
+    if ( interpreter == NULL ) return 1;
+    Parrot_init(interpreter);
+
+    a = Parrot_PMC_new(interpreter,Parrot_PMC_typenum(interpreter, "PerlInt"));
+    Parrot_PerlInt_set_number_native(interpreter, a, 42.0);
+    printf("%d\n", (int) Parrot_PerlInt_get_number(interpreter, a));
+
+    Parrot_exit(0);
+    return 0;
+}
+
+CODE
+42
+OUTPUT
+
 1;

Reply via email to