home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pctchnqs / 1991 / number4 / normname.c < prev    next >
Text File  |  1991-07-29  |  6KB  |  195 lines

  1. /* NormalizeName() and helper functions. */
  2. #include  <stdio.h>
  3. #include  <stdlib.h>
  4. #include  <ctype.h>
  5. #include  <string.h>
  6.  
  7. /*#define NEEDCLEANING*/   /* uncomment to compile CleanString */
  8. /*#define GENTESTPROGRAM*/ /* uncomment to compile main */
  9. #define HARDSPACE '\xff' /* a 'hard', i.e. non-breaking, space */
  10.  
  11. extern char *strupr(char *s); /* not prototyped in ANSI string.h */
  12.  
  13. /* Special characters to capitalize after: space,
  14.    apostrophe, hyphen, and HARDSPACE. */
  15. static char CapAfterCharList[] = " '-\xff";
  16.  
  17. /*  The list of nonbreaking prefixes. */
  18. static char *NonBreakingPrefixList[] = {
  19.      "St.","De","Del","Della","Di","De La",
  20.      "Running",
  21.      0
  22.      };
  23.  
  24. #if defined(NEEDCLEANING)
  25. /* -------------------- CleanString --------------------- */
  26. static void CleanString(register char *s) {
  27.   register char *t;
  28.   for (t = s; *t; t++) /* convert control chars to spaces */
  29.   if (iscntrl(*t)) *t = ' ';
  30.   for (t = s; isspace(*t); t++); /* remove leading spaces */
  31.   if (t != s) strcpy(s, t);
  32.   /* remove trailing spaces */
  33.   for (t = s + strlen(s) - 1; isspace(*t); t--);
  34.   *(t + 1) = '\0';
  35.   /* remove redundant internal spaces */
  36.   if (*s) {  /* check that there's still something there */
  37.     for (t = s; *t;) {
  38.       while (*t && *t != ' ') {   /* find a blank */
  39.         *s = *t;
  40.         s++;
  41.         t++;
  42.       }
  43.       *s = *t;             /* copy one blank */
  44.       if (*t) {
  45.         s++;
  46.         t++;
  47.         while (*t && *t == ' ') t++;
  48.       } /* find next nonblank */
  49.     }
  50.   }
  51.   return;
  52. }
  53. #endif
  54.  
  55. /* -------------------- DoCapAfterChar -------------------- */
  56. static void DoCapAfterChar(char *s){
  57.   register char *p, *t;
  58.   /* check for NULL pointer or zero length string */
  59.   if ((s == (char *) NULL) || !(*s)) return;
  60.   for (p = CapAfterCharList; *p; p++) {
  61.   /* move through the string, one char at a time */
  62.     t = s;
  63.     while (*(t + 1) != '\0') { /* terminate if '\0' */
  64.       if (*t == *p)
  65.         *(t + 1) = toupper(*(t + 1));
  66.         t++;
  67.     }
  68.   }
  69.   return;
  70. }
  71.  
  72. /* -------------------- CapAfterStr -------------------- */
  73. static void CapAfterStr(register char *s, char const * const pat) {
  74.   int patlen;
  75.   char *stop;
  76.  
  77.   /* check for NULL pointers and zero length strings */
  78.   if ((s == (char *) NULL) || !(*s) || (pat == (char *) NULL) ||
  79.   !(*pat))
  80.      return;
  81.  
  82.   patlen = strlen(pat);     /* length of pattern */
  83.   stop = s + strlen(s);     /* stop points to end of string ('\0') */
  84.   while (1) {
  85.     if ((s = strstr(s, pat)) == (char *) NULL)   /* look for match */
  86.       return;         /* no more matches, so return */
  87.   /* point to char after pattern and check for end of string */
  88.     if ((s += patlen) >= stop)
  89.       return;         /* don't cap past the end of the string */
  90.     *s = toupper(*s);   /* capitalize char after matched pattern */
  91.   }
  92. }
  93.  
  94. /* -------------------- DoNonBreakingPrefixes ------------------- */
  95. static void DoNonBreakingPrefixes(char *s) {
  96.   int patlen;
  97.   char *t, **listp;
  98.   for (listp = NonBreakingPrefixList; *listp; listp++) {
  99.     patlen = strlen(*listp);
  100.     t = s;
  101.     while (1) {
  102.       if ((t = strstr(t, *listp)) == (char *) NULL)
  103.         break;              /* no more matches */
  104.       if (*(t + patlen) != ' ')
  105.         break;              /* past end of string? */
  106.       (*(t + patlen) = HARDSPACE);
  107.       t += patlen;            /* move past match */
  108.     }
  109.   }
  110. }
  111.  
  112. /* -------------------- RemoveHardSpaces --------------------- */
  113. static void RemoveHardSpaces(register char *s) {
  114.   while (s != (char *) NULL)
  115.     if ((s = strchr(s, HARDSPACE)) != (char *) NULL)
  116.       *s = ' ';
  117. }
  118.  
  119. /* ------------------- LookForSuffixes ----------------------- */
  120. static char *LookForSuffixes(char *s) {
  121.   char *sptr;
  122.   if ((sptr = strstr(s, " Jr")) != (char *) NULL) {
  123.     if (*(sptr + 3) == '\0') /* needs a period */
  124.       strcat(sptr, ".");
  125.   }
  126.   else if ((sptr = strstr(s, " Sr")) != (char *) NULL) {
  127.     if (*(sptr + 3) == '\0') /* needs a period */
  128.       strcat(sptr, ".");
  129.   }
  130.   else if ((sptr = strstr(s, " Iii")) != (char *) NULL)
  131.     strupr(sptr);
  132.   else if ((sptr = strstr(s, " Iv")) != (char *) NULL)
  133.     strupr(sptr);
  134.   else if ((sptr = strstr(s, " III")) != (char *) NULL)
  135.   /* don't need to do anything */;
  136.   else if ((sptr = strstr(s, " IV")) != (char *) NULL)
  137.   /* don't need to do anything */;
  138.   if (sptr != (char *) NULL)
  139.     *sptr++ = '\0';     /* disconnect and point to suffix */
  140.   return (sptr);
  141. }
  142.  
  143. /* ------------------ NormalizeName ------------------- */
  144. char *NormalizeName(char *s) {
  145.   char *LastName, *Suffix, *TempString;
  146. #if defined(NEEDCLEANING)
  147.   CleanString(s);      /* clean up the string */
  148. #endif
  149.  
  150. /* capitalization section */
  151.   *s = toupper(*s);         /* always capitalize first char */
  152.   DoCapAfterChar(s);
  153.   CapAfterStr(s, "Mc");     /* always capitalize after Mc */
  154.  
  155. /* name rearrangement section */
  156.   if (strchr(s, ',') == (char *) NULL) { /* put first name last */
  157. /* allocate a temporary buffer to build new copy of string */
  158.     if ((TempString = (char *) malloc(strlen(s) + 3)) !=
  159.     (char *) NULL) {   /* connect any non-breaking prefixes */
  160.        DoNonBreakingPrefixes(s);
  161.        Suffix = LookForSuffixes(s);   /* disconnect suffixes */
  162.        if ((LastName = strrchr(s, ' ')) != (char *) NULL) {
  163.          strcpy(TempString, LastName + 1);  /* copy last name */
  164.          strcat(TempString, ", ");          /* append comma */
  165.          strncat(TempString, s, (LastName - s)); /* append rest */
  166.          if (Suffix != (char *) NULL) {     /* reconnect suffixes */
  167.            strcat(TempString, " ");
  168.            strcat(TempString, Suffix);
  169.          }
  170.          RemoveHardSpaces(TempString);
  171.          strcpy(s, TempString); /* copy back to original string */
  172.        }
  173.        free(TempString);         /* release temporary buffer */
  174.     }
  175.   }
  176.   return (s);    /* return pointer to normalized string */
  177. }
  178.  
  179. /* -------------------- Test Program ------------------- */
  180. #if defined(GENTESTPROGRAM)
  181. #define   NAMESIZE  80
  182. void main(void) {
  183.   char buf[NAMESIZE];
  184.   fputs("Testing\n", stdout);
  185.   while (fgets(buf, (NAMESIZE - 2), stdin) != NULL) {
  186.     if (strchr(buf, '\n') != NULL)     /* remove newline */
  187.       *(strchr(buf, '\n')) = '\0';
  188.     fputs("-->", stdout);
  189.     fputs(NormalizeName(buf), stdout);
  190.     fputs("<--\n", stdout);
  191.   }
  192.   exit(0);
  193. }
  194. #endif
  195.