2323
2424#include < stdlib.h>
2525#include < stdio.h>
26- #include < getopt.h>
2726#include < errno.h>
2827#include < string.h>
2928#include < assert.h>
30- #include < glob.h>
3129
3230#include < iostream>
3331#include < fstream>
3432#include < sstream>
3533#include < vector>
3634#include < set>
3735
36+ #include " simpleopt.h"
37+ #include " simpleglob.h"
3838#include " importdata.h"
3939#include " common.h"
4040
@@ -330,6 +330,29 @@ ImportData::ImportData(bool temporary_table)
330330{
331331}
332332
333+ // ! define identifiers for command line arguments
334+ enum { OPT_HELP, OPT_VERBOSE,
335+ OPT_FIRSTLINE, OPT_ALL_LINES, OPT_NO_DUPLICATE,
336+ OPT_COLUMN_NUMBERS, OPT_EMPTY_OKAY,
337+ OPT_TEMPORARY_TABLE, OPT_PERMANENT_TABLE,
338+ OPT_DATABASE };
339+
340+ // ! define command line arguments
341+ static CSimpleOpt::SOption sopt_list[] = {
342+ { OPT_HELP, " -?" , SO_NONE },
343+ { OPT_HELP, " -h" , SO_NONE },
344+ { OPT_VERBOSE, " -v" , SO_NONE },
345+ { OPT_FIRSTLINE, " -1" , SO_NONE },
346+ { OPT_ALL_LINES, " -a" , SO_NONE },
347+ { OPT_NO_DUPLICATE, " -d" , SO_NONE },
348+ { OPT_COLUMN_NUMBERS, " -C" , SO_NONE },
349+ { OPT_EMPTY_OKAY, " -E" , SO_NONE },
350+ { OPT_TEMPORARY_TABLE, " -T" , SO_NONE },
351+ { OPT_PERMANENT_TABLE, " -P" , SO_NONE },
352+ { OPT_DATABASE, " -D" , SO_REQ_SEP },
353+ SO_END_OF_OPTIONS
354+ };
355+
333356// ! print command line usage
334357int ImportData::print_usage (const std::string& progname)
335358{
@@ -349,55 +372,68 @@ int ImportData::print_usage(const std::string& progname)
349372}
350373
351374// ! process command line arguments and data
352- int ImportData::main (int argc, char * const argv[])
375+ int ImportData::main (int argc, char * argv[])
353376{
354377 FieldSet::check_detect ();
355378
356- int save_optind = 1 ;
357- std::swap (optind, save_optind);
379+ // ! parse command line parameters using SimpleOpt
380+ CSimpleOpt args (argc, argv, sopt_list);
381+
382+ while (args.Next ())
383+ {
384+ if (args.LastError () != SO_SUCCESS) {
385+ OUT (argv[0 ] << " : invalid command line argument '" << args.OptionText () << " '" );
386+ return EXIT_FAILURE;
387+ }
358388
359- /* parse command line parameters */
360- int opt;
389+ switch (args.OptionId ())
390+ {
391+ case OPT_HELP: default :
392+ return print_usage (argv[0 ]);
361393
362- while ((opt = getopt (argc, argv, " h1avdCETPD:" )) != -1 ) {
363- switch (opt) {
364- case ' 1' :
394+ case OPT_FIRSTLINE:
365395 mopt_firstline = true ;
366396 break ;
367- case ' a' :
397+
398+ case OPT_ALL_LINES:
368399 mopt_all_lines = true ;
369400 break ;
370- case ' v' :
401+
402+ case OPT_VERBOSE:
371403 mopt_verbose++;
372404 break ;
373- case ' d' :
405+
406+ case OPT_NO_DUPLICATE:
374407 mopt_noduplicates = true ;
375408 break ;
376- case ' C' :
409+
410+ case OPT_COLUMN_NUMBERS:
377411 mopt_colnums = true ;
378412 break ;
379- case ' E' :
413+
414+ case OPT_EMPTY_OKAY:
380415 mopt_empty_okay = true ;
381416 break ;
382- case ' T' :
417+
418+ case OPT_TEMPORARY_TABLE:
383419 mopt_temporary_table = true ;
384420 break ;
385- case ' P' :
421+
422+ case OPT_PERMANENT_TABLE:
386423 mopt_temporary_table = false ;
387424 break ;
388- case ' D' :
389- gopt_db_connection = optarg;
425+
426+ case OPT_DATABASE:
427+ gopt_db_connection = args.OptionArg ();
390428 break ;
391- case ' h' : default :
392- return print_usage (argv[0 ]);
393429 }
394430 }
395431
396432 // no table name given
397- if (optind == argc )
433+ if (args. FileCount () == 0 )
398434 print_usage (argv[0 ]);
399435
400- m_tablename = argv[optind++] ;
436+ m_tablename = args. File ( 0 ) ;
401437
402438 // maybe connect to database
403439 bool opt_dbconnect = false ;
@@ -412,47 +448,41 @@ int ImportData::main(int argc, char* const argv[])
412448 g_db->execute (" BEGIN" );
413449
414450 // process file commandline arguments
415- if (optind < argc )
451+ if (args. FileCount () )
416452 {
417- while (optind < argc)
418- {
419- // glob() for matching file names
420- glob_t globbuf;
453+ // glob to expand wild cards in arguments
421454
422- int gflags = GLOB_TILDE | GLOB_BRACE ;
423- if (mopt_empty_okay) gflags |= GLOB_NOCHECK ;
455+ int gflags = SG_GLOB_TILDE | SG_GLOB_ONLYFILE ;
456+ if (mopt_empty_okay) gflags |= SG_GLOB_NOCHECK ;
424457
425- int gr = glob (argv[optind], gflags, NULL , &globbuf);
426- if (gr != 0 ) {
427- OUT_THROW (" Error globing " << argv[optind] << " : " << strerror (errno));
458+ CSimpleGlob glob (SG_GLOB_NODOT | SG_GLOB_NOCHECK);
459+ if (SG_SUCCESS != glob.Add (args.FileCount () - 1 , args.Files () + 1 )) {
460+ OUT_THROW (" Error while globbing files" );
461+ return EXIT_FAILURE;
462+ }
463+
464+ for (int fi = 0 ; fi < glob.FileCount (); ++fi)
465+ {
466+ const char * fname = glob.File (fi);
467+
468+ m_count = 0 ;
469+ std::ifstream in (fname);
470+ if (!in.good ()) {
471+ if (mopt_empty_okay)
472+ OUT (" Error reading " << fname << " : " << strerror (errno));
473+ else
474+ OUT_THROW (" Error reading " << fname << " : " << strerror (errno));
428475 }
476+ else {
477+ process_stream (in);
429478
430- for (size_t gi = 0 ; gi < globbuf.gl_pathc ; ++gi)
431- {
432- const char * fname = globbuf.gl_pathv [gi];
433-
434- m_count = 0 ;
435- std::ifstream in (fname);
436- if (!in.good ()) {
437- if (mopt_empty_okay)
438- OUT (" Error reading " << fname << " : " << strerror (errno));
439- else
440- OUT_THROW (" Error reading " << fname << " : " << strerror (errno));
479+ if (mopt_firstline) {
480+ OUT (" Imported " << m_count << " rows of data from " << fname);
441481 }
442482 else {
443- process_stream (in);
444-
445- if (mopt_firstline) {
446- OUT (" Imported " << m_count << " rows of data from " << fname);
447- }
448- else {
449- OUT (" Cached " << m_count << " rows of data from " << fname);
450- }
483+ OUT (" Cached " << m_count << " rows of data from " << fname);
451484 }
452485 }
453-
454- globfree (&globbuf);
455- ++optind;
456486 }
457487 }
458488 else // no file arguments -> process stdin
@@ -462,8 +492,6 @@ int ImportData::main(int argc, char* const argv[])
462492 process_stream (std::cin);
463493 }
464494
465- std::swap (optind, save_optind);
466-
467495 // process cached data lines
468496 if (!mopt_firstline)
469497 {
0 commit comments