Permalink
Browse files

Initial skeleton of a Parrot library which uses winxed and rosella

  • Loading branch information...
0 parents commit 64b5dc2ccb0b98c097792a364841dd108ca6d296 @leto leto committed Jul 5, 2011
Showing with 911 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +30 −0 CREDITS
  3. +674 −0 LICENSE
  4. +3 −0 README.md
  5. +103 −0 bin/header2nci.pl
  6. +89 −0 setup.winxed
  7. +11 −0 t/harness
@@ -0,0 +1 @@
+*.swp
30 CREDITS
@@ -0,0 +1,30 @@
+=pod
+
+
+Following in the steps of other open source projects that eventually take over
+the world, here is the partial list of people who have contributed to
+parrot-libgit2 and its supporting works. It is sorted by name and formatted to
+allow easy grepping and beautification by scripts. The fields are: name (N),
+email (E), web-address (W), description (D), main username (U), alias usernames
+(pA) and snail-mail address (S).
+
+ Thanks,
+
+ The parrot-libgit2 Team
+ PS: Yes, this looks remarkably like the Linux CREDITS format
+ PPS: This file is encoded in UTF-8
+ PPPS: To turn this file into a author map for git-svn, see tools/dev/mk_author_map.pl
+
+----------
+
+N: Bob Kuo
+E: bobjkuo@gmail.com
+U: bubaflub
+
+N: Jonathan "Duke" Leto
+E: jonathan@leto.net
+W: http://leto.net
+U: dukeleto
+A: leto
+A: Duke Leto
+S: Portland, OR
674 LICENSE
Oops, something went wrong.
@@ -0,0 +1,3 @@
+# Parrot Virtual Machine bindings to libgit2
+
+Here be dragons.
@@ -0,0 +1,103 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use File::Slurp;
+use List::MoreUtils qw(any);
+use YAML qw(LoadFile);
+
+# Description: reads a local gmp.h and outputs an NCI definition file
+
+if (scalar @ARGV != 1 || ! -e $ARGV[0]) {
+ die "Usage: perl gmph2ncidef.pl /path/to/gmp.h\n";
+}
+
+my $filename = $ARGV[0];
+
+my %mappings = %{LoadFile('conf/c_to_nci_mappings.yml')};
+
+# blacklist is an array of function names to not bother with
+my @blacklist = @{LoadFile('conf/blacklist.yml')};
+
+my $functions = process_gmph($filename);
+print_ncidef($functions);
+
+sub process_gmph {
+ my $filename = shift;
+ my %functions;
+
+ open my $gmp_header, '<', $filename;
+
+ while(<$gmp_header>) {
+ chomp;
+ next if $_ !~ m/^#/;
+ # note: in the future, we will look for more functions
+ # and not just mpz types
+ my $prefix = '(?:_?mpz|gmp_u?rand)';
+ # does the line match a C-style declare?
+ if ($_ =~ m/#define ($prefix\S+) (__\S+)/) {
+ # $1 is the convenient name used everywhere else
+ my $convenient_name = $1;
+ # $2 is the name we must use in the NCI def
+ my $internal_name = $2;
+ # skip if it's on our blacklist
+ next if any { $convenient_name eq $_ } @blacklist;
+ $functions{$convenient_name}{'internal_name'} = $internal_name;
+ # read until the next blank line into a definition
+ my $definition;
+ while ((my $following_line = <$gmp_header>) !~ m/^$/) {
+ chomp $following_line;
+ # some functions have complex conditions to check if
+ # __GMP_DECLSPEC should be called ...
+ # let's get these functions signatures regardless of those conditions
+ next if $following_line =~ m/^(#if|#endif)/;
+
+ # remove inline comments from the definition
+ $following_line =~ s!/\*.*\*/!!;
+ $definition .= $following_line;
+ }
+ # process the definition into a return type and a method signature
+ if ($definition =~ m/__GMP_DECLSPEC\s+(.+)$convenient_name __GMP_PROTO \(\((.+)\)\)/) {
+ my $return_type = $1;
+ my $method_signature = $2;
+
+ # process return_type and method_signature - we need to convert
+ # it from a valid C type to an NCI def - ie. void -> v
+ my $converted_return_type = process_types($return_type);
+ $functions{$convenient_name}{'return_type'} = $converted_return_type;
+ my $converted_method_signature = join '', map { process_types($_) } split /,/, $method_signature;
+ $functions{$convenient_name}{'method_signature'} = $converted_method_signature;
+ } else {
+ warn "Line does not match function definition: $definition";
+ }
+ }
+ }
+
+ close $gmp_header;
+
+ return \%functions;
+}
+
+sub process_types {
+ my $type = shift;
+ # GMP uses the __gmp_const macro as a placeholder to handle compilers that
+ # don't support const - we'll ignore this macro as the burden is on the
+ # developer (not the bindings) to ensure no const data structures get
+ # modified
+ $type =~ s/__gmp_const//g;
+ # trim any extra space
+ $type =~ s/^\s+//g;
+ $type =~ s/\s+$//g;
+ return $mappings{$type} if exists $mappings{$type};
+ warn "No extant mapping for $type; setting as void";
+ return 'v';
+}
+
+sub print_ncidef {
+ my $functions = shift;
+
+ while(my ($function_name, $details) = each(%{$functions})) {
+ print $details->{'return_type'} . " " . $details->{'internal_name'} . " " . $details->{'method_signature'} . " # " . $function_name . "\n";
+ }
+}
@@ -0,0 +1,89 @@
+$include_const "iglobals.pasm";
+using extern "io_ops";
+
+function main[main](argv) {
+ var parrot_libgit2 = {
+ "name" : 'parrot-libgit2',
+ "abstract" : 'Parrot bindings for libgit2',
+ "description" : 'Parrot bindings for libgit2 - the linkable git library',
+ "authority" : 'http://github.com/leto',
+ "copyright_holder" : 'Jonathan "Duke" Leto',
+ "keywords" : ["parrot", "git", "libgit2],
+ "license_type" : 'Artistic License 2.0',
+ "license_uri" : 'http://www.perlfoundation.org/artistic_license_2_0',
+ "checkout_uri" : 'git://github.com/leto/parrot-libgit2.git',
+ "browser_uri" : 'git://github.com/leto/parrot-libgit2',
+ "project_uri" : 'git://github.com/leto/parrot-libgit2',
+ "pir_winxed" : {},
+ "pbc_pir" : {},
+ "inst_lib" : [],
+ "installable_pbc" : {},
+ "include_winxed" : {},
+ "manifest_includes" : ["README.md", "setup.winxed"]
+ };
+
+ if (argv[1] == "test")
+ do_test();
+
+ setup_stable_libraries(parrot_libgit2);
+
+ load_bytecode('distutils.pir');
+ using setup;
+ using register_step_before;
+
+ register_step_before("build", check_dependencies);
+ register_step_before("clean", clean_build_dir);
+
+ argv.shift();
+ setup(argv, parrot_libgit2);
+}
+
+function setup_stable_libraries(var parrot_libgit2) {
+ var libs = [
+ 'Git2'
+ ];
+
+ string prefix = "src/";
+
+ for (string source in libs) {
+ string winxed_file = prefix + source + ".winxed";
+ string pir_file = prefix + source + ".pir";
+ string pbc_file = source + ".pbc";
+ parrot_libgit2["pir_winxed"][pir_file] = winxed_file;
+ parrot_libgit2["pbc_pir"][pbc_file] = pir_file;
+ parrot_libgit2["inst_lib"].push(pbc_file);
+ }
+}
+
+function do_test() {
+ int result;
+ string cmd = "parrot-nqp t/harness";
+ ${ spawnw result, cmd };
+ ${ exit result };
+}
+
+function check_dependencies() {
+ var config = getinterp()[IGLOBALS_CONFIG_HASH];
+ // Check if Parrot is > 3.2.0
+ int maj = config['MAJOR'];
+ int min = config['MINOR'];
+ if (maj < 3 || (maj == 3 && min < 2)) {
+ die("You need at least Parrot 3.2.0 to use parrot-libgit2");
+ }
+ // Check if Parrot has been built/configured with libffi
+ int has_libffi = config['has_libffi'];
+ if (!has_libffi) {
+ die("You need to have Parrot configured with libffi to use parrot-libgit2");
+ }
+}
+
+function clean_build_dir() {
+ var config = getinterp()[IGLOBALS_CONFIG_HASH];
+ string exe = "build/git2_test" + string(config['exe']);
+ int e = 0;
+ ${ stat e, exe, 0 };
+ if (e) {
+ say("unlink " + exe);
+ unlink(exe);
+ }
+}
@@ -0,0 +1,11 @@
+#! parrot-nqp
+INIT { pir::load_bytecode('rosella/harness.pbc'); }
+my $factory := Rosella::construct(Rosella::Harness::TestRun::Factory);
+$factory.add_test_dirs("Winxed", "t/integer", :recurse(1));
+$factory.add_test_dirs("Winxed", "t/random", :recurse(1));
+my $testrun := $factory.create();
+my $harness := Rosella::construct(Rosella::Harness);
+my $testview := $harness.default_view();
+$testview.add_run($testrun, 0);
+$harness.run($testrun, $testview);
+$testview.show_results();

0 comments on commit 64b5dc2

Please sign in to comment.