Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* findhyphen.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Zerlegung von Worten in Silben gemaess dem TeX-Algorithmus                */
  8. /*                                                                           */
  9. /* Historie: 17.2.1998 Grundsteinlegung                                      */
  10. /*                                                                           */
  11. /*****************************************************************************/
  12.  
  13. #undef DEBUG
  14.  
  15. #include "stdinc.h"
  16. #include <string.h>
  17. #include <ctype.h>
  18.  
  19. #include "strutil.h"
  20.  
  21. #ifdef DEBUG
  22. #include "ushyph.h"
  23. #endif
  24.  
  25. #include "findhyphen.h"
  26.  
  27. /*****************************************************************************/
  28.  
  29. #define LCNT (26 + 1 + 4)
  30. #define SEPCNT 10
  31.  
  32. typedef struct sHyphenNode
  33. {
  34.   Byte sepcnts[SEPCNT];
  35.   struct sHyphenNode *Daughters[LCNT];
  36. } THyphenNode, *PHyphenNode;
  37.  
  38. typedef struct sHyphenException
  39. {
  40.   struct sHyphenException *next;
  41.   char *word;
  42.   int poscnt, *posis;
  43. } THyphenException, *PHyphenException;
  44.  
  45. /*****************************************************************************/
  46.  
  47. static PHyphenNode HyphenRoot = NULL;
  48. static PHyphenException FirstException = NULL;
  49.  
  50. /*****************************************************************************/
  51.  
  52. #if 0
  53. char b[10];
  54.  
  55. static void PrintNode(PHyphenNode Node, int Level)
  56. {
  57.   int z;
  58.  
  59.   for (z = 1; z < Level; z++)
  60.     putchar(' ');
  61.   for (z = 1; z <= Level; z++)
  62.     putchar(b[z]);
  63.   for (z = 0; z < SEPCNT; z++)
  64.     if (Node->sepcnts[z] > 0)
  65.       break;
  66.   if (z < SEPCNT)
  67.     putchar('!');
  68.   printf(" %p", Node);
  69.   puts("");
  70.   for (z = 0; z < LCNT; z++)
  71.     if (Node->Daughters[z])
  72.     {
  73.       b[Level + 1] = z + 'a' - 1;
  74.       PrintNode(Node->Daughters[z], Level + 1);
  75.     }
  76. }
  77. #endif
  78.  
  79. static int GetIndex(char ch)
  80. {
  81.   if ((as_tolower(ch) >= 'a' - 1) && (as_tolower(ch) <= 'z'))
  82.     return (as_tolower(ch) - ('a' - 1));
  83.   else if (ch == '.')
  84.     return 0;
  85.   else if ((ch == *HYPHEN_CHR_ae) || (ch == *HYPHEN_CHR_AE))
  86.     return 27;
  87.   else if ((ch == *HYPHEN_CHR_oe) || (ch == *HYPHEN_CHR_OE))
  88.     return 28;
  89.   else if ((ch == *HYPHEN_CHR_ue) || (ch == *HYPHEN_CHR_UE))
  90.     return 29;
  91.   else if (ch == *HYPHEN_CHR_sz)
  92.     return 30;
  93.   else
  94.   {
  95.     printf("unallowed character %d\n", ch); return -1;
  96.   }
  97. }
  98.  
  99. static void InitHyphenNode(PHyphenNode Node)
  100. {
  101.   int z;
  102.  
  103.   for (z = 0; z < LCNT; Node->Daughters[z++] = NULL);
  104.   for (z = 0; z < SEPCNT; Node->sepcnts[z++] = 0);
  105. }
  106.  
  107. void BuildTree(char **Patterns)
  108. {
  109.   char **run, ch, *pos, sing[500], *rrun;
  110.   Byte RunCnts[SEPCNT];
  111.   int z, l, rc, index;
  112.   PHyphenNode Lauf;
  113.  
  114.   HyphenRoot = (PHyphenNode) malloc(sizeof(THyphenNode));
  115.   InitHyphenNode(HyphenRoot);
  116.  
  117.   for (run = Patterns; *run != NULL; run++)
  118.   {
  119.     strcpy(sing, *run);
  120.     rrun = sing;
  121.     do
  122.     {
  123.       pos = strchr(rrun, ' ');
  124.       if (pos) *pos = '\0';
  125.       l = strlen(rrun);
  126.       rc = 0;
  127.       Lauf = HyphenRoot;
  128.       for (z = 0; z < SEPCNT; RunCnts[z++] = 0);
  129.       for (z = 0; z < l; z++)
  130.       {
  131.         ch = rrun[z];
  132.         if ((ch >= '0') && (ch <= '9'))
  133.           RunCnts[rc] = ch - '0';
  134.         else
  135.         {
  136.           index = GetIndex(ch);
  137.           if (!Lauf->Daughters[index])
  138.           {
  139.             Lauf->Daughters[index] = (PHyphenNode) malloc(sizeof(THyphenNode));
  140.             InitHyphenNode(Lauf->Daughters[index]);
  141.           }
  142.           Lauf = Lauf->Daughters[index];
  143.           rc++;
  144.         }
  145.       }
  146.       memcpy(Lauf->sepcnts, RunCnts, sizeof(Byte)*SEPCNT);
  147.       if (pos)
  148.         rrun = pos + 1;
  149.     }
  150.     while (pos);
  151.   }
  152. }
  153.  
  154. void AddException(char *Name)
  155. {
  156.   char tmp[300], *dest, *src;
  157.   int pos[100];
  158.   PHyphenException New;
  159.  
  160.   New = (PHyphenException) malloc(sizeof(THyphenException));
  161.   New->next = FirstException;
  162.   New->poscnt = 0;
  163.   dest = tmp;
  164.   for (src = Name; *src != '\0'; src++)
  165.     if (*src == '-') pos[New->poscnt++] = dest - tmp;
  166.   else
  167.     *(dest++) = *src;
  168.   *dest = '\0';
  169.   New->word = as_strdup(tmp);
  170.   if (New->poscnt)
  171.   {
  172.     New->posis = (int *) malloc(sizeof(int) * New->poscnt);
  173.     memcpy(New->posis, pos, sizeof(int) * New->poscnt);
  174.   }
  175.   else
  176.     New->posis = NULL;
  177.   FirstException = New;
  178. }
  179.  
  180. void DestroyNode(PHyphenNode Node)
  181. {
  182.   int z;
  183.  
  184.   for (z = 0; z < LCNT; z++)
  185.     if (Node->Daughters[z]) DestroyNode(Node->Daughters[z]);
  186.   free(Node);
  187. }
  188.  
  189. void DestroyTree(void)
  190. {
  191.   PHyphenException Old;
  192.  
  193.   if (HyphenRoot)
  194.     DestroyNode(HyphenRoot);
  195.   HyphenRoot = NULL;
  196.  
  197.   while (FirstException)
  198.   {
  199.     Old = FirstException;
  200.     FirstException = Old->next;
  201.     free(Old->word);
  202.     if (Old->poscnt > 0)
  203.       free(Old->posis);
  204.     free(Old);
  205.   }
  206. }
  207.  
  208. void DoHyphens(char *word, int **posis, int *posicnt)
  209. {
  210.   char Field[300];
  211.   Byte Res[300];
  212.   int z, z2, z3, l;
  213.   PHyphenNode Lauf;
  214.   PHyphenException Ex;
  215.  
  216.   for (Ex = FirstException; Ex; Ex = Ex->next)
  217.     if (!as_strcasecmp(Ex->word, word))
  218.     {
  219.       if (Ex->poscnt)
  220.       {
  221.         *posis = (int *) malloc(sizeof(int) * Ex->poscnt);
  222.         memcpy(*posis, Ex->posis, sizeof(int) * Ex->poscnt);
  223.       }
  224.       else
  225.         *posis = NULL;
  226.       *posicnt = Ex->poscnt;
  227.       return;
  228.     }
  229.  
  230.   l = strlen(word);
  231.   *posicnt = 0;
  232.   *Field = 'a' - 1;
  233.   for (z = 0; z < l; z++)
  234.   {
  235.     Field[z + 1] = tolower((unsigned int) word[z]);
  236.     if (GetIndex(Field[z + 1]) <= 0)
  237.       return;
  238.   }
  239.   Field[l + 1] = 'a' - 1;
  240.   l += 2;
  241.   for (z = 0; z <= l + 1; Res[z++] = 0);
  242.  
  243.   if (!HyphenRoot)
  244.     return;
  245.  
  246.   for (z = 0; z < l; z++)
  247.   {
  248.     Lauf = HyphenRoot;
  249.     for (z2 = z; z2 < l; z2++)
  250.     {
  251.       Lauf = Lauf->Daughters[GetIndex(Field[z2])];
  252.       if (!Lauf)
  253.         break;
  254. #ifdef DEBUG
  255.       for (z3 = 0; z3 < SEPCNT; z3++)
  256.         if (Lauf->sepcnts[z3] > 0)
  257.           break;
  258.       if (z3 < SEPCNT)
  259.       {
  260.         printf("Apply pattern ");
  261.         for (z3 = z; z3 <= z2; putchar(Field[z3++]));
  262.         printf(" at position %d with values", z);
  263.         for (z3 = 0; z3 < SEPCNT; printf(" %d", Lauf->sepcnts[z3++]));
  264.         puts("");
  265.       }
  266. #endif
  267.       for (z3 = 0; z3 <= z2 - z + 2; z3++)
  268.         if (Lauf->sepcnts[z3] > Res[z + z3])
  269.           Res[z + z3] = Lauf->sepcnts[z3];
  270.     }
  271.   }
  272.  
  273. #ifdef DEBUG
  274.   for (z = 0; z < l; z++)
  275.     printf(" %c", Field[z]);
  276.   puts("");
  277.   for (z = 0; z <= l; z++)
  278.     printf("%d ", Res[z]);
  279.   puts("");
  280.   for (z = 0; z < l - 2; z++)
  281.   {
  282.     if ((z > 0) && ((Res[z + 1]) & 1))
  283.       putchar('-');
  284.     putchar(Field[z + 1]);
  285.   }
  286.   puts("");
  287. #endif
  288.  
  289.   *posis = (int *) malloc(sizeof(int)*l);
  290.   *posicnt = 0;
  291.   for (z = 3; z < l - 2; z++)
  292.     if ((Res[z]&1) == 1)
  293.       (*posis)[(*posicnt)++] = z - 1;
  294.   if (*posicnt == 0)
  295.   {
  296.     free(*posis);
  297.     *posis = NULL;
  298.   }
  299. }
  300.  
  301. /*****************************************************************************/
  302.  
  303. #ifdef DEBUG
  304. int main(int argc, char **argv)
  305. {
  306.   int z, z2, cnt, *posis, posicnt;
  307.  
  308.   BuildTree(USHyphens);
  309.   for (z = 1; z < argc; z++)
  310.   {
  311.     DoHyphens(argv[z], &posis, &cnt);
  312.     for (z2 = 0; z2 < cnt; printf("%d ", posis[z2++]));
  313.      puts("");
  314.     if (posicnt > 0)
  315.       free(posis);
  316.   }
  317. #if 0
  318.   DoHyphens("hyphenation");
  319.   DoHyphens("concatenation");
  320.   DoHyphens("supercalifragilisticexpialidocous");
  321. #endif
  322. }      
  323. #endif
  324.