home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 2 / DATAFILE_PDCD2.iso / utilities2 / desklib / Libraries / Msgs / c / LoadFind < prev    next >
Encoding:
Text File  |  1993-07-14  |  8.1 KB  |  338 lines

  1. /*
  2.     ####             #    #     # #
  3.     #   #            #    #       #          The FreeWare C library for 
  4.     #   #  ##   ###  #  # #     # ###             RISC OS machines
  5.     #   # #  # #     # #  #     # #  #   ___________________________________
  6.     #   # ####  ###  ##   #     # #  #                                      
  7.     #   # #        # # #  #     # #  #    Please refer to the accompanying
  8.     ####   ### ####  #  # ##### # ###    documentation for conditions of use
  9.     ________________________________________________________________________
  10.  
  11.     File:    Msgs.LoadFind.c
  12.     Author:  Copyright © 1992 Jason Williams
  13.     Version: 1.00 (08 Apr 1992)
  14.     Purpose: MessageTrans-like message handling functions.
  15.              (If you want MessageTrans, use the SWI interface, if you want
  16.              high-level message handling, use this code...)
  17.  
  18.              NOTE: Although it may seem as if this chunk of code could be
  19.              split into smaller chunks, I don't see much point, as the
  20.              functions are all inter-dependent - there seems to be no point
  21.              in trying to use Msgs_Load without using the other functions
  22.              defined here (even using Msgs_printf calls Msgs_Lookup)
  23. */
  24.  
  25.  
  26. #include "Core.h"
  27. #include "Error.h"
  28. #include "Resource.h"
  29. #include "TextFile.h"
  30.  
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. #include "string.h"
  34.  
  35.  
  36. typedef struct msg_def *msgdefptr;
  37.  
  38. typedef struct msg_def
  39. {
  40.   msgdefptr   next;
  41.   union
  42.   {
  43.     char        *text;
  44.     msgdefptr   taglist;
  45.   } data;
  46.   char        tag[10];
  47. } msg_def;
  48.  
  49.  
  50. msgdefptr msgs_grouplist = NULL;
  51.  
  52.  
  53. #define MatchTokenI(t1, t2) (((int*)t1)[0]==((int*)t2)[0] && ((int*)t1)[1]==((int*)t2)[1])
  54.  
  55.  
  56.  
  57. extern BOOL Msgs__MatchToken(char *tag1, char *tag2, BOOL wcallowed)
  58. {
  59.   int loop = 0;
  60.  
  61.   if (!wcallowed)   /* Don't allow wildcard matching when inserting records! */
  62.     return(MatchTokenI(tag1, tag2));
  63.  
  64.   while (loop < 9 && tag1[loop] != '\0' && tag2[loop] != '\0')
  65.   {
  66.     if (tag1[loop] == '*' || tag2[loop] == '*')
  67.       return(TRUE);
  68.  
  69.     if (tag1[loop] != tag2[loop])
  70.       return(FALSE);
  71.     loop++;
  72.   }
  73.  
  74.   if (tag1[loop] == '*' || tag2[loop] == '*')
  75.     return(TRUE);
  76.  
  77.   if (tag1[loop] != tag2[loop])
  78.     return(FALSE);
  79.  
  80.   return(TRUE);
  81. }
  82.  
  83.  
  84.  
  85. extern msgdefptr Msgs__Find(msgdefptr *liststart, char *tag,
  86.                             BOOL create, BOOL wcallowed)
  87. /* Find the given tag in either the group list or a message list (list header
  88.  * passed in as *liststart). If not found, possibly create a new record
  89.  * to hold this tag.
  90.  * Returns ptr to the found/created record, or NULL if not found/created
  91.  */
  92. {
  93.   msgdefptr ptr;
  94.  
  95.   ptr = *liststart;
  96.   while (ptr != NULL)
  97.   {
  98.     if (Msgs__MatchToken(tag, ptr->tag, wcallowed))
  99.       return(ptr);
  100.     ptr = ptr->next;
  101.   }
  102.  
  103.   if (!create)                     /* not found & don't want us to create it */
  104.     return(NULL);
  105.  
  106.   ptr = (msgdefptr) malloc(sizeof(msg_def));             /* create new group */
  107.   if (ptr != NULL)
  108.   {
  109.     ptr->next = *liststart;                   /* link in to head of msg list */
  110.     *liststart = ptr;
  111.  
  112.     strncpy(ptr->tag, tag, 9);
  113.     ptr->tag[9] = 0;
  114.     ptr->data.taglist = NULL;         /* equivalent to ptr->data.text = NULL */
  115.   }
  116.  
  117.   return(ptr);
  118. }
  119.  
  120.  
  121. static void CopyMessage(char *s1, char *s2, int maxlength);
  122.  
  123. extern BOOL Msgs_Lookup(char *tag, char *result, int maxlength)
  124. {
  125.   msgdefptr    ptr;
  126.   char         grouptag[10], msgtag[10];
  127.   register int index, index2;
  128.  
  129.   result[0] = '\0';
  130.   for(index = 0; index < 10; index++)
  131.   {
  132.     grouptag[index] = 0;
  133.     msgtag[index] = 0;
  134.   }
  135.  
  136.   index = 0;
  137.   while (index < 9)
  138.   {
  139.     if (tag[index] == '.')
  140.       break;
  141.  
  142.     grouptag[index] = tag[index];
  143.     index++;
  144.   }
  145.  
  146.   if (tag[index] != '.')   /* invalid tag  */
  147.     return(FALSE);
  148.  
  149.   index++;                 /* Skip the '.' */
  150.   index2 = 0;
  151.   while (index2 < 9)
  152.   {
  153.     if (tag[index] == ':' || tag[index] == '\0')
  154.       break;
  155.  
  156.     msgtag[index2++] = tag[index++];
  157.   }
  158.  
  159.   /* Find the group the message is in - use 2 passes, once with wildcards
  160.    * disabled, and then a second time with them enabled, so that order of
  161.    * definitiion is less important.
  162.    */
  163.   ptr = Msgs__Find(&msgs_grouplist, grouptag, FALSE, FALSE);
  164.   if (ptr == NULL)  /* not found, so scan again */
  165.     ptr = Msgs__Find(&msgs_grouplist, grouptag, FALSE, TRUE);
  166.  
  167.  
  168.   /* Now, do the same  passes on the group's message list to find the actual
  169.    * message.
  170.    */
  171.   if (ptr != NULL)
  172.   {
  173.     msgdefptr ptr2;
  174.  
  175.     ptr2 = Msgs__Find(&(ptr->data.taglist), msgtag, FALSE, FALSE);
  176.     if (ptr2 == NULL)  /* not found, so scan again */
  177.       ptr = Msgs__Find(&(ptr->data.taglist), msgtag, FALSE, TRUE);
  178.     else
  179.       ptr = ptr2;
  180.   }
  181.  
  182.   if (ptr == NULL)  /* still not found - have we been supplied with default? */
  183.   {
  184.     if (tag[index] != '\0')
  185.     {
  186.       strncpy(result, &(tag[index + 1]), maxlength);
  187.       result[maxlength] = 0;
  188.       return(TRUE);                                /* return default       */
  189.     }
  190.     return(FALSE);                                 /* Failed completely    */
  191.   }
  192.  
  193.   CopyMessage(result, ptr->data.text, maxlength);  /* Return found message */
  194.   return(TRUE);
  195. }
  196.  
  197.  
  198.  
  199. static void CopyMessage(char *dest, char *src, int maxlength)
  200. {
  201.   register int  from = 0, to = 0, i;
  202.   register char c;
  203.   char includetag[24];
  204.  
  205.   while (from < maxlength - 1)
  206.   {
  207.     c = src[from];
  208.     if (c == 0)
  209.       break;
  210.  
  211.     if (c == '<')
  212.     {
  213.       if (src[from + 1] == '>')
  214.       {
  215.         from++;                     /* found "<>" - skip to output "<" only */
  216.         dest[to++] = '<';
  217.       }
  218.       else
  219.       {
  220.         from++;    /* Search from < to > to extract the include message tag */
  221.         i = 0;
  222.         while (c != '>')
  223.         {
  224.           c = src[from++];
  225.           includetag[i++] = c;
  226.         }
  227.         includetag[i - 1] = '\0';
  228.         from--;                         /* whoa boy! back up one character! */
  229.  
  230.         /*  Found include tag, so recurse on it to insert it into final
  231.          *  message at this point
  232.          */
  233.  
  234.         Msgs_Lookup(includetag, &(dest[to]), maxlength - to);
  235.  
  236.         /*  And now, we must search ahead from OUR "to" index (the start
  237.          *  of the section inserted) until we find the new end-of-string
  238.          */
  239.         while(dest[to] != '\0')
  240.           to++;
  241.       }
  242.     }
  243.     else
  244.       dest[to++] = c;
  245.  
  246.     from++;
  247.   }
  248.  
  249.   dest[to] = '\0';   /* Add string terminator */
  250. }
  251.  
  252.  
  253.  
  254. static BOOL AddMessage(char *grouptag, char *msgtag, char *message)
  255. {
  256.   char *msg;
  257.   msgdefptr ptr;
  258.  
  259.   msg = (char *) malloc(strlen(message) + 1);
  260.   if (msg == NULL)  return(Error_OutOfMemory(FALSE, "Messages"));
  261.   strcpy(msg, message);
  262.  
  263.   ptr = Msgs__Find(&msgs_grouplist, grouptag, TRUE, FALSE);
  264.   if (ptr != NULL)
  265.     ptr = Msgs__Find(&(ptr->data.taglist), msgtag, TRUE, FALSE);
  266.  
  267.   if (ptr != NULL)
  268.   {
  269.     if (ptr->data.text != NULL)
  270.       free(ptr->data.text);                  /* Overwrite previous occurence */
  271.  
  272.     ptr->data.text = msg;
  273.     return(TRUE);
  274.   }
  275.   return(FALSE);
  276. }
  277.  
  278.  
  279.  
  280. extern BOOL Msgs_LoadFile(char *leafname)
  281. /*  Merges the given messages file into the current list of messages
  282.  *  Messages with the same group.msg tag will be overwritten by the
  283.  *  new messages coming in from the file.
  284.  *
  285.  *  Expects lines of the form:
  286.  *    group.msg: message text continuing to newline
  287.  *  Leading spaces are ignored
  288.  */
  289. {
  290.   char filename[60];
  291.   char groupname[10], tagname[10];
  292.   char buffer[1024];
  293.   FILE *infile;
  294.   int  loop;
  295.   char ch;
  296.  
  297.   strcpy(filename, resource_pathname);
  298.   strcat(filename, leafname);
  299.  
  300.   infile = fopen(filename, "r");
  301.   if (infile == NULL)
  302.     return(FALSE);
  303.  
  304.   while (!feof(infile))
  305.   {
  306.     for (loop = 0; loop < 10; loop++)
  307.     {
  308.       groupname[loop] = 0;
  309.       tagname[loop] = 0;
  310.     }
  311.  
  312.     while (TRUE) /* Skip comments */
  313.     {
  314.       TextFile_SkipBlanks(infile);
  315.       if ((ch = getc(infile)) == '#')
  316.         TextFile_ReadToDelimiter(infile, '\n', buffer, 510);
  317.       else
  318.       {
  319.         ungetc(ch, infile);
  320.         break;
  321.       }
  322.     }
  323.  
  324.     TextFile_ReadToDelimiter(infile, '.', groupname, 10);
  325.     TextFile_ReadToDelimiter(infile, ':', tagname, 10);
  326.     TextFile_ReadToDelimiter(infile, '\n', buffer, 510);
  327.  
  328.     if (!feof(infile) && !AddMessage(groupname, tagname, buffer))
  329.     {
  330.       fclose(infile);
  331.       return(FALSE);
  332.     }
  333.   }
  334.  
  335.   fclose(infile);
  336.   return(TRUE);
  337. }
  338.