On 25/12/2011 23:34, Daniel Stenberg wrote:
If
I would point out a very minor flaw in the readability of the output it
would be that it interleaves the curl_formadd() calls within the seires
of curl_easy_setopt() calls. It would possibly look better if they were
made separate of each other.

Maybe; there are few other improvements I could make too, but maybe not this week.

CURLOPT_SSH_KNOWNHOSTS is used conditionally and needs to be stripped
out from the test output before comparing. I'm working on that.

OK, I'll leave that to you.

... I really ought to check that the generated code
really does work the same as the curl tool with the given options.

For the moment, I have not released this but only used it within my
own tree,

If you post what you have this far with a basic description then I think
I can give a shot at doing the proper autotool massaging to get it used
properly!

See the attached patch.  Example use would be:

 ./convsrctest.pl -c data/test1400 > libtest/lib1500.c
 ./convsrctest.pl -test=1500 data/test1400 > data/test1500

Regards,
--
Colin
>From b6f701d0c3f9cb971b56ceacc1ba1761d2a8c7bb Mon Sep 17 00:00:00 2001
From: Colin Hogben <c...@pythontech.co.uk>
Date: Tue, 27 Dec 2011 18:37:57 +0000
Subject: [PATCH] Script to convert --libcurl test

This script reads a test definition which exercises curl's --libcurl
option and generates either compilable source code for a new test
tool, or a new test definition which runs the tool and expects the
same output.
---
 tests/convsrctest.pl |  250 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 250 insertions(+), 0 deletions(-)
 create mode 100755 tests/convsrctest.pl

diff --git a/tests/convsrctest.pl b/tests/convsrctest.pl
new file mode 100755
index 0000000..56a4f85
--- /dev/null
+++ b/tests/convsrctest.pl
@@ -0,0 +1,250 @@
+#!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2011, Daniel Stenberg, <dan...@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+#***************************************************************************
+
+#=======================================================================
+# Read a test definition which exercises curl's --libcurl option.
+# Generate either compilable source code for a new test tool,
+# or a new test definition which runs the tool and expects the
+# same output.
+# This should verify that the --libcurl code really does perform
+# the same actions as the original curl invocation.
+#=======================================================================
+use strict;
+require "getpart.pm";
+
+# Boilerplate code for test tool
+my $head =
+'#include "test.h"
+#include "memdebug.h"
+
+int test(char *URL)
+{
+  CURLcode res;
+  CURL *curl;
+';
+# Other declarations from --libcurl come here
+# e.g. curl_slist
+my $init =
+'
+  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+    fprintf(stderr, "curl_global_init() failed\n");
+    return TEST_ERR_MAJOR_BAD;
+  }
+
+  if ((curl = curl_easy_init()) == NULL) {
+    fprintf(stderr, "curl_easy_init() failed\n");
+    curl_global_cleanup();
+    return TEST_ERR_MAJOR_BAD;
+  }
+';
+# Option setting comes here
+my $doit =
+'
+  res = curl_easy_perform(curl);
+
+test_cleanup:
+';
+# Other cleanup code comes here
+my $exit =
+'  curl_easy_cleanup(curl);
+  curl_global_cleanup();
+
+  return (int)res;
+}
+';
+
+my $myname = leaf($0);
+sub usage {die "Usage: $myname -c|-test=num testfile\n";}
+
+sub main {
+    @ARGV == 2
+        or usage;
+    my($opt,$testfile) = @ARGV;
+
+    if(loadtest($testfile)) {
+        die "$myname: $testfile doesn't look like a test case\n";
+    }
+
+    my $comment = sprintf("DO NOT EDIT - generated from %s by %s",
+                          leaf($testfile), $myname);
+    if($opt eq '-c') {
+        generate_c($comment);
+    }
+    elsif(my($num) = $opt =~ /^-test=(\d+)$/) {
+        generate_test($comment, $num);
+    }
+    else {
+        usage;
+    }
+}
+
+sub generate_c {
+    my($comment) = @_;
+    # Fetch the generated code, which is the output file checked by
+    # the old test.
+    my @libcurl = getpart("verify", "file")
+        or die "$myname: no <verify><file> section found\n";
+
+    # Mangle the code into a suitable form for a test tool.
+    # We want to extract the important parts (declarations,
+    # URL, setopt calls, cleanup code) from the --libcurl
+    # boilerplate and insert them into a new boilerplate.
+    my(@decl,@setopt,@clean);
+    my($seen_main,$seen_setopt,$seen_perform,$seen_return);
+    foreach (@libcurl) {
+        # Check state changes first (even though it
+        # duplicates some matches) so that the other tests
+        # are in a logical order).
+        if(/^int main/) {
+            $seen_main = 1;
+        }
+        if($seen_main and /curl_easy_setopt/) {
+            # Don't match 'curl_easy_setop' in comment!
+            $seen_setopt = 1;
+        }
+        if(/curl_easy_perform/) {
+            $seen_perform = 1;
+        }
+        if(/^\s*return/) {
+            $seen_return = 1;
+        }
+
+        # Now filter the code according to purpose
+        if(! $seen_main) {
+            next;
+        }
+        elsif(! $seen_setopt) {
+            if(/^\s*(int main|\{|CURLcode |CURL )/) {
+                next;
+            }
+            else {
+                push @decl, $_;
+            }
+        }
+        elsif(! $seen_perform) {
+            if (/CURLOPT_URL/) {
+                # URL will be passed in as argument
+                s/\"[^\"]*\"/URL/;
+            }
+            # Convert to macro wrapper
+            s/curl_easy_setopt\(\w+/test_setopt\(curl/;
+            push @setopt, $_;
+        }
+        elsif(! $seen_return) {
+            if(/curl_easy_(perform|cleanup)/) {
+                next;
+            }
+            else {
+                push @clean, $_;
+            }
+        }
+    }
+
+    print ("/* $comment */\n",
+           $head,
+           @decl,
+           $init,
+           @setopt,
+           $doit,
+           @clean,
+           $exit);
+}
+
+sub generate_test {
+    my($comment,$newnumber) = @_;
+    my @libcurl = getpart("verify", "file")
+        or die "$myname: no <verify><file> section found\n";
+    my $url;
+    foreach (@libcurl) {
+        if(my($u) = /CURLOPT_URL, \"([^\"]*)\"/) {
+            $url = $u;
+        }
+    }
+    die "$myname: CURLOPT_URL not found\n"
+        unless defined $url;
+
+    # The new test is identical to the old except:
+    # - no <verify><file> section (was --libcurl output)
+    # - <client><tool> set to our new C program
+    # - <client><command> is the URL from CURLOPT_URL
+    my @new;
+    my(@path,$path,$skip);
+    foreach (getall()) {
+        if(my($end) = /\s*<(\/?)testcase>/) {
+            push @new, $_;
+            push @new, "# $comment\n"
+                unless $end;
+        }
+        elsif(my($tag) = /^\s*<(\w+)/) {
+            push @path, $tag;
+            $path = join '/', @path;
+            if($path eq 'verify/file') {
+                $skip = 1;
+            }
+            push @new, $_
+                unless $skip;
+            if($path eq 'client') {
+                push @new, ("<tool>\n",
+                            "lib$newnumber\n",
+                            "</tool>\n");
+            }
+            elsif($path eq 'client/command') {
+                push @new, sh_quote($url)."\n";
+            }
+        }
+        elsif(my($etag) = /^\s*<\/(\w+)/) {
+            my $tag = pop @path;
+            die "$myname: mismatched </$etag>\n"
+                unless $tag eq $etag;
+            push @new, $_
+                unless $skip;
+            $skip --
+                if $path eq 'verify/file';
+            $path = join '/', @path;
+        }
+        else {
+            if($path eq 'client/command') {
+                # Replaced above
+            }
+            else {
+                push @new, $_
+                    unless $skip;
+            }
+        }
+    }
+    print @new;
+}
+
+sub leaf {
+    # Works for POSIX filenames
+    (my $path = shift) =~ s!.*/!!;
+    return $path;
+}
+
+sub sh_quote {
+    my $word = shift;
+    $word =~ s/[\$\"\'\\]/\\$&/g;
+    return '"' . $word . '"';
+}
+
+main;
-- 
1.6.5.6

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to