Skip to content

Commit

Permalink
Use getopt so ini is optional
Browse files Browse the repository at this point in the history
  • Loading branch information
nyetwurk committed Jan 3, 2013
1 parent b4bd6d1 commit bfccf92
Show file tree
Hide file tree
Showing 5 changed files with 439 additions and 18 deletions.
75 changes: 58 additions & 17 deletions me7sum.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h> /* isprint() */

#if _MSC_VER
#define snprintf _snprintf
#include "os/getopt.h"
#else
#include <getopt.h>
#endif

#include "inifile_prop.h"
Expand Down Expand Up @@ -110,45 +114,82 @@ static int DoChecksumBlk(struct ImageHandle *ih, uint32_t nStartBlk);
*
*/

static void usage(const char *prog)
{
printf("Usage: %s [-i <config.ini>] <inrom.bin> [outrom.bin]\n", prog);
exit(-1);
}

int main(int argc, char **argv)
{
int iTemp;
int result;
int num_of;
char *prog=argv[0];
char *inifile=NULL;
char *input=NULL;
char *output=NULL;
char c;
struct ImageHandle ih;
struct section *osconfig;
struct section *osconfig=NULL;

// information about the tool
printf("ME7Tool [ Management tool for Bosch ME7.x firmwares]\n");
printf("Inspiration from Andy Whittaker's tools and information\n");
printf("Written by 360trev and nyet [BSD License Open Source]. \n\n");

if(argc < 3 || argc > 4)
opterr=0;

while ((c = getopt(argc, argv, "i:")) != -1)
{
printf("Usage: %s <config.ini> <inrom.bin> [outrom.bin]\n",argv[0]);
return -1;
switch (c)
{
case 'i':
inifile=optarg;
break;
case '?':
if (optopt == 'i')
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint(optopt))
fprintf(stderr, "Unknown option '-%c'.\n", optopt);
// break; // fallthrough
default:
usage(prog);
return -1;
}
}

if(argc==3)
{
argc-=optind;
argv+=optind;

if (argc==0 || argc>2)
usage(prog);

input = argv[0];

if (argc>1)
output = argv[1];
else
Config.readonly=1;
}

printf("Attemping to open firmware config file %s\n",argv[1]);
// load properties file into memory
osconfig = read_properties(argv[1]);
if(osconfig == NULL)
if (inifile)
{
printf("failed to open config file\n");
return -1;
printf("Attemping to open firmware config file %s\n",inifile);
// load properties file into memory
osconfig = read_properties(inifile);
if(osconfig == NULL)
{
printf("failed to open config file\n");
return -1;
}
}

// get rom region information from config file (see defined property list)
result = process_properties_list(osconfig, romProps);

// open the firmware file
printf("\nAttemping to open firmware file %s\n",argv[2]);
if (iload_file(&ih, argv[2], 0))
printf("\nAttemping to open firmware file %s\n",input);
if (iload_file(&ih, input, 0))
{
printf("failed to open firmware file\n");
goto out;
Expand Down Expand Up @@ -230,9 +271,9 @@ int main(int argc, char **argv)
printf("Skipping Multipoint Checksum Block... undefined\n");
}

if(argc>3 && ErrorsCorrected > 0) {
if(output && ErrorsCorrected > 0) {
// write crc corrected file out
save_file(argv[3],ih.d.p,ih.len);
save_file(output,ih.d.p,ih.len);
}

out:
Expand Down
2 changes: 1 addition & 1 deletion nmakefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
TARGET = me7sum.exe
SOURCES = crc32.c inifile_prop.c me7sum.c utils.c inifile/inifile.c
SOURCES = crc32.c inifile_prop.c me7sum.c utils.c inifile/inifile.c os/pgetopt.c

all: $(TARGET)
$(TARGET):$(SOURCES)
Expand Down
12 changes: 12 additions & 0 deletions os/getopt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _GETOPT_H
#define _GETOPT_H

#include "pgetopt.h"
#define getopt pgetopt
/* popterr does the WRONG thing */
static int opterr;
#define optind poptind
#define optarg poptarg
#define optopt poptopt

#endif
233 changes: 233 additions & 0 deletions os/pgetopt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
/*
* pgetopt.c - Portable implementation of getopt() command line args parser,
* originally made available by IBM and the authors listed below.
*
* Created on 8/8/08.
* Portions of this document are Copyright (C) 2008, PlexFX,
* All Rights Reserved.
*
* History:
* Original Date Unknown
* This code is quite old, but it was originally called GETOPT.C
* in the comments, along with a GETOPT.H thin header, and used the
* same namespace as the getopt() implementation on my UNIX variant
* platforms. The original date has been lost. It may date back
* to even pre-ANSI C. The development team at PlexFX has been
* using it (primarily for Windows command line tools, but also on
* other platforms for many years. A search for historical dates
* via web search engines found it widely used, but no date stamps
* on its original form seem to have been preserved.
* It can be found in various forms in open source packages, such
* as using a search engine on one or both of the author strings
* shown in the original comment block below. For example, as of
* the creation date on this file, a slightly modified verion of
* it was used in library code found in the CVS tree for
* OpenSolaris.
*
* It was also included on at least some of the MSDN Library discs
* Around the early 2001-2003 time frame.
*
* 2008-08-08 This version is a modified version of the original IBM code, but
* the filename and namespace used has been altered along with some
* calling convention changes. As such, it can be used as a drop-
* in replacement for getopt() even on UNIX or Linux systems that
* have their own getopt() implementations in libc without naming
* collisions. This means it can be used portably on any OS with
* a conforming C compiler. It does *not* attempt to implement the
* more long-winded getopt_long() interface. Naming of APIs,
* headers and the optarg/optind externs have been prefixed with
* 'p' to accomplish this. Examples: pgetopt(), poptarg, poptind,
* pgetopt.c, pgetopt.h.
* Note: This interface keeps external state (to match original
* calling conventions). As such, it is not thread safe,
* and should be called in only one thread (use from main()
* before additional threads are started). As the command
* line should never change, this should not be an issue.
*
*/

/* Original IBM "AS IS" license follows */

/*****************************************************************************
*
* MODULE NAME : GETOPT.C
*
* COPYRIGHTS:
* This module contains code made available by IBM
* Corporation on an AS IS basis. Any one receiving the
* module is considered to be licensed under IBM copyrights
* to use the IBM-provided source code in any way he or she
* deems fit, including copying it, compiling it, modifying
* it, and redistributing it, with or without
* modifications. No license under any IBM patents or
* patent applications is to be implied from this copyright
* license.
*
* A user of the module should understand that IBM cannot
* provide technical support for the module and will not be
* responsible for any consequences of use of the program.
*
* Any notices, including this one, are not to be removed
* from the module without the prior written consent of
* IBM.
*
* AUTHOR: Original author:
* G. R. Blair (BOBBLAIR at AUSVM1)
* Internet: [email protected]
*
* Extensively revised by:
* John Q. Walker II, Ph.D. (JOHHQ at RALVM6)
* Internet: [email protected]
*
*****************************************************************************/

/******************************************************************************
* pgetopt()
*
* The pgetopt() function is a command line parser. It returns the next
* option character in argv that matches an option character in optstring.
*
* The argv argument points to an array of argc+1 elements containing argc
* pointers to character strings followed by a null pointer.
*
* The optstring argument points to a string of option characters; if an
* option character is followed by a colon, the option is expected to have
* an argument that may or may not be separated from it by white space.
* The external variable poptarg is set to point to the start of the option
* argument on return from pgetopt().
*
* The pgetopt() function places in poptind the argv index of the next argument
* to be processed. The system initializes the external variable poptind to
* 1 before the first call to pgetopt().
*
* When all options have been processed (that is, up to the first nonoption
* argument), pgetopt() returns -1. The special option "--" may be used to
* delimit the end of the options; -1 will be returned, and "--" will be
* skipped.
*
* The pgetopt() function returns a question mark (?) when it encounters an
* option character not included in optstring. This error message can be
* disabled by setting popterr to zero. Otherwise, it returns the option
* character that was detected.
*
* If the special option "--" is detected, or all options have been
* processed, -1 is returned.
*
* Options are marked by either a minus sign (-) or a slash (/).
*
* No other errors are defined.
*****************************************************************************/

//#include <stdio.h> /* for EOF */
#include <string.h> /* for strchr() */
#include "pgetopt.h" /* pgetopt() interface and example code */

/* global variables that are specified as exported by pgetopt() */
char *poptarg = NULL; /* pointer to the start of the option argument */
int poptind = 1; /* number of the next argv[] to be evaluated */
int popterr = 1; /* non-zero if a question mark should be returned
* when a non-valid option character is detected */
int poptopt = 0; /* original opt when we return ? */

/* handle possible future character set concerns by putting this in a macro */
#define _next_char(string) (char)(*(string+1))

int
pgetopt(int argc, char *argv[], char *optstring)
{
static char *IndexPosition = NULL; /* place inside current argv string */
char *ArgString = NULL; /* where to start from next */
char *OptString; /* the string in our program */


if (IndexPosition != NULL) {
/* we last left off inside an argv string */
if (*(++IndexPosition)) {
/* there is more to come in the most recent argv */
ArgString = IndexPosition;
}
}

if (ArgString == NULL) {
/* we didn't leave off in the middle of an argv string */
if (poptind >= argc) {
/* more command-line arguments than the argument count */
IndexPosition = NULL; /* not in the middle of anything */
return -1; /* used up all command-line arguments */
}

/*---------------------------------------------------------------------
* If the next argv[] is not an option, there can be no more options.
*-------------------------------------------------------------------*/
ArgString = argv[poptind++]; /* set this to the next argument ptr */

if (('/' != *ArgString) && /* doesn't start with a slash or a dash? */
('-' != *ArgString)) {
--poptind; /* point to current arg once we're done */
poptarg = NULL; /* no argument follows the option */
IndexPosition = NULL; /* not in the middle of anything */
return -1; /* used up all the command-line flags */
}

/* check for special end-of-flags markers */
if ((strcmp(ArgString, "-") == 0) ||
(strcmp(ArgString, "--") == 0)) {
poptarg = NULL; /* no argument follows the option */
IndexPosition = NULL; /* not in the middle of anything */
return -1; /* encountered the special flag */
}

ArgString++; /* look past the / or - */
}

if (':' == *ArgString) { /* is it a colon? */
/*---------------------------------------------------------------------
* Rare case: if opterr is non-zero, return a question mark;
* otherwise, just return the colon we're on.
*-------------------------------------------------------------------*/
return (popterr ? (int)'?' : (int)':');
}
else if ((OptString = strchr(optstring, *ArgString)) == 0) {
/*---------------------------------------------------------------------
* The letter on the command-line wasn't any good.
*-------------------------------------------------------------------*/
poptarg = NULL; /* no argument follows the option */
IndexPosition = NULL; /* not in the middle of anything */
poptopt = (int)*ArgString;
return (popterr ? (int)'?' : (int)*ArgString);
}
else {
/*---------------------------------------------------------------------
* The letter on the command-line matches one we expect to see
*-------------------------------------------------------------------*/
if (':' == _next_char(OptString)) { /* is the next letter a colon? */
/* It is a colon. Look for an argument string. */
if ('\0' != _next_char(ArgString)) { /* argument in this argv? */
poptarg = &ArgString[1]; /* Yes, it is */
}
else {
/*-------------------------------------------------------------
* The argument string must be in the next argv.
* But, what if there is none (bad input from the user)?
* In that case, return the letter, and poptarg as NULL.
*-----------------------------------------------------------*/
if (poptind < argc)
poptarg = argv[poptind++];
else {
poptarg = NULL;
poptopt = (int)*ArgString;
return (popterr ? (int)'?' : (int)*ArgString);
}
}
IndexPosition = NULL; /* not in the middle of anything */
}
else {
/* it's not a colon, so just return the letter */
poptarg = NULL; /* no argument follows the option */
IndexPosition = ArgString; /* point to the letter we're on */
}
return (int)*ArgString; /* return the letter that matched */
}
}


Loading

0 comments on commit bfccf92

Please sign in to comment.