home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 1
/
ARM_CLUB_CD.iso
/
contents
/
education
/
a
/
biology1
/
!Biology1
/
c
/
FileRead
< prev
next >
Wrap
Text File
|
1991-12-03
|
11KB
|
381 lines
/* c.fileread */
/* To read the file of specified name into testdir */
/* Returns error message if load failed */
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "flex.h"
#include "os.h"
#include "werr.h"
#include "$.malcolm.txt2tst.TestTag.h"
#include "data.h"
#include "utils.h"
int std_line;
static unsigned char *buffer;
static unsigned char *ptr;
char *load_file (char *filename)
{ os_filestr file_block;
int length;
file_block.action = 17; /* Read catalogue info */
file_block.name = filename;
if (os_file (&file_block))
return ("File not found");
if (file_block.action != 1)
return ("File not found"); /* Not a file */
length = file_block.start;
if (0==flex_alloc ((flex_ptr)&buffer, length))
return ("Flex Failed");
file_block.action = 255;
file_block.name = filename;
file_block.loadaddr = (int) buffer;
file_block.execaddr = 0;
if (os_file (&file_block))
{ flex_free ((flex_ptr)&buffer);
return ("Problem loading data"); /* Some problem loading */
}
return (NULL);
}
void seek (long position)
{ ptr = buffer + position;
}
char rchar (void)
{ return (*ptr++);
}
int rint (void)
{ int res = *ptr++;
res = res + (*ptr << 8);
if (*ptr++ & 0x80) /* as int is actually longer than 2 bytes */
res -= 0x10000;
return (res);
}
long rlong (void)
{ long res = *ptr++;
res = res + ((long)*ptr++ << 8);
res = res + ((long)*ptr++ << 16);
res = res + ((long)*ptr++ << 24);
return (res);
}
char *rstring (void)
{ int len = *ptr++;
char *str = malloc (len + 1);
if (str == NULL)
return (NULL);
memcpy (str, ptr, len);
str[len] = '\0';
ptr += len;
return (str);
}
void rtext (text *txt)
{
/* For now whilst text is saved as a string!!! */
char *str = rstring ();
/* Put in new lines up to line_len chars */
char *line_start;
for (line_start = str; *line_start; )
{
int max_eol = min (std_line, strlen (line_start)),
eol = max_eol;
while (eol > 0 && line_start [eol] && line_start [eol] != ' ')
eol--;
if (eol == 0)
eol = max_eol;
line_start += eol;
if (*line_start)
{
*line_start = '\n';
line_start ++;
}
}
*txt = str;
}
void reset_testdir (void)
{ int i;
tdir.title = NULL;
tdir.appl_name = NULL;
for (i=0; i<26; i++)
tdir.udg[i].exists = FALSE;
tdir.no_topics = 0;
tdir.topic = NULL;
}
void reset_topic (topic *top)
{ top->name = NULL;
top->shortname = NULL;
top->no_subtopics = 0;
top->subtopic = NULL;
}
void reset_subtopic (subtopic *sub)
{ sub->menu_name = NULL;
sub->title = NULL;
sub->line_len = 60;
std_line = 60;
sub->header = NULL;
sub->statement = NULL;
sub->instruction1 = NULL;
sub->instruction2 = NULL;
sub->no_quest = 0;
sub->question = NULL;
sub->test_pic = -1;
sub->test_asp = -1;
}
void reset_question (question *q)
{ q->quest = NULL;
q->ans = NULL;
q->iar = NULL;
q->no_choice = 0;
q->choice = NULL;
q->quest_pic = 0;
q->quest_asp = 0;
}
/* Extract information; it's ok to point into the flex block as
* I don't make any intervening flex calls, and I don't call wimp_poll
* so nobody else can either.
* Having established it's a correct file I make no consistancy checks
* here at all, it is intended that consistancy should be checked by
* txt2tst.
*/
char *decode_file (void)
{ topic *top;
subtopic *sub;
question *quest;
char *str;
int num, tag;
int i,j;
int choice;
seek (0L);
str = rstring ();
if (strcmp (str, "ReinfFile"))
return ("File format error");
free (str);
num = rint ();
if (num != Version)
return ("Unknown data version");
reset_testdir ();
do
{ tag = rint ();
switch (tag)
{ case END_TESTDIR :
break;
case TITLE :
tdir.title = rstring ();
break;
case APPL_NAME :
tdir.appl_name = rstring ();
break;
case UDGS_TYPED :
tdir.udgs_typed = rint ();
break;
case NO_UDGS : /* I cater for 26 anyhow */
rint ();
break;
case UDG :
num = rint ();
tdir.udg[num].exists = TRUE;
for (i=0; i<8; i++)
tdir.udg[num].row[i] = rchar ();
break;
case NO_TOPICS :
tdir.no_topics = rint ();
tdir.topic = malloc (tdir.no_topics * sizeof (topic));
if (tdir.topic == NULL)
return ("Malloc failed");
top = NULL;
break;
case TOPIC :
if (top == NULL)
top = tdir.topic;
else
top++;
reset_topic (top);
break;
case TOPIC_NAME :
top->name = rstring ();
break;
case TOPIC_SHORTNAME :
top->shortname = rstring ();
break;
case NO_SUBTOPICS :
top->no_subtopics = rint ();
top->subtopic = malloc (top->no_subtopics*sizeof(subtopic));
if (top->subtopic == NULL)
return ("Malloc failed");
sub = NULL;
break;
case SUBTOPIC :
if (sub == NULL)
sub = top->subtopic;
else
sub++;
reset_subtopic (sub);
break;
case SUBTOPIC_NAME :
sub->menu_name = rstring ();
break;
case LEAFNAME : /* irelevant */
free (rstring ());
break;
case FILE_OFFSET :
sub->offset = rlong ();
break;
default :
return ("Unknown testdir tag");
}
} while (tag != END_TESTDIR);
for (top = tdir.topic, i=0; i<tdir.no_topics; top++, i++)
{ for (sub = top->subtopic, j=0; j<top->no_subtopics; sub++, j++)
{ seek (sub->offset);
std_line = 60;
do
{ tag = rint ();
switch (tag)
{ case END_TEST :
break;
case TEST_TITLE :
sub->title = rstring ();
break;
case HEADER :
rtext (&sub->header);
break;
case STATEMENT :
rtext (&sub->statement);
break;
case INSTRUCTION1 :
rtext (&sub->instruction1);
break;
case INSTRUCTION2 :
rtext (&sub->instruction2);
break;
case TEST_TYPE :
sub->test_type = rint ();
break;
case RESPONSE_TYPE :
sub->res_type = rint ();
break;
case TEST_PIC :
sub->test_pic = rint ();
break;
case TEST_ASP :
sub->test_asp = rint ();
break;
case NO_QUESTIONS :
sub->no_quest = rint ();
sub->question =
malloc (sub->no_quest * sizeof (question));
if (sub->question == NULL)
return ("Malloc failed");
quest = NULL;
break;
case QUESTION :
if (quest == NULL)
quest = sub->question;
else
quest++;
reset_question (quest);
break;
case QUEST_TEXT :
rtext (&quest->quest);
break;
case ANSWER_TEXT :
rtext (&quest->ans);
break;
case IAR_TEXT :
rtext (&quest->iar);
break;
case NO_CHOICE :
/* this covers hints and clues - they are stored as choices by txt2tst */
quest->no_choice = rint ();
quest->choice = malloc (quest->no_choice
* sizeof (text));
if (quest->choice == NULL)
return ("Malloc failed");
choice = 0;
break;
case CHOICE :
rtext (&quest->choice[choice++]);
break;
/* case NO_HINTS :
quest->no_hints = rint ();
quest->hint = malloc (quest->no_hints
* sizeof (text));
if (quest->hint == NULL)
return ("Malloc failed");
hint = 0;
break;
case HINT :
rtext (&quest->hint[hint++]);
break;
case NO_CLUES :
quest->no_clues = rint ();
quest->clue = malloc (quest->no_clues
* sizeof (text));
if (quest->clue == NULL)
return ("Malloc failed");
clue = 0;
break;
case CLUE :
rtext (&quest->clue[clue++]);
break; */
case QUEST_PIC :
quest->quest_pic = rint ();
break;
case QUEST_ASP :
quest->quest_asp = rint ();
break;
case LINE_LEN :
sub->line_len = rint ();
std_line = sub->line_len;
break;
default :
return ("Unknown test tag");
} /* switch */
} while (tag != END_TEST);
} /* for sub loop */
} /* for top loop */
return (NULL);
}
char *read_testdir (char *filename)
{ char *err = NULL;
if ((err = load_file (filename)) != NULL)
return (err);
err = decode_file ();
flex_free ((flex_ptr)&buffer);
return (err);
}