|
Packit |
534379 |
// Copyright(c) 2018, Intel Corporation
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// Redistribution and use in source and binary forms, with or without
|
|
Packit |
534379 |
// modification, are permitted provided that the following conditions are met:
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// * Redistributions of source code must retain the above copyright notice,
|
|
Packit |
534379 |
// this list of conditions and the following disclaimer.
|
|
Packit |
534379 |
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
Packit |
534379 |
// this list of conditions and the following disclaimer in the documentation
|
|
Packit |
534379 |
// and/or other materials provided with the distribution.
|
|
Packit |
534379 |
// * Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
534379 |
// may be used to endorse or promote products derived from this software
|
|
Packit |
534379 |
// without specific prior written permission.
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
534379 |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
534379 |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
534379 |
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
Packit |
534379 |
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
Packit |
534379 |
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
Packit |
534379 |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
Packit |
534379 |
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
Packit |
534379 |
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
534379 |
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
Packit |
534379 |
// POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
534379 |
#include "argsfilter.h"
|
|
Packit |
534379 |
#include <getopt.h>
|
|
Packit |
534379 |
#include <stdlib.h>
|
|
Packit |
534379 |
#include <string.h>
|
|
Packit |
534379 |
#ifdef _WIN32
|
|
Packit |
534379 |
#define EX_OK 0
|
|
Packit |
534379 |
#define EX_USAGE (-1)
|
|
Packit |
534379 |
#define EX_SOFTWARE (-2)
|
|
Packit |
534379 |
#else
|
|
Packit |
534379 |
#include <sysexits.h>
|
|
Packit |
534379 |
#endif
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define RETURN_ON_ERR(res, desc) \
|
|
Packit |
534379 |
do { \
|
|
Packit |
534379 |
if ((res) != FPGA_OK) { \
|
|
Packit |
534379 |
optind = 1; \
|
|
Packit |
534379 |
opterr = old_opterr; \
|
|
Packit |
534379 |
fprintf(stderr, "Error %s: %s\n", (desc), \
|
|
Packit |
534379 |
fpgaErrStr(res)); \
|
|
Packit |
534379 |
return EX_SOFTWARE; \
|
|
Packit |
534379 |
} \
|
|
Packit |
534379 |
} while (0)
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int set_properties_from_args(fpga_properties filter, fpga_result *result,
|
|
Packit |
534379 |
int *argc, char *argv[])
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
// prefix the short options with '-' so that unrecognized options are
|
|
Packit |
534379 |
// ignored
|
|
Packit |
534379 |
const char *short_opts = "-:B:D:F:S:";
|
|
Packit |
534379 |
struct option longopts[] = {
|
|
Packit |
534379 |
{"bus", required_argument, NULL, 'B'},
|
|
Packit |
534379 |
{"device", required_argument, NULL, 'D'},
|
|
Packit |
534379 |
{"function", required_argument, NULL, 'F'},
|
|
Packit |
534379 |
{"socket-id", required_argument, NULL, 'S'},
|
|
Packit |
534379 |
{"segment", required_argument, NULL, 0xe},
|
|
Packit |
534379 |
{0, 0, 0, 0},
|
|
Packit |
534379 |
};
|
|
Packit |
534379 |
int supported_options = sizeof(longopts) / sizeof(longopts[0]) - 1;
|
|
Packit |
534379 |
int getopt_ret = -1;
|
|
Packit |
534379 |
int option_index = 0;
|
|
Packit |
534379 |
char *endptr = NULL;
|
|
Packit |
534379 |
int found_opts[] = {0, 0, 0, 0, 0};
|
|
Packit |
534379 |
int next_found = 0;
|
|
Packit |
534379 |
int old_opterr = opterr;
|
|
Packit |
534379 |
opterr = 0;
|
|
Packit |
534379 |
struct _args_filter_config {
|
|
Packit |
534379 |
int bus;
|
|
Packit |
534379 |
int device;
|
|
Packit |
534379 |
int function;
|
|
Packit |
534379 |
int socket_id;
|
|
Packit |
534379 |
int segment;
|
|
Packit |
534379 |
} args_filter_config = {
|
|
Packit |
534379 |
.bus = -1, .device = -1, .function = -1, .socket_id = -1,
|
|
Packit |
534379 |
.segment = -1 };
|
|
Packit |
534379 |
|
|
Packit |
534379 |
while (-1
|
|
Packit |
534379 |
!= (getopt_ret = getopt_long(*argc, argv, short_opts, longopts,
|
|
Packit |
534379 |
&option_index))) {
|
|
Packit |
534379 |
const char *tmp_optarg = optarg;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((optarg) && ('=' == *tmp_optarg))
|
|
Packit |
534379 |
++tmp_optarg;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
switch (getopt_ret) {
|
|
Packit |
534379 |
case 'B': /* bus */
|
|
Packit |
534379 |
if (NULL == tmp_optarg)
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
endptr = NULL;
|
|
Packit |
534379 |
args_filter_config.bus =
|
|
Packit |
534379 |
(int)strtoul(tmp_optarg, &endptr, 0);
|
|
Packit |
534379 |
if (endptr != tmp_optarg + strlen(tmp_optarg)) {
|
|
Packit |
534379 |
fprintf(stderr, "invalid bus: %s\n",
|
|
Packit |
534379 |
tmp_optarg);
|
|
Packit |
534379 |
return EX_USAGE;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
found_opts[next_found++] = optind - 2;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
case 'D': /* device */
|
|
Packit |
534379 |
if (NULL == tmp_optarg)
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
endptr = NULL;
|
|
Packit |
534379 |
args_filter_config.device =
|
|
Packit |
534379 |
(int)strtoul(tmp_optarg, &endptr, 0);
|
|
Packit |
534379 |
if (endptr != tmp_optarg + strlen(tmp_optarg)) {
|
|
Packit |
534379 |
fprintf(stderr, "invalid device: %s\n",
|
|
Packit |
534379 |
tmp_optarg);
|
|
Packit |
534379 |
return EX_USAGE;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
found_opts[next_found++] = optind - 2;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
case 'F': /* function */
|
|
Packit |
534379 |
if (NULL == tmp_optarg)
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
endptr = NULL;
|
|
Packit |
534379 |
args_filter_config.function =
|
|
Packit |
534379 |
(int)strtoul(tmp_optarg, &endptr, 0);
|
|
Packit |
534379 |
if (endptr != tmp_optarg + strlen(tmp_optarg)) {
|
|
Packit |
534379 |
fprintf(stderr, "invalid function: %s\n",
|
|
Packit |
534379 |
tmp_optarg);
|
|
Packit |
534379 |
return EX_USAGE;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
found_opts[next_found++] = optind - 2;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
case 'S': /* socket */
|
|
Packit |
534379 |
if (NULL == tmp_optarg)
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
endptr = NULL;
|
|
Packit |
534379 |
args_filter_config.socket_id =
|
|
Packit |
534379 |
(int)strtoul(tmp_optarg, &endptr, 0);
|
|
Packit |
534379 |
if (endptr != tmp_optarg + strlen(tmp_optarg)) {
|
|
Packit |
534379 |
fprintf(stderr, "invalid socket: %s\n",
|
|
Packit |
534379 |
tmp_optarg);
|
|
Packit |
534379 |
return EX_USAGE;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
found_opts[next_found++] = optind - 2;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
case 0xe: /* segment */
|
|
Packit |
534379 |
if (NULL == tmp_optarg)
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
endptr = NULL;
|
|
Packit |
534379 |
args_filter_config.segment =
|
|
Packit |
534379 |
(int)strtoul(tmp_optarg, &endptr, 0);
|
|
Packit |
534379 |
if (endptr != tmp_optarg + strlen(tmp_optarg)) {
|
|
Packit |
534379 |
fprintf(stderr, "invalid segment: %s\n",
|
|
Packit |
534379 |
tmp_optarg);
|
|
Packit |
534379 |
return EX_USAGE;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
found_opts[next_found++] = optind - 2;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
case ':': /* missing option argument */
|
|
Packit |
534379 |
fprintf(stderr, "Missing option argument\n");
|
|
Packit |
534379 |
return EX_USAGE;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
case '?':
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
case 1:
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
default: /* invalid option */
|
|
Packit |
534379 |
fprintf(stderr, "Invalid cmdline options\n");
|
|
Packit |
534379 |
return EX_USAGE;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (-1 != args_filter_config.bus) {
|
|
Packit |
534379 |
*result = fpgaPropertiesSetBus(filter, args_filter_config.bus);
|
|
Packit |
534379 |
RETURN_ON_ERR(*result, "setting bus");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (-1 != args_filter_config.device) {
|
|
Packit |
534379 |
*result = fpgaPropertiesSetDevice(filter,
|
|
Packit |
534379 |
args_filter_config.device);
|
|
Packit |
534379 |
RETURN_ON_ERR(*result, "setting device");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (-1 != args_filter_config.function) {
|
|
Packit |
534379 |
*result = fpgaPropertiesSetFunction(
|
|
Packit |
534379 |
filter, args_filter_config.function);
|
|
Packit |
534379 |
RETURN_ON_ERR(*result, "setting function");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (-1 != args_filter_config.socket_id) {
|
|
Packit |
534379 |
*result = fpgaPropertiesSetSocketID(
|
|
Packit |
534379 |
filter, args_filter_config.socket_id);
|
|
Packit |
534379 |
RETURN_ON_ERR(*result, "setting socket id");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (-1 != args_filter_config.segment) {
|
|
Packit |
534379 |
*result = fpgaPropertiesSetSegment(
|
|
Packit |
534379 |
filter, args_filter_config.segment);
|
|
Packit |
534379 |
RETURN_ON_ERR(*result, "setting segment");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
// using the list of optind values
|
|
Packit |
534379 |
// shorten the argv vector starting with a decrease
|
|
Packit |
534379 |
// of 2 and incrementing that amount by two for each option found
|
|
Packit |
534379 |
int removed = 0;
|
|
Packit |
534379 |
int i, j;
|
|
Packit |
534379 |
for (i = 0; i < supported_options; ++i) {
|
|
Packit |
534379 |
if (found_opts[i]) {
|
|
Packit |
534379 |
for (j = found_opts[i] - removed; j < *argc - 2; j++) {
|
|
Packit |
534379 |
argv[j] = argv[j + 2];
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
removed += 2;
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
*argc -= removed;
|
|
Packit |
534379 |
// restore getopt variables
|
|
Packit |
534379 |
// setting optind to zero will cause getopt to reinitialize for future
|
|
Packit |
534379 |
// calls within the program
|
|
Packit |
534379 |
optind = 0;
|
|
Packit |
534379 |
opterr = old_opterr;
|
|
Packit |
534379 |
return EX_OK;
|
|
Packit |
534379 |
}
|