/*****************************************************************************/
-
+
#include <stdio.h>
#include <string.h>
+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 */
{
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 {
+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;
+}
+
+
+
* 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 */
* 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 */
/* common */
#include "fileid.h"
-/* sp65 */
+/* sp65 */
#include "error.h"
#include "input.h"
#include "pcx.h"
+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.
ifCount /* Number of actual input formats w/o ifAuto*/
};
-typedef enum InputFormat InputFormat;
+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.
#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 */
/*****************************************************************************/
" -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);
-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);
}