From 54e47cf729721dba20f2de58fce9bd9091c47d00 Mon Sep 17 00:00:00 2001 From: "Julian M. Kunkel" Date: Sat, 14 Jul 2018 08:41:35 +0100 Subject: [PATCH] IOR: use new option parser. TODO: Parse "-O" options --- src/Makefile.am | 6 +- src/aiori-DUMMY.c | 6 +- src/aiori-MMAP.c | 2 +- src/aiori-MPIIO.c | 19 +- src/aiori-NCMPI.c | 6 +- src/aiori-POSIX.c | 2 +- src/aiori-RADOS.c | 9 +- src/aiori-S3.c | 44 +-- src/aiori.c | 6 +- src/aiori.h | 4 +- src/getopt/COPYING | 674 -------------------------------------- src/getopt/COPYING.LESSER | 165 ---------- src/getopt/README | 82 ----- src/getopt/optlist.c | 290 ---------------- src/getopt/optlist.h | 71 ---- src/getopt/sample.c | 103 ------ src/ior-output.c | 5 +- src/ior.c | 171 +++------- src/ior.h | 28 +- src/mdtest.c | 4 +- src/option.c | 77 ++++- src/option.h | 7 +- src/parse_options.c | 403 ++++++++--------------- 23 files changed, 303 insertions(+), 1881 deletions(-) delete mode 100644 src/getopt/COPYING delete mode 100644 src/getopt/COPYING.LESSER delete mode 100644 src/getopt/README delete mode 100644 src/getopt/optlist.c delete mode 100644 src/getopt/optlist.h delete mode 100644 src/getopt/sample.c diff --git a/src/Makefile.am b/src/Makefile.am index 447b9b9..9c27d89 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,19 +3,19 @@ if USE_CAPS bin_PROGRAMS += IOR MDTEST endif -noinst_HEADERS = ior.h utilities.h parse_options.h aiori.h iordef.h getopt/optlist.h ior-internal.h option.h +noinst_HEADERS = ior.h utilities.h parse_options.h aiori.h iordef.h ior-internal.h option.h extraSOURCES = aiori.c aiori-DUMMY.c extraLDADD = extraLDFLAGS = extraCPPFLAGS = -ior_SOURCES = ior-main.c ior.c utilities.c parse_options.c getopt/optlist.c ior-output.c option.c +ior_SOURCES = ior-main.c ior.c utilities.c parse_options.c ior-output.c option.c ior_LDFLAGS = ior_LDADD = ior_CPPFLAGS = -mdtest_SOURCES = mdtest-main.c mdtest.c utilities.c getopt/optlist.c option.c +mdtest_SOURCES = mdtest-main.c mdtest.c utilities.c option.c mdtest_LDFLAGS = mdtest_LDADD = mdtest_CPPFLAGS = diff --git a/src/aiori-DUMMY.c b/src/aiori-DUMMY.c index 511a97c..660a16b 100755 --- a/src/aiori-DUMMY.c +++ b/src/aiori-DUMMY.c @@ -80,9 +80,9 @@ static void DUMMY_Delete(char *testFileName, IOR_param_t * param) } } -static void DUMMY_SetVersion(IOR_param_t * test) +static char * DUMMY_getVersion() { - sprintf(test->apiVersion, "DUMMY-0.5"); + return "0.5"; } static IOR_offset_t DUMMY_GetFileSize(IOR_param_t * test, MPI_Comm testComm, char *testFileName) @@ -136,7 +136,7 @@ ior_aiori_t dummy_aiori = { DUMMY_Xfer, DUMMY_Close, DUMMY_Delete, - DUMMY_SetVersion, + DUMMY_getVersion, DUMMY_Fsync, DUMMY_GetFileSize, DUMMY_statfs, diff --git a/src/aiori-MMAP.c b/src/aiori-MMAP.c index ac622ff..f812bdd 100644 --- a/src/aiori-MMAP.c +++ b/src/aiori-MMAP.c @@ -42,7 +42,7 @@ ior_aiori_t mmap_aiori = { .xfer = MMAP_Xfer, .close = MMAP_Close, .delete = POSIX_Delete, - .set_version = aiori_set_version, + .get_version = aiori_get_version, .fsync = MMAP_Fsync, .get_file_size = POSIX_GetFileSize, }; diff --git a/src/aiori-MPIIO.c b/src/aiori-MPIIO.c index 7405ca5..d218b18 100755 --- a/src/aiori-MPIIO.c +++ b/src/aiori-MPIIO.c @@ -38,7 +38,7 @@ static void *MPIIO_Open(char *, IOR_param_t *); static IOR_offset_t MPIIO_Xfer(int, void *, IOR_size_t *, IOR_offset_t, IOR_param_t *); static void MPIIO_Close(void *, IOR_param_t *); -static void MPIIO_SetVersion(IOR_param_t *); +static char* MPIIO_GetVersion(); static void MPIIO_Fsync(void *, IOR_param_t *); @@ -51,7 +51,7 @@ ior_aiori_t mpiio_aiori = { .xfer = MPIIO_Xfer, .close = MPIIO_Close, .delete = MPIIO_Delete, - .set_version = MPIIO_SetVersion, + .get_version = MPIIO_GetVersion, .fsync = MPIIO_Fsync, .get_file_size = MPIIO_GetFileSize, .statfs = aiori_posix_statfs, @@ -411,13 +411,16 @@ void MPIIO_Delete(char *testFileName, IOR_param_t * param) /* * Determine api version. */ -static void MPIIO_SetVersion(IOR_param_t * test) +static char* MPIIO_GetVersion() { - int version, subversion; - MPI_CHECK(MPI_Get_version(&version, &subversion), - "cannot get MPI version"); - sprintf(test->apiVersion, "%s (version=%d, subversion=%d)", - test->api, version, subversion); + static char ver[1024] = {}; + if (ver){ + return ver; + } + int version, subversion; + MPI_CHECK(MPI_Get_version(&version, &subversion), "cannot get MPI version"); + sprintf(ver, "(%d.%d)", version, subversion); + return ver; } /* diff --git a/src/aiori-NCMPI.c b/src/aiori-NCMPI.c index d990dfd..42ee19e 100755 --- a/src/aiori-NCMPI.c +++ b/src/aiori-NCMPI.c @@ -67,7 +67,7 @@ ior_aiori_t ncmpi_aiori = { .xfer = NCMPI_Xfer, .close = NCMPI_Close, .delete = NCMPI_Delete, - .set_version = NCMPI_SetVersion, + .get_version = NCMPI_GetVersion, .fsync = NCMPI_Fsync, .get_file_size = NCMPI_GetFileSize, .statfs = aiori_posix_statfs, @@ -341,9 +341,9 @@ static void NCMPI_Delete(char *testFileName, IOR_param_t * param) /* * Determine api version. */ -static void NCMPI_SetVersion(IOR_param_t * test) +static char* NCMPI_GetVersion() { - sprintf(test->apiVersion, "%s (%s)", test->api, ncmpi_inq_libvers()); + return ncmpi_inq_libvers(); } /* diff --git a/src/aiori-POSIX.c b/src/aiori-POSIX.c index 24d1d45..9e740a6 100755 --- a/src/aiori-POSIX.c +++ b/src/aiori-POSIX.c @@ -78,7 +78,7 @@ ior_aiori_t posix_aiori = { .xfer = POSIX_Xfer, .close = POSIX_Close, .delete = POSIX_Delete, - .set_version = aiori_set_version, + .get_version = aiori_get_version, .fsync = POSIX_Fsync, .get_file_size = POSIX_GetFileSize, .statfs = aiori_posix_statfs, diff --git a/src/aiori-RADOS.c b/src/aiori-RADOS.c index a1f51c1..da27dec 100755 --- a/src/aiori-RADOS.c +++ b/src/aiori-RADOS.c @@ -49,7 +49,6 @@ static IOR_offset_t RADOS_Xfer(int, void *, IOR_size_t *, IOR_offset_t, IOR_param_t *); static void RADOS_Close(void *, IOR_param_t *); static void RADOS_Delete(char *, IOR_param_t *); -static void RADOS_SetVersion(IOR_param_t *); static void RADOS_Fsync(void *, IOR_param_t *); static IOR_offset_t RADOS_GetFileSize(IOR_param_t *, MPI_Comm, char *); static int RADOS_StatFS(const char *, ior_aiori_statfs_t *, IOR_param_t *); @@ -67,7 +66,7 @@ ior_aiori_t rados_aiori = { .xfer = RADOS_Xfer, .close = RADOS_Close, .delete = RADOS_Delete, - .set_version = RADOS_SetVersion, + .get_version = aiori_get_version, .fsync = RADOS_Fsync, .get_file_size = RADOS_GetFileSize, .statfs = RADOS_StatFS, @@ -257,12 +256,6 @@ static void RADOS_Delete(char *testFileName, IOR_param_t * param) return; } -static void RADOS_SetVersion(IOR_param_t * test) -{ - strcpy(test->apiVersion, test->api); - return; -} - static IOR_offset_t RADOS_GetFileSize(IOR_param_t * test, MPI_Comm testComm, char *testFileName) { diff --git a/src/aiori-S3.c b/src/aiori-S3.c index 08a4f75..7e45711 100755 --- a/src/aiori-S3.c +++ b/src/aiori-S3.c @@ -122,7 +122,6 @@ static IOR_offset_t EMC_Xfer(int, void*, IOR_size_t*, IOR_offset_t, IOR_param_t* static void EMC_Close(void*, IOR_param_t*); static void S3_Delete(char*, IOR_param_t*); -static void S3_SetVersion(IOR_param_t*); static void S3_Fsync(void*, IOR_param_t*); static IOR_offset_t S3_GetFileSize(IOR_param_t*, MPI_Comm, char*); @@ -138,7 +137,7 @@ ior_aiori_t s3_aiori = { .xfer = S3_Xfer, .close = S3_Close, .delete = S3_Delete, - .set_version = S3_SetVersion, + .get_version = aiori_get_version, .fsync = S3_Fsync, .get_file_size = S3_GetFileSize, }; @@ -183,7 +182,7 @@ ior_aiori_t s3_emc_aiori = { fflush(stdout); \ MPI_Abort((PARAM)->testComm, -1); \ } while (0) - + #define CURL_WARN(MSG, CURL_ERRNO) \ do { \ @@ -192,7 +191,7 @@ ior_aiori_t s3_emc_aiori = { __FILE__, __LINE__); \ fflush(stdout); \ } while (0) - + /* buffer is used to generate URLs, err_msgs, etc */ @@ -446,7 +445,7 @@ S3_Create_Or_Open_internal(char* testFileName, if ( n_to_n || (rank == 0) ) { // rank0 handles truncate - if ( needs_reset) { + if ( needs_reset) { aws_iobuf_reset(param->io_buf); AWS4C_CHECK( s3_put(param->io_buf, testFileName) ); /* 0-length write */ AWS4C_CHECK_OK( param->io_buf ); @@ -510,7 +509,7 @@ S3_Create_Or_Open_internal(char* testFileName, fprintf( stdout, "rank %d resetting\n", rank); } - + aws_iobuf_reset(param->io_buf); AWS4C_CHECK( s3_put(param->io_buf, testFileName) ); AWS4C_CHECK_OK( param->io_buf ); @@ -641,7 +640,7 @@ EMC_Open( char *testFileName, IOR_param_t * param ) { /* In the EMC case, instead of Multi-Part Upload we can use HTTP * "byte-range" headers to write parts of a single object. This appears to * have several advantages over the S3 MPU spec: - * + * * (a) no need for a special "open" operation, to capture an "UploadID". * Instead we simply write byte-ranges, and the server-side resolves * any races, producing a single winner. In the IOR case, there should @@ -808,7 +807,7 @@ S3_Xfer_internal(int access, printf("rank %d: part %d = ETag %s\n", rank, part_number, param->io_buf->eTag); } - // drop ptrs to , in param->io_buf + // drop ptrs to , in param->io_buf aws_iobuf_reset(param->io_buf); } else { // use EMC's byte-range write-support, instead of MPU @@ -830,7 +829,7 @@ S3_Xfer_internal(int access, AWS4C_CHECK ( s3_put(param->io_buf, file) ); AWS4C_CHECK_OK( param->io_buf ); - // drop ptrs to , in param->io_buf + // drop ptrs to , in param->io_buf aws_iobuf_reset(param->io_buf); } @@ -867,7 +866,7 @@ S3_Xfer_internal(int access, ERR_SIMPLE(buff); } - // drop refs to , in param->io_buf + // drop refs to , in param->io_buf aws_iobuf_reset(param->io_buf); } @@ -1126,7 +1125,7 @@ S3_Close_internal( void* fd, start_multiplier = ETAG_SIZE; /* one ETag */ stride = etag_data_size; /* one rank's-worth of Etag data */ } - + xml = aws_iobuf_new(); aws_iobuf_growth_size(xml, 1024 * 8); @@ -1305,7 +1304,7 @@ S3_Delete( char *testFileName, IOR_param_t * param ) { #if 0 // EMC BUG: If file was written with appends, and is deleted, // Then any future recreation will result in an object that can't be read. - // this + // this AWS4C_CHECK( s3_delete(param->io_buf, testFileName) ); #else // just replace with a zero-length object for now @@ -1334,7 +1333,7 @@ EMC_Delete( char *testFileName, IOR_param_t * param ) { #if 0 // EMC BUG: If file was written with appends, and is deleted, // Then any future recreation will result in an object that can't be read. - // this + // this AWS4C_CHECK( s3_delete(param->io_buf, testFileName) ); #else // just replace with a zero-length object for now @@ -1353,25 +1352,6 @@ EMC_Delete( char *testFileName, IOR_param_t * param ) { - -/* - * Determine API version. - */ - -static -void -S3_SetVersion( IOR_param_t * param ) { - if (param->verbose >= VERBOSE_2) { - printf("-> S3_SetVersion\n"); - } - - strcpy( param->apiVersion, param->api ); - - if (param->verbose >= VERBOSE_2) { - printf("<- S3_SetVersion\n"); - } -} - /* * HTTP HEAD returns meta-data for a "file". * diff --git a/src/aiori.c b/src/aiori.c index 8e3319e..2816bc1 100644 --- a/src/aiori.c +++ b/src/aiori.c @@ -112,13 +112,11 @@ int aiori_posix_stat (const char *path, struct stat *buf, IOR_param_t * param) return stat (path, buf); } -void aiori_set_version(IOR_param_t * test) +char* aiori_get_version() { - strcpy(test->apiVersion, test->api); + return ""; } - - const ior_aiori_t *aiori_select (const char *api) { char warn_str[256] = {0}; diff --git a/src/aiori.h b/src/aiori.h index c815a9b..afb763f 100755 --- a/src/aiori.h +++ b/src/aiori.h @@ -71,7 +71,7 @@ typedef struct ior_aiori { IOR_offset_t, IOR_param_t *); void (*close)(void *, IOR_param_t *); void (*delete)(char *, IOR_param_t *); - void (*set_version)(IOR_param_t *); + char* (*get_version)(); void (*fsync)(void *, IOR_param_t *); IOR_offset_t (*get_file_size)(IOR_param_t *, MPI_Comm, char *); int (*statfs) (const char *, ior_aiori_statfs_t *, IOR_param_t * param); @@ -99,7 +99,7 @@ int aiori_count (void); const char *aiori_default (void); /* some generic POSIX-based backend calls */ -void aiori_set_version(IOR_param_t * test); +char * aiori_get_version(); int aiori_posix_statfs (const char *path, ior_aiori_statfs_t *stat_buf, IOR_param_t * param); int aiori_posix_mkdir (const char *path, mode_t mode, IOR_param_t * param); int aiori_posix_rmdir (const char *path, IOR_param_t * param); diff --git a/src/getopt/COPYING b/src/getopt/COPYING deleted file mode 100644 index 94a9ed0..0000000 --- a/src/getopt/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/src/getopt/COPYING.LESSER b/src/getopt/COPYING.LESSER deleted file mode 100644 index fc8a5de..0000000 --- a/src/getopt/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/src/getopt/README b/src/getopt/README deleted file mode 100644 index 662c082..0000000 --- a/src/getopt/README +++ /dev/null @@ -1,82 +0,0 @@ -DESCRIPTION ------------ -This archive contains the source code and supporting documentation for OptList, -an ANSI C command line option parser library. - -OptList is released under the GNU LGPL version 3.0. - -The latest revision of this program may be found at: -http://michael.dipperstein.com/optlist.html - -FILES ------ -COPYING - Rules for copying and distributing GNU GPL software -COPYING.LESSER - Rules for copying and distributing GNU LGPL software -optlist.c - Source code for the Optlist function and supporting - function. -optlist.h - Header file to be included by code using OptList -Makefile - Makefile for this project (assumes gcc compiler and GNU make) -README - This file -sample.c - A small program demonstrating how to use OptList - -BUILDING --------- -To build these files with GNU make and gcc: -1. Windows users should define the environment variable OS to be Windows or - Windows_NT. This is often already done. -2. Enter the command "make" from the command line. - -USAGE ------ -The file sample.c demonstrates the usage of OptList. - -SYNOPSIS -typedef struct option_t -{ - char option; - char *argument; - int argIndex; - struct option_t *next; -} option_t; - -option_t *GetOptList(int argc, char *const argv[], char *const options); - - -DESCRIPTION -The GetOptList() function is similar to getopt(). Its most notable differences -are that it returns a linked list to the command line arguments and their -parameters. One call to GetOptList() will return all of the command line -options and their arguments. GetOptList() will not modify argc or argv. - -GetOptList()'s parameters "argc" and "argv" are the argument count and array as -passed to the main() function on program invocation. An element of argv that -starts with "-" is an option element. The character following the "-" is option -an character. - -The parameter "options" is a string containing the legitimate option characters. -If such a character is followed by a colon, the option requires an argument. -(e.g. "a:bc?" a, b ,c, and, ? are all options. a should be followed by an -argument.) - -GetOptList() returns a linked list of type option_t. The "*next" field of the -element at the end of the list will be set to NULL. The "option" field will -contain the option character. A pointer to the following text in the same -argv-element, or the text of the following argv-element will be stored in the -"arguement" field, otherwise the "arguement" field is set to NULL. The index -of the argv-element containing the argument will be stored in the "argIndex". -If there is no argument, the field will contain OL_NOINDEX. - -HISTORY -------- -08/01/07 - Initial release -09/13/14 - Added FindFileName function, because I always use it with GetOptList - Tighter adherence to Michael Barr's "Top 10 Bug-Killing Coding - Standard Rules" (http://www.barrgroup.com/webinars/10rules). - -TODO ----- -- Add support for --option_name - -AUTHOR ------- -Michael Dipperstein (mdipper@alumni.engr.ucsb.edu) diff --git a/src/getopt/optlist.c b/src/getopt/optlist.c deleted file mode 100644 index 544855b..0000000 --- a/src/getopt/optlist.c +++ /dev/null @@ -1,290 +0,0 @@ -/*************************************************************************** -* Command Line Option Parser -* -* File : optlist.c -* Purpose : Provide getopt style command line option parsing -* Author : Michael Dipperstein -* Date : August 1, 2007 -* -**************************************************************************** -* -* OptList: A command line option parsing library -* Copyright (C) 2007, 2014 by -* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu) -* -* This file is part of the OptList library. -* -* OptList is free software; you can redistribute it and/or modify it -* under the terms of the GNU Lesser General Public License as published by -* the Free Software Foundation; either version 3 of the License, or (at -* your option) any later version. -* -* OptList is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -* General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this program. If not, see . -* -***************************************************************************/ - -/*************************************************************************** -* INCLUDED FILES -***************************************************************************/ -#include "optlist.h" -#include -#include -#include - -/*************************************************************************** -* TYPE DEFINITIONS -***************************************************************************/ - -/*************************************************************************** -* CONSTANTS -***************************************************************************/ - -/*************************************************************************** -* GLOBAL VARIABLES -***************************************************************************/ - -/*************************************************************************** -* PROTOTYPES -***************************************************************************/ -static option_t *MakeOpt( - const char option, char *const argument, const int index); - -static size_t MatchOpt( - const char argument, char *const options); - -/*************************************************************************** -* FUNCTIONS -***************************************************************************/ - -/**************************************************************************** -* Function : GetOptList -* Description: This function is similar to the POSIX function getopt. All -* options and their corresponding arguments are returned in a -* linked list. This function should only be called once per -* an option list and it does not modify argv or argc. -* Parameters : argc - the number of command line arguments (including the -* name of the executable) -* argv - pointer to the open binary file to write encoded -* output -* options - getopt style option list. A NULL terminated -* string of single character options. Follow an -* option with a colon to indicate that it requires -* an argument. -* Effects : Creates a link list of command line options and their -* arguments. -* Returned : option_t type value where the option and arguement fields -* contain the next option symbol and its argument (if any). -* The argument field will be set to NULL if the option is -* specified as having no arguments or no arguments are found. -* The option field will be set to PO_NO_OPT if no more -* options are found. -* -* NOTE: The caller is responsible for freeing up the option list when it -* is no longer needed. -****************************************************************************/ -option_t *GetOptList(const int argc, char *const argv[], char *const options) -{ - int nextArg; - option_t *head, *tail; - size_t optIndex; - size_t argIndex; - - /* start with first argument and nothing found */ - nextArg = 1; - head = NULL; - tail = NULL; - - /* loop through all of the command line arguments */ - while (nextArg < argc) - { - argIndex = 1; - - while ((strlen(argv[nextArg]) > argIndex) && ('-' == argv[nextArg][0])) - { - /* attempt to find a matching option */ - optIndex = MatchOpt(argv[nextArg][argIndex], options); - - if (options[optIndex] == argv[nextArg][argIndex]) - { - /* we found the matching option */ - if (NULL == head) - { - head = MakeOpt(options[optIndex], NULL, OL_NOINDEX); - tail = head; - } - else - { - tail->next = MakeOpt(options[optIndex], NULL, OL_NOINDEX); - tail = tail->next; - } - - if (':' == options[optIndex + 1]) - { - /* the option found should have a text arguement */ - argIndex++; - - if (strlen(argv[nextArg]) > argIndex) - { - /* no space between argument and option */ - tail->argument = &(argv[nextArg][argIndex]); - tail->argIndex = nextArg; - } - else if (nextArg < argc) - { - /* there must be space between the argument option */ - nextArg++; - tail->argument = argv[nextArg]; - tail->argIndex = nextArg; - } - - break; /* done with argv[nextArg] */ - } - } - - argIndex++; - } - - nextArg++; - } - - return head; -} - -/**************************************************************************** -* Function : MakeOpt -* Description: This function uses malloc to allocate space for an option_t -* type structure and initailizes the structure with the -* values passed as a parameter. -* Parameters : option - this option character -* argument - pointer string containg the argument for option. -* Use NULL for no argument -* index - argv[index] contains argument use OL_NOINDEX for -* no argument -* Effects : A new option_t type variable is created on the heap. -* Returned : Pointer to newly created and initialized option_t type -* structure. NULL if space for structure can't be allocated. -****************************************************************************/ -static option_t *MakeOpt( - const char option, char *const argument, const int index) -{ - option_t *opt; - - opt = malloc(sizeof(option_t)); - - if (opt != NULL) - { - opt->option = option; - opt->argument = argument; - opt->argIndex = index; - opt->next = NULL; - } - else - { - perror("Failed to Allocate option_t"); - } - - return opt; -} - -/**************************************************************************** -* Function : FreeOptList -* Description: This function will free all the elements in an option_t -* type linked list starting from the node passed as a -* parameter. -* Parameters : list - head of linked list to be freed -* Effects : All elements of the linked list pointed to by list will -* be freed and list will be set to NULL. -* Returned : None -****************************************************************************/ -void FreeOptList(option_t *list) -{ - option_t *head, *next; - - head = list; - list = NULL; - - while (head != NULL) - { - next = head->next; - free(head); - head = next; - } - - return; -} - -/**************************************************************************** -* Function : MatchOpt -* Description: This function searches for an arguement in an option list. -* It will return the index to the option matching the -* arguement or the index to the NULL if none is found. -* Parameters : arguement - character arguement to be matched to an -* option in the option list -* options - getopt style option list. A NULL terminated -* string of single character options. Follow an -* option with a colon to indicate that it requires -* an argument. -* Effects : None -* Returned : Index of argument in option list. Index of end of string -* if arguement does not appear in the option list. -****************************************************************************/ -static size_t MatchOpt( - const char argument, char *const options) -{ - size_t optIndex = 0; - - /* attempt to find a matching option */ - while ((options[optIndex] != '\0') && - (options[optIndex] != argument)) - { - do - { - optIndex++; - } - while ((options[optIndex] != '\0') && - (':' == options[optIndex])); - } - - return optIndex; -} - -/**************************************************************************** -* Function : FindFileName -* Description: This is function accepts a pointer to the name of a file -* along with path information and returns a pointer to the -* first character that is not part of the path. -* Parameters : fullPath - pointer to an array of characters containing -* a file name and possible path modifiers. -* Effects : None -* Returned : Returns a pointer to the first character after any path -* information. -****************************************************************************/ -char *FindFileName(const char *const fullPath) -{ - int i; - const char *start; /* start of file name */ - const char *tmp; - const char delim[3] = {'\\', '/', ':'}; /* path deliminators */ - - start = fullPath; - - /* find the first character after all file path delimiters */ - for (i = 0; i < 3; i++) - { - tmp = strrchr(start, delim[i]); - - if (tmp != NULL) - { - start = tmp + 1; - } - } - - return (char *)start; -} - diff --git a/src/getopt/optlist.h b/src/getopt/optlist.h deleted file mode 100644 index c8d7af7..0000000 --- a/src/getopt/optlist.h +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************** -* Command Line Option Parser -* -* File : optlist.h -* Purpose : Header for getopt style command line option parsing -* Author : Michael Dipperstein -* Date : August 1, 2007 -* -**************************************************************************** -* -* OptList: A command line option parsing library -* Copyright (C) 2007, 20014 by -* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu) -* -* This file is part of the OptList library. -* -* OptList is free software; you can redistribute it and/or modify it -* under the terms of the GNU Lesser General Public License as published by -* the Free Software Foundation; either version 3 of the License, or (at -* your option) any later version. -* -* OptList is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -* General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this program. If not, see . -* -***************************************************************************/ -#ifndef OPTLIST_H -#define OPTLIST_H - -/*************************************************************************** -* INCLUDED FILES -***************************************************************************/ - -/*************************************************************************** -* MACROS -***************************************************************************/ - -/*************************************************************************** -* CONSTANTS -***************************************************************************/ -#define OL_NOINDEX -1 /* this option has no arguement */ - -/*************************************************************************** -* TYPE DEFINITIONS -***************************************************************************/ -typedef struct option_t -{ - char option; /* the current character option character */ - char *argument; /* pointer to arguments for this option */ - int argIndex; /* index into argv[] containing the argument */ - struct option_t *next; /* the next option in the linked list */ -} option_t; - -/*************************************************************************** -* PROTOTYPES -***************************************************************************/ - -/* returns a linked list of options and arguments similar to getopt() */ -option_t *GetOptList(int argc, char *const argv[], char *const options); - -/* frees the linked list of option_t returned by GetOptList */ -void FreeOptList(option_t *list); - -/* return a pointer to file name in a full path. useful for argv[0] */ -char *FindFileName(const char *const fullPath); - -#endif /* ndef OPTLIST_H */ diff --git a/src/getopt/sample.c b/src/getopt/sample.c deleted file mode 100644 index d589515..0000000 --- a/src/getopt/sample.c +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************** -* OptList Usage Sample -* -* File : sample.c -* Purpose : Demonstrates usage of optlist library. -* Author : Michael Dipperstein -* Date : July 23, 2004 -* -**************************************************************************** -* -* Sample: A optlist library sample usage program -* Copyright (C) 2007, 2014 by -* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu) -* -* This file is part of the optlist library. -* -* The optlist library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public License as -* published by the Free Software Foundation; either version 3 of the -* License, or (at your option) any later version. -* -* The optlist library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -* General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this program. If not, see . -* -***************************************************************************/ - -/*************************************************************************** -* INCLUDED FILES -***************************************************************************/ -#include -#include -#include "optlist.h" - -/*************************************************************************** -* PROTOTYPES -***************************************************************************/ - -/*************************************************************************** -* FUNCTIONS -***************************************************************************/ - -/**************************************************************************** -* Function : main -* Description: This is the main function for this program, it calls -* optlist to parse the command line input displays the -* results of the parsing. -* Parameters : argc - number of parameters -* argv - parameter list -* Effects : parses command line parameters -* Returned : EXIT_SUCCESS for success, otherwise EXIT_FAILURE. -****************************************************************************/ -int main(int argc, char *argv[]) -{ - option_t *optList, *thisOpt; - - /* get list of command line options and their arguments */ - optList = NULL; - optList = GetOptList(argc, argv, "a:bcd:ef?"); - - /* display results of parsing */ - while (optList != NULL) - { - thisOpt = optList; - optList = optList->next; - - if ('?' == thisOpt->option) - { - printf("Usage: %s \n\n", FindFileName(argv[0])); - printf("options:\n"); - printf(" -a : option excepting argument.\n"); - printf(" -b : option without arguments.\n"); - printf(" -c : option without arguments.\n"); - printf(" -d : option excepting argument.\n"); - printf(" -e : option without arguments.\n"); - printf(" -f : option without arguments.\n"); - printf(" -? : print out command line options.\n\n"); - - FreeOptList(thisOpt); /* free the rest of the list */ - return EXIT_SUCCESS; - } - - printf("found option %c\n", thisOpt->option); - - if (thisOpt->argument != NULL) - { - printf("\tfound argument %s", thisOpt->argument); - printf(" at index %d\n", thisOpt->argIndex); - } - else - { - printf("\tno argument for this option\n"); - } - - free(thisOpt); /* done with this item, free it */ - } - - return EXIT_SUCCESS; -} diff --git a/src/ior-output.c b/src/ior-output.c index 8a88876..0bb3d5a 100644 --- a/src/ior-output.c +++ b/src/ior-output.c @@ -78,7 +78,7 @@ static void PrintKeyValEnd(){ } static void PrintKeyVal(char * key, char * value){ - if(value[strlen(value) -1 ] == '\n'){ + if(value[0] != 0 && value[strlen(value) -1 ] == '\n'){ // remove \n value[strlen(value) -1 ] = 0; } @@ -352,7 +352,6 @@ void ShowTestStart(IOR_param_t *test) PrintKeyValInt("useExistingTestFile", test->useExistingTestFile); PrintKeyValInt("showHints", test->showHints); PrintKeyValInt("uniqueDir", test->uniqueDir); - PrintKeyValInt("showHelp", test->showHelp); PrintKeyValInt("individualDataSets", test->individualDataSets); PrintKeyValInt("singleXferAttempt", test->singleXferAttempt); PrintKeyValInt("readFile", test->readFile); @@ -407,7 +406,7 @@ void ShowTestEnd(IOR_test_t *tptr){ */ void ShowSetup(IOR_param_t *params) { - if (strcmp(params->debug, "") != 0) { + if (params->debug) { fprintf(out_logfile, "\n*** DEBUG MODE ***\n"); fprintf(out_logfile, "*** %s ***\n\n", params->debug); } diff --git a/src/ior.c b/src/ior.c index 36f13d6..4cfd821 100755 --- a/src/ior.c +++ b/src/ior.c @@ -43,10 +43,9 @@ static int totalErrorCount; static const ior_aiori_t *backend; static void DestroyTests(IOR_test_t *tests_head); -static void DisplayUsage(char **); static char *PrependDir(IOR_param_t *, char *); static char **ParseFileName(char *, int *); -static IOR_test_t *SetupTests(int, char **); +static void InitTests(IOR_test_t * , MPI_Comm); static void TestIoSys(IOR_test_t *); static void ValidateTests(IOR_param_t *); static IOR_offset_t WriteOrRead(IOR_param_t * test, IOR_results_t * results, void *fd, int access, IOR_io_buffers* ioBuffers); @@ -70,14 +69,9 @@ IOR_test_t * ior_run(int argc, char **argv, MPI_Comm world_com, FILE * world_out } /* setup tests, and validate parameters */ - tests_head = SetupTests(argc, argv); + tests_head = ParseCommandLine(argc, argv); + InitTests(tests_head, world_com); verbose = tests_head->params.verbose; - tests_head->params.testComm = world_com; - - /* check for commandline 'help' request */ - if (rank == 0 && tests_head->params.showHelp == TRUE) { - DisplayUsage(argv); - } PrintHeader(argc, argv); @@ -85,7 +79,6 @@ IOR_test_t * ior_run(int argc, char **argv, MPI_Comm world_com, FILE * world_out for (tptr = tests_head; tptr != NULL; tptr = tptr->next) { totalErrorCount = 0; verbose = tptr->params.verbose; - tptr->params.testComm = world_com; if (rank == 0 && verbose >= VERBOSE_0) { ShowTestStart(&tptr->params); } @@ -114,15 +107,8 @@ int ior_main(int argc, char **argv) /* * check -h option from commandline without starting MPI; - * if the help option is requested in a script file (showHelp=TRUE), - * the help output will be displayed in the MPI job */ - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-h") == 0) { - DisplayUsage(argv); - return (0); - } - } + tests_head = ParseCommandLine(argc, argv); #ifdef USE_S3_AIORI /* This is supposed to be done before *any* threads are created. @@ -152,18 +138,8 @@ int ior_main(int argc, char **argv) } /* setup tests, and validate parameters */ - tests_head = SetupTests(argc, argv); + InitTests(tests_head, mpi_comm_world); verbose = tests_head->params.verbose; - tests_head->params.testComm = mpi_comm_world; - - /* check for commandline 'help' request */ - if (tests_head->params.showHelp == TRUE) { - if( rank == 0 ){ - DisplayUsage(argv); - } - MPI_Finalize(); - exit(0); - } PrintHeader(argc, argv); @@ -223,9 +199,12 @@ void init_IOR_Param_t(IOR_param_t * p) p->mode = IOR_IRUSR | IOR_IWUSR | IOR_IRGRP | IOR_IWGRP; p->openFlags = IOR_RDWR | IOR_CREAT; - strncpy(p->api, default_aiori, MAX_STR); - strncpy(p->platform, "HOST(OSTYPE)", MAX_STR); - strncpy(p->testFileName, "testFile", MAX_PATHLEN); + p->api = strdup(default_aiori); + p->platform = strdup("HOST(OSTYPE)"); + p->testFileName = strdup("testFile"); + + p->writeFile = p->readFile = FALSE; + p->checkWrite = p->checkRead = FALSE; p->nodes = 1; p->tasksPerNode = 1; @@ -244,8 +223,8 @@ void init_IOR_Param_t(IOR_param_t * p) hdfs_user = getenv("USER"); if (!hdfs_user) - hdfs_user = ""; - strncpy(p->hdfs_user, hdfs_user, MAX_STR); + hdfs_user = ""; + p->hdfs_user = strdup(hdfs_user); p->hdfs_name_node = "default"; p->hdfs_name_node_port = 0; /* ??? */ p->hdfs_fs = NULL; @@ -557,7 +536,7 @@ static void aligned_buffer_free(void *buf) free(*(void **)((char *)buf - sizeof(char *))); } -void AllocResults(IOR_test_t *test) +static void AllocResults(IOR_test_t *test) { int reps; if (test->results != NULL) @@ -619,12 +598,12 @@ IOR_test_t *CreateTest(IOR_param_t *init_params, int test_num) if (newTest == NULL) ERR("malloc() of IOR_test_t failed"); newTest->params = *init_params; - GetPlatformName(newTest->params.platform); - newTest->params.nodes = init_params->numTasks / tasksPerNode; - newTest->params.tasksPerNode = tasksPerNode; + newTest->params.platform = GetPlatformName(); newTest->params.id = test_num; newTest->next = NULL; newTest->results = NULL; + + AllocResults(newTest); return newTest; } @@ -644,82 +623,6 @@ static void DestroyTests(IOR_test_t *tests_head) } } -/* - * Display usage of script file. - */ -static void DisplayUsage(char **argv) -{ - char *opts[] = { - "OPTIONS:", - " -a S api -- API for I/O [POSIX|MMAP|MPIIO|HDF5|HDFS|S3|S3_EMC|NCMPI]", - " -A N refNum -- user supplied reference number to include in the summary", - " -b N blockSize -- contiguous bytes to write per task (e.g.: 8, 4k, 2m, 1g)", - " -B useO_DIRECT -- uses O_DIRECT for POSIX, bypassing I/O buffers", - " -c collective -- collective I/O", - " -C reorderTasks -- changes task ordering to n+1 ordering for readback", - " -d N interTestDelay -- delay between reps in seconds", - " -D N deadlineForStonewalling -- seconds before stopping write or read phase", - " -O stoneWallingWearOut=1 -- once the stonewalling timout is over, all process finish to access the amount of data", - " -O stoneWallingWearOutIterations=N -- stop after processing this number of iterations, needed for reading data back written with stoneWallingWearOut", - " -O stoneWallingStatusFile=FILE -- this file keeps the number of iterations from stonewalling during write and allows to use them for read", - " -e fsync -- perform fsync/msync upon POSIX/MMAP write close", - " -E useExistingTestFile -- do not remove test file before write access", - " -f S scriptFile -- test script name", - " -F filePerProc -- file-per-process", - " -g intraTestBarriers -- use barriers between open, write/read, and close", - " -G N setTimeStampSignature -- set value for time stamp signature/random seed", - " -h showHelp -- displays options and help", - " -H showHints -- show hints", - " -i N repetitions -- number of repetitions of test", - " -I individualDataSets -- datasets not shared by all procs [not working]", - " -j N outlierThreshold -- warn on outlier N seconds from mean", - " -J N setAlignment -- HDF5 alignment in bytes (e.g.: 8, 4k, 2m, 1g)", - " -k keepFile -- don't remove the test file(s) on program exit", - " -K keepFileWithError -- keep error-filled file(s) after data-checking", - " -l datapacket type-- type of packet that will be created [offset|incompressible|timestamp|o|i|t]", - " -m multiFile -- use number of reps (-i) for multiple file count", - " -M N memoryPerNode -- hog memory on the node (e.g.: 2g, 75%)", - " -n noFill -- no fill in HDF5 file creation", - " -N N numTasks -- number of tasks that should participate in the test", - " -o S testFile -- full name for test", - " -O S string of IOR directives (e.g. -O checkRead=1,lustreStripeCount=32)", - " -p preallocate -- preallocate file size", - " -P useSharedFilePointer -- use shared file pointer [not working]", - " -q quitOnError -- during file error-checking, abort on error", - " -Q N taskPerNodeOffset for read tests use with -C & -Z options (-C constant N, -Z at least N)", - " -r readFile -- read existing file", - " -R checkRead -- verify that the output of read matches the expected signature (used with -G)", - " -s N segmentCount -- number of segments", - " -S useStridedDatatype -- put strided access into datatype [not working]", - " -t N transferSize -- size of transfer in bytes (e.g.: 8, 4k, 2m, 1g)", - " -T N maxTimeDuration -- max time in minutes executing repeated test; it aborts only between iterations and not within a test!", - " -u uniqueDir -- use unique directory name for each file-per-process", - " -U S hintsFileName -- full name for hints file", - " -v verbose -- output information (repeating flag increases level)", - " -V useFileView -- use MPI_File_set_view", - " -w writeFile -- write file", - " -W checkWrite -- check read after write", - " -x singleXferAttempt -- do not retry transfer if incomplete", - " -X N reorderTasksRandomSeed -- random seed for -Z option", - " -Y fsyncPerWrite -- perform fsync/msync after each POSIX/MMAP write", - " -z randomOffset -- access is to random, not sequential, offsets within a file", - " -Z reorderTasksRandom -- changes task ordering to random ordering for readback", - " -O summaryFile=FILE -- store result data into this file", - " -O summaryFormat=[default,JSON,CSV] -- use the format for outputing the summary", - " ", - " NOTE: S is a string, N is an integer number.", - " ", - "" - }; - int i = 0; - - fprintf(out_logfile, "Usage: %s [OPTIONS]\n\n", *argv); - for (i = 0; strlen(opts[i]) > 0; i++) - fprintf(out_logfile, "%s\n", opts[i]); - - return; -} - /* * Distribute IOR_HINTs to all tasks' environments. */ @@ -823,9 +726,10 @@ FillBuffer(void *buffer, /* * Return string describing machine name and type. */ -void GetPlatformName(char *platformName) +char * GetPlatformName() { char nodeName[MAX_STR], *p, *start, sysName[MAX_STR]; + char platformName[MAX_STR]; struct utsname name; if (uname(&name) != 0) { @@ -858,6 +762,7 @@ void GetPlatformName(char *platformName) } sprintf(platformName, "%s(%s)", nodeName, sysName); + return strdup(platformName); } @@ -1097,14 +1002,16 @@ static void RemoveFile(char *testFileName, int filePerProc, IOR_param_t * test) * Setup tests by parsing commandline and creating test script. * Perform a sanity-check on the configured parameters. */ -static IOR_test_t *SetupTests(int argc, char **argv) +static void InitTests(IOR_test_t *tests, MPI_Comm com) { - IOR_test_t *tests, *testsHead; + IOR_test_t *testsHead = tests; + int size; + + MPI_CHECK(MPI_Comm_size(com, & size), "MPI_Comm_size() error"); /* count the tasks per node */ - tasksPerNode = CountTasksPerNode(mpi_comm_world); + tasksPerNode = CountTasksPerNode(com); - testsHead = tests = ParseCommandLine(argc, argv); /* * Since there is no guarantee that anyone other than * task 0 has the environment settings for the hints, pass @@ -1114,6 +1021,16 @@ static IOR_test_t *SetupTests(int argc, char **argv) /* check validity of tests and create test queue */ while (tests != NULL) { + IOR_param_t *params = & tests->params; + params->testComm = com; + params->nodes = params->numTasks / tasksPerNode; + params->tasksPerNode = tasksPerNode; + if (params->numTasks == 0) { + params->numTasks = size; + } + params->expectedAggFileSize = + params->blockSize * params->segmentCount * params->numTasks; + ValidateTests(&tests->params); tests = tests->next; } @@ -1122,8 +1039,6 @@ static IOR_test_t *SetupTests(int argc, char **argv) /* seed random number generator */ SeedRandGen(mpi_comm_world); - - return (testsHead); } /* @@ -1468,8 +1383,7 @@ static void TestIoSys(IOR_test_t *test) } if (params->reorderTasks) { /* move two nodes away from writing node */ - rankOffset = - (2 * params->tasksPerNode) % params->numTasks; + rankOffset = (2 * params->tasksPerNode) % params->numTasks; } // update the check buffer @@ -1497,9 +1411,8 @@ static void TestIoSys(IOR_test_t *test) /* Constant process offset reading */ if (params->reorderTasks) { /* move taskPerNodeOffset nodes[1==default] away from writing node */ - rankOffset = - (params->taskPerNodeOffset * - params->tasksPerNode) % params->numTasks; + rankOffset = (params->taskPerNodeOffset * + params->tasksPerNode) % params->numTasks; } /* random process offset reading */ if (params->reorderTasksRandom) { @@ -1626,10 +1539,6 @@ static void ValidateTests(IOR_param_t * test) IOR_param_t defaults; init_IOR_Param_t(&defaults); - /* get the version of the tests */ - AioriBind(test->api, test); - backend->set_version(test); - if (test->repetitions <= 0) WARN_RESET("too few test repetitions", test, &defaults, repetitions); @@ -2005,7 +1914,7 @@ static IOR_offset_t WriteOrRead(IOR_param_t * test, IOR_results_t * results, voi && ((GetTimeStamp() - startForStonewall) > test->deadlineForStonewalling)); - if(access == READ && test->stoneWallingStatusFile[0]){ + if(access == READ && test->stoneWallingStatusFile){ test->stoneWallingWearOutIterations = ReadStoneWallingIterations(test->stoneWallingStatusFile); if(test->stoneWallingWearOutIterations == -1){ ERR("Could not read back the stonewalling status from the file!"); diff --git a/src/ior.h b/src/ior.h index e8e465a..b6655b3 100755 --- a/src/ior.h +++ b/src/ior.h @@ -87,17 +87,18 @@ typedef struct IO_BUFFERS typedef struct { - char debug[MAX_STR]; /* debug info string */ + const void * backend; + char * debug; /* debug info string */ unsigned int mode; /* file permissions */ unsigned int openFlags; /* open flags (see also ) */ int referenceNumber; /* user supplied reference number */ - char api[MAX_STR]; /* API for I/O */ - char apiVersion[MAX_STR]; /* API version */ - char platform[MAX_STR]; /* platform type */ - char testFileName[MAXPATHLEN]; /* full name for test */ - char testFileName_fppReadCheck[MAXPATHLEN];/* filename for fpp read check */ - char hintsFileName[MAXPATHLEN]; /* full name for hints file */ - char options[MAXPATHLEN]; /* options string */ + char * api; /* API for I/O */ + char * apiVersion; /* API version */ + char * platform; /* platform type */ + char * testFileName; /* full name for test */ + char * testFileName_fppReadCheck;/* filename for fpp read check */ + char * hintsFileName; /* full name for hints file */ + char * options; /* options string */ int numTasks; /* number of tasks for test */ int nodes; /* number of nodes for test */ int tasksPerNode; /* number of tasks per node */ @@ -131,7 +132,6 @@ typedef struct int useStridedDatatype; /* put strided access into datatype */ int useO_DIRECT; /* use O_DIRECT, bypassing I/O buffers */ int showHints; /* show hints */ - int showHelp; /* show options and help */ int summary_every_test; /* flag to print summary every test, not just at end */ int uniqueDir; /* use unique directory for each fpp */ int useExistingTestFile; /* do not delete test file before access */ @@ -139,7 +139,7 @@ typedef struct int deadlineForStonewalling; /* max time in seconds to run any test phase */ int stoneWallingWearOut; /* wear out the stonewalling, once the timout is over, each process has to write the same amount */ uint64_t stoneWallingWearOutIterations; /* the number of iterations for the stonewallingWearOut, needed for readBack */ - char stoneWallingStatusFile[MAXPATHLEN]; + char * stoneWallingStatusFile; int maxTimeDuration; /* max time in minutes to run each test */ int outlierThreshold; /* warn on outlier N seconds from mean */ @@ -173,7 +173,7 @@ typedef struct IOR_offset_t setAlignment; /* alignment in bytes */ /* HDFS variables */ - char hdfs_user[MAX_STR]; /* copied from ENV, for now */ + char * hdfs_user; /* copied from ENV, for now */ const char* hdfs_name_node; tPort hdfs_name_node_port; /* (uint16_t) */ hdfsFS hdfs_fs; /* file-system handle */ @@ -190,8 +190,7 @@ typedef struct IOBuf* io_buf; /* aws4c places parsed header values here */ IOBuf* etags; /* accumulate ETags for N:1 parts */ size_t part_number; /* multi-part upload increment (PER-RANK!) */ -# define MAX_UPLOAD_ID_SIZE 256 /* seems to be 32, actually */ - char UploadId[MAX_UPLOAD_ID_SIZE +1]; /* key for multi-part-uploads */ + char* UploadId; /* key for multi-part-uploads */ /* RADOS variables */ rados_t rados_cluster; /* RADOS cluster handle */ @@ -245,8 +244,7 @@ typedef struct IOR_test_t { IOR_test_t *CreateTest(IOR_param_t *init_params, int test_num); -void AllocResults(IOR_test_t *test); -void GetPlatformName(char *); +char * GetPlatformName(); void init_IOR_Param_t(IOR_param_t *p); /* diff --git a/src/mdtest.c b/src/mdtest.c index 2da9edc..53250e2 100644 --- a/src/mdtest.c +++ b/src/mdtest.c @@ -2154,7 +2154,7 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE * int printhelp = 0; int parsed_options = option_parse(argc, argv, options, & printhelp); - backend = aiori_select (backend_name); + backend = aiori_select(backend_name); if (NULL == backend) { FAIL("Could not find suitable backend to use"); } @@ -2164,7 +2164,7 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE * } if(printhelp != 0){ - printf("\nSynopsis: %s ", argv[0]); + printf("Usage: %s ", argv[0]); option_print_help(options, 0); diff --git a/src/option.c b/src/option.c index f9f6183..13b239d 100644 --- a/src/option.c +++ b/src/option.c @@ -6,6 +6,45 @@ #include +/* +* Takes a string of the form 64, 8m, 128k, 4g, etc. and converts to bytes. +*/ +int64_t string_to_bytes(char *size_str) +{ + int64_t size = 0; + char range; + int rc; + + rc = sscanf(size_str, " %lld %c ", (long long*) & size, &range); + if (rc == 2) { + switch ((int)range) { + case 'k': + case 'K': + size <<= 10; + break; + case 'm': + case 'M': + size <<= 20; + break; + case 'g': + case 'G': + size <<= 30; + break; + case 't': + case 'T': + size <<= 40; + break; + case 'p': + case 'P': + size <<= 50; + break; + } + } else if (rc == 0) { + size = -1; + } + return (size); +} + /* * Initial revision by JK */ @@ -16,6 +55,10 @@ static int print_value(option_help * o){ assert(o->variable != NULL); switch(o->type){ + case('p'):{ + pos += printf("=STRING"); + break; + } case('F'):{ pos += printf("=%.14f ", *(double*) o->variable); break; @@ -59,12 +102,12 @@ static void print_help_section(option_help * args, option_value_type type, char first = 1; option_help * o; for(o = args; o->shortVar != 0 || o->longVar != 0 || o->help != NULL ; o++){ - if( o->shortVar == 0 && o->longVar == 0 && o->help != NULL){ - printf("%-15s %s\n", "", o->help); - continue; - } if (o->arg == type){ + if( o->shortVar == 0 && o->longVar == 0 && o->help != NULL){ + printf("%s\n", o->help); + continue; + } if (first){ printf("\n%s\n", name); first = 0; @@ -235,13 +278,13 @@ int option_parse(int argc, char ** argv, option_help * args, int * printhelp){ // try to find matching option help for(option_help * o = args; o->shortVar != 0 || o->longVar != 0 || o->help != NULL ; o++ ){ - if ( (strlen(txt) == 2 && txt[0] == '-' && o->shortVar == txt[1]) || (strlen(txt) > 2 && txt[0] == '-' && txt[1] == '-' && o->longVar != NULL && strcmp(txt + 2, o->longVar) == 0)){ - foundOption = 1; + if( o->shortVar == 0 && o->longVar == 0 ){ + // section + continue; + } - if( o->shortVar == 0 && o->longVar == 0 && o->help != NULL){ - // section - continue; - } + if ( (txt[0] == '-' && o->shortVar == txt[1]) || (strlen(txt) > 2 && txt[0] == '-' && txt[1] == '-' && o->longVar != NULL && strcmp(txt + 2, o->longVar) == 0)){ + foundOption = 1; // now process the option. switch(o->arg){ @@ -254,9 +297,13 @@ int option_parse(int argc, char ** argv, option_help * args, int * printhelp){ case (OPTION_REQUIRED_ARGUMENT):{ // check if next is an argument if(arg == NULL){ - // simply take the next value as argument - i++; - arg = argv[i]; + if(o->shortVar == txt[1] && txt[2] != 0){ + arg = & txt[2]; + }else{ + // simply take the next value as argument + i++; + arg = argv[i]; + } } switch(o->type){ @@ -269,7 +316,7 @@ int option_parse(int argc, char ** argv, option_help * args, int * printhelp){ break; } case('d'):{ - *(int*) o->variable = atoi(arg); + *(int*) o->variable = string_to_bytes(arg); break; } case('H'): @@ -285,7 +332,7 @@ int option_parse(int argc, char ** argv, option_help * args, int * printhelp){ break; } case('l'):{ - *(long long*) o->variable = atoll(arg); + *(long long*) o->variable = string_to_bytes(arg); break; } } diff --git a/src/option.h b/src/option.h index e2f5249..8337d8d 100644 --- a/src/option.h +++ b/src/option.h @@ -1,5 +1,7 @@ -#ifndef IOR_OPTION_H -#define IOR_OPTION_H +#ifndef _IOR_OPTION_H +#define _IOR_OPTION_H + +#include /* * Initial revision by JK @@ -23,6 +25,7 @@ typedef struct{ #define LAST_OPTION {0, 0, 0, (option_value_type) 0, 0, NULL} +int64_t string_to_bytes(char *size_str); void option_print_help(option_help * args, int is_plugin); void option_print_current(option_help * args); diff --git a/src/parse_options.c b/src/parse_options.c index 4696727..cc68263 100755 --- a/src/parse_options.c +++ b/src/parse_options.c @@ -22,54 +22,17 @@ #include -#include #include "utilities.h" #include "ior.h" #include "aiori.h" #include "parse_options.h" +#include "option.h" +#include "aiori.h" #define ISPOWEROFTWO(x) ((x != 0) && !(x & (x - 1))) IOR_param_t initialTestParams; -/* - * Takes a string of the form 64, 8m, 128k, 4g, etc. and converts to bytes. - */ -static IOR_offset_t StringToBytes(char *size_str) -{ - IOR_offset_t size = 0; - char range; - int rc; - - rc = sscanf(size_str, " %lld %c ", &size, &range); - if (rc == 2) { - switch ((int)range) { - case 'k': - case 'K': - size <<= 10; - break; - case 'm': - case 'M': - size <<= 20; - break; - case 'g': - case 'G': - size <<= 30; - break; - case 't': - case 'T': - size <<= 40; - break; - case 'p': - case 'P': - size <<= 50; - break; - } - } else if (rc == 0) { - size = -1; - } - return (size); -} static size_t NodeMemoryStringToBytes(char *size_str) { @@ -81,7 +44,7 @@ static size_t NodeMemoryStringToBytes(char *size_str) rc = sscanf(size_str, " %d %% ", &percent); if (rc == 0) - return (size_t)StringToBytes(size_str); + return (size_t) string_to_bytes(size_str); if (percent > 100 || percent < 0) ERR("percentage must be between 0 and 100"); @@ -98,11 +61,6 @@ static size_t NodeMemoryStringToBytes(char *size_str) return mem / 100 * percent; } -static void RecalculateExpectedFileSize(IOR_param_t *params) -{ - params->expectedAggFileSize = - params->blockSize * params->segmentCount * params->numTasks; -} /* * Check and correct all settings of each test in queue for correctness. @@ -143,13 +101,6 @@ static void CheckRunSettings(IOR_test_t *tests) params->openFlags |= IOR_WRONLY; } - /* If numTasks set to 0, use all tasks */ - if (params->numTasks == 0) { - MPI_CHECK(MPI_Comm_size(mpi_comm_world, - ¶ms->numTasks), - "MPI_Comm_size() error"); - RecalculateExpectedFileSize(params); - } } } @@ -247,15 +198,13 @@ void DecodeDirective(char *line, IOR_param_t *params) } else if (strcasecmp(option, "quitonerror") == 0) { params->quitOnError = atoi(value); } else if (strcasecmp(option, "segmentcount") == 0) { - params->segmentCount = StringToBytes(value); - RecalculateExpectedFileSize(params); + params->segmentCount = string_to_bytes(value); } else if (strcasecmp(option, "blocksize") == 0) { - params->blockSize = StringToBytes(value); - RecalculateExpectedFileSize(params); + params->blockSize = string_to_bytes(value); } else if (strcasecmp(option, "transfersize") == 0) { - params->transferSize = StringToBytes(value); + params->transferSize = string_to_bytes(value); } else if (strcasecmp(option, "setalignment") == 0) { - params->setAlignment = StringToBytes(value); + params->setAlignment = string_to_bytes(value); } else if (strcasecmp(option, "singlexferattempt") == 0) { params->singleXferAttempt = atoi(value); } else if (strcasecmp(option, "individualdatasets") == 0) { @@ -284,8 +233,6 @@ void DecodeDirective(char *line, IOR_param_t *params) params->useStridedDatatype = atoi(value); } else if (strcasecmp(option, "showhints") == 0) { params->showHints = atoi(value); - } else if (strcasecmp(option, "showhelp") == 0) { - params->showHelp = atoi(value); } else if (strcasecmp(option, "uniqueDir") == 0) { params->uniqueDir = atoi(value); } else if (strcasecmp(option, "useexistingtestfile") == 0) { @@ -297,7 +244,7 @@ void DecodeDirective(char *line, IOR_param_t *params) } else if (strcasecmp(option, "randomoffset") == 0) { params->randomOffset = atoi(value); } else if (strcasecmp(option, "memoryPerTask") == 0) { - params->memoryPerTask = StringToBytes(value); + params->memoryPerTask = string_to_bytes(value); params->memoryPerNode = 0; } else if (strcasecmp(option, "memoryPerNode") == 0) { params->memoryPerNode = NodeMemoryStringToBytes(value); @@ -312,7 +259,7 @@ void DecodeDirective(char *line, IOR_param_t *params) #ifndef HAVE_LUSTRE_LUSTRE_USER_H ERR("ior was not compiled with Lustre support"); #endif - params->lustre_stripe_size = StringToBytes(value); + params->lustre_stripe_size = string_to_bytes(value); params->lustre_set_striping = 1; } else if (strcasecmp(option, "lustrestartost") == 0) { #ifndef HAVE_LUSTRE_LUSTRE_USER_H @@ -346,12 +293,11 @@ void DecodeDirective(char *line, IOR_param_t *params) #ifndef HAVE_BEEGFS_BEEGFS_H ERR("ior was not compiled with BeeGFS support"); #endif - params->beegfs_chunkSize = StringToBytes(value); + params->beegfs_chunkSize = string_to_bytes(value); if (!ISPOWEROFTWO(params->beegfs_chunkSize) || params->beegfs_chunkSize < (1<<16)) ERR("beegfsChunkSize must be a power of two and >64k"); } else if (strcasecmp(option, "numtasks") == 0) { params->numTasks = atoi(value); - RecalculateExpectedFileSize(params); } else if (strcasecmp(option, "summaryalways") == 0) { params->summary_every_test = atoi(value); } else { @@ -377,7 +323,6 @@ void ParseLine(char *line, IOR_param_t * test) DecodeDirective(start, test); start = end + 1; } while (end != NULL); - } /* @@ -445,7 +390,6 @@ IOR_test_t *ReadConfigScript(char *scriptName) if (sscanf(linebuf, " #%s", empty) == 1) continue; if (contains_only(linebuf, "ior stop")) { - AllocResults(tail); break; } else if (contains_only(linebuf, "run")) { if (runflag) { @@ -454,7 +398,6 @@ IOR_test_t *ReadConfigScript(char *scriptName) tail->next = CreateTest(&tail->params, test_num++); tail = tail->next; } - AllocResults(tail); runflag = 1; } else if (runflag) { /* If this directive was preceded by a "run" line, then @@ -475,214 +418,148 @@ IOR_test_t *ReadConfigScript(char *scriptName) return head; } + +static IOR_param_t * parameters; + +static void decodeDirectiveWrapper(char *line){ + DecodeDirective(line, parameters); +} + /* * Parse Commandline. */ IOR_test_t *ParseCommandLine(int argc, char **argv) { - char * const opts = - "a:A:b:BcCd:D:eEf:FgG:hHi:Ij:J:kKl:mM:nN:o:O:pPqQ:rRs:St:T:uU:vVwWxX:YzZ"; + char * testscripts = NULL; + int toggleG = FALSE; + char * buffer_type = ""; + char * memoryPerNode = NULL; + init_IOR_Param_t(& initialTestParams); + parameters = & initialTestParams; + + option_help options [] = { + {'a', NULL, "API for I/O [POSIX|MPIIO|HDF5|HDFS|S3|S3_EMC|NCMPI]", OPTION_OPTIONAL_ARGUMENT, 's', & initialTestParams.api}, + {'A', NULL, "refNum -- user supplied reference number to include in the summary", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.referenceNumber}, + {'b', NULL, "blockSize -- contiguous bytes to write per task (e.g.: 8, 4k, 2m, 1g)", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.blockSize}, + {'B', NULL, "useO_DIRECT -- uses O_DIRECT for POSIX, bypassing I/O buffers", OPTION_FLAG, 'd', & initialTestParams.useO_DIRECT}, + {'c', NULL, "collective -- collective I/O", OPTION_FLAG, 'd', & initialTestParams.collective}, + {'C', NULL, "reorderTasks -- changes task ordering to n+1 ordering for readback", OPTION_FLAG, 'd', & initialTestParams.reorderTasks}, + {'d', NULL, "interTestDelay -- delay between reps in seconds", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.interTestDelay}, + {'D', NULL, "deadlineForStonewalling -- seconds before stopping write or read phase", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.deadlineForStonewalling}, + {.help=" -O stoneWallingWearOut=1 -- once the stonewalling timout is over, all process finish to access the amount of data", .arg = OPTION_OPTIONAL_ARGUMENT}, + {.help=" -O stoneWallingWearOutIterations=N -- stop after processing this number of iterations, needed for reading data back written with stoneWallingWearOut", .arg = OPTION_OPTIONAL_ARGUMENT}, + {.help=" -O stoneWallingStatusFile=FILE -- this file keeps the number of iterations from stonewalling during write and allows to use them for read", .arg = OPTION_OPTIONAL_ARGUMENT}, + {'e', NULL, "fsync -- perform fsync/msync upon POSIX/MMAP write close", OPTION_FLAG, 'd', & initialTestParams.fsync}, + {'E', NULL, "useExistingTestFile -- do not remove test file before write access", OPTION_FLAG, 'd', & initialTestParams.useExistingTestFile}, + {'f', NULL, "scriptFile -- test script name", OPTION_FLAG, 'd', & testscripts}, + {'F', NULL, "filePerProc -- file-per-process", OPTION_FLAG, 'd', & initialTestParams.filePerProc}, + {'g', NULL, "intraTestBarriers -- use barriers between open, write/read, and close", OPTION_FLAG, 'd', & initialTestParams.intraTestBarriers}, + /* This option toggles between Incompressible Seed and Time stamp sig based on -l, + * so we'll toss the value in both for now, and sort it out in initialization + * after all the arguments are in and we know which it keep. + */ + {'G', NULL, "setTimeStampSignature -- set value for time stamp signature/random seed", OPTION_FLAG, 'd', & toggleG}, + {'H', NULL, "showHints -- show hints", OPTION_FLAG, 'd', & initialTestParams.showHints}, + {'i', NULL, "repetitions -- number of repetitions of test", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.repetitions}, + {'I', NULL, "individualDataSets -- datasets not shared by all procs [not working]", OPTION_FLAG, 'd', & initialTestParams.individualDataSets}, + {'j', NULL, "outlierThreshold -- warn on outlier N seconds from mean", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.outlierThreshold}, + {'J', NULL, "setAlignment -- HDF5 alignment in bytes (e.g.: 8, 4k, 2m, 1g)", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.setAlignment}, + {'k', NULL, "keepFile -- don't remove the test file(s) on program exit", OPTION_FLAG, 'd', & initialTestParams.keepFile}, + {'K', NULL, "keepFileWithError -- keep error-filled file(s) after data-checking", OPTION_FLAG, 'd', & initialTestParams.keepFileWithError}, + {'l', NULL, "datapacket type-- type of packet that will be created [offset|incompressible|timestamp|o|i|t]", OPTION_OPTIONAL_ARGUMENT, 's', & buffer_type}, + {'m', NULL, "multiFile -- use number of reps (-i) for multiple file count", OPTION_FLAG, 'd', & initialTestParams.multiFile}, + {'M', NULL, "memoryPerNode -- hog memory on the node (e.g.: 2g, 75%)", OPTION_OPTIONAL_ARGUMENT, 's', & memoryPerNode}, + {'n', NULL, "noFill -- no fill in HDF5 file creation", OPTION_FLAG, 'd', & initialTestParams.noFill}, + {'N', NULL, "numTasks -- number of tasks that should participate in the test", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.numTasks}, + {'o', NULL, "testFile -- full name for test", OPTION_OPTIONAL_ARGUMENT, 's', & initialTestParams.testFileName}, + {'O', NULL, "string of IOR directives (e.g. -O checkRead=1,lustreStripeCount=32)", OPTION_OPTIONAL_ARGUMENT, 'p', & decodeDirectiveWrapper}, + {'p', NULL, "preallocate -- preallocate file size", OPTION_FLAG, 'd', & initialTestParams.preallocate}, + {'P', NULL, "useSharedFilePointer -- use shared file pointer [not working]", OPTION_FLAG, 'd', & initialTestParams.useSharedFilePointer}, + {'q', NULL, "quitOnError -- during file error-checking, abort on error", OPTION_FLAG, 'd', & initialTestParams.quitOnError}, + {'Q', NULL, "taskPerNodeOffset for read tests use with -C & -Z options (-C constant N, -Z at least N)", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.taskPerNodeOffset}, + {'r', NULL, "readFile -- read existing file", OPTION_FLAG, 'd', & initialTestParams.readFile}, + {'R', NULL, "checkRead -- verify that the output of read matches the expected signature (used with -G)", OPTION_FLAG, 'd', & initialTestParams.checkRead}, + {'s', NULL, "segmentCount -- number of segments", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.segmentCount}, + {'S', NULL, "useStridedDatatype -- put strided access into datatype [not working]", OPTION_FLAG, 'd', & initialTestParams.useStridedDatatype}, + {'t', NULL, "transferSize -- size of transfer in bytes (e.g.: 8, 4k, 2m, 1g)", OPTION_OPTIONAL_ARGUMENT, 'l', & initialTestParams.transferSize}, + {'T', NULL, "maxTimeDuration -- max time in minutes executing repeated test; it aborts only between iterations and not within a test!", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.maxTimeDuration}, + {'u', NULL, "uniqueDir -- use unique directory name for each file-per-process", OPTION_FLAG, 'd', & initialTestParams.uniqueDir}, + {'U', NULL, "hintsFileName -- full name for hints file", OPTION_OPTIONAL_ARGUMENT, 's', & initialTestParams.hintsFileName}, + {'v', NULL, "verbose -- output information (repeating flag increases level)", OPTION_FLAG, 'd', & initialTestParams.verbose}, + {'V', NULL, "useFileView -- use MPI_File_set_view", OPTION_FLAG, 'd', & initialTestParams.useFileView}, + {'w', NULL, "writeFile -- write file", OPTION_FLAG, 'd', & initialTestParams.writeFile}, + {'W', NULL, "checkWrite -- check read after write", OPTION_FLAG, 'd', & initialTestParams.checkWrite}, + {'x', NULL, "singleXferAttempt -- do not retry transfer if incomplete", OPTION_FLAG, 'd', & initialTestParams.singleXferAttempt}, + {'X', NULL, "reorderTasksRandomSeed -- random seed for -Z option", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.reorderTasksRandomSeed}, + {'Y', NULL, "fsyncPerWrite -- perform fsync/msync after each POSIX/MMAP write", OPTION_FLAG, 'd', & initialTestParams.fsyncPerWrite}, + {'z', NULL, "randomOffset -- access is to random, not sequential, offsets within a file", OPTION_FLAG, 'd', & initialTestParams.randomOffset}, + {'Z', NULL, "reorderTasksRandom -- changes task ordering to random ordering for readback", OPTION_FLAG, 'd', & initialTestParams.reorderTasksRandom}, + {.help=" -O summaryFile=FILE -- store result data into this file", .arg = OPTION_OPTIONAL_ARGUMENT}, + {.help=" -O summaryFormat=[default,JSON,CSV] -- use the format for outputing the summary", .arg = OPTION_OPTIONAL_ARGUMENT}, + LAST_OPTION, + }; + int i; IOR_test_t *tests = NULL; - char * optarg; - init_IOR_Param_t(&initialTestParams); GetPlatformName(initialTestParams.platform); - initialTestParams.writeFile = initialTestParams.readFile = FALSE; - initialTestParams.checkWrite = initialTestParams.checkRead = FALSE; + int printhelp = 0; + int parsed_options = option_parse(argc, argv, options, & printhelp); - option_t *optList, *thisOpt; - optList = GetOptList(argc, argv, opts); - - while (optList != NULL) { - thisOpt = optList; - optarg = thisOpt->argument; - optList = optList->next; - switch (thisOpt->option) { - case 'a': - strcpy(initialTestParams.api, optarg); - break; - case 'A': - initialTestParams.referenceNumber = atoi(optarg); - break; - case 'b': - initialTestParams.blockSize = StringToBytes(optarg); - RecalculateExpectedFileSize(&initialTestParams); - break; - case 'B': - initialTestParams.useO_DIRECT = TRUE; - break; - case 'c': - initialTestParams.collective = TRUE; - break; - case 'C': - initialTestParams.reorderTasks = TRUE; - break; - case 'd': - initialTestParams.interTestDelay = atoi(optarg); - break; - case 'D': - initialTestParams.deadlineForStonewalling = - atoi(optarg); - break; - case 'e': - initialTestParams.fsync = TRUE; - break; - case 'E': - initialTestParams.useExistingTestFile = TRUE; - break; - case 'f': - tests = ReadConfigScript(optarg); - break; - case 'F': - initialTestParams.filePerProc = TRUE; - break; - case 'g': - initialTestParams.intraTestBarriers = TRUE; - break; - case 'G': - /* This option toggles between Incompressible Seed and Time stamp sig based on -l, - * so we'll toss the value in both for now, and sort it out in initialization - * after all the arguments are in and we know which it keep. - */ - initialTestParams.setTimeStampSignature = atoi(optarg); - initialTestParams.incompressibleSeed = atoi(optarg); - break; - case 'h': - initialTestParams.showHelp = TRUE; - break; - case 'H': - initialTestParams.showHints = TRUE; - break; - case 'i': - initialTestParams.repetitions = atoi(optarg); - break; - case 'I': - initialTestParams.individualDataSets = TRUE; - break; - case 'j': - initialTestParams.outlierThreshold = atoi(optarg); - break; - case 'J': - initialTestParams.setAlignment = StringToBytes(optarg); - break; - case 'k': - initialTestParams.keepFile = TRUE; - break; - case 'K': - initialTestParams.keepFileWithError = TRUE; - break; - case 'l': - switch(*optarg) { - case 'i': /* Incompressible */ - initialTestParams.dataPacketType = incompressible; - break; - case 't': /* timestamp */ - initialTestParams.dataPacketType = timestamp; - break; - case 'o': /* offset packet */ - initialTestParams.storeFileOffset = TRUE; - initialTestParams.dataPacketType = offset; - break; - default: - fprintf(out_logfile, - "Unknown arguement for -l %s generic assumed\n", optarg); - break; - } - break; - case 'm': - initialTestParams.multiFile = TRUE; - break; - case 'M': - initialTestParams.memoryPerNode = - NodeMemoryStringToBytes(optarg); - break; - case 'n': - initialTestParams.noFill = TRUE; - break; - case 'N': - initialTestParams.numTasks = atoi(optarg); - RecalculateExpectedFileSize(&initialTestParams); - break; - case 'o': - strcpy(initialTestParams.testFileName, optarg); - break; - case 'O': - ParseLine(optarg, &initialTestParams); - break; - case 'p': - initialTestParams.preallocate = TRUE; - break; - case 'P': - initialTestParams.useSharedFilePointer = TRUE; - break; - case 'q': - initialTestParams.quitOnError = TRUE; - break; - case 'Q': - initialTestParams.taskPerNodeOffset = atoi(optarg); - break; - case 'r': - initialTestParams.readFile = TRUE; - break; - case 'R': - initialTestParams.checkRead = TRUE; - break; - case 's': - initialTestParams.segmentCount = atoi(optarg); - RecalculateExpectedFileSize(&initialTestParams); - break; - case 'S': - initialTestParams.useStridedDatatype = TRUE; - break; - case 't': - initialTestParams.transferSize = StringToBytes(optarg); - break; - case 'T': - initialTestParams.maxTimeDuration = atoi(optarg); - break; - case 'u': - initialTestParams.uniqueDir = TRUE; - break; - case 'U': - strcpy(initialTestParams.hintsFileName, optarg); - break; - case 'v': - initialTestParams.verbose++; - break; - case 'V': - initialTestParams.useFileView = TRUE; - break; - case 'w': - initialTestParams.writeFile = TRUE; - break; - case 'W': - initialTestParams.checkWrite = TRUE; - break; - case 'x': - initialTestParams.singleXferAttempt = TRUE; - break; - case 'X': - initialTestParams.reorderTasksRandomSeed = atoi(optarg); - break; - case 'Y': - initialTestParams.fsyncPerWrite = TRUE; - break; - case 'z': - initialTestParams.randomOffset = TRUE; - break; - case 'Z': - initialTestParams.reorderTasksRandom = TRUE; - break; - default: - fprintf(out_logfile, - "ParseCommandLine: unknown option `-%c'.\n", - optopt); - } + if (toggleG){ + initialTestParams.setTimeStampSignature = toggleG; + initialTestParams.incompressibleSeed = toggleG; } - tests = CreateTest(&initialTestParams, 0); - AllocResults(tests); + if (buffer_type[0] != 0){ + switch(buffer_type[0]) { + case 'i': /* Incompressible */ + initialTestParams.dataPacketType = incompressible; + break; + case 't': /* timestamp */ + initialTestParams.dataPacketType = timestamp; + break; + case 'o': /* offset packet */ + initialTestParams.storeFileOffset = TRUE; + initialTestParams.dataPacketType = offset; + break; + default: + fprintf(out_logfile, + "Unknown arguement for -l %s; generic assumed\n", buffer_type); + break; + } + } + if (memoryPerNode){ + initialTestParams.memoryPerNode = NodeMemoryStringToBytes(optarg); + } + + /* get the version of the tests */ + + const ior_aiori_t * backend = aiori_select(initialTestParams.api); + initialTestParams.backend = backend; + initialTestParams.apiVersion = backend->get_version(); + + if(printhelp != 0){ + printf("Usage: %s ", argv[0]); + + option_print_help(options, 0); + + if(backend->get_options != NULL){ + printf("\nPlugin options for backend %s (%s)\n", initialTestParams.api, backend->get_version()); + option_print_help(backend->get_options(), 1); + } + if(printhelp == 1){ + exit(0); + }else{ + exit(1); + } + } + + if (testscripts){ + tests = ReadConfigScript(testscripts); + }else{ + tests = CreateTest(&initialTestParams, 0); + } CheckRunSettings(tests);