Author: wyoung
Date: Mon Jul 16 18:43:27 2007
New Revision: 1700

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=1700&view=rev
Log:
Redid examples' command line handling: using AT&T's public domain
getopt() implementation, which has many benefits, including allowing
options in any order.

Added:
    trunk/examples/att_getopt.cpp
    trunk/examples/att_getopt.h
Modified:
    trunk/README.examples
    trunk/Wishlist
    trunk/doc/userman/userman.dbx
    trunk/examples/load_jpeg.cpp
    trunk/examples/util.cpp
    trunk/examples/util.h
    trunk/mysql++.bkl

Modified: trunk/README.examples
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/README.examples?rev=1700&r1=1699&r2=1700&view=diff
==============================================================================
--- trunk/README.examples (original)
+++ trunk/README.examples Mon Jul 16 18:43:27 2007
@@ -30,41 +30,33 @@
     Before running the other examples, you must first create the
     sample database.  On POSIX systems, you do that like so:
 
-        $ ./exrun resetdb [password] [user] [server_addr]
+        $ ./exrun resetdb [-s server_addr] [-u user] [-p password]
 
     On Windows, that would instead be:
 
-        C:\mysql++\> exrun.bat resetdb [password] [user] [server_addr]
+        C:\mysql++\> exrun.bat resetdb [-s server] [-u user] [-p pass]
 
-    You may give any number of these arguments, but they must be in
-    the order listed, and you can't skip over arguments.  So, you
-    may give just a password, in which case it will assume you mean
-    to connect using your current user name to a server on the local
-    machine using the default connection method.  If you wanted to give
-    a host name, you would also have to give a user name and password.
+    You don't have to give any of these options.  If you don't pass -s,
+    it assumes the database server is running on the same machine,
+    and so tries to contact the server over some form of local IPC.
+    If you don't pass -u, it uses your own user name when logging
+    into to the database server.  If you don't pass -p, it assumes the
+    database user has an empty password, which hopefully is not true.
 
-    The server_addr parameter accepts many different forms.  The main
-    one is some sort of TCP/IP address, in either dotted quad IP form
-    or as a host or domain name.  You can also give a Unix domain
-    socket name, or just a period if on Windows to select named pipes.
-    If you give a TCP/IP address, you can follow it with a colon and
-    a port number or a symbolic service name.  All of these are legal:
+    The -s option accepts many different forms of address.  The main
+    one is some sort of TCP/IP address, with an optional port number
+    or service name.  On Unixy systems, you can give a Unix domain
+    socket name.  On Windows, you can give just a period to use named
+    pipes, if the server supports it.  All of these are legal:
 
+        .
         localhost
         172.20.0.252:12345
+        /var/run/mysqld.sock
         my.server.name.com:mysql
 
-    If you mistakenly run resetdb directly instead of through exrun,
-    it will either fail to run because it can't find the MySQL++
-    library, or it will find an old version and complain about it.
-    None of the other examples are protected against mixed versions
-    in this way, but since you have to run resetdb before all the
-    other examples, this should pose no problem.
-
-    You can give as few of the parameters as you want, but they must
-    be in that order.  That is, if you want to give a user name,
-    you must give the host first.  It defaults to localhost with
-    your user name, no password, and the default MySQL port (3306).
+    If you give -s but don't give a port number or service name with
+    it, it assumes the default, port 3306.
 
 
 Running the Other Command Line Examples

Modified: trunk/Wishlist
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/Wishlist?rev=1700&r1=1699&r2=1700&view=diff
==============================================================================
--- trunk/Wishlist (original)
+++ trunk/Wishlist Mon Jul 16 18:43:27 2007
@@ -17,9 +17,6 @@
       and document them in both userman and refman.  Needed for the
       uncommon case where you don't know the number of parameters at
       compile time.
-
-    o Use AT&T getopt code in examples for platform-independent
-      command line parsing.
 
     o Fix single-parameter template query stuff.
 

Modified: trunk/doc/userman/userman.dbx
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/doc/userman/userman.dbx?rev=1700&r1=1699&r2=1700&view=diff
==============================================================================
--- trunk/doc/userman/userman.dbx (original)
+++ trunk/doc/userman/userman.dbx Mon Jul 16 18:43:27 2007
@@ -330,7 +330,7 @@
         <para>Most of the examples require a test database, created
         by <filename>resetdb</filename>. You run it like so:</para>
 
-        <screen>        ./exrun resetdb [password [user 
[server_addr]]]</screen>
+        <screen>        ./exrun resetdb [-s server_addr] [-u user] [-p 
password]</screen>
 
         <para><filename>exrun</filename> is a shell script that
         ensures that the MySQL++ example program you give as its
@@ -346,21 +346,15 @@
         there's a Windows version of <filename>exrun</filename>, called
         <filename>exrun.bat</filename>. It works the same way.)</para>
 
-        <para>All of the program arguments are optional, but they
-        must be in the order listed, and you can't skip over any
-        arguments. The arguments are in this order on purpose. The
-        most likely one you'll need to change is the password, so
-        it's first.  After that is the user name, in case you use
-        a different login scheme with the database than the host
-        operating system. Last of all is the server address, since
-        most of the time developers have a database server on the
-        machine they're using to work with MySQL++.</para>
-
-        <para>If you leave off the server address, it uses the MySQL C
-        API defaults. It assumes the server is on the local machine,
-        and can be contacted in any number of ways, depending on how
-        the C API library and server are configured. You may pass
-        many different sorts of things for the server address:</para>
+        <para>All of the program arguments are optional.</para>
+
+        <para>If you don't give <option>-s</option>, the underlying
+        MySQL C API assumes the server is on the local machine.
+        Depending on how the C API library and the server are
+        configured, it can use any of several different IPC methods
+        to contact the server. You can instead specify how to contact
+        the server yourself, with the method depending on the value
+        you give for the server address:</para>
 
         <itemizedlist>
             <listitem>
@@ -399,19 +393,16 @@
         combination. If the name doesn't contain a colon, it uses
         the default port, 3306.</para>
 
-        <para>If you leave off the user name, it uses your login
-        name.</para>
-
-        <para>If you leave off the password, it probably won't work,
-        because it will go looking for a login defaults file, and
-        the examples don't set that up for you. If you really have
-        no password on the server, you can probably give "" here to
-        indicate a blank password. Better is to just add a password for
-        that user. It's a wild world out there; play safe, kids.</para>
+        <para>If you don't give <option>-u</option>, it uses your
+        user name to log into the database server.</para>
+
+        <para>If you don't give <option>-p</option>, it will assume
+        the MySQL user doesn't have a password, which had better not be
+        the case.  It's a wild world out there; play safe, kids.</para>
 
         <para>A typical invocation is:</para>
 
-        <screen>        ./exrun resetdb nunyabinness mydbuser</screen>
+        <screen>        ./exrun resetdb -u mydbuser -p nunyabinness</screen>
 
         <para>For <filename>resetdb</filename>, the user name needs to
         be for an account with permission to create databases. Once

Added: trunk/examples/att_getopt.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/att_getopt.cpp?rev=1700&view=auto
==============================================================================
--- trunk/examples/att_getopt.cpp (added)
+++ trunk/examples/att_getopt.cpp Mon Jul 16 18:43:27 2007
@@ -1,0 +1,78 @@
+/* att_getopt.cpp: a public domain implementation of getopt()
+ *
+ * The following source code is an adaptation of the public domain
+ * getopt() implementation presented at the 1985 UNIFORUM conference
+ * in Dallas, Texas.  Slight changes have been made to improve style
+ * and readability.  The result is released into the public domain
+ * like that from which it was derived.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+int ag_optind = 1;
+int ag_optopt;
+char* ag_optarg;
+
+int
+att_getopt(int argc, char* const argv[], const char* ag_opts)
+{
+       static int sp = 1;
+       register int c;
+       register char *cp;
+
+       if (sp == 1) {
+               /* If all args are processed, finish */
+               if (ag_optind >= argc) {
+                       return EOF;
+               }
+               if (argv[ag_optind][0] != '-' || argv[ag_optind][1] == '\0') {
+                       return EOF;
+               }
+       }
+       else if (!strcmp(argv[ag_optind], "--")) {
+               /* No more ag_options to be processed after this one */
+               ag_optind++;
+               return EOF;
+       }
+
+       ag_optopt = c = argv[ag_optind][sp];
+
+       /* Check for invalid ag_option */
+       if (c == ':' || (cp = strchr(ag_opts, c)) == NULL) {
+               fprintf(stderr, "%s: illegal option -- %c\n", argv[0], c);
+               if (argv[ag_optind][++sp] == '\0') {
+                       ag_optind++;
+                       sp = 1;
+               }
+
+               return '?';
+       }
+
+       /* Does this ag_option require an argument? */
+       if (*++cp == ':') {
+               /* If so, get argument; if none provided output error */
+               if (argv[ag_optind][sp + 1] != '\0') {
+                       ag_optarg = &argv[ag_optind++][sp + 1];
+               }
+               else if (++ag_optind >= argc) {
+                       fprintf(stderr,
+                                       "%s: option requires an argument -- 
%c\n", argv[0], c);
+                       sp = 1;
+                       return '?';
+               }
+               else {
+                       ag_optarg = argv[ag_optind++];
+               }
+               sp = 1;
+       }
+       else {
+               if (argv[ag_optind][++sp] == '\0') {
+                       sp = 1;
+                       ag_optind++;
+               }
+               ag_optarg = NULL;
+       }
+
+       return c;
+}

Added: trunk/examples/att_getopt.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/att_getopt.h?rev=1700&view=auto
==============================================================================
--- trunk/examples/att_getopt.h (added)
+++ trunk/examples/att_getopt.h Mon Jul 16 18:43:27 2007
@@ -1,0 +1,11 @@
+#if !defined(ATT_GETOPT_H)
+#define ATT_GETOPT_H
+
+extern int att_getopt(int argc, char* const argv[], const char* opts);
+
+extern int ag_optind;
+extern int ag_optopt;
+extern const char* ag_optarg;
+
+#endif // !defined(ATT_GETOPT_H)
+

Modified: trunk/examples/load_jpeg.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/load_jpeg.cpp?rev=1700&r1=1699&r2=1700&view=diff
==============================================================================
--- trunk/examples/load_jpeg.cpp (original)
+++ trunk/examples/load_jpeg.cpp Mon Jul 16 18:43:27 2007
@@ -26,6 +26,7 @@
 ***********************************************************************/
 
 #include "util.h"
+#include "att_getopt.h"
 
 #include <mysql++.h>
 
@@ -46,41 +47,43 @@
 int
 main(int argc, char *argv[])
 {
-       // Assume that the last command line argument is a file.  Try to
-       // read that file's data into img_data, and check it to see if it
-       // appears to be a JPEG file.  Bail otherwise.
-       string img_data;
-       if ((argc > 1) && (argv[1][0] != '-')) {
-               ifstream img_file(argv[argc - 1], ios::ate);
-               if (img_file) {
-                       size_t img_size = img_file.tellg();
-                       if (img_size > 10) {
-                               img_file.seekg(0, ios::beg);
-                               char* img_buffer = new char[img_size];
-                               img_file.read(img_buffer, img_size);
-                               if (is_jpeg((unsigned char*)img_buffer)) {
-                                       img_data.assign(img_buffer, img_size);
+       try {
+               // Parse the command line and establish the connection to the
+               // database server.
+               mysqlpp::Connection con(mysqlpp::use_exceptions);
+               if (!connect_to_db(argc, argv, con, 0, "[jpeg_file]")) {
+                       return 1;
+               }
+
+               // Assume that the last command line argument is a file.  Try
+               // to read that file's data into img_data, and check it to see
+               // if it appears to be a JPEG file.  Bail otherwise.
+               string img_name, img_data;
+               if (argc - ag_optind >= 1) {
+                       img_name = argv[ag_optind];
+                       ifstream img_file(img_name.c_str(), ios::ate);
+                       if (img_file) {
+                               size_t img_size = img_file.tellg();
+                               if (img_size > 10) {
+                                       img_file.seekg(0, ios::beg);
+                                       char* img_buffer = new char[img_size];
+                                       img_file.read(img_buffer, img_size);
+                                       if (is_jpeg((unsigned 
char*)img_buffer)) {
+                                               img_data.assign(img_buffer, 
img_size);
+                                       }
+                                       else {
+                                               cerr << '"' << img_file <<
+                                                               "\" isn't a 
JPEG!" << endl;
+                                       }
+                                       delete[] img_buffer;
                                }
                                else {
-                                       cerr << "File does not appear to be a 
JPEG!" << endl;
+                                       cerr << "File is too short to be a 
JPEG!" << endl;
                                }
-                               delete[] img_buffer;
-                       }
-                       else {
-                               cerr << "File is too short to be a JPEG!" << 
endl;
                        }
                }
-       }
-       if (img_data.empty()) {
-               print_usage(argv[0], "[jpeg_file]");
-               return 1;
-       }
-       --argc;         // pop filename argument off end of list
-
-       try {
-               // Establish the connection to the database server.
-               mysqlpp::Connection con(mysqlpp::use_exceptions);
-               if (!connect_to_db(argc, argv, con)) {
+               if (img_data.empty()) {
+                       print_usage(argv[0], "[jpeg_file]");
                        return 1;
                }
 
@@ -95,7 +98,7 @@
                ResNSel res = query.execute();
 
                // If we get here, insertion succeeded
-               cout << "Inserted \"" << argv[argc] <<
+               cout << "Inserted \"" << img_name <<
                                "\" into images table, " << img_data.size() <<
                                " bytes, ID " << res.insert_id() << endl;
        }

Modified: trunk/examples/util.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/util.cpp?rev=1700&r1=1699&r2=1700&view=diff
==============================================================================
--- trunk/examples/util.cpp (original)
+++ trunk/examples/util.cpp Mon Jul 16 18:43:27 2007
@@ -26,6 +26,7 @@
 ***********************************************************************/
 
 #include "util.h"
+#include "att_getopt.h"
 
 #include <iostream>
 #include <iomanip>
@@ -149,15 +150,12 @@
 print_usage(const char* program_name, const char* extra_parms)
 {
        cout << "usage: " << program_name <<
-                       " [password [user [server_addr]]] " << extra_parms << 
endl;
+                       " [-s server_addr] [-u user] [-p password] " <<
+                       extra_parms << endl;
        cout << endl;
-       cout << "    If no arguments are given, connects to database "
+       cout << "    If no options are given, connects to database "
                        "server on localhost" << endl;
-       cout << "    using your user name and no password.  You may give "
-                       "any number of" << endl;
-       cout << "    these arguments, but they must be in the order "
-                       "listed, and you" << endl;
-       cout << "    cannot skip preceding arguments." << endl;
+       cout << "    using your user name and no password." << endl;
        if (strlen(extra_parms) > 0) {
                cout << endl;
                cout << "    The extra parameter " << extra_parms <<
@@ -176,7 +174,7 @@
 
 bool
 connect_to_db(int argc, char *argv[], mysqlpp::Connection& con,
-               const char *kdb)
+               const char *kdb, const char* extra_parms)
 {
        if (argc < 1) {
                cerr << "Bad argument count: " << argc << '!' << endl;
@@ -187,25 +185,22 @@
                kdb = kpcSampleDatabase;
        }
 
-       if ((argc > 1) && (argv[1][0] == '-')) {
-               print_usage(argv[0]);
-               return false;
-       }
-
-       if (argc == 1) {
-               con.connect(kdb);
-       }
-       else if (argc == 2) {
-               con.connect(kdb, argv[1]);
-       }
-       else if (argc == 3) {
-               con.connect(kdb, argv[1], argv[2]);
-       }
-       else if (argc >= 4) {
-               con.connect(kdb, argv[1], argv[2], argv[3]);
-       }
-
-       if (con) {
+       int ch;
+       const char* pass = "";     // 0 means something different!
+       const char* server = 0;
+       const char* user = 0;
+       while ((ch = att_getopt(argc, argv, "p:s:u:")) != EOF) {
+               switch (ch) {
+                       case 'p': pass = ag_optarg;   break;
+                       case 's': server = ag_optarg; break;
+                       case 'u': user = ag_optarg;   break;
+                       default:
+                               print_usage(argv[0], extra_parms);
+                               return false;
+               }
+       }
+
+       if (con.connect(kdb, server, user, pass)) {
                return true;
        }
        else {

Modified: trunk/examples/util.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/util.h?rev=1700&r1=1699&r2=1700&view=diff
==============================================================================
--- trunk/examples/util.h (original)
+++ trunk/examples/util.h Mon Jul 16 18:43:27 2007
@@ -43,7 +43,7 @@
 void print_usage(const char* program_name,
                const char* extra_parms = "");
 bool connect_to_db(int argc, char *argv[], mysqlpp::Connection& con,
-               const char* kdb = 0);
+               const char* kdb = 0, const char* extra_parms = "");
 
 #endif // !defined(MYSQLPP_UTIL_H)
 

Modified: trunk/mysql++.bkl
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/mysql%2B%2B.bkl?rev=1700&r1=1699&r2=1700&view=diff
==============================================================================
--- trunk/mysql++.bkl (original)
+++ trunk/mysql++.bkl Mon Jul 16 18:43:27 2007
@@ -189,6 +189,7 @@
                <lib id="util" template="examples">
                        <libname>mysqlpp_util</libname>
                        <sources>examples/util.cpp</sources>
+                       <sources>examples/att_getopt.cpp</sources>
                </lib>
                
                <!-- The examples themselves -->


_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits

Reply via email to