home *** CD-ROM | disk | FTP | other *** search
- /*
- #### # # # #
- # # # # # The FreeWare C library for
- # # ## ### # # # # ### RISC OS machines
- # # # # # # # # # # # ___________________________________
- # # #### ### ## # # # #
- # # # # # # # # # # Please refer to the accompanying
- #### ### #### # # ##### # ### documentation for conditions of use
- ________________________________________________________________________
-
- File: Msgs.LoadFind.c
- Author: Copyright © 1992 Jason Williams
- Version: 1.00 (08 Apr 1992)
- Purpose: MessageTrans-like message handling functions.
- (If you want MessageTrans, use the SWI interface, if you want
- high-level message handling, use this code...)
-
- NOTE: Although it may seem as if this chunk of code could be
- split into smaller chunks, I don't see much point, as the
- functions are all inter-dependent - there seems to be no point
- in trying to use Msgs_Load without using the other functions
- defined here (even using Msgs_printf calls Msgs_Lookup)
- */
-
-
- #include "Core.h"
- #include "Error.h"
- #include "Resource.h"
- #include "TextFile.h"
-
- #include <stdlib.h>
- #include <stdio.h>
- #include "string.h"
-
-
- typedef struct msg_def *msgdefptr;
-
- typedef struct msg_def
- {
- msgdefptr next;
- union
- {
- char *text;
- msgdefptr taglist;
- } data;
- char tag[10];
- } msg_def;
-
-
- msgdefptr msgs_grouplist = NULL;
-
-
- #define MatchTokenI(t1, t2) (((int*)t1)[0]==((int*)t2)[0] && ((int*)t1)[1]==((int*)t2)[1])
-
-
-
- extern BOOL Msgs__MatchToken(char *tag1, char *tag2, BOOL wcallowed)
- {
- int loop = 0;
-
- if (!wcallowed) /* Don't allow wildcard matching when inserting records! */
- return(MatchTokenI(tag1, tag2));
-
- while (loop < 9 && tag1[loop] != '\0' && tag2[loop] != '\0')
- {
- if (tag1[loop] == '*' || tag2[loop] == '*')
- return(TRUE);
-
- if (tag1[loop] != tag2[loop])
- return(FALSE);
- loop++;
- }
-
- if (tag1[loop] == '*' || tag2[loop] == '*')
- return(TRUE);
-
- if (tag1[loop] != tag2[loop])
- return(FALSE);
-
- return(TRUE);
- }
-
-
-
- extern msgdefptr Msgs__Find(msgdefptr *liststart, char *tag,
- BOOL create, BOOL wcallowed)
- /* Find the given tag in either the group list or a message list (list header
- * passed in as *liststart). If not found, possibly create a new record
- * to hold this tag.
- * Returns ptr to the found/created record, or NULL if not found/created
- */
- {
- msgdefptr ptr;
-
- ptr = *liststart;
- while (ptr != NULL)
- {
- if (Msgs__MatchToken(tag, ptr->tag, wcallowed))
- return(ptr);
- ptr = ptr->next;
- }
-
- if (!create) /* not found & don't want us to create it */
- return(NULL);
-
- ptr = (msgdefptr) malloc(sizeof(msg_def)); /* create new group */
- if (ptr != NULL)
- {
- ptr->next = *liststart; /* link in to head of msg list */
- *liststart = ptr;
-
- strncpy(ptr->tag, tag, 9);
- ptr->tag[9] = 0;
- ptr->data.taglist = NULL; /* equivalent to ptr->data.text = NULL */
- }
-
- return(ptr);
- }
-
-
- static void CopyMessage(char *s1, char *s2, int maxlength);
-
- extern BOOL Msgs_Lookup(char *tag, char *result, int maxlength)
- {
- msgdefptr ptr;
- char grouptag[10], msgtag[10];
- register int index, index2;
-
- result[0] = '\0';
- for(index = 0; index < 10; index++)
- {
- grouptag[index] = 0;
- msgtag[index] = 0;
- }
-
- index = 0;
- while (index < 9)
- {
- if (tag[index] == '.')
- break;
-
- grouptag[index] = tag[index];
- index++;
- }
-
- if (tag[index] != '.') /* invalid tag */
- return(FALSE);
-
- index++; /* Skip the '.' */
- index2 = 0;
- while (index2 < 9)
- {
- if (tag[index] == ':' || tag[index] == '\0')
- break;
-
- msgtag[index2++] = tag[index++];
- }
-
- /* Find the group the message is in - use 2 passes, once with wildcards
- * disabled, and then a second time with them enabled, so that order of
- * definitiion is less important.
- */
- ptr = Msgs__Find(&msgs_grouplist, grouptag, FALSE, FALSE);
- if (ptr == NULL) /* not found, so scan again */
- ptr = Msgs__Find(&msgs_grouplist, grouptag, FALSE, TRUE);
-
-
- /* Now, do the same passes on the group's message list to find the actual
- * message.
- */
- if (ptr != NULL)
- {
- msgdefptr ptr2;
-
- ptr2 = Msgs__Find(&(ptr->data.taglist), msgtag, FALSE, FALSE);
- if (ptr2 == NULL) /* not found, so scan again */
- ptr = Msgs__Find(&(ptr->data.taglist), msgtag, FALSE, TRUE);
- else
- ptr = ptr2;
- }
-
- if (ptr == NULL) /* still not found - have we been supplied with default? */
- {
- if (tag[index] != '\0')
- {
- strncpy(result, &(tag[index + 1]), maxlength);
- result[maxlength] = 0;
- return(TRUE); /* return default */
- }
- return(FALSE); /* Failed completely */
- }
-
- CopyMessage(result, ptr->data.text, maxlength); /* Return found message */
- return(TRUE);
- }
-
-
-
- static void CopyMessage(char *dest, char *src, int maxlength)
- {
- register int from = 0, to = 0, i;
- register char c;
- char includetag[24];
-
- while (from < maxlength - 1)
- {
- c = src[from];
- if (c == 0)
- break;
-
- if (c == '<')
- {
- if (src[from + 1] == '>')
- {
- from++; /* found "<>" - skip to output "<" only */
- dest[to++] = '<';
- }
- else
- {
- from++; /* Search from < to > to extract the include message tag */
- i = 0;
- while (c != '>')
- {
- c = src[from++];
- includetag[i++] = c;
- }
- includetag[i - 1] = '\0';
- from--; /* whoa boy! back up one character! */
-
- /* Found include tag, so recurse on it to insert it into final
- * message at this point
- */
-
- Msgs_Lookup(includetag, &(dest[to]), maxlength - to);
-
- /* And now, we must search ahead from OUR "to" index (the start
- * of the section inserted) until we find the new end-of-string
- */
- while(dest[to] != '\0')
- to++;
- }
- }
- else
- dest[to++] = c;
-
- from++;
- }
-
- dest[to] = '\0'; /* Add string terminator */
- }
-
-
-
- static BOOL AddMessage(char *grouptag, char *msgtag, char *message)
- {
- char *msg;
- msgdefptr ptr;
-
- msg = (char *) malloc(strlen(message) + 1);
- if (msg == NULL) return(Error_OutOfMemory(FALSE, "Messages"));
- strcpy(msg, message);
-
- ptr = Msgs__Find(&msgs_grouplist, grouptag, TRUE, FALSE);
- if (ptr != NULL)
- ptr = Msgs__Find(&(ptr->data.taglist), msgtag, TRUE, FALSE);
-
- if (ptr != NULL)
- {
- if (ptr->data.text != NULL)
- free(ptr->data.text); /* Overwrite previous occurence */
-
- ptr->data.text = msg;
- return(TRUE);
- }
- return(FALSE);
- }
-
-
-
- extern BOOL Msgs_LoadFile(char *leafname)
- /* Merges the given messages file into the current list of messages
- * Messages with the same group.msg tag will be overwritten by the
- * new messages coming in from the file.
- *
- * Expects lines of the form:
- * group.msg: message text continuing to newline
- * Leading spaces are ignored
- */
- {
- char filename[60];
- char groupname[10], tagname[10];
- char buffer[1024];
- FILE *infile;
- int loop;
- char ch;
-
- strcpy(filename, resource_pathname);
- strcat(filename, leafname);
-
- infile = fopen(filename, "r");
- if (infile == NULL)
- return(FALSE);
-
- while (!feof(infile))
- {
- for (loop = 0; loop < 10; loop++)
- {
- groupname[loop] = 0;
- tagname[loop] = 0;
- }
-
- while (TRUE) /* Skip comments */
- {
- TextFile_SkipBlanks(infile);
- if ((ch = getc(infile)) == '#')
- TextFile_ReadToDelimiter(infile, '\n', buffer, 510);
- else
- {
- ungetc(ch, infile);
- break;
- }
- }
-
- TextFile_ReadToDelimiter(infile, '.', groupname, 10);
- TextFile_ReadToDelimiter(infile, ':', tagname, 10);
- TextFile_ReadToDelimiter(infile, '\n', buffer, 510);
-
- if (!feof(infile) && !AddMessage(groupname, tagname, buffer))
- {
- fclose(infile);
- return(FALSE);
- }
- }
-
- fclose(infile);
- return(TRUE);
- }
-