Skip to content

Commit

Permalink
atmega_common: fixed issues in getopt implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Viraj Sahai committed May 24, 2018
1 parent d8a6703 commit fa96102
Show file tree
Hide file tree
Showing 5 changed files with 15,396 additions and 15,424 deletions.
2 changes: 0 additions & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@
# when the heading is exactly 7 characters long.
*.md conflict-marker-size=100
*.txt conflict-marker-size=100
*.c text eof=lf
*.h text eof=lf
175 changes: 74 additions & 101 deletions cpu/atmega_common/getopt.c
Original file line number Diff line number Diff line change
@@ -1,182 +1,155 @@
/*
* Copyright (C) 2018 Viraj Sahai <vsahai@usc.edu, virajsahai32@gmail.com>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
* Copyright (C) 2018 Viraj Sahai <vsahai@usc.edu, virajsahai32@gmail.com>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/

/**
* @ingroup cpu_atmega_common
* @{
*
* @file getopt.c
* @brief Implementation of getopt lib.
*
* This implements the getopt and getopt_r functionality. getopt_r has a few caveats, make sure to use it correctly.
*
* @author Viraj Sahai <vsahai@usc.edu, virajsahai32@gmail.com>
*
*/
* @ingroup cpu_atmega_common
* @{
*
* @file getopt.c
* @brief Implementation of getopt lib.
*
* This implements the getopt and getopt_r functionality. getopt_r has a few caveats, make sure to use it correctly.
*
* @author Viraj Sahai <vsahai@usc.edu, virajsahai32@gmail.com>
*
*/

#include <stdio.h>
#include <string.h>
#include "getopt.h"

char* optarg;
char *optarg;
int optind = 1, opterr = 1, optopt;

int getopt(int argc, char* const argv[], const char* optstring)
int getopt(int argc, char *const argv[], const char *optstring)
{
char* loc_optstr = NULL, loc_argvptr = NULL;
char *loc_optstr = NULL;
char *loc_argvptr = NULL;
char opt;

optarg = NULL;

if(optind < 1 || optind > argc)
{
if (optind < 1 || optind >= argc) {
return -1;
}

if(*argv[optind] != '-' || !(argv[optind]+1) || *(argv[optind]+1) == '\0' || *(argv[optind]+1) == '-')
{
if (*argv[optind] != '-' || !(argv[optind] + 1) || *(argv[optind] + 1) == '\0' || *(argv[optind] + 1) == '-') {
return -1;
}

opt = *(argv[optind] + 1);
loc_optstr = strchr(optstring, (int)opt);

if(loc_optstr == NULL)
{
if(opterr && optstring[0] != ':')
{
fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
if (loc_optstr == NULL) {
if (opterr && optstring[0] != ':') {
fprintf(stderr, "%s: unknown option -%c\n", argv[0], opt);
}
optopt = c;
optopt = opt;
return '?';
}

if((argv[optind] + 2) && *(argv[optind] + 2) != '\0')
{
if ((argv[optind] + 2) && *(argv[optind] + 2) != '\0') {
loc_argvptr = argv[optind] + 2;
}

++optind;
++loc_optstr;

if(*loc_optstr == ':')
{
if (*loc_optstr == ':') {
++loc_optstr;

if(*loc_optstr == ':')
{
if(loc_argvptr != NULL)
{
if (*loc_optstr == ':') {
if (loc_argvptr != NULL) {
optarg = loc_argvptr;
}
}
else
{
if(loc_argvptr != NULL)
{
else {
if (loc_argvptr != NULL) {
optarg = loc_argvptr;
}
else
{
if(optind < argc && *(argv[optind]) != '-')
{
else {
if (optind < argc && *(argv[optind]) != '-') {
optarg = argv[optind++];
}
else
{
if(opterr && optstring[0] != ':')
{
fprintf(stderr, "%s: missing argument for -%c\n", argv[0], c);
else {
if (opterr && optstring[0] != ':') {
fprintf(stderr, "%s: missing argument for -%c\n", argv[0], opt);
}
if(optstring[0] == ':')
{
return ":";
if (optstring[0] == ':') {
return ':';
}
return "?";
return '?';
}
}
}
}
return c;
return opt;
}

int getopt_r(int argc, char* const argv[], const char* optstring, opt_t* r)
int getopt_r(int argc, char *const argv[], const char *optstring, opt_t *r)
{
char* loc_optstr = NULL, loc_argvptr = NULL;
char *loc_optstr = NULL;
char *loc_argvptr = NULL;
char opt;

if(r.optind < 1 || r.optind > argc)
{
if (r->optind < 1 || r->optind >= argc) {
return -1;
}

if(*argv[r.optind] != '-' || !(argv[r.optind]+1) || *(argv[r.optind]+1) == '\0' || *(argv[r.optind]+1) == '-')
{
if (*argv[r->optind] != '-' || !(argv[r->optind] + 1) || *(argv[r->optind] + 1) == '\0' || *(argv[r->optind] + 1) == '-') {
return -1;
}

opt = *(argv[r.optind] + 1);
opt = *(argv[r->optind] + 1);
loc_optstr = strchr(optstring, (int)opt);

if(loc_optstr == NULL)
{
if(r.opterr && optstring[0] != ':')
{
fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
if (loc_optstr == NULL) {
if (r->opterr && optstring[0] != ':') {
fprintf(stderr, "%s: unknown option -%c\n", argv[0], opt);
}
r.optopt = c;
r->optopt = opt;
return '?';
}

if((argv[r.optind] + 2) && *(argv[r.optind] + 2) != '\0')
{
loc_argvptr = argv[r.optind] + 2;
if ((argv[r->optind] + 2) && *(argv[r->optind] + 2) != '\0') {
loc_argvptr = argv[r->optind] + 2;
}

++r.optind;
++r->optind;
++loc_optstr;

if(*loc_optstr == ':')
{
if (*loc_optstr == ':') {
++loc_optstr;

if(*loc_optstr == ':')
{
if(loc_argvptr != NULL)
{
r.optarg = loc_argvptr;
if (*loc_optstr == ':') {
if (loc_argvptr != NULL) {
r->optarg = loc_argvptr;
}
}
else
{
if(loc_argvptr != NULL)
{
r.optarg = loc_argvptr;
else {
if (loc_argvptr != NULL) {
r->optarg = loc_argvptr;
}
else
{
if(r.optind < argc && *(argv[r.optind]) != '-')
{
r.optarg = argv[r.optind++];
else {
if (r->optind < argc && *(argv[r->optind]) != '-') {
r->optarg = argv[r->optind++];
}
else
{
if(r.opterr && optstring[0] != ':')
{
fprintf(stderr, "%s: missing argument for -%c\n", argv[0], c);
else {
if (r->opterr && optstring[0] != ':') {
fprintf(stderr, "%s: missing argument for -%c\n", argv[0], opt);
}
if(optstring[0] == ':')
{
return ":";
if (optstring[0] == ':') {
return ':';
}
return "?";
return '?';
}
}
}
}
return c;
}
return opt;
}
88 changes: 45 additions & 43 deletions cpu/atmega_common/include/getopt.h
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
/*
* Copyright (C) 2018 Viraj Sahai <vsahai@usc.edu, virajsahai32@gmail.com>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
* Copyright (C) 2018 Viraj Sahai <vsahai@usc.edu, virajsahai32@gmail.com>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/

/**
* @ingroup cpu_atmega_common
* @{
*
* @file header
* @brief Implementation of getopt lib.
*
* This implements the getopt and getopt_r functionality. getopt_r has a few caveats, make sure to use it correctly.
*
* @author Viraj Sahai <vsahai@usc.edu, virajsahai32@gmail.com>
*
*/
* @ingroup cpu_atmega_common
* @{
*
* @file header
* @brief Implementation of getopt lib.
*
* This implements the getopt and getopt_r functionality. getopt_r has a few caveats, make sure to use it correctly.
*
* @author Viraj Sahai <vsahai@usc.edu, virajsahai32@gmail.com>
*
*/

#ifndef GETOPT_H
#define GETOPT_H
Expand All @@ -26,47 +26,49 @@
extern "C" {
#endif

typedef struct{
char* optarg;
typedef struct {
char *optarg;
int optind;
int opterr;
int optopt;
} opt_t;

static const opt_t def_opt = {NULL,1,1,-1};

/*Don't forget to use this else the call to getopt_r will fail eg. opt_t x = INIT_OPT_T(x);*/
/*Don't forget to use this else the call to getopt_r will fail eg. opt_t *x = INIT_OPT_T_PTR;*/
/*INIT_OPT_T_PTR is used to initalize an opt_t* variable, INIT_OPT_T for opt_t. */
/*To change options, edit the fields of opt_t and call getopt_r*/

#define INIT_OPT_T(x) x = def_opt
#define INIT_OPT_T_PTR &(opt_t){ NULL, 1, 1, -1 }
#define INIT_OPT_T { NULL, 1, 1, -1 }

extern char* optarg;
extern char *optarg;
extern int optind, opterr, optopt;

/**
* @brief Non re-entrant version of getopt.
*
* @param[in] argc The count of the number of arguments.
* @param[in] argv The array containing all the arguments.
* @param[in] optstring The string of expected options.
*
* @return ASCII value of the option if option was succesfully found, '?' or ':' when unknown option is found or argument is missing.
*/
* @brief Non re-entrant version of getopt.
*
* @param[in] argc The count of the number of arguments.
* @param[in] argv The array containing all the arguments.
* @param[in] optstring The string of expected options.
*
* @return ASCII value of the option if option was succesfully found.
* '?' or ':' when unknown option is found or argument is missing.
*/

int getopt(int argc, char* const argv[], const char* optstring);
int getopt(int argc, char *const argv[], const char *optstring);

/**
* @brief Re-entrant version of getopt.
*
* @param[in] argc The count of the number of arguments.
* @param[in] argv The array containing all the arguments.
* @param[in] optstring The string of expected options.
* @param[out] r The per call struct for holding return args and other options.
*
* @return ASCII value of the option if option was succesfully found, '?' or ':' when unknown option is found or argument is missing.
*/
* @brief Re-entrant version of getopt.
*
* @param[in] argc The count of the number of arguments.
* @param[in] argv The array containing all the arguments.
* @param[in] optstring The string of expected options.
* @param[out] r The per call struct for holding return args and other options.
*
* @return ASCII value of the option if option was succesfully found.
* '?' or ':' when unknown option is found or argument is missing.
*/

int getopt_r(int argc, char* const argv[], const char* optstring, opt_t* r);
int getopt_r(int argc, char *const argv[], const char *optstring, opt_t *r);

#ifdef __cplusplus
}
Expand Down
Loading

0 comments on commit fa96102

Please sign in to comment.