15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ***** BEGIN LICENSE BLOCK *****
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Version: MPL 1.1/GPL 2.0/LGPL 2.1
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The contents of this file are subject to the Mozilla Public License Version
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1.1 (the "License"); you may not use this file except in compliance with
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the License. You may obtain a copy of the License at
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.mozilla.org/MPL/
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Software distributed under the License is distributed on an "AS IS" basis,
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for the specific language governing rights and limitations under the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Original Code is nm2tsv.c code, released
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Oct 10, 2002.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Initial Developer of the Original Code is
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Netscape Communications Corporation.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Portions created by the Initial Developer are Copyright (C) 2002
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Initial Developer. All Rights Reserved.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Contributor(s):
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   Garrett Arch Blythe, 10-October-2002
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Alternatively, the contents of this file may be used under the terms of
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * either the GNU General Public License Version 2 or later (the "GPL"), or
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in which case the provisions of the GPL or the LGPL are applicable instead
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of those above. If you wish to allow use of your version of this file only
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * under the terms of either the GPL or the LGPL, and not to allow others to
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * use your version of this file under the terms of the MPL, indicate your
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * decision by deleting the provisions above and replace them with the notice
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and other provisions required by the GPL or the LGPL. If you do not delete
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the provisions above, a recipient may use your version of this file under
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the terms of any one of the MPL, the GPL or the LGPL.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ***** END LICENSE BLOCK ***** */
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ERROR_REPORT(num, val, msg)   fprintf(stderr, "error(%d):\t\"%s\"\t%s\n", (num), (val), (msg));
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CLEANUP(ptr)    do { if(NULL != ptr) { free(ptr); ptr = NULL; } } while(0)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct __struct_Options
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Options to control how we perform.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mProgramName    Used in help text.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mInput          File to read for input.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                  Default is stdin.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mInputName      Name of the file.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mOutput         Output file, append.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                  Default is stdout.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mOutputName     Name of the file.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mHelp           Whether or not help should be shown.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* mProgramName;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE* mInput;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* mInputName;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE* mOutput;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* mOutputName;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHelp;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Options;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct __struct_Switch
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Command line options.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* mLongName;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* mShortName;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHasValue;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* mValue;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* mDescription;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Switch;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DESC_NEWLINE "\n\t\t"
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch gInputSwitch = {"--input", "-i", 1, NULL, "Specify input file." DESC_NEWLINE "stdin is default."};
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch gOutputSwitch = {"--output", "-o", 1, NULL, "Specify output file." DESC_NEWLINE "Appends if file exists." DESC_NEWLINE "stdout is default."};
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch gHelpSwitch = {"--help", "-h", 0, NULL, "Information on usage."};
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch* gSwitches[] = {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &gInputSwitch,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &gOutputSwitch,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &gHelpSwitch
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char* scanWhite(char* inScan)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Scan for whitespace.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* retval = inScan;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while('\0' != *retval && 0 == isspace(*retval))
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval++;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void trimWhite(char* inString)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Remove any whitespace from the end of the string.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len = strlen(inString);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while(len)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len--;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(isspace(*(inString + len)))
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *(inString + len) = '\0';
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int nm2tsv(Options* inOptions)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Read all input.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Output tab separated value data.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  We expect our data to be in a particular format.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  nm --format=bsd --size-sort --print-file-name --demangle
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char lineBuffer[4096];  /* yes, the are some very large symbols */
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* module = NULL;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* size = NULL;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* type = NULL;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* symbol = NULL;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Read in the nm file.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while(0 == retval && NULL != fgets(lineBuffer, sizeof(lineBuffer), inOptions->mInput))
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trimWhite(lineBuffer);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ** Find the various pieces of information we'll be looking for.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        size = strchr(lineBuffer, ':');
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(NULL != size)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *size = '\0';
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            size++;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            module = strrchr(lineBuffer, '/');
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(NULL == module)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                module = lineBuffer;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                *module = '\0';
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                module++;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            type = scanWhite(size);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *type = '\0';
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            type++;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            symbol = type + 1;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *symbol = '\0';
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            symbol++;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Skip certain types.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            switch(*type)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case '-':
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    continue;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                default:
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Simply output the data with a little more interpretation.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  First is size.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(inOptions->mOutput, "%s\t", size);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Type, CODE or DATA
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            switch(toupper(*type))
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case 'T': /* text (code) */
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case 'W': /* weak symbol ??? */
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    fprintf(inOptions->mOutput, "CODE\t");
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                default:
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    fprintf(inOptions->mOutput, "DATA\t");
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Scope, PUBLIC, STATIC, or UNDEF
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(islower(*type))
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                fprintf(inOptions->mOutput, "STATIC\t");
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                switch(*type)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    case '?':
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        fprintf(inOptions->mOutput, "UNDEF\t");
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    default:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        fprintf(inOptions->mOutput, "PUBLIC\t");
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Module name, segment.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(inOptions->mOutput, "%s\t", module);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(inOptions->mOutput, "%c\t", toupper(*type));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Origin
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(inOptions->mOutput, "UNDEF:%s:%c\t", module, toupper(*type));
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Symbol is last.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(inOptions->mOutput, "%s\n", symbol);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = __LINE__;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ERROR_REPORT(retval, lineBuffer, "Malformed input line.");
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(0 == retval && 0 != ferror(inOptions->mInput))
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = __LINE__;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ERROR_REPORT(retval, inOptions->mInputName, "Unable to read file.");
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int initOptions(Options* outOptions, int inArgc, char** inArgv)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  returns int     0 if successful.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int loop = 0;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int switchLoop = 0;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int match = 0;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int switchCount = sizeof(gSwitches) / sizeof(gSwitches[0]);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Switch* current = NULL;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Set any defaults.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(outOptions, 0, sizeof(Options));
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outOptions->mProgramName = inArgv[0];
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outOptions->mInput = stdin;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outOptions->mInputName = strdup("stdin");
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outOptions->mOutput = stdout;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outOptions->mOutputName = strdup("stdout");
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL == outOptions->mOutputName || NULL == outOptions->mInputName)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = __LINE__;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ERROR_REPORT(retval, "stdin/stdout", "Unable to strdup.");
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Go through and attempt to do the right thing.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(loop = 1; loop < inArgc && 0 == retval; loop++)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        match = 0;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current = NULL;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for(switchLoop = 0; switchLoop < switchCount && 0 == retval; switchLoop++)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(0 == strcmp(gSwitches[switchLoop]->mLongName, inArgv[loop]))
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                match = __LINE__;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else if(0 == strcmp(gSwitches[switchLoop]->mShortName, inArgv[loop]))
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                match = __LINE__;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(match)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(gSwitches[switchLoop]->mHasValue)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /*
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **  Attempt to absorb next option to fullfill value.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    */
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(loop + 1 < inArgc)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        loop++;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        current = gSwitches[switchLoop];
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        current->mValue = inArgv[loop];
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    current = gSwitches[switchLoop];
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(0 == match)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            outOptions->mHelp = __LINE__;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = __LINE__;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ERROR_REPORT(retval, inArgv[loop], "Unknown command line switch.");
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else if(NULL == current)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            outOptions->mHelp = __LINE__;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = __LINE__;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ERROR_REPORT(retval, inArgv[loop], "Command line switch requires a value.");
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ** Do something based on address/swtich.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(current == &gInputSwitch)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CLEANUP(outOptions->mInputName);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(NULL != outOptions->mInput && stdin != outOptions->mInput)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    fclose(outOptions->mInput);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    outOptions->mInput = NULL;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                outOptions->mInput = fopen(current->mValue, "r");
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(NULL == outOptions->mInput)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    retval = __LINE__;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ERROR_REPORT(retval, current->mValue, "Unable to open input file.");
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    outOptions->mInputName = strdup(current->mValue);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(NULL == outOptions->mInputName)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, current->mValue, "Unable to strdup.");
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else if(current == &gOutputSwitch)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CLEANUP(outOptions->mOutputName);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(NULL != outOptions->mOutput && stdout != outOptions->mOutput)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    fclose(outOptions->mOutput);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    outOptions->mOutput = NULL;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                outOptions->mOutput = fopen(current->mValue, "a");
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(NULL == outOptions->mOutput)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    retval = __LINE__;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ERROR_REPORT(retval, current->mValue, "Unable to open output file.");
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    outOptions->mOutputName = strdup(current->mValue);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(NULL == outOptions->mOutputName)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, current->mValue, "Unable to strdup.");
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else if(current == &gHelpSwitch)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                outOptions->mHelp = __LINE__;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                retval = __LINE__;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ERROR_REPORT(retval, current->mLongName, "No handler for command line switch.");
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void cleanOptions(Options* inOptions)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Clean up any open handles.
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLEANUP(inOptions->mInputName);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL != inOptions->mInput && stdin != inOptions->mInput)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fclose(inOptions->mInput);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLEANUP(inOptions->mOutputName);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL != inOptions->mOutput && stdout != inOptions->mOutput)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fclose(inOptions->mOutput);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(inOptions, 0, sizeof(Options));
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void showHelp(Options* inOptions)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Show some simple help text on usage.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int loop = 0;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int switchCount = sizeof(gSwitches) / sizeof(gSwitches[0]);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* valueText = NULL;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("usage:\t%s [arguments]\n", inOptions->mProgramName);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("\n");
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("arguments:\n");
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(loop = 0; loop < switchCount; loop++)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(gSwitches[loop]->mHasValue)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            valueText = " <value>";
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            valueText = "";
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("\t%s%s\n", gSwitches[loop]->mLongName, valueText);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("\t %s%s", gSwitches[loop]->mShortName, valueText);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf(DESC_NEWLINE "%s\n\n", gSwitches[loop]->mDescription);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("This tool normalizes nm output for use by other tools.\n");
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("GNU nm is assumed for symbol type determination.\n");
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("i.e. Use this tool to parse the output of:\n");
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("\t/usr/bin/nm --format=bsd --size-sort --print-file-name --demangle <exefile>\n");
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int inArgc, char** inArgv)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Options options;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retval = initOptions(&options, inArgc, inArgv);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(options.mHelp)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        showHelp(&options);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if(0 == retval)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = nm2tsv(&options);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cleanOptions(&options);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
506