##stringtype C
##shortstrings
/****************************************************************
   This file was created automatically by `%fv'
   from "%f0".

   Do NOT edit by hand!
****************************************************************/

#include <string.h>

#include <exec/memory.h>
#include <libraries/iffparse.h>


#if defined(__SASC)  ||  defined(_DCC)
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include <proto/iffparse.h>
#include <proto/locale.h>
#elif defined(__GNUC__)
#include <inline/locale.h>
#include <inline/iffparse.h>
#include <inline/dos.h>
#include <inline/exec.h>
#include <inline/utility.h>
#else
#include <clib/iffparse_protos.h>
#include <clib/locale_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/utility_protos.h>
#endif





static LONG %b_Version = %v;
static const STRPTR %b_BuiltInLanguage = (STRPTR) %l;

struct FC_Type
{   LONG    ID;
    STRPTR  Str;
};

const struct FC_Type _%i = { %d, %s };

static struct Catalog *%b_Catalog = NULL;
static struct FC_Type *%b_OwnCatalog = NULL;
static LONG %b_OwnStrings;
static LONG %b_OwnBytes;

void Open%bCatalog(struct Locale *loc, STRPTR language)
{ LONG tag, tagarg;
  extern struct Library *LocaleBase;
  extern struct Library *IFFParseBase;
  extern void Close%bCatalog(void);

  Close%bCatalog();  /*  Not needed if the programmer pairs Open-()
			 and CloseCatalog() right, but does no harm. */
  if (language == NULL)
  { tag = TAG_IGNORE;
  }
  else
  { tag = OC_Language;
    tagarg = (LONG) language;
  }
  if (LocaleBase != NULL  &&  %b_Catalog == NULL)
  { %b_Catalog = OpenCatalog(loc, (STRPTR) "%b.catalog",
			     OC_BuiltInLanguage, %b_BuiltInLanguage,
			     tag, tagarg,
			     OC_Version, %b_Version,
			     TAG_DONE);
  }
  if (LocaleBase == NULL  &&  IFFParseBase != NULL  &&  language != NULL  &&
      Stricmp(language, %b_BuiltInLanguage) != 0)
  { struct IFFHandle *iffhandle;
    char path[128]; /*	Enough to hold 4 path items (dos.library 3.0)  */

    if ((iffhandle = AllocIFF())  !=  NULL)
    { /*  Trying to open the catalog  */
      strcpy(path, "Catalogs");
      AddPart((STRPTR) path, language, sizeof(path));
      AddPart((STRPTR) path, (STRPTR) "%b.catalog", sizeof(path));
      if ((iffhandle->iff_Stream = Open((STRPTR) path, MODE_OLDFILE))
				 ==  NULL)
      { strcpy(path, "Locale:Catalogs");
	AddPart((STRPTR) path, language, sizeof(path));
	AddPart((STRPTR) path, (STRPTR) "%b.catalog", sizeof(path));
	iffhandle->iff_Stream = Open((STRPTR) path, MODE_OLDFILE);
      }

      if (iffhandle->iff_Stream)
      { InitIFFasDOS(iffhandle);
	if (!OpenIFF(iffhandle, IFFF_READ))
	{ if (!PropChunk(iffhandle, MAKE_ID('C','T','L','G'),
			 MAKE_ID('S','T','R','S')))
	  { struct StoredProperty *sp;
	    int error;

	    for (;;)
	    { if ((error = ParseIFF(iffhandle, IFFPARSE_STEP))
			 ==  IFFERR_EOC)
	      { continue;
	      }
	      if (error != 0)
	      { break;
	      }

	      if (sp = FindProp(iffhandle, MAKE_ID('C','T','L','G'),
				MAKE_ID('S','T','R','S')))
	      { LONG *ptr;
		LONG BytesToScan, StrLength;

		/*  First scan: Check the number of strings		*/
		/*  Note that this assumes that the strings are padded	*/
		/*  to a longword boundary!				*/
		%b_OwnBytes = 0;
		%b_OwnStrings = 0;
		BytesToScan = sp->sp_Size;
		ptr = sp->sp_Data;
		while (BytesToScan > 0)
		{ ++%b_OwnStrings;
		  ++ptr;		      /*  Skip ID		*/
		  StrLength = *ptr+1;	      /*  NUL-Byte!		*/
		  %b_OwnBytes += StrLength;
		  ptr += 1+(StrLength+3)/4;   /*  Skip Length and String*/
		  BytesToScan -= 8+((StrLength+3)/4)*4;
		}

		/*  Marginal check: BytesToScan has to be 0!		*/
		if (BytesToScan == 0)
		{ char *cptr;
		  LONG i;

		  if (%b_OwnCatalog = (struct FC_Type *)
		      AllocMem(%b_OwnStrings*sizeof(struct FC_Type)+%b_OwnBytes,
			       MEMF_ANY))
		  { /*	Second scan: Copy the strings and their ID's    */
		    cptr = (char *) &%b_OwnCatalog[%b_OwnStrings];
		    BytesToScan = sp->sp_Size;
		    ptr = sp->sp_Data;
		    i = 0;
		    while (BytesToScan > 0)
		    { %b_OwnCatalog[i].ID = *(ptr++);
		      %b_OwnCatalog[i].Str = (STRPTR) cptr;
		      StrLength = *ptr+1;     /*  NUL-Byte!		*/
		      ptr++;
		      strncpy(cptr, (char *) ptr, StrLength);
					/*  Not more, not less bytes!	*/
		      cptr+=StrLength;
		      ptr += (StrLength+3)/4;
		      BytesToScan -= 8+((StrLength+3)/4)*4;
		      ++i;
		    }
		    break;
		  }
		}
	      }
	    }
	  }
	  CloseIFF(iffhandle);
	}
	Close(iffhandle->iff_Stream);
      }

      FreeIFF(iffhandle);
    }
  }
}


void Close%bCatalog(void)
{ if (LocaleBase != NULL)
  { CloseCatalog(%b_Catalog);
  }
  %b_Catalog = NULL;
  if (%b_OwnCatalog != NULL)
  { FreeMem(%b_OwnCatalog,
	    %b_OwnStrings*sizeof(struct FC_Type)+%b_OwnBytes);
    %b_OwnCatalog = NULL;
  }
}


STRPTR Get%bString(APTR fcstr)
{ STRPTR defaultstr = NULL;
  LONG strnum, i;

  strnum = ((struct FC_Type *) fcstr)->ID;
  defaultstr = ((struct FC_Type *) fcstr)->Str;

  if (%b_Catalog == NULL)
  { if (%b_OwnCatalog != NULL)
    { for (i = 0;  i < %b_OwnStrings;  i++)
       { if (%b_OwnCatalog[i].ID == strnum)
	 { return(%b_OwnCatalog[i].Str);
	 }
       }
    }
    return(defaultstr);
  }
  return(GetCatalogStr(%b_Catalog, strnum, defaultstr));
}
