510
514
static struct my_option my_long_options[] =
512
516
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
514
518
{"auto-generate-sql-select-columns", OPT_SLAP_AUTO_GENERATE_SELECT_COLUMNS,
515
"Provide a string to use for the select fields used in auto tests.",
516
(char**) &auto_generate_selected_columns_opt,
517
(char**) &auto_generate_selected_columns_opt,
518
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
519
"Provide a string to use for the select fields used in auto tests.",
520
(char**) &auto_generate_selected_columns_opt,
521
(char**) &auto_generate_selected_columns_opt,
522
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
519
523
{"auto-generate-sql", 'a',
520
"Generate SQL where not supplied by file or command line.",
521
(char**) &auto_generate_sql, (char**) &auto_generate_sql,
522
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
524
"Generate SQL where not supplied by file or command line.",
525
(char**) &auto_generate_sql, (char**) &auto_generate_sql,
526
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
523
527
{"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
524
"Add an AUTO_INCREMENT column to auto-generated tables.",
525
(char**) &auto_generate_sql_autoincrement,
526
(char**) &auto_generate_sql_autoincrement,
527
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
528
"Add an AUTO_INCREMENT column to auto-generated tables.",
529
(char**) &auto_generate_sql_autoincrement,
530
(char**) &auto_generate_sql_autoincrement,
531
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
528
532
{"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
529
"Set this number to generate a set number of queries to run.",
530
(char**) &auto_actual_queries, (char**) &auto_actual_queries,
531
0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
533
"Set this number to generate a set number of queries to run.",
534
(char**) &auto_actual_queries, (char**) &auto_actual_queries,
535
0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
532
536
{"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
533
"Add GUID based primary keys to auto-generated tables.",
534
(char**) &auto_generate_sql_guid_primary,
535
(char**) &auto_generate_sql_guid_primary,
536
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
537
"Add GUID based primary keys to auto-generated tables.",
538
(char**) &auto_generate_sql_guid_primary,
539
(char**) &auto_generate_sql_guid_primary,
540
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
537
541
{"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE,
538
"Specify test load type: mixed, update, write, key, or read; default is mixed.",
539
(char**) &opt_auto_generate_sql_type, (char**) &opt_auto_generate_sql_type,
540
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
541
{"auto-generate-sql-secondary-indexes",
542
OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES,
543
"Number of secondary indexes to add to auto-generated tables.",
544
(char**) &auto_generate_sql_secondary_indexes,
545
(char**) &auto_generate_sql_secondary_indexes, 0,
546
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
547
{"auto-generate-sql-unique-query-number",
548
OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
549
"Number of unique queries to generate for automatic tests.",
550
(char**) &auto_generate_sql_unique_query_number,
551
(char**) &auto_generate_sql_unique_query_number,
552
0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
553
{"auto-generate-sql-unique-write-number",
554
OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
555
"Number of unique queries to generate for auto-generate-sql-write-number.",
556
(char**) &auto_generate_sql_unique_write_number,
557
(char**) &auto_generate_sql_unique_write_number,
558
0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
542
"Specify test load type: mixed, update, write, key, or read; default is mixed.",
543
(char**) &opt_auto_generate_sql_type, (char**) &opt_auto_generate_sql_type,
544
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
545
{"auto-generate-sql-secondary-indexes",
546
OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES,
547
"Number of secondary indexes to add to auto-generated tables.",
548
(char**) &auto_generate_sql_secondary_indexes,
549
(char**) &auto_generate_sql_secondary_indexes, 0,
550
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
551
{"auto-generate-sql-unique-query-number",
552
OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
553
"Number of unique queries to generate for automatic tests.",
554
(char**) &auto_generate_sql_unique_query_number,
555
(char**) &auto_generate_sql_unique_query_number,
556
0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
557
{"auto-generate-sql-unique-write-number",
558
OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
559
"Number of unique queries to generate for auto-generate-sql-write-number.",
560
(char**) &auto_generate_sql_unique_write_number,
561
(char**) &auto_generate_sql_unique_write_number,
562
0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
559
563
{"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
560
"Number of row inserts to perform for each thread (default is 100).",
561
(char**) &auto_generate_sql_number, (char**) &auto_generate_sql_number,
562
0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0},
564
"Number of row inserts to perform for each thread (default is 100).",
565
(char**) &auto_generate_sql_number, (char**) &auto_generate_sql_number,
566
0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0},
563
567
{"burnin", OPT_SLAP_BURNIN, "Run full test case in infinite loop.",
564
(char**) &opt_burnin, (char**) &opt_burnin, 0, GET_BOOL, NO_ARG, 0, 0, 0,
566
{"ignore-sql-errors", OPT_SLAP_IGNORE_SQL_ERRORS,
567
"Ignore SQL erros in query run.",
568
(char**) &opt_ignore_sql_errors,
569
(char**) &opt_ignore_sql_errors,
570
0, GET_BOOL, NO_ARG, 0, 0, 0,
568
(char**) &opt_burnin, (char**) &opt_burnin, 0, GET_BOOL, NO_ARG, 0, 0, 0,
570
{"ignore-sql-errors", OPT_SLAP_IGNORE_SQL_ERRORS,
571
"Ignore SQL erros in query run.",
572
(char**) &opt_ignore_sql_errors,
573
(char**) &opt_ignore_sql_errors,
574
0, GET_BOOL, NO_ARG, 0, 0, 0,
572
576
{"commit", OPT_SLAP_COMMIT, "Commit records every X number of statements.",
573
(char**) &commit_rate, (char**) &commit_rate, 0, GET_UINT, REQUIRED_ARG,
577
(char**) &commit_rate, (char**) &commit_rate, 0, GET_UINT, REQUIRED_ARG,
575
579
{"compress", 'C', "Use compression in server/client protocol.",
576
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
580
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
578
582
{"concurrency", 'c', "Number of clients to simulate for query to run.",
579
(char**) &concurrency_str, (char**) &concurrency_str, 0, GET_STR,
580
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
583
(char**) &concurrency_str, (char**) &concurrency_str, 0, GET_STR,
584
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
581
585
{"create", OPT_SLAP_CREATE_STRING, "File or string to use create tables.",
582
(char**) &create_string, (char**) &create_string, 0, GET_STR, REQUIRED_ARG,
586
(char**) &create_string, (char**) &create_string, 0, GET_STR, REQUIRED_ARG,
584
588
{"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
585
(char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR,
586
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
589
(char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR,
590
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
587
591
{"csv", OPT_SLAP_CSV,
588
"Generate CSV output to named file or to stdout if no file is named.",
589
(char**) &opt_csv_str, (char**) &opt_csv_str, 0, GET_STR,
590
OPT_ARG, 0, 0, 0, 0, 0, 0},
592
"Generate CSV output to named file or to stdout if no file is named.",
593
(char**) &opt_csv_str, (char**) &opt_csv_str, 0, GET_STR,
594
OPT_ARG, 0, 0, 0, 0, 0, 0},
591
595
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
592
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
593
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
596
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
597
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
594
598
{"debug-info", 'T', "Print some debug info at exit.", (char**) &debug_info_flag,
595
(char**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
596
{"delayed-start", OPT_SLAP_DELAYED_START,
597
"Delay the startup of threads by a random number of microsends (the maximum of the delay)",
598
(char**) &opt_delayed_start, (char**) &opt_delayed_start, 0, GET_UINT,
599
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
599
(char**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
600
{"delayed-start", OPT_SLAP_DELAYED_START,
601
"Delay the startup of threads by a random number of microsends (the maximum of the delay)",
602
(char**) &opt_delayed_start, (char**) &opt_delayed_start, 0, GET_UINT,
603
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
600
604
{"delimiter", 'F',
601
"Delimiter to use in SQL statements supplied in file or command line.",
602
(char**) &delimiter, (char**) &delimiter, 0, GET_STR, REQUIRED_ARG,
605
"Delimiter to use in SQL statements supplied in file or command line.",
606
(char**) &delimiter, (char**) &delimiter, 0, GET_STR, REQUIRED_ARG,
604
608
{"detach", OPT_SLAP_DETACH,
605
"Detach (close and reopen) connections after X number of requests.",
606
(char**) &detach_rate, (char**) &detach_rate, 0, GET_UINT, REQUIRED_ARG,
609
"Detach (close and reopen) connections after X number of requests.",
610
(char**) &detach_rate, (char**) &detach_rate, 0, GET_UINT, REQUIRED_ARG,
608
612
{"engine", 'e', "Storage engine to use for creating the table.",
609
(char**) &default_engine, (char**) &default_engine, 0,
610
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
613
(char**) &default_engine, (char**) &default_engine, 0,
614
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
611
615
{"host", 'h', "Connect to host.", (char**) &host, (char**) &host, 0, GET_STR,
612
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
616
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
613
617
{"iterations", 'i', "Number of times to run the tests.", (char**) &iterations,
614
(char**) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
618
(char**) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
615
619
{"label", OPT_SLAP_LABEL, "Label to use for print and csv output.",
616
(char**) &opt_label, (char**) &opt_label, 0,
617
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
618
{"number-blob-cols", OPT_SLAP_BLOB_COL,
619
"Number of BLOB columns to create table with if specifying --auto-generate-sql. Example --number-blob-cols=3:1024/2048 would give you 3 blobs with a random size between 1024 and 2048. ",
620
(char**) &num_blob_cols_opt, (char**) &num_blob_cols_opt, 0, GET_STR, REQUIRED_ARG,
622
{"number-char-cols", 'x',
623
"Number of VARCHAR columns to create in table if specifying --auto-generate-sql.",
624
(char**) &num_char_cols_opt, (char**) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
626
{"number-int-cols", 'y',
627
"Number of INT columns to create in table if specifying --auto-generate-sql.",
628
(char**) &num_int_cols_opt, (char**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG,
630
{"number-of-queries", OPT_DRIZZLE_NUMBER_OF_QUERY,
631
"Limit each client to this number of queries (this is not exact).",
632
(char**) &num_of_query, (char**) &num_of_query, 0,
633
GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
634
{"only-print", OPT_DRIZZLE_ONLY_PRINT,
635
"This causes drizzleslap to not connect to the databases, but instead print "
636
"out what it would have done instead.",
637
(char**) &opt_only_print, (char**) &opt_only_print, 0, GET_BOOL, NO_ARG,
620
(char**) &opt_label, (char**) &opt_label, 0,
621
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
622
{"number-blob-cols", OPT_SLAP_BLOB_COL,
623
"Number of BLOB columns to create table with if specifying --auto-generate-sql. Example --number-blob-cols=3:1024/2048 would give you 3 blobs with a random size between 1024 and 2048. ",
624
(char**) &num_blob_cols_opt, (char**) &num_blob_cols_opt, 0, GET_STR, REQUIRED_ARG,
626
{"number-char-cols", 'x',
627
"Number of VARCHAR columns to create in table if specifying --auto-generate-sql.",
628
(char**) &num_char_cols_opt, (char**) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
630
{"number-int-cols", 'y',
631
"Number of INT columns to create in table if specifying --auto-generate-sql.",
632
(char**) &num_int_cols_opt, (char**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG,
634
{"number-of-queries", OPT_MYSQL_NUMBER_OF_QUERY,
635
"Limit each client to this number of queries (this is not exact).",
636
(char**) &num_of_query, (char**) &num_of_query, 0,
637
GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
638
{"only-print", OPT_MYSQL_ONLY_PRINT,
639
"This causes mysqlslap to not connect to the databases, but instead print "
640
"out what it would have done instead.",
641
(char**) &opt_only_print, (char**) &opt_only_print, 0, GET_BOOL, NO_ARG,
639
643
{"password", 'p',
640
"Password to use when connecting to server. If password is not given it's "
641
"asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
642
{"port", 'P', "Port number to use for connection.", (char**) &opt_drizzle_port,
643
(char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
644
"Password to use when connecting to server. If password is not given it's "
645
"asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
646
{"port", 'P', "Port number to use for connection.", (char**) &opt_mysql_port,
647
(char**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
645
649
{"post-query", OPT_SLAP_POST_QUERY,
646
"Query to run or file containing query to execute after tests have completed.",
647
(char**) &user_supplied_post_statements,
648
(char**) &user_supplied_post_statements,
649
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
650
"Query to run or file containing query to execute after tests have completed.",
651
(char**) &user_supplied_post_statements,
652
(char**) &user_supplied_post_statements,
653
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
650
654
{"post-system", OPT_SLAP_POST_SYSTEM,
651
"system() string to execute after tests have completed.",
652
(char**) &post_system,
653
(char**) &post_system,
654
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
655
{"pre-query", OPT_SLAP_PRE_QUERY,
656
"Query to run or file containing query to execute before running tests.",
657
(char**) &user_supplied_pre_statements,
658
(char**) &user_supplied_pre_statements,
659
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
660
{"pre-system", OPT_SLAP_PRE_SYSTEM,
661
"system() string to execute before running tests.",
662
(char**) &pre_system,
663
(char**) &pre_system,
664
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
665
{"protocol", OPT_DRIZZLE_PROTOCOL,
666
"The protocol of connection (tcp,socket,pipe,memory).",
667
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
655
"system() string to execute after tests have completed.",
656
(char**) &post_system,
657
(char**) &post_system,
658
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
659
{"pre-query", OPT_SLAP_PRE_QUERY,
660
"Query to run or file containing query to execute before running tests.",
661
(char**) &user_supplied_pre_statements,
662
(char**) &user_supplied_pre_statements,
663
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
664
{"pre-system", OPT_SLAP_PRE_SYSTEM,
665
"system() string to execute before running tests.",
666
(char**) &pre_system,
667
(char**) &pre_system,
668
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
669
{"protocol", OPT_MYSQL_PROTOCOL,
670
"The protocol of connection (tcp,socket,pipe,memory).",
671
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
668
672
{"query", 'q', "Query to run or file containing query to run.",
669
(char**) &user_supplied_query, (char**) &user_supplied_query,
670
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
671
{"set-random-seed", OPT_SLAP_SET_RANDOM_SEED,
672
"Seed for random number generator (srandom(3))",
673
(char**)&opt_set_random_seed,
674
(char**)&opt_set_random_seed,0,
675
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
673
(char**) &user_supplied_query, (char**) &user_supplied_query,
674
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
675
{"set-random-seed", OPT_SLAP_SET_RANDOM_SEED,
676
"Seed for random number generator (srandom(3))",
677
(char**)&opt_set_random_seed,
678
(char**)&opt_set_random_seed,0,
679
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
681
{"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
682
"Base name of shared memory.", (char**) &shared_memory_base_name,
683
(char**) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG,
676
686
{"silent", 's', "Run program in silent mode - no output.",
677
(char**) &opt_silent, (char**) &opt_silent, 0, GET_BOOL, NO_ARG,
687
(char**) &opt_silent, (char**) &opt_silent, 0, GET_BOOL, NO_ARG,
679
689
{"socket", 'S', "Socket file to use for connection.",
680
(char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
681
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
682
{"timer-length", OPT_SLAP_TIMER_LENGTH,
683
"Require drizzleslap to run each specific test a certain amount of time in seconds.",
684
(char**) &opt_timer_length, (char**) &opt_timer_length, 0, GET_UINT,
685
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
690
(char**) &opt_mysql_unix_port, (char**) &opt_mysql_unix_port, 0, GET_STR,
691
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
692
{"timer-length", OPT_SLAP_TIMER_LENGTH,
693
"Require mysqlslap to run each specific test a certain amount of time in seconds.",
694
(char**) &opt_timer_length, (char**) &opt_timer_length, 0, GET_UINT,
695
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
686
696
#ifndef DONT_ALLOW_USER_CHANGE
687
697
{"user", 'u', "User for login if not current user.", (char**) &user,
688
(char**) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
698
(char**) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
691
"More verbose output; you can use this multiple times to get even more "
692
"verbose output.", (char**) &verbose, (char**) &verbose, 0,
693
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
701
"More verbose output; you can use this multiple times to get even more "
702
"verbose output.", (char**) &verbose, (char**) &verbose, 0,
703
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
694
704
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
695
NO_ARG, 0, 0, 0, 0, 0, 0},
705
NO_ARG, 0, 0, 0, 0, 0, 0},
696
706
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
710
#include <help_start.h>
700
712
static void print_version(void)
702
714
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname, SLAP_VERSION,
703
drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
715
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
707
719
static void usage(void)
710
puts("Copyright (C) 2005 DRIZZLE AB");
722
puts("Copyright (C) 2005 MySQL AB");
711
723
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
712
724
\nand you are welcome to modify and redistribute it under the GPL \