home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / CSSRC / FNVALRNG.C < prev    next >
Text File  |  1990-10-12  |  5KB  |  213 lines

  1. /*
  2.       fnvalrng.c            3/27/90
  3.  
  4.     % valid_Range
  5.  
  6.     Range checker for (whole number) numeric strings
  7.  
  8.     C-scape 3.2
  9.     Copyright (c) 1988, by Oakland Group, Inc.
  10.     ALL RIGHTS RESERVED.
  11.  
  12.     Revision History:
  13.     -----------------
  14.      3/27/90 pmcm     made
  15. */
  16.  
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20.  
  21. #include "cscape.h"
  22. #include "strdecl.h"        /* for C-scape string functions */
  23. #include "fnfunc.h"            /* For the rest of the str functions */
  24.  
  25.  
  26. OSTATIC int   ostr_NumCmp(char *s1, char *s2);
  27. OSTATIC char *oskipchars(char *s, char *c);
  28. OSTATIC int   ostrdigits(char *s);
  29.  
  30. boolean valid_Range(sed_type sed, long min, long max)
  31.  
  32.     /*     compares digit string in current record to max and min
  33.  
  34.         returns TRUE     if within bounds
  35.         returns FALSE     if out of bounds
  36.  
  37.         a digit string is:
  38.     
  39.             leading whitespace     followed by
  40.             '-' or '+' sign           followed by
  41.             leading 0's            followed by
  42.             digits
  43.  
  44.         the end of a digit string is marked by '\0' or any non-digit
  45.         (such as commas or an alphabetic letter)
  46.     */
  47.  
  48. {
  49.     char bound[30];    /* scratchpad for long */
  50.  
  51.     /* put current field record in sed scratchpad */
  52.     strcpy(sed_GetScratchPad(sed), sed_GetCurrRecord(sed));
  53.  
  54.     sprintf(bound, "%-ld", min);
  55.     if (ostr_NumCmp(sed_GetScratchPad(sed), bound) == -1) {
  56.         /* is less than the minimum bound */
  57.         return(FALSE);
  58.     }
  59.     sprintf(bound, "%-ld", max);
  60.     if (ostr_NumCmp(sed_GetScratchPad(sed), bound) == 1) {    
  61.         /* is greater than maximum bound */
  62.         return(FALSE);
  63.     }
  64.  
  65.     /* within bounds */
  66.     return(TRUE);
  67. }
  68.  
  69.  
  70. static int ostr_NumCmp(char *s1, char *s2)
  71.  
  72.     /*     s1 and s2 are digit strings denoting (signed) whole numbers.
  73.  
  74.         RETURNS:
  75.  
  76.             1 if s1 >  s2
  77.             0 if s1 == s2
  78.            -1 if s1 <  s2
  79.  
  80.  
  81.         A digit string is:
  82.     
  83.             leading whitespace     followed by
  84.             '-' or '+' sign           followed by
  85.             leading 0's            followed by
  86.             digits
  87.  
  88.         The end of a digit string is marked by '\0' or any non-digit
  89.         (such as commas or an alphabetic letter).
  90.     */
  91.  
  92. {
  93.     int         ndigits1;
  94.     int         ndigits2;
  95.     char *        tmp;
  96.     boolean     rev;
  97.     
  98.     if (s1 == NULL || s2 == NULL) {
  99.         /* one or both of the pointers is null, do something */
  100.         return((s1) ? 1 : -1);
  101.     }
  102.     
  103.     /* skip whitespace at start of strings */
  104.     s1 = oskipchars(s1, " \t\r\n");
  105.     s2 = oskipchars(s2, " \t\r\n");
  106.  
  107.     /* check the signs of the digit strings first */
  108.     rev = FALSE;
  109.     if (*s1 == '-' || *s2 == '-') {
  110.         /* flag negatives for later on (the both negative case) */
  111.         rev = TRUE;
  112.         if (*s1 != *s2) {
  113.     
  114.             /*     only one of them is negative so we can make quick evaluation */
  115.             rev = FALSE;
  116.             if (*s2 == '-') {
  117.                 /* flip pointers to save from duplicating logic */
  118.                 rev = TRUE;
  119.                     tmp = s1;
  120.                 s1  = s2;
  121.                 s2  = tmp;
  122.             }
  123.             s1 = oskipchars(++s1, "0");
  124.             if (isdigit(*s1)) {
  125.             /* is non-zero and negative */
  126.                 return((rev ? 1 : -1));
  127.             }
  128.                else {
  129.                 s2 = oskipchars(((*s2 == '+') ? ++s2 : s2), "0");
  130.                 return ((isdigit(*s2)) ? (rev ? 1 : -1) : 0);
  131.             }
  132.         }    
  133.     }
  134.         
  135.     /*     both have same sign, compare number of digits next */
  136.  
  137.     s1 = oskipchars(oskipchars(s1,"-+"), "0");
  138.     s2 = oskipchars(oskipchars(s2,"-+"), "0");
  139.     
  140.     if ((ndigits1 = ostrdigits(s1)) > (ndigits2 = ostrdigits(s2))) {
  141.         return((rev ? -1 :  1));
  142.      }
  143.  
  144.      if (ndigits1 < ndigits2) {
  145.           return((rev ?  1 : -1));
  146.      }
  147.  
  148.     /* same number of digits, compare digit by digit */
  149.  
  150.     for ( ;ndigits1 > 0 ;ndigits1--, s1++, s2++) {
  151.         if(*s1 > *s2) {
  152.             return((rev ? -1 :  1));
  153.         }
  154.         else if (*s1 < *s2) {
  155.              return((rev ?  1 : -1));
  156.         }
  157.     }
  158.     return(0);
  159. }
  160.  
  161.  
  162. static char *oskipchars(char *s, char *c)
  163.  
  164.     /*     RETURNS a pointer to the first character in s 
  165.         that is not one of the given characters in c
  166.  
  167.         s and c must be null terminated strings
  168.     */
  169. {
  170.     char *c1;
  171.  
  172.     if (s != NULL && c != NULL) {
  173.         for ( ; *s != '\0'; s++) {
  174.              for (c1 = c; *c1 != '\0' && *s != *c1; c1++){}
  175.             if (*c1 == '\0') {
  176.                 /* we passed through the list of chars w/o a match in s */
  177.                 break;
  178.             }
  179.         }
  180.     }
  181.     return(s);
  182.  
  183. }
  184.  
  185. static int ostrdigits(char *s)
  186.  
  187.     /*     Skips whitespace, -/+ sign, 
  188.         then counts digits (including leading 0's) 
  189.         up to first non-digit
  190.  
  191.         RETURNS count of digits
  192.     */
  193. {
  194.     int count = 0;
  195.  
  196.     if(s != NULL) {
  197.     
  198.         /* skip leading whitespace, then -/+ sign, then leading 0's */
  199.  
  200.         s = oskipchars(oskipchars(s, " \t\r\n"), "-+");
  201.  
  202.         for( ; *s; s++) {
  203.             if (isdigit(*s)) {
  204.                 count++;
  205.             }
  206.             else {
  207.                 break;
  208.             }
  209.         }
  210.     }
  211.     return(count);
  212. }
  213.