selftest: allow running a subset of the tests

If given command line arguments, interpret them as test names and only
run those tests.
diff --git a/ChangeLog b/ChangeLog
index 2061be0..80e44dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,8 @@
 
 Features
    * Allow comments in test data files.
+   * The selftest program can execute a subset of the tests based on command
+     line arguments.
 
 Bugfix
    * Fix memory leak in mbedtls_ssl_set_hostname() when called multiple times.
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 16ff310..fc3b0eb 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -256,10 +256,14 @@
 #endif
     {NULL, NULL}
 };
+#endif /* MBEDTLS_SELF_TEST */
 
 int main( int argc, char *argv[] )
 {
+#if defined(MBEDTLS_SELF_TEST)
     const selftest_t *test;
+#endif /* MBEDTLS_SELF_TEST */
+    char **argp = argc >= 1 ? argv + 1 : argv;
     int v, suites_tested = 0, suites_failed = 0;
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_SELF_TEST)
     unsigned char buf[1000000];
@@ -287,10 +291,11 @@
         mbedtls_exit( MBEDTLS_EXIT_FAILURE );
     }
 
-    if( argc == 2 && ( strcmp( argv[1], "--quiet" ) == 0  ||
+    if( argc >= 2 && ( strcmp( argv[1], "--quiet" ) == 0  ||
         strcmp( argv[1], "-q" ) == 0 ) )
     {
         v = 0;
+        ++argp;
     }
     else
     {
@@ -304,13 +309,41 @@
     mbedtls_memory_buffer_alloc_init( buf, sizeof(buf) );
 #endif
 
-    for( test = selftests; test->name != NULL; test++ )
+    if( *argp != NULL )
     {
-        if( test->function( v )  != 0 )
+        /* Run the specified tests */
+        for( ; *argp != NULL; argp++ )
         {
-            suites_failed++;
+            for( test = selftests; test->name != NULL; test++ )
+            {
+                if( !strcmp( *argp, test->name ) )
+                {
+                    if( test->function( v )  != 0 )
+                    {
+                        suites_failed++;
+                    }
+                    suites_tested++;
+                    break;
+                }
+            }
+            if( test->name == NULL )
+            {
+                mbedtls_printf( "  Test suite %s not available -> failed\n\n", *argp );
+                suites_failed++;
+            }
         }
-        suites_tested++;
+    }
+    else
+    {
+        /* Run all the tests */
+        for( test = selftests; test->name != NULL; test++ )
+        {
+            if( test->function( v )  != 0 )
+            {
+                suites_failed++;
+            }
+            suites_tested++;
+        }
     }
 
 #else