From 3cef75b26c15242dcce41e41a7f7b1cd79c87d2d Mon Sep 17 00:00:00 2001 From: uz Date: Sun, 4 Mar 2012 21:02:31 +0000 Subject: [PATCH] Added parsing of arguments to --read. The explicit format spec is currently broken. git-svn-id: svn://svn.cc65.org/cc65/trunk@5576 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/sp65/attr.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++- src/sp65/attr.h | 29 +++++++++++++ src/sp65/input.c | 15 ++++++- src/sp65/input.h | 7 ++- src/sp65/main.c | 42 +++++++++++++++++- 5 files changed, 198 insertions(+), 6 deletions(-) diff --git a/src/sp65/attr.c b/src/sp65/attr.c index dfad5cc4f..d3449f0a9 100644 --- a/src/sp65/attr.c +++ b/src/sp65/attr.c @@ -32,7 +32,7 @@ /*****************************************************************************/ - + #include #include @@ -139,6 +139,62 @@ int FindAttr (const Collection* C, const char* Name, unsigned* Index) +const Attr* GetAttr (const Collection* C, const char* Name) +/* Search for an attribute with the given name and return it. The function + * returns NULL if the attribute wasn't found. + */ +{ + /* Search for the attribute and return it */ + unsigned Index; + if (FindAttr (C, Name, &Index)) { + return CollConstAt (C, Index); + } else { + /* Not found */ + return 0; + } +} + + + +const Attr* NeedAttr (const Collection* C, const char* Name, const char* Context) +/* Search for an attribute with the given name and return it. If the attribute + * is not found, the function terminates with an error using Context as + * additional context in the error message. + */ +{ + /* Search for the attribute and return it */ + unsigned Index; + if (!FindAttr (C, Name, &Index)) { + Error ("Found no attribute named `%s' in %s", Name, Context); + } + return CollConstAt (C, Index); +} + + + +const char* GetAttrVal (const Collection* C, const char* Name) +/* Search for an attribute with the given name and return its value. The + * function returns NULL if the attribute wasn't found. + */ +{ + const Attr* A = GetAttr (C, Name); + return (A == 0)? 0 : A->Value; +} + + + +const char* NeedAttrVal (const Collection* C, const char* Name, const char* Context) +/* Search for an attribute with the given name and return its value. If the + * attribute wasn't not found, the function terminates with an error using + * Context as additional context in the error message. + */ +{ + const Attr* A = NeedAttr (C, Name, Context); + return (A == 0)? 0 : A->Value; +} + + + void AddAttr (Collection* C, const char* Name, const char* Value) /* Add an attribute to an alphabetically sorted attribute collection */ { @@ -170,7 +226,7 @@ void SplitAddAttr (Collection* C, const char* Combined, const char* Name) if (Pos == 0) { /* Combined is actually a value */ if (Name == 0) { - Error ("Command line attribute `%s' doesn't contain a name", Name); + Error ("Command line attribute `%s' doesn't contain a name", Combined); } AddAttr (C, Name, Combined); } else { @@ -189,3 +245,54 @@ void SplitAddAttr (Collection* C, const char* Combined, const char* Name) +Collection* ParseAttrList (const char* List, const char** NameList, unsigned NameCount) +/* Parse a list containing name/value pairs into a sorted collection. Some + * attributes may not need a name, so NameList contains these names. If there + * were no errors, the function returns a alphabetically sorted collection + * containing Attr entries. + */ +{ + const char* Name; + + /* Create a new collection */ + Collection* C = NewCollection (); + + /* Name/value pairs are separated by commas */ + const char* L = List; + StrBuf B = AUTO_STRBUF_INITIALIZER; + while (1) { + if (*L == ',' || *L == '\0') { + + /* Terminate the string */ + SB_Terminate (&B); + + /* Determine the default name */ + if (CollCount (C) >= NameCount) { + Name = 0; + } else { + Name = NameList[CollCount (C)]; + } + + /* Split and add this attribute/value pair */ + SplitAddAttr (C, SB_GetConstBuf (&B), Name); + + /* Done, clear the buffer. */ + SB_Clear (&B); + if (*L == '\0') { + break; + } + } else { + SB_AppendChar (&B, *L); + } + ++L; + } + + /* Free memory */ + SB_Done (&B); + + /* Return the collection with the attributes */ + return C; +} + + + diff --git a/src/sp65/attr.h b/src/sp65/attr.h index 3d81cbf50..b1a6b92be 100644 --- a/src/sp65/attr.h +++ b/src/sp65/attr.h @@ -85,6 +85,28 @@ int FindAttr (const Collection* C, const char* Name, unsigned* Index); * will contain the insert position. */ +const Attr* GetAttr (const Collection* C, const char* Name); +/* Search for an attribute with the given name and return it. The function + * returns NULL if the attribute wasn't found. + */ + +const Attr* NeedAttr (const Collection* C, const char* Name, const char* Context); +/* Search for an attribute with the given name and return it. If the attribute + * is not found, the function terminates with an error using Context as + * additional context in the error message. + */ + +const char* GetAttrVal (const Collection* C, const char* Name); +/* Search for an attribute with the given name and return its value. The + * function returns NULL if the attribute wasn't found. + */ + +const char* NeedAttrVal (const Collection* C, const char* Name, const char* Context); +/* Search for an attribute with the given name and return its value. If the + * attribute wasn't not found, the function terminates with an error using + * Context as additional context in the error message. + */ + void AddAttr (Collection* C, const char* Name, const char* Value); /* Add an attribute to an alphabetically sorted attribute collection */ @@ -94,6 +116,13 @@ void SplitAddAttr (Collection* C, const char* Combined, const char* Name); * Name is NULL, terminate with an error. */ +Collection* ParseAttrList (const char* List, const char** NameList, unsigned NameCount); +/* Parse a list containing name/value pairs into a sorted collection. Some + * attributes may not need a name, so NameList contains these names. If there + * were no errors, the function returns a alphabetically sorted collection + * containing Attr entries. + */ + /* End of attr.h */ diff --git a/src/sp65/input.c b/src/sp65/input.c index d7b17686f..735e4920c 100644 --- a/src/sp65/input.c +++ b/src/sp65/input.c @@ -36,7 +36,7 @@ /* common */ #include "fileid.h" -/* sp65 */ +/* sp65 */ #include "error.h" #include "input.h" #include "pcx.h" @@ -78,6 +78,19 @@ static const FileId FormatTable[] = { +int FindInputFormat (const char* Name) +/* Find an input format by name. The function returns a value less than zero + * if Name is not a known input format. + */ +{ + /* Search for the entry in the table */ + const FileId* F = GetFileId (Name, FormatTable, + sizeof (FormatTable) / sizeof (FormatTable[0])); + return (F == 0)? -1 : F->Id; +} + + + Bitmap* ReadInputFile (const char* Name, InputFormat Format) /* Read a bitmap from a file and return it. If Format is ifAuto, the routine * tries to determine the format from the file name extension. diff --git a/src/sp65/input.h b/src/sp65/input.h index 7f2aff393..b0a5cd27b 100644 --- a/src/sp65/input.h +++ b/src/sp65/input.h @@ -55,7 +55,7 @@ enum InputFormat { ifCount /* Number of actual input formats w/o ifAuto*/ }; -typedef enum InputFormat InputFormat; +typedef enum InputFormat InputFormat; @@ -66,6 +66,11 @@ typedef enum InputFormat InputFormat; +int FindInputFormat (const char* Name); +/* Find an input format by name. The function returns a value less than zero + * if Name is not a known input format. + */ + Bitmap* ReadInputFile (const char* Name, InputFormat Format); /* Read a bitmap from a file and return it. If Format is ifAuto, the routine * tries to determine the format from the file name extension. diff --git a/src/sp65/main.c b/src/sp65/main.c index 61c7818ed..cd159a1b3 100644 --- a/src/sp65/main.c +++ b/src/sp65/main.c @@ -44,11 +44,26 @@ #include "version.h" /* sp65 */ +#include "attr.h" #include "error.h" #include "input.h" +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Bitmap first read */ +static Bitmap* B; + +/* Bitmap last processed */ +static Bitmap* C; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -66,7 +81,7 @@ static void Usage (void) " -v\t\t\tIncrease verbosity\n" "\n" "Long options:\n" - " --help\t\tHelp (this text)\n" + " --help\t\tHelp (this text)\n" " --verbose\t\tIncrease verbosity\n" " --version\t\tPrint the version number and exit\n", ProgName); @@ -84,9 +99,32 @@ static void OptHelp (const char* Opt attribute ((unused)), -static void OptRead (const char* Opt attribute ((unused)), const char* Arg) +static void OptRead (const char* Opt, const char* Arg) /* Read an input file */ { + static const char* NameList[] = { + "name", "format" + }; + + + /* Parse the argument */ + Collection* C = ParseAttrList (Arg, NameList, 2); + + /* Must have a file name given */ + const char* FileName = NeedAttrVal (C, "name", Opt); + + /* Determine the format of the input file */ + int IF = ifAuto; + const char* Format = GetAttrVal (C, "format"); + if (Format != 0) { + IF = FindInputFormat (Format); + if (IF <= 0) { + Error ("Unknown input format `%s'", Format); + } + } + + /* Read the file */ + B = ReadInputFile (FileName, IF); } -- 2.39.5