home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / extra / ustdio / uscanf_p.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-16  |  4.7 KB  |  188 lines

  1. /*
  2. *******************************************************************************
  3. *                                                                             *
  4. * COPYRIGHT:                                                                  *
  5. *   (C) Copyright International Business Machines Corporation, 1998           *
  6. *   Licensed Material - Program-Property of IBM - All Rights Reserved.        *
  7. *   US Government Users Restricted Rights - Use, duplication, or disclosure   *
  8. *   restricted by GSA ADP Schedule Contract with IBM Corp.                    *
  9. *                                                                             *
  10. *******************************************************************************
  11. *
  12. * File uscnnf_p.c
  13. *
  14. * Modification History:
  15. *
  16. *   Date        Name        Description
  17. *   12/02/98    stephen        Creation.
  18. *   03/13/99    stephen     Modified for new C API.
  19. *******************************************************************************
  20. */
  21.  
  22. #include "uscanf_p.h"
  23. #include "ufmt_cmn.h"
  24.  
  25. /* flag characters for u_scanf */
  26. #define FLAG_ASTERISK 0x002A
  27. #define FLAG_PAREN 0x0028
  28.  
  29. #define ISFLAG(s)    (s) == FLAG_ASTERISK || \
  30.             (s) == FLAG_PAREN
  31.  
  32. /* special characters for u_scanf */
  33. #define SPEC_DOLLARSIGN 0x0024
  34.  
  35. /* unicode digits */
  36. #define DIGIT_ZERO 0x0030
  37. #define DIGIT_ONE 0x0031
  38. #define DIGIT_TWO 0x0032
  39. #define DIGIT_THREE 0x0033
  40. #define DIGIT_FOUR 0x0034
  41. #define DIGIT_FIVE 0x0035
  42. #define DIGIT_SIX 0x0036
  43. #define DIGIT_SEVEN 0x0037
  44. #define DIGIT_EIGHT 0x0038
  45. #define DIGIT_NINE 0x0039
  46.  
  47. #define ISDIGIT(s)    (s) == DIGIT_ZERO || \
  48.             (s) == DIGIT_ONE || \
  49.             (s) == DIGIT_TWO || \
  50.             (s) == DIGIT_THREE || \
  51.             (s) == DIGIT_FOUR || \
  52.             (s) == DIGIT_FIVE || \
  53.             (s) == DIGIT_SIX || \
  54.             (s) == DIGIT_SEVEN || \
  55.             (s) == DIGIT_EIGHT || \
  56.             (s) == DIGIT_NINE
  57.  
  58. /* u_scanf modifiers */
  59. #define MOD_H 0x0068
  60. #define MOD_LOWERL 0x006C
  61. #define MOD_L 0x004C
  62.  
  63. #define ISMOD(s)    (s) == MOD_H || \
  64.             (s) == MOD_LOWERL || \
  65.             (s) == MOD_L
  66.  
  67. /* We parse the argument list in Unicode */
  68. int32_t
  69. u_scanf_parse_spec (const UChar     *fmt,
  70.             u_scanf_spec    *spec)
  71. {
  72.   const UChar *s = fmt;
  73.   const UChar *backup;
  74.  
  75.   /* initialize spec to default values */  
  76.   spec->fArgPos            = -1;
  77.   spec->fSkipArg        = FALSE;
  78.  
  79.   spec->fInfo.fSpec         = 0x0000;
  80.   spec->fInfo.fWidth         = -1;
  81.   spec->fInfo.fPadChar         = 0x0020;
  82.   spec->fInfo.fIsLongDouble     = FALSE;
  83.   spec->fInfo.fIsShort         = FALSE;
  84.   spec->fInfo.fIsLong         = FALSE;
  85.   spec->fInfo.fIsLongLong    = FALSE;
  86.  
  87.  
  88.   /* skip over the initial '%' */
  89.   *s++;
  90.  
  91.   /* Check for positional argument */
  92.   if(ISDIGIT(*s)) {
  93.  
  94.     /* Save the current position */
  95.     backup = s;
  96.     
  97.     /* handle positional parameters */
  98.     if(ISDIGIT(*s)) {
  99.       spec->fArgPos = (int) (*s++ - DIGIT_ZERO);
  100.       
  101.       while(ISDIGIT(*s)) {
  102.     spec->fArgPos *= 10;
  103.     spec->fArgPos += (int) (*s++ - DIGIT_ZERO);
  104.       }
  105.     }
  106.     
  107.     /* if there is no '$', don't read anything */
  108.     if(*s != SPEC_DOLLARSIGN) {
  109.       spec->fArgPos = -1;
  110.       s = backup;
  111.     }
  112.     /* munge the '$' */
  113.     else
  114.       *s++;
  115.   }
  116.   
  117.   /* Get any format flags */
  118.   while(ISFLAG(*s)) {
  119.     switch(*s++) {
  120.       
  121.       /* skip argument */
  122.     case FLAG_ASTERISK:
  123.       spec->fSkipArg = TRUE;
  124.       break;
  125.  
  126.       /* pad character specified */
  127.     case FLAG_PAREN:
  128.  
  129.       /* first four characters are hex values for pad char */
  130.       spec->fInfo.fPadChar = ufmt_digitvalue(*s++);
  131.       spec->fInfo.fPadChar *= 16;
  132.       spec->fInfo.fPadChar += ufmt_digitvalue(*s++);
  133.       spec->fInfo.fPadChar *= 16;
  134.       spec->fInfo.fPadChar += ufmt_digitvalue(*s++);
  135.       spec->fInfo.fPadChar *= 16;
  136.       spec->fInfo.fPadChar += ufmt_digitvalue(*s++);
  137.       
  138.       /* final character is ignored */
  139.       *s++;
  140.       
  141.       break;
  142.     }
  143.   }
  144.  
  145.   /* Get the width */
  146.   if(ISDIGIT(*s)){
  147.     spec->fInfo.fWidth = (int) (*s++ - DIGIT_ZERO);
  148.     
  149.     while(ISDIGIT(*s)) {
  150.       spec->fInfo.fWidth *= 10;
  151.       spec->fInfo.fWidth += (int) (*s++ - DIGIT_ZERO);
  152.     }
  153.   }
  154.   
  155.   /* Get any modifiers */
  156.   if(ISMOD(*s)) {
  157.     switch(*s++) {
  158.  
  159.       /* short */
  160.     case MOD_H:
  161.       spec->fInfo.fIsShort = TRUE;
  162.       break;
  163.  
  164.       /* long or long long */
  165.     case MOD_LOWERL:
  166.       if(*s == MOD_LOWERL) {
  167.     spec->fInfo.fIsLongLong = TRUE;
  168.     /* skip over the next 'l' */
  169.     *s++;
  170.       }
  171.       else
  172.     spec->fInfo.fIsLong = TRUE;
  173.       break;
  174.       
  175.       /* long double */
  176.     case MOD_L:
  177.       spec->fInfo.fIsLongDouble = TRUE;
  178.       break;
  179.     }
  180.   }
  181.  
  182.   /* finally, get the specifier letter */
  183.   spec->fInfo.fSpec = *s++;
  184.  
  185.   /* return # of characters in this specifier */
  186.   return (s - fmt);
  187. }
  188.