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
This commit is contained in:
109
src/sp65/attr.c
109
src/sp65/attr.c
@@ -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)
|
void AddAttr (Collection* C, const char* Name, const char* Value)
|
||||||
/* Add an attribute to an alphabetically sorted attribute collection */
|
/* 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) {
|
if (Pos == 0) {
|
||||||
/* Combined is actually a value */
|
/* Combined is actually a value */
|
||||||
if (Name == 0) {
|
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);
|
AddAttr (C, Name, Combined);
|
||||||
} else {
|
} 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,28 @@ int FindAttr (const Collection* C, const char* Name, unsigned* Index);
|
|||||||
* will contain the insert position.
|
* 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);
|
void AddAttr (Collection* C, const char* Name, const char* Value);
|
||||||
/* Add an attribute to an alphabetically sorted attribute collection */
|
/* 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.
|
* 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 */
|
/* End of attr.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)
|
Bitmap* ReadInputFile (const char* Name, InputFormat Format)
|
||||||
/* Read a bitmap from a file and return it. If Format is ifAuto, the routine
|
/* 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.
|
* tries to determine the format from the file name extension.
|
||||||
|
|||||||
@@ -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);
|
Bitmap* ReadInputFile (const char* Name, InputFormat Format);
|
||||||
/* Read a bitmap from a file and return it. If Format is ifAuto, the routine
|
/* 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.
|
* tries to determine the format from the file name extension.
|
||||||
|
|||||||
@@ -44,11 +44,26 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
/* sp65 */
|
/* sp65 */
|
||||||
|
#include "attr.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Bitmap first read */
|
||||||
|
static Bitmap* B;
|
||||||
|
|
||||||
|
/* Bitmap last processed */
|
||||||
|
static Bitmap* C;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -66,7 +81,7 @@ static void Usage (void)
|
|||||||
" -v\t\t\tIncrease verbosity\n"
|
" -v\t\t\tIncrease verbosity\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Long options:\n"
|
"Long options:\n"
|
||||||
" --help\t\tHelp (this text)\n"
|
" --help\t\tHelp (this text)\n"
|
||||||
" --verbose\t\tIncrease verbosity\n"
|
" --verbose\t\tIncrease verbosity\n"
|
||||||
" --version\t\tPrint the version number and exit\n",
|
" --version\t\tPrint the version number and exit\n",
|
||||||
ProgName);
|
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 */
|
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user