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;