home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / os2 / thread / pmnthrd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-27  |  4.2 KB  |  217 lines

  1.  
  2. /*
  3.     PMNEWS 1.0
  4.  
  5.     Threading functions for the PMNEWS news reader
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License, version 1, as
  9.     published by the Free Software Foundation.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     See the file COPYING, which contains a copy of the GNU General
  17.     Public License.
  18.  
  19.  */
  20. #include  <ctype.h>
  21. #include  <string.h>
  22. #include  <os2.h>    /* for typedefs used below */
  23. #include "defs.h"
  24. #include "pmnews.h"
  25.  
  26.  
  27. static int strip_off_part(char *str)
  28. {
  29.   char *ptr = str + strlen(str);
  30.  
  31.   /* strip off (case-insensitive) things like:
  32.      - "Part01/10"
  33.      - "Patch02a/04"
  34.      - "Part 01/10"
  35.      - "Part 01 of 10"
  36.      - "(1 of 10)"
  37.      - "1 of 10"
  38.    */
  39.  
  40.   while ( ptr > str && ptr[-1] == ' ' )
  41.     ptr--;
  42.  
  43.   if ( ptr > str && ptr[-1] == ')' )
  44.     ptr--;
  45.  
  46.   while ( ptr > str && isdigit(ptr[-1]) )
  47.     ptr--;
  48.  
  49.   if ( !isdigit(*ptr) )
  50.     return 0;
  51.  
  52.   if ( ptr > str && ptr[-1] == '/' )
  53.     ptr--;
  54.   else if ( ptr > str + 3 && strnicmp(ptr - 4, " of ", 4) == 0 )
  55.     ptr -= 4;
  56.   else
  57.     return 0;
  58.  
  59.   if ( ptr > str && 'a' <= ptr[-1] && ptr[-1] <= 'z' )
  60.     ptr--;
  61.  
  62.   while ( ptr > str && isdigit(ptr[-1]) )
  63.     ptr--;
  64.  
  65.   if ( !isdigit(*ptr) )
  66.     return 0;
  67.  
  68.   if ( ptr > str && ptr[-1] == '(' )
  69.     ptr--;
  70.  
  71.   while ( ptr > str && ptr[-1] == ' ' )
  72.     ptr--;
  73.  
  74.   if ( ptr > str + 3 && strnicmp(ptr - 4, "Part", 4) == 0 )
  75.     ptr -= 4;
  76.  
  77.   while ( ptr > str && ptr[-1] == ' ' )
  78.     ptr--;
  79.  
  80.   if ( ptr > str && ptr[-1] == ',' )
  81.     ptr--;
  82.   else if ( ptr > str && ptr[-1] == ':' )
  83.     ptr--;
  84.  
  85.   *ptr = 0;
  86.   return 1;
  87. }
  88.  
  89. static char *skip_vi(char *str)
  90. {
  91.   char *ptr = str;
  92.  
  93.   /* skip things like "v02i0027: " */
  94.  
  95.   if ( *ptr++ != 'v' )
  96.     return str;
  97.  
  98.   if ( !isdigit(*ptr) )
  99.     return str;
  100.  
  101.   while ( isdigit(*ptr) )
  102.     ptr++;
  103.  
  104.   if ( *ptr++ != 'i' )
  105.     return str;
  106.  
  107.   if ( !isdigit(*ptr) )
  108.     return str;
  109.  
  110.   while ( isdigit(*ptr) )
  111.     ptr++;
  112.  
  113.   if ( *ptr++ != ':' )
  114.     return str;
  115.  
  116.   if ( *ptr++ != ' ' )
  117.     return str;
  118.  
  119.   return ptr;
  120. }
  121.  
  122. static int smartcmp(char *str1, char *str2)
  123. {
  124.   char s1[256], s2[256];
  125.  
  126.   strcpy(s1, str1);
  127.   strcpy(s2, str2);
  128.  
  129.   if ( strip_off_part(s1) && strip_off_part(s2) )
  130.   {
  131.     str1 = skip_vi(s1);
  132.     str2 = skip_vi(s2);
  133.   }
  134.  
  135.   return stricmp(str1, str2);
  136. }
  137.  
  138.  
  139.  
  140. /* threading algorithm returns a pointer which it wants
  141.    passed to it with each  new subject line from the index */
  142. void * thread_init( void )
  143. {
  144.   void * tmp_anch;
  145.  
  146.   tmp_anch = xmalloc( sizeof(ARTICLE* ) );
  147.   *(ARTICLE**)tmp_anch = NULL;
  148.   return tmp_anch;
  149. }
  150.  
  151. /* called at completion of thread pass for the newsgroup */
  152. void thread_end( void * anch )
  153. {
  154.   free( anch );
  155.   return;
  156. }
  157.  
  158.  
  159. /* called for each new subject line.
  160.    returns TRUE if it found a subject (ARTICLE) to thread-to,
  161.    FALSE if it had to allocate an ARTICLE.
  162.    'targ' is stored in all cases */
  163.  
  164. BOOL thread_compare( char * subjline, void * anch, ARTICLE **targ )
  165. {
  166.  
  167.     ARTICLE  *tmp;
  168.     ARTICLE **ptr;
  169.     int     cmp;
  170.  
  171.  
  172.     ptr = NULL;
  173.  
  174.     for ( tmp = *(ARTICLE **)anch; tmp != NULL; ) {
  175.  
  176.         cmp = smartcmp(subjline, tmp->header);
  177.  
  178.         if (cmp > 0) {
  179.            if (tmp->left)
  180.               tmp = tmp->left;
  181.            else {
  182.               ptr = &(tmp->left);
  183.               break;
  184.               }
  185.            }
  186.         else if (cmp < 0) {
  187.                 if (tmp->right)
  188.                    tmp = tmp->right;
  189.                 else {
  190.                    ptr = &(tmp->right);
  191.                    break;
  192.                    }
  193.                 }
  194.         else {
  195.               /* found this subject */
  196.               *targ = tmp;
  197.               return TRUE;
  198.              }
  199.     }
  200.  
  201.  
  202.     /* not found - allocate new ARTICLE (thread) */
  203.  
  204.     tmp = xmalloc(sizeof (ARTICLE));
  205.     *targ = tmp;
  206.  
  207.     if ( *(ARTICLE **)anch == NULL )
  208.        *(ARTICLE **)anch = tmp;
  209.     if ( ptr != NULL )
  210.        *ptr = tmp;
  211.  
  212.     return FALSE;
  213.  
  214.  
  215. }
  216.  
  217.