On Tue, Feb 14, 2006 at 10:04:59PM +0100, Leopold Toetsch wrote:
> On Feb 14, 2006, at 18:29, Tim Bunce wrote:
> 
> >The runtime dlfunc code will need to be altered to normalize away the
> >trailing v so old code won't break. Should it warn about that?
> 
> Yes, a warning please.

Here's the patch.

 - removes 'v' argument entries from src/call_list.txt
 - adds mysqlclient signatures to src/call_list.txt [*]
 - tweaks docs/pdds/clip/pdd16_native_call.pod to match
 - adds list of definition files used into generated nci.c
 - adds sanity checking of return and argument sig chars
 - adds compile time warning for deprecated 'v' argument
 - adds optional duplicate signature warning (disabled)
 - adds runtime warning for deprecated 'v' argument

Tim.

[*] I'm planning a followup patch that splits src/call_list.txt
into multiple files in a subdirectory. The mysqlclient defs would then
be in their own file. With the current arrangement no one can safely
remove a signature because there's no indication of what that signature
exists for.

The same ncidef file could then be used for both tools/build/nativecall.pl
and tools/util/ncidef2pasm.pl (which I also plan to work on).

Any objections or comments?
Index: src/call_list.txt
===================================================================
--- src/call_list.txt   (revision 11741)
+++ src/call_list.txt   (working copy)
@@ -49,14 +49,12 @@
 c                # t/pmc/nci.t
 c      p
 c      pi
-c      v
 
 d                # t/pmc/nci.t
 d      d
 d      JOd      # Parrot builtins
 I       JOS
 S       JOS      # ParrotIO.readline
-d      v
 I      JI       # Parrot_is_char_*
 v       JOSP     # String.trans
 v       JOS      # String.reverse
@@ -83,7 +81,6 @@
 f                # t/pmc/nci.t
 f      ff       # t/pmc/nci.t
 f      is
-f      v
 
 i
 i      b        # t/pmc/nci.t
@@ -148,7 +145,6 @@
 i      ssss
 i      t
 i      ti
-i      v
 i      4
 i      4i
 i      42p
@@ -160,7 +156,6 @@
 l      pi
 l      pii
 l      p33l
-l      v
 l      33l
 
 P      Ji       # Needed for parrot threads
@@ -185,10 +180,8 @@
 p      t
 p      tpp
 p      ttttttt
-p      v
 
 s             # t/pmc/nci.t
-s      v
 
 t             # t/pmc/nci.t
 t      i
@@ -200,7 +193,6 @@
 t      t
 t      tl4
 t      t4
-t      v
 
 v
 v      Jiiip    # examples/japh/japh11.pasm
@@ -215,7 +207,6 @@
 v      piiii
 v      pl
 v      pp
-v      v
 
 # These are needed for parrotio.pmc
 i      JP
@@ -343,3 +334,77 @@
 
 # Make lua stop panic'ing.
 P      JOI
+
+
+# --- start mysqlclient library ---
+# Created from mysql.h using the following manual method:
+# Edited copy of mysql.h using vi by doing g/, *$/j (repeat) then g/\* *$/j 
(repeat)
+# to get all functions on one line each.
+# Extracted list of api func names from 
http://dev.mysql.com/doc/refman/4.1/en/c-api-functions.html
+# and copied to a temporary file to clean up (mysql_api_names.txt)
+# Stripped down to bare names and merged into one line separated by |
+# then egrep -w `cat mysql_api_names.txt` mysql.h > mysql_api.ncidef
+# then edit mysql_api.ncidef in vi: %s/^/   #  /
+# to create space for nci signatures and to use original definition as a # 
comment.
+# This method isn't ideal, I'm just noting it here in case it helps others.
+# Ideally the process should be automated - but there be many dragons along # 
that path.
+#
+# long long values (my_ulonglong) aren't handled by nci - spec'd as just long 
for now
+#
+#      MYSQL_FIELD and MYSQL_RES are structs
+#      typedef char **MYSQL_ROW;               /* return data as array of 
strings */
+#      typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */
+#      typedef MYSQL_ROWS *MYSQL_ROW_OFFSET;   /* offset to current row */
+#
+l p    #! my_ulonglong mysql_num_rows(MYSQL_RES *res)
+i p    #  unsigned int mysql_num_fields(MYSQL_RES *res)
+c p    #  my_bool mysql_eof(MYSQL_RES *res)
+p pi   #  MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *res, unsigned int 
fieldnr)
+p p    #  MYSQL_FIELD * mysql_fetch_fields(MYSQL_RES *res)
+p p    #  MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *res)
+i p    #  MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *res)
+i p    #  unsigned int mysql_field_count(MYSQL *mysql)
+l p    #! my_ulonglong mysql_affected_rows(MYSQL *mysql)
+l p    #! my_ulonglong mysql_insert_id(MYSQL *mysql)
+i p    #  unsigned int mysql_errno(MYSQL *mysql)
+t p    #  const char * mysql_error(MYSQL *mysql)
+t p    #  const char * mysql_info(MYSQL *mysql)
+l p    #  unsigned long mysql_thread_id(MYSQL *mysql)
+t p    #  const char * mysql_character_set_name(MYSQL *mysql)
+p p    #  MYSQL * mysql_init(MYSQL *mysql)
+i pttttt       #  int mysql_ssl_set(MYSQL *mysql, const char *key, const char 
*cert, const char *ca, const char *capath, const char *cipher)
+c pttt         #  my_bool mysql_change_user(MYSQL *mysql, const char *user, 
const char *passwd, const char *db)
+p pttttiti     #  MYSQL * mysql_real_connect(MYSQL *mysql, const char *host, 
const char *user, const char *passwd, const char *db, unsigned int port, const 
char *unix_socket, unsigned int clientflag)
+v p    #  void mysql_close(MYSQL *sock)
+i pt   #  int mysql_select_db(MYSQL *mysql, const char *db)
+i pt   #  int mysql_query(MYSQL *mysql, const char *q)
+i ptl  #  int mysql_real_query(MYSQL *mysql, const char *q, unsigned long 
length)
+i p    #  int mysql_shutdown(MYSQL *mysql)
+i p    #  int mysql_dump_debug_info(MYSQL *mysql)
+i pi   #  int mysql_refresh(MYSQL *mysql, unsigned int refresh_options)
+i pl   #  int mysql_kill(MYSQL *mysql,unsigned long pid)
+i p    #  int mysql_ping(MYSQL *mysql)
+t p    #  const char * mysql_stat(MYSQL *mysql)
+t p    #  const char * mysql_get_server_info(MYSQL *mysql)
+t p    #  const char * mysql_get_client_info(void)
+l      #  unsigned long mysql_get_client_version(void)
+t p    #  const char * mysql_get_host_info(MYSQL *mysql)
+t p    #  unsigned int mysql_get_proto_info(MYSQL *mysql)
+p pt   #  MYSQL_RES * mysql_list_dbs(MYSQL *mysql,const char *wild)
+p pt   #  MYSQL_RES * mysql_list_tables(MYSQL *mysql,const char *wild)
+p ptt  #  MYSQL_RES * mysql_list_fields(MYSQL *mysql, const char *table, const 
char *wild)
+p p    #  MYSQL_RES * mysql_list_processes(MYSQL *mysql)
+p p    #  MYSQL_RES * mysql_store_result(MYSQL *mysql)
+p p    #  MYSQL_RES * mysql_use_result(MYSQL *mysql)
+i pit  #  int mysql_options(MYSQL *mysql,enum mysql_option option, const char 
*arg)
+v p    #  void mysql_free_result(MYSQL_RES *result)
+v pl   #  void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset)
+p pp   #  MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET 
offset)
+i pi   #  MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, 
MYSQL_FIELD_OFFSET offset)
+p p    #  MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
+l p    #  unsigned long * mysql_fetch_lengths(MYSQL_RES *result)
+p p    #  MYSQL_FIELD * mysql_fetch_field(MYSQL_RES *result)
+l ttl  #  unsigned long mysql_escape_string(char *to,const char *from, 
unsigned long from_length)
+l pttl #  unsigned long mysql_real_escape_string(MYSQL *mysql, char *to,const 
char *from, unsigned long length)
+v t    #  void mysql_debug(const char *debug)
+# --- end mysqlclient library ---
Index: docs/pdds/clip/pdd16_native_call.pod
===================================================================
--- docs/pdds/clip/pdd16_native_call.pod        (revision 11741)
+++ docs/pdds/clip/pdd16_native_call.pod        (working copy)
@@ -51,10 +51,12 @@
 
 =item v
 
-Void. As a return type indicates that there I<is> no return type. As a
-parameter indicates that there are no parameters. Can't be mixed with other
-parameter types.
+Void. As a return type it indicates that there I<is> no return type.
 
+As a parameter it indicates that there are no parameters (this use is now
+deprecated - use an empty parameter string to indicate that there are no
+parameters). Can't be mixed with other parameter types.
+
 =item c
 
 Char. This is an integer type, taken from (or put into) an I register. NOTE: it
Index: tools/build/nativecall.pl
===================================================================
--- tools/build/nativecall.pl   (revision 11741)
+++ tools/build/nativecall.pl   (working copy)
@@ -31,11 +31,12 @@
 use strict;
 use warnings;
 
+my $opt_warndups = 0;
 
 # This file will eventually be compiled
 open NCI, ">", "src/nci.c" or die "Can't open nci.c!";
 
-print_head();
+print_head([EMAIL PROTECTED]);
 
 my %ret_type =
      ( p => "void *",
@@ -187,17 +188,33 @@
     s/\s*$//;
     next unless $_;
 
+    my ($ret, $args) = split /\s+/, $_;
+
+    $args = '' if not defined $args;
+    $args =~ s/^v$//
+      and warn "Removed deprecated 'v' argument signature on line $. of $ARGV";
+
+    die "Invalid return signature char '$ret' on line $. of $ARGV"
+      unless exists $ret_assign{$ret};
+
+    if (($seen{"$ret$args"} ||= $.) != $.) {
+      warn sprintf "Ignored signature '%s' on line %d (previously seen on line 
%d) of $ARGV",
+              "$ret$args", $., $seen{"$ret$args"}
+        if $opt_warndups;
+      next;
+    }
+
     my @extra_preamble;
     my @extra_postamble;
     my @temps;
-    my ($ret, $args) = split /\s+/, $_;
-    ## next if $seen{"$ret$;$args"}++;
     my @arg;
     my $reg_num = 0;
     my $sig = '';
 
     if (defined $args and not $args =~ m/^\s*$/ ) {
         foreach (split //, $args) {
+            die "Invalid argument signature char '$_' on line $. of $ARGV"
+                unless exists $sig_char{$_};
             push @arg, make_arg($_, $reg_num++, \$temp_cnt, [EMAIL PROTECTED],
                                 [EMAIL PROTECTED], [EMAIL PROTECTED]);
             $sig .= $sig_char{$_};
@@ -220,11 +237,13 @@
 
 
 sub print_head {
+    my ($definitions) = @_;
     print NCI << "HEAD";
 /*
  * !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
  *
- * This file is generated automatically by tools/build/nativecall.pl.
+ * This file is generated automatically by tools/build/nativecall.pl
+ * from definitions in @$definitions
  *
  * Any changes made here will be lost!
  *
@@ -490,7 +509,7 @@
                               qq{$ret_type_decl return_data;} :
                               q{};
 
-    if (defined $params) {
+    if (length $params) {
         my $proto = join ', ', map { $proto_type_ref->{$_} } split( '', 
$params );
         # This is an after-the-fact hack: real fix would be in make_arg
         # or somewhere at that level.  The main point being that one cannot
@@ -542,7 +561,7 @@
         $call_state = '' if 'v' eq $return;
         print NCI << "HEADER";
 static void
-pcf_${return}(Interp *interpreter, PMC *self)
+pcf_${return}_(Interp *interpreter, PMC *self)
 {
     $ret_type (*pointer)(void);
     $return_data
@@ -590,6 +609,7 @@
     PMC        *b;
     PMC        *iglobals;
     PMC        *temp_pmc;
+    UINTVAL    signature_len;
 
     void       *result        = NULL;
     Hash       *known_frames  = NULL;
@@ -610,7 +630,14 @@
     /* And in here is the platform-independent way. Which is to say
        "here there be hacks" */
     UNUSED(pmc_nci);
-    if (0 == string_length(interpreter, signature)) return F2DPTR(pcf_v_v);
+    signature_len = string_length(interpreter, signature);
+    if (0 == signature_len) return F2DPTR(pcf_v_);
+    /* remove deprecated void argument 'v' character */
+    if (2 == signature_len && 'v' == string_index(interpreter, signature, 1)) {
+       Parrot_warn(interpreter, PARROT_WARNINGS_ALL_FLAG, "function signature 
argument character 'v' ignored");
+       signature = string_chopn(interpreter, signature, 1, 1);
+       signature_len = string_length(interpreter, signature);
+    }
 
     iglobals = interpreter->iglobals;
 

Reply via email to