home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #3
/
amigamamagazinepolishissue1998.iso
/
bazy
/
db3.4
/
dbparser.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-02-01
|
22KB
|
858 lines
/* dbparser.c, -an RFFparser for db */
#include <exec/lists.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <proto/exec.h>
#include <proto/utility.h>
#include <proto/dos.h>
#include <clib/alib_protos.h> /* NewList() */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include "db.h"
#include "dbparser.h"
#include "dbGUI.h"
#include "dbRexx.h" /* Only for the handling of the RXPORTNAME tag */
#define BUFSIZE 65536
#define Rewind(fp) Seek(fp, 0, OFFSET_BEGINNING)
char *RFFTagNames[] = {
"dummy",
"@RFF",
"TYPE",
"FLEN",
"LNAM",
"NAME",
"SIZE",
"OFFS",
"NEXT",
"TABSIZE",
"RXFILE",
"RXSTRING",
"AUTORXFILE",
"AUTORXSTRING",
"NEWRECORDRXFILE",
"NEWRECORDRXSTRING",
"FTYP",
"CENT",
"SFMT",
"RXPORTNAME",
"PLACE",
"ROWS",
"XPOS",
"YPOS",
NULL
};
BPTR InFile;
void DeleteTag(struct RFFTag *ot)
{
if (ot) {
if (ot->Name) FreeMem(ot->Name,strlen(ot->Name)+1);
if (ot->Data) FreeMem(ot->Data,strlen(ot->Data)+1);
FreeMem(ot,sizeof(struct RFFTag));
}
}
void DeleteRFFLine(struct RFFLine *ol)
{
if (ol) {
if (ol->Line) FreeMem(ol->Line,strlen(ol->Line)+1);
FreeMem(ol,sizeof(struct RFFLine));
}
}
struct RFFLine *NewRFFLine(const char *line)
{
/* holds unknown RFF lines */
struct RFFLine *nl;
if (!(nl = AllocMem(sizeof(struct RFFLine),0))) return NULL;
if (!(nl->Line = AllocMem(strlen(line)+1,0))) {
DeleteRFFLine(nl);
return NULL;
}
nl->mln.mln_Pred = NULL;
nl->mln.mln_Succ = NULL;
strcpy(nl->Line,line);
return nl;
}
struct RFFTag *NewTag(const char *name, int nlen, const char *data, int dlen)
{
struct RFFTag *nt;
int i;
if (!(nt = AllocMem(sizeof(struct RFFTag),MEMF_CLEAR))) return NULL;
if (!(nt->Name = AllocMem(nlen+1,0))) {
DeleteTag(nt);
return NULL;
}
if (!(nt->Data = AllocMem(dlen+1,0))) {
DeleteTag(nt);
return NULL;
}
stccpy(nt->Name,name,nlen+1);
stccpy(nt->Data,data,dlen+1);
nt->ID = UNKNOWN;
for(i=1; RFFTagNames[i]; i++)
if (!Stricmp((STRPTR)nt->Name,(STRPTR)RFFTagNames[i])) {
nt->ID = i;
break;
}
return nt;
}
struct FldInfo *NewFldInfo(void)
{
/* Allocates and initializes a FldInfo struct with default values */
struct FldInfo *f;
if (!(f = AllocMem(sizeof(struct FldInfo),0))) return NULL;
NewList((struct List *)&f->FldTags);
f->Next = NULL;
f->Len = DEFMAXFLDLEN;
/* f->Type = something */
return f;
}
/* // Nice, but later on maybe. See DeletePro()
void DeleteRxInfo(struct RxInfo *ri)
{
struct RFFTag *ot;
while (ot = (struct RFFTag *)RemHead((struct List *)&ri->RxTags))
DeleteTag(ot);
FreeMem(ri, sizeof(struct RxInfo));
}
*/
struct RxInfo *NewRxInfo(void)
{
/* Allocates and initializes an RxInfo struct with default values */
struct RxInfo *ri;
if (ri = AllocMem(sizeof(struct RxInfo),0)) {
NewList((struct List *)&ri->RxTags);
ri->Next = NULL;
}
return ri;
}
void DeleteVisFldInfo(struct VisFldInfo *vf)
{
struct RFFTag *ot;
if (!vf) return;
if (vf->CEnt) FreeMem(vf->CEnt, (vf->NEnt+1)*sizeof(char *));
while (ot = (struct RFFTag *)RemHead((struct List *)&vf->VisTags))
DeleteTag(ot);
FreeMem(vf, sizeof(struct VisFldInfo));
}
struct VisFldInfo *NewVisFldInfo(void)
{
/* Allocates and initializes a VisFldInfo struct with default values */
struct VisFldInfo *vf;
struct IntuiText label = { 1,0,JAM1,0,0,NULL,NULL,NULL };
if (!(vf = AllocMem(sizeof(struct VisFldInfo),0))) return NULL;
NewList((struct List *)&vf->VisTags);
vf->Next = NULL;
vf->Gadget = NULL;
vf->Name[0] = '\0';
vf->Offset = 0;
vf->VisLen = 25;
vf->VisSep = '\n';
vf->Code = 0;
vf->CEnt = NULL;
vf->NEnt = 0;
vf->Label = label;
vf->Label.IText = vf->Name;
return vf;
}
/* Support functions for RFFOut */
struct RFFTag *FirstTag(struct MinList *list)
{
struct RFFTag *tag = (struct RFFTag *)list->mlh_Head;
if (!tag->mln.mln_Succ) return NULL; /* The MinList node */
return tag;
}
struct RFFTag *NextTag(struct RFFTag *tag)
{
tag = (struct RFFTag *)tag->mln.mln_Succ;
if (!tag->mln.mln_Succ) return NULL; /* The MinList node */
return tag;
}
struct RFFTag *NextSameTag(struct RFFTag *tag)
{
short int oldID = tag->ID;
for (;;) {
tag = (struct RFFTag *)tag->mln.mln_Succ;
if (!tag->mln.mln_Succ) return NULL; /* The MinList node */
if (tag->ID == oldID) return tag;
}
}
struct VisFldInfo *CopyVisFldInfo(struct VisFldInfo *vf)
{
struct RFFTag *tag, *nt;
struct VisFldInfo *newvf;
int i;
if (!(newvf = NewVisFldInfo())) return NULL;
*newvf = *vf; /* Shallow copy. We have to do more than that */
newvf->Label.IText = newvf->Name;
NewList((struct List *)&newvf->VisTags);
newvf->CEnt = NULL;
for (tag = FirstTag(&vf->VisTags); tag; tag = NextTag(tag)) {
if (!(nt = NewTag(tag->Name, strlen(tag->Name), tag->Data, strlen(tag->Data)))) {
DeleteVisFldInfo(newvf);
return NULL;
}
else AddTail((struct List *)&newvf->VisTags, (struct Node *)nt);
}
if (tag = SearchTag(CurrentPro, newvf, NULL, CENT)) {
if (!(newvf->CEnt =
AllocMem((vf->NEnt+1)*sizeof(char *), 0)))
{
DeleteVisFldInfo(newvf);
return NULL;
}
for (i=0; tag ;i++, tag = NextSameTag(tag))
newvf->CEnt[i] = tag->Data;
newvf->CEnt[i] = NULL; /* Nullterm cycleentrylist */
}
return newvf;
}
struct RFFTag *CreateAndAddTag(struct MinList *list, short int id, char *newdata)
{
struct RFFTag *tag;
if (!(tag = NewTag(RFFTagNames[id], strlen(RFFTagNames[id]),
newdata, strlen(newdata)))) return NULL;
AddTail((struct List *)list, (struct Node *)tag);
return tag;
}
struct RFFTag *UpdateTag(struct MinList *list, short int id, char *newdata)
{
/* Updates tag with ID=id in RFFTaglist list. Creates tag if missing */
/* Returns updated tag or NULL if memory error */
struct RFFTag *tag;
if (!(tag = FindTag(list, id))) { /* Create new tag */
if (!(tag = NewTag(RFFTagNames[id], strlen(RFFTagNames[id]),
newdata, strlen(newdata)))) return NULL;
AddTail((struct List *)list, (struct Node *)tag);
}
else { /* old tag found */
int dlen = strlen(newdata);
char *to;
if (!(to = AllocMem(dlen+1,0))) return NULL;
if (tag->Data) FreeMem(tag->Data,strlen(tag->Data)+1);
tag->Data = to;
stccpy(tag->Data,newdata,dlen+1);
}
return tag;
}
void WriteVisTags(struct VisFldInfo *vf)
{
/* Copy information from vf to vf's tags */
/* i.e. write vf's Name, Offset, VisLen & VisSep to the name, offs, size & next tags */
char buf[10]; /* Well enough */
UpdateTag(&vf->VisTags, NAME, vf->Name);
sprintf(buf, "%d", vf->Offset);
UpdateTag(&vf->VisTags, OFFS, buf);
sprintf(buf, "%d", vf->VisLen);
UpdateTag(&vf->VisTags, SIZE, buf);
switch (vf->VisSep) {
case ' ':
UpdateTag(&vf->VisTags, NEXT, STR_SPACE); break;
case '\t':
UpdateTag(&vf->VisTags, NEXT, STR_TAB); break;
case '\f':
UpdateTag(&vf->VisTags, NEXT, STR_PARA); break;
case '\n':
UpdateTag(&vf->VisTags, NEXT, "nl"); break;
}
}
int ReadVisTags(struct Pro *Pr, struct VisFldInfo *vf)
{
/* Parse vf's tags and fill vf. If information is incorrect, return RFF_ERR */
/* Information is incorrect when there is no corresponding field to an offset, */
/* or when there is a cycle gadget with no cycle entries. */
struct RFFTag *nt;
struct FldInfo *f;
int i;
if (nt = FindTag(&vf->VisTags, OFFS))
vf->Offset = atoi(nt->Data);
if (nt = SearchTag(Pr, vf, NULL, SIZE)) vf->VisLen = atoi(nt->Data);
if (nt = SearchTag(Pr, vf, NULL, NEXT)) {
if (!Stricmp(nt->Data,"space")) vf->VisSep = ' ';
else if (!Stricmp(nt->Data,"tab")) vf->VisSep = '\t';
else if (!Stricmp(nt->Data,"para")) vf->VisSep = '\f';
}
/* Delete old cycle array if there was one */
if (vf->CEnt) {
FreeMem(vf->CEnt, (vf->NEnt+1)*sizeof(char *));
vf->CEnt = NULL;
vf->NEnt = 0;
}
if (nt = SearchTag(Pr, vf, NULL, FTYP)) { /* Build new cycle array */
if (!Stricmp(nt->Data,"cycle")) {
if (nt = SearchTag(Pr, vf, NULL, CENT)) {
for (; nt; ++vf->NEnt, nt = NextSameTag(nt));
/* Now vf->NEnt holds the number of cycleentries */
if (nt = SearchTag(Pr, vf, NULL, CENT)) {
if (!(vf->CEnt =
AllocMem((vf->NEnt+1)*sizeof(char *), 0)))
return MEM_ERR;
for (i=0; nt ;i++, nt = NextSameTag(nt))
vf->CEnt[i] = nt->Data;
vf->CEnt[i] = NULL; /* Nullterm cycleentrylist */
}
}
else return RFF_ERR; /* There must be atleast one choice */
}
}
f = GetFldInfo(Pr, vf->Offset);
if (nt = FindTag(&vf->VisTags, NAME))
stccpy(vf->Name, nt->Data, FIELDNAMELENGTH);
else if (f) strcpy(vf->Name,f->Name);
if (!f) return RFF_ERR; /* Finally check that there is a corresponding FldInfo */
return 0;
}
/* End of support functions */
struct RFFTag *FindTag(struct MinList *list, short int id)
{
struct RFFTag *tag;
for (tag = (struct RFFTag *)list->mlh_Head; tag->mln.mln_Succ;
tag = (struct RFFTag *)tag->mln.mln_Succ) if (id == tag->ID) return tag;
return NULL;
}
static struct RFFTag *FindTags(struct MinList *list, short tag1ID, short tag2ID)
{
struct RFFTag *tag;
if (!(tag = FindTag(list, tag1ID)))
if (tag2ID) tag = FindTag(list, tag2ID);
return tag;
}
struct RFFTag *SearchTags(struct Pro *Pr, struct VisFldInfo *vf, Where *where, short tag1ID, short tag2ID)
{
struct RFFTag *tag;
Where dummydest;
if (!where) where = &dummydest;
/* Find the current VisualField */
if (!vf && !(vf = GetVisFldInfo(Pr->CurrentLayout, LastGad))) return NULL;
if (tag = FindTags(&vf->VisTags, tag1ID, tag2ID)) *where = VIEW_LOCAL;
else if (tag = FindTags(&Pr->CurrentLayout->LayTags, tag1ID, tag2ID)) *where = VIEW_GLOBAL;
else if (tag = FindTags(&GetFldInfo(Pr, vf->Offset)->FldTags, tag1ID, tag2ID)) *where = PRO_LOCAL;
else if (tag = FindTags(&CurrentPro->ProTags, tag1ID, tag2ID)) *where = PRO_GLOBAL;
return tag;
}
struct RFFTag *SearchTag(struct Pro *Pr, struct VisFldInfo *vf, Where *where, short tagID)
{
struct RFFTag *tag;
Where dummydest;
if (!where) where = &dummydest;
/* Find the current VisualField */
if (!vf && !(vf = GetVisFldInfo(Pr->CurrentLayout, LastGad))) return NULL;
if (tag = FindTag(&vf->VisTags, tagID)) *where = VIEW_LOCAL;
else if (tag = FindTag(&Pr->CurrentLayout->LayTags, tagID)) *where = VIEW_GLOBAL;
else if (tag = FindTag(&GetFldInfo(Pr, vf->Offset)->FldTags, tagID)) *where = PRO_LOCAL;
else if (tag = FindTag(&CurrentPro->ProTags, tagID)) *where = PRO_GLOBAL;
return tag;
}
struct FldInfo *GetFldInfo(struct Pro *Pr, short Offset)
{
/* Returns pointer to a FldInfo struct, returns NULL if not found */
struct FldInfo *f, *old=NULL;
int i;
if (!Pr) return NULL; /* Safety, Should never happen */
for (f = Pr->FirstFldInfo, i=0; i<=Offset; f = f->Next, i++) {
if (!f) return NULL;
else old = f;
}
return old;
}
struct VisFldInfo *GetVisFldInfo(struct Layout *Lay, struct Gadget *g)
{
struct VisFldInfo *vf = Lay->FirstVisFldInfo;
for (;vf ;vf = vf->Next) if (vf->Gadget == g) break;
return vf;
}
__inline char *SkipSpc(const char *s)
{
/* Returns a pointer to the first non-space character or a pointer to NULL */
/* A comma is also considered a space */
/* if no non-space characters are found */
while (*s && (*s == ' ' || *s == ',')) s++;
return s;
}
struct RFFTag *GetTag(const char **cursor)
{
/* Takes a comma and tabseparated RFFLine and returns an RFFTag */
/* Starts searching from cursor which is also updated after each call */
/* Will return NULL when hitting a \t or \0 character */
struct RFFTag *nt = NULL;
const char *brkchar, *nameptr, *dataptr = NULL;
int namelen, datalen;
*cursor = SkipSpc(*cursor);
if (**cursor == '\t') {
(*cursor)++;
return NULL;
}
/* Name part*/
if (brkchar = strpbrk(*cursor,"= ")) {
namelen = brkchar - *cursor;
nameptr = *cursor;
*cursor = brkchar+1;
/* Data part */
if (**cursor == '\"') { /* "Quotes" */
if (brkchar = strpbrk(++(*cursor),"\"")) { /* The other " */
datalen = brkchar - *cursor;
dataptr = *cursor;
*cursor = brkchar+1;
}
}
else { /* No quotes */
if (brkchar = strpbrk(*cursor,", \t\n")) datalen = brkchar - *cursor;
else datalen = strlen(*cursor);
dataptr = *cursor;
*cursor = brkchar;
}
if (dataptr) nt = NewTag(nameptr,namelen,dataptr,datalen);
}
return nt;
}
/*
BOOL PutTag(struct RFFTag *tag, BPTR fp)
{
if (FPuts(fp, tag->Name) == EOF) return FALSE;
if (FPutC(fp, '=') == EOF) return FALSE;
if (tag->Data && strlen(tag->Data)) {
if (FPuts(fp, tag->Data) == EOF) return FALSE;
}
else if (FPuts(fp, "\"\"") == EOF) return FALSE;
return TRUE;
}
*/
BOOL PutTag(struct RFFTag *tag, BPTR fp)
{
BOOL quotes = FALSE;
if (FPuts(fp, tag->Name) == EOF) return FALSE;
if (FPutC(fp, '=') == EOF) return FALSE;
if (tag->Data && strlen(tag->Data)) {
if (strpbrk(tag->Data," ,\t")) {
quotes = TRUE;
if (FPutC(fp, '"') == EOF) return FALSE;
}
if (FPuts(fp, tag->Data) == EOF) return FALSE;
if (quotes) if (FPutC(fp, '"') == EOF) return FALSE;
}
else if (FPuts(fp, "\"\"") == EOF) return FALSE;
return TRUE;
}
BOOL PutTags(struct RFFTag *tag, BPTR fp)
{
if (!PutTag(tag,fp)) return FALSE;
while (tag = NextTag(tag)) {
if (FPutC(fp, ',') == EOF) return FALSE;
if (!PutTag(tag,fp)) return FALSE;
}
return TRUE;
}
BOOL RFFOut(struct Pro *Pr, BPTR fp)
{
/* Writes all RFFtags to disk */
struct Layout *lay;
struct FldInfo *f;
struct RxInfo *ri;
struct VisFldInfo *vf;
struct RFFLine *rl;
struct RFFTag *tag;
/* Save schema:
ProTags, all FldTags, \n
RxTags, \n
for all layouts: LayTags, all VisTags \n
(UnknownLines, \n)
*/
ProTags:
if (!(tag = FirstTag(&Pr->ProTags))) goto RxTags;
if (!PutTags(tag,fp)) return FALSE;
FldTags:
for (f = Pr->FirstFldInfo; f; f = f->Next) {
if (FPutC(fp, '\t') == EOF) return FALSE;
if (!(tag = FirstTag(&f->FldTags))) continue;
if (!PutTags(tag,fp)) return FALSE;
}
if (FPutC(fp, '\n') == EOF) return FALSE;
RxTags:
for (ri = Pr->FirstRxInfo; ri; ri = ri->Next) {
if (ri != Pr->FirstRxInfo && FPutC(fp, '\t') == EOF) return FALSE;
if (!(tag = FirstTag(&ri->RxTags))) continue;
if (!PutTags(tag,fp)) return FALSE;
}
if (Pr->FirstRxInfo && FPutC(fp, '\n') == EOF) return FALSE;
Layouts:
for (lay = Pr->FirstLayout; lay; lay = lay->NextLayout) {
Laytags:
if (!(tag = FirstTag(&lay->LayTags))) continue;
if (!PutTags(tag,fp)) return FALSE;
VisTags:
for (vf = lay->FirstVisFldInfo; vf; vf = vf->Next) {
if (FPutC(fp, '\t') == EOF) return FALSE;
if (!(tag = FirstTag(&vf->VisTags))) continue;
if (!PutTags(tag,fp)) return FALSE;
}
if (FPutC(fp, '\n') == EOF) return FALSE;
}
UnknownLines:
for (rl = (struct RFFLine *)Pr->UnknownLines.mlh_Head; rl->mln.mln_Succ;
rl = (struct RFFLine *)rl->mln.mln_Succ) {
if (FPuts(fp, rl->Line) == EOF) return FALSE;
}
return TRUE;
}
BOOL DoASCIIParsing(struct Pro *Pr)
{
/* Build default VisFldInfos if file lacks recognizable RFF lines */
struct VisFldInfo *vf, *oldv = NULL;
struct FldInfo *f;
short off;
if (!NewLayout(Pr)) return FALSE;
/* Get the layoutname from the project name */
stccpy(Pr->CurrentLayout->Name, Pr->Name, LAYOUTNAMELENGTH);
/* Add an @rff=1.1 and a type=form tag */
CreateAndAddTag(&Pr->CurrentLayout->LayTags, RFF, "1.1");
CreateAndAddTag(&Pr->CurrentLayout->LayTags, TYPE, "form");
for (f = Pr->FirstFldInfo, off = 0; f; f = f->Next, off++) {
if (!(vf = NewVisFldInfo())) return FALSE;
strcpy(vf->Name,f->Name); /* Same name as the internal names */
vf->Offset = off;
WriteVisTags(vf);
/* Finally fix the links */
if (!oldv) {
oldv = vf;
Pr->CurrentLayout->FirstVisFldInfo = vf;
}
else { /* Fix backward links */
oldv->Next = vf;
oldv = vf;
}
}
return TRUE;
}
int DoParsing(BPTR fp, struct Pro *Pr, char *buffer)
{
/* Do the actual parsing */
/* Return number of RFF lines found (both known and unknown */
/* Negative numbers indicate errors */
char *cursor;
int n,len;
struct VisFldInfo *vf, *oldv;
struct FldInfo *f, *old = NULL;
struct RFFTag *nt;
struct RFFLine *rl;
short defoffset;
char *brkchar;
int ret;
/* Read first line and build the FldInfo list */
if (!FGets(fp, buffer,BUFSIZE)) return FILE_ERR;
cursor = buffer;
while (brkchar = strpbrk(cursor,"\t\n")) {
len = brkchar - cursor;
if (len >= FIELDNAMELENGTH) return FILE_ERR;
if (!(f = NewFldInfo())) return MEM_ERR;
stccpy(f->Name, cursor,len+1);
if (!old) {
old = f;
Pr->FirstFldInfo = f;
}
else { /* Fix previous links */
old->Next = f;
old = f;
}
cursor += len+1;
}
/* Parse the RFF lines */
for (n=0;;++n) {
if (!FGets(fp, buffer,BUFSIZE)) return n;
cursor=buffer;
/* In RFF1.x The first two tags has to be @RFF and TYPE */
if (!(nt = GetTag(&cursor))) return n; /* Not an RFF line */
if (nt->ID != RFF) { /* Not an RFF line */
DeleteTag(nt);
return n;
}
if (Strnicmp(nt->Data,"1.",2)) { /* Unknown RFF line */
DeleteTag(nt);
if (rl = NewRFFLine(buffer))
AddTail((struct List *)&Pr->UnknownLines, (struct Node *)rl);
continue;
}
/* It's at least an RFF 1.1 line... */
AddTail((struct List *)&Pr->ProTags, (struct Node *)nt);
if (!(nt = GetTag(&cursor))) return n; /* no more tags?? */
if (nt->ID != TYPE) { /* Unknown RFF line */
DeleteTag(nt);
DeleteTag((struct RFFTag *)RemTail((struct List *)&Pr->ProTags));
if (rl = NewRFFLine(buffer))
AddTail((struct List *)&Pr->UnknownLines, (struct Node *)rl);
continue;
}
/* Handle the different types */
if (!Stricmp(nt->Data,"internal")) {
AddTail((struct List *)&Pr->ProTags, (struct Node *)nt);
/* Add rest of tags till we hit the first \t char */
while (nt = GetTag(&cursor))
AddTail((struct List *)&Pr->ProTags, (struct Node *)nt);
/* Work thru all tags adding information to the FldInfo structs */
for (f = Pr->FirstFldInfo; f; f = f->Next) {
while (nt = GetTag(&cursor)) {
AddTail((struct List *)&f->FldTags, (struct Node *)nt);
}
if (nt = FindTag(&f->FldTags, FLEN)) f->Len = atoi(nt->Data);
}
/* Change the portname of this project if the RXPORTNAME tag is found */
if (nt = FindTag(&Pr->ProTags, RXPORTNAME)) {
if (MyRexxPort) CloseRexxPort(MyRexxPort);
if ((MyRexxPort = SetupRexxPort(nt->Data)) == NULL) return MEM_ERR;
}
}
else if (!Stricmp(nt->Data,"form")) {
if (!NewLayout(Pr)) {
DeleteTag(nt);
return MEM_ERR;
}
AddHead((struct List *)&Pr->CurrentLayout->LayTags, RemTail((struct List *)&Pr->ProTags));
AddTail((struct List *)&Pr->CurrentLayout->LayTags, (struct Node *)nt);
/* Add rest of tags till we hit the first \t char */
while (nt = GetTag(&cursor))
AddTail((struct List *)&Pr->CurrentLayout->LayTags, (struct Node *)nt);
/* Get the layoutname from the taglist */
if (nt = FindTag(&Pr->CurrentLayout->LayTags, LNAM))
stccpy(Pr->CurrentLayout->Name, nt->Data, LAYOUTNAMELENGTH);
/* Read window position tags */
{
struct RFFTag *xpos, *ypos;
if (xpos = FindTag(&Pr->CurrentLayout->LayTags, XPOS))
Pr->CurrentLayout->XPos = atoi(xpos->Data);
if (ypos = FindTag(&Pr->CurrentLayout->LayTags, YPOS))
Pr->CurrentLayout->YPos = atoi(ypos->Data);
}
/* Work thru all tags building VisFldInfo structs along the way */
for (oldv=0, defoffset=0;;defoffset++) {
if (!(nt = GetTag(&cursor))) break;
if (!(vf = NewVisFldInfo())) {
DeleteTag(nt);
return MEM_ERR;
}
/* Fix the links now so we don't loose it if some error occurs */
if (!oldv) {
oldv = vf;
Pr->CurrentLayout->FirstVisFldInfo = vf;
}
else { /* Fix backward links */
oldv->Next = vf;
oldv = vf;
}
AddTail((struct List *)&vf->VisTags, (struct Node *)nt);
while (nt = GetTag(&cursor))
AddTail((struct List *)&vf->VisTags, (struct Node *)nt);
/* Add values from the RFF tags */
vf->Offset = defoffset;
if ((ret = ReadVisTags(Pr, vf)) < 0) return ret;
defoffset = vf->Offset;
}
}
else if (!Stricmp(nt->Data,"rxmenu")) {
struct RxInfo *ri;
if (!(Pr->FirstRxInfo = NewRxInfo())) return MEM_ERR;
AddHead((struct List *)&Pr->FirstRxInfo->RxTags, RemTail((struct List *)&Pr->ProTags));
AddTail((struct List *)&Pr->FirstRxInfo->RxTags, (struct Node *)nt);
/* Add rest of tags till we hit the first \t char */
while (nt = GetTag(&cursor))
AddTail((struct List *)&Pr->FirstRxInfo->RxTags, (struct Node *)nt);
/* Work thru all tags building RxInfo structs along the way */
ri = Pr->FirstRxInfo;
while ((nt = GetTag(&cursor)) && (ri = ri->Next = NewRxInfo())) {
AddTail((struct List *)&ri->RxTags, (struct Node *)nt);
while (nt = GetTag(&cursor))
AddTail((struct List *)&ri->RxTags, (struct Node *)nt);
}
if (nt) {
DeleteTag(nt);
return MEM_ERR;
}
}
else { /* Other unknown RFF types */
if (rl = NewRFFLine(buffer))
AddTail((struct List *)&Pr->UnknownLines, (struct Node *)rl);
DeleteTag((struct RFFTag *)RemTail((struct List *)&Pr->ProTags));
DeleteTag(nt);
continue;
}
}
}
BOOL IsBinary(BPTR fp)
{
/* If the file contains at least one \0 character it's considered binary */
int d;
Rewind(fp); // The last FGets() might have read past the file
while ((d = FGetC(fp)) != EOF)
if (!d) return TRUE;
return FALSE;
}
int RFFParse(struct Pro *Pr, BPTR fp)
{
/* Checks if fp is a valid RFF file. If so. The RFF tags will be parsed */
/* and inserted into the project. */
/* When finished, the next character read will be the first non-RFF line */
char *buffer;
int n; /* Retval from DoParsing(). Number of RFF lines in file */
/* Allocate enough space for one line */
if (!(buffer = AllocMem(BUFSIZE,0))) return MEM_ERR;
n = DoParsing(fp, Pr, buffer);
Pr->CurrentLayout = Pr->FirstLayout;
if (n > 0) { /* Some RFF lines exist */
Rewind(fp);
while(1 + n--) FGets(fp, buffer, BUFSIZE); /* first line and RFF lines */
}
else if (n == 0) {
if (IsBinary(fp)) {
FreeMem(buffer,BUFSIZE);
return FILE_ERR;
}
else { /* An ASCII file */
Rewind(fp);
FGets(fp, buffer,BUFSIZE); /* Skip 1st line */
}
}
else {
FreeMem(buffer,BUFSIZE); /* Some error */
return n;
}
FreeMem(buffer,BUFSIZE);
if (!Pr->FirstLayout) /* There has to be at least one layout */
if (!DoASCIIParsing(Pr)) return MEM_ERR; /* Build default VisFldInfos */
return 0;
}