|
|
/*++
Copyright (C) Microsoft Corporation, 1995 - 1999
Module Name:
tclHelp
Abstract:
Routines to simplify Tcl command line parsing.
Author:
Doug Barlow (dbarlow) 9/16/1997
Environment:
Tcl for Windows NT.
Notes:
--*/
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h> // All the Windows definitions.
#ifndef __STDC__
#define __STDC__ 1
#endif
#include "tclhelp.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
char outfile[FILENAME_MAX];
int commonParams( Tcl_Interp *interp, int argc, char *argv[], unsigned long int *cmdIndex, formatType *inFormat, formatType *outFormat) { if (NULL != inFormat) *inFormat = format_hexidecimal; if (NULL != outFormat) { *outFormat = format_hexidecimal; outfile[0] = '\000'; }
while (*cmdIndex < (unsigned long int)argc) { switch (poption(argv[(*cmdIndex)++], "-INPUT", "/INPUT", "-OUTPUT", "/OUTPUT", NULL)) { case 1: // -input { text | hexidecimal | file }
case 2: if (NULL == inFormat) { badSyntax(interp, argv, --(*cmdIndex)); goto ErrorExit; } if (*cmdIndex == (unsigned long int)argc) { Tcl_AppendResult(interp, "Insufficient parameters", NULL); goto ErrorExit; } switch (poption(argv[(*cmdIndex)++], "TEXT", "HEXIDECIMAL", "FILE", NULL)) { case 1: *inFormat = format_text; break; case 2: *inFormat = format_hexidecimal; break; case 3: *inFormat = format_file; break; default: Tcl_AppendResult(interp, "Unknown input format", NULL); goto ErrorExit; } break;
case 3: // -output { text | hexidecimal | file <filename> }
case 4: if (NULL == outFormat) { badSyntax(interp, argv, --(*cmdIndex)); goto ErrorExit; } if (*cmdIndex == (unsigned long int)argc) { Tcl_AppendResult(interp, "Insufficient parameters", NULL); goto ErrorExit; } switch (poption(argv[(*cmdIndex)++], "TEXT", "HEXIDECIMAL", "FILE", "DROP", NULL)) { case 1: *outFormat = format_text; break; case 2: *outFormat = format_hexidecimal; break; case 3: if (*cmdIndex == (unsigned long int)argc) { Tcl_AppendResult(interp, "Insufficient parameters", NULL); goto ErrorExit; } strcpy(outfile, argv[(*cmdIndex)++]); *outFormat = format_file; break; case 4: *outFormat = format_empty; break; default: Tcl_AppendResult(interp, "Unknown output format", NULL); goto ErrorExit; } break;
default: *cmdIndex -= 1; return TCL_OK; } } return TCL_OK;
ErrorExit: return TCL_ERROR; }
int setResult( Tcl_Interp *interp, BYTE *aResult, BYTE aResultLen, formatType outFormat) { static char hexbuf[514]; DWORD index; FILE * fid = NULL;
switch (outFormat) { case format_empty: break;
case format_text: aResult[aResultLen] = '\000'; Tcl_AppendResult(interp, aResult, NULL); break;
case format_hexidecimal: for (index = 0; index < aResultLen; index += 1) sprintf(&hexbuf[index * 2], "%02x", aResult[index]); hexbuf[aResultLen * 2] = '\000'; Tcl_AppendResult(interp, hexbuf, NULL); break;
case format_file: if ('\000' == outfile[0]) { Tcl_AppendResult(interp, "Illegal output format", NULL); goto ErrorExit; } fid = fopen(outfile, "wb"); index = fwrite(aResult, sizeof(BYTE), aResultLen, fid); if (index != aResultLen) { Tcl_AppendResult(interp, ErrorString(GetLastError()), NULL); goto ErrorExit; } fclose(fid); Tcl_AppendResult(interp, outfile, NULL); break;
default: Tcl_AppendResult(interp, "Unknown output format", NULL); goto ErrorExit; } return TCL_OK;
ErrorExit: if (NULL != fid) fclose(fid); return TCL_ERROR; }
int inParam( Tcl_Interp *interp, BYTE **output, BYTE *length, char *input, formatType format) { static BYTE buffer[256]; unsigned long int len, index, hex; FILE * fid = NULL;
len = strlen(input); switch (format) { case format_text: if (255 < len) { Tcl_AppendResult(interp, "Input too long.", NULL); goto ErrorExit; } *output = (BYTE *)input; *length = (BYTE)len; break;
case format_hexidecimal: if (510 < len) { Tcl_AppendResult(interp, "Input too long.", NULL); goto ErrorExit; } if (len != strspn(input, "0123456789ABCDEFabcdef")) { fprintf(stderr, "Invalid Hex number.\n"); goto ErrorExit; } for (index = 0; index < len; index += 2) { sscanf(&input[index], " %2lx", &hex); buffer[index / 2] = (BYTE)hex; } *output = buffer; *length = (BYTE)((0 == (len & 0x01)) ? (len / 2) : (len / 2 + 1)); break;
case format_file: fid = fopen(input, "rb"); if (NULL == fid) { Tcl_AppendResult(interp, ErrorString(GetLastError()), NULL); goto ErrorExit; } *length = (BYTE)fread(buffer, sizeof(BYTE), sizeof(buffer), fid); if (0 != ferror(fid)) { Tcl_AppendResult(interp, ErrorString(GetLastError()), NULL); goto ErrorExit; } *output = buffer; fclose(fid); break;
default: Tcl_AppendResult(interp, "Unknown input format", NULL); goto ErrorExit; }
return TCL_OK;
ErrorExit: if (NULL != fid) fclose(fid); return TCL_ERROR; }
BOOL ParamCount( Tcl_Interp *interp, DWORD argc, DWORD cmdIndex, DWORD dwCount) { BOOL fSts = TRUE; if (cmdIndex + dwCount > (unsigned long int)argc) { Tcl_AppendResult(interp, "Insufficient parameters", NULL); fSts = FALSE; } return fSts; }
void badSyntax( Tcl_Interp *interp, char *argv[], unsigned long int cmdIndex) { unsigned long int index;
Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Invalid option '", NULL); Tcl_AppendResult(interp, argv[cmdIndex], NULL); Tcl_AppendResult(interp, "' to the '", NULL); for (index = 0; index < cmdIndex; index += 1) Tcl_AppendResult(interp, argv[index], " ", NULL); Tcl_AppendResult(interp, "...' command.", NULL); }
void SetMultiResult( Tcl_Interp *interp, LPTSTR mszResult) { LPTSTR sz = mszResult; while (0 != *sz) { Tcl_AppendElement(interp, sz); sz += strlen(sz) + 1; } }
LPWSTR Unicode( LPCSTR sz) { static WCHAR szUnicode[2048]; int length;
length = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sz, strlen(sz), szUnicode, sizeof(szUnicode) / sizeof(WCHAR)); szUnicode[length] = 0; return szUnicode; }
static char * ErrorBuffer = NULL;
char * ErrorString( long theError) { if (NULL != ErrorBuffer) { LocalFree(ErrorBuffer); ErrorBuffer = NULL; } if (0 == FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, theError, LANG_NEUTRAL, (LPTSTR)&ErrorBuffer, 0, NULL)) { if (0 == FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE, GetModuleHandle(NULL), theError, LANG_NEUTRAL, (LPTSTR)&ErrorBuffer, 0, NULL)) { if (0 == FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE, GetModuleHandle(TEXT("winscard")), theError, LANG_NEUTRAL, (LPTSTR)&ErrorBuffer, 0, NULL)) { ErrorBuffer = LocalAlloc(LMEM_FIXED, 32 * sizeof(TCHAR)); sprintf(ErrorBuffer, "Unknown error code 0x%08x", theError); } } } return ErrorBuffer; } /* end LastErrorString */
void FreeErrorString( void) { if (NULL != ErrorBuffer) LocalFree(ErrorBuffer); ErrorBuffer = NULL; } /* end FreeErrorString */
int poption( const char *opt, ...)
/*
* * Function description: * * poption takes a list of keywords, supplied by parameters, and returns * the number in the list that matches the input option in the first * parameter. If the input option doesn't match any in the list, then a * zero is returned. If the input option is an abbreviation of an option, * then the match completes. For example, an input option of "de" would * match "debug" or "decode". If both were present in the possible * options list, then a match would be declared for the first possible * option encountered. * * * Arguments: * * opt - The option to match against. * * opt1, opt2, ... - Pointers to null terminated strings containing * the possible options to look for. The last option must be NULL, * indicating the end of the list. * * * Return value: * * 0 - No match found * 1-n - Match on option number i, 0 < i <= n, where n is the number * of options given, excluding the terminating NULL. * * * Side effects: * * None. * */
{ /*
* Local Variable Definitions: %local-vars% * Variable Description -------- --------------------------------------------*/ va_list ap; /* My parameter context. */ int len, /* Length of the option string. */ ret /* The return value. */ = 0, index /* loop index. */ = 1; char *kw; /* Pointer to the next option */
/*
* Start of Code. */
va_start(ap, opt);
/*
* Step through each input parameter until we find an exact match. */
len = strlen(opt); if (0 == len) return 0; /* Empty strings don't match anything. */ kw = va_arg(ap, char*); while (NULL != kw) { if (0 == _strnicmp(kw, opt, len)) { ret = index; break; } kw = va_arg(ap, char*); index += 1; } va_end(ap); return ret; } /* end poption */
|