Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

uscanf_p.c

00001 /*
00002 *******************************************************************************
00003 *
00004 *   Copyright (C) 1998-1999, International Business Machines
00005 *   Corporation and others.  All Rights Reserved.
00006 *
00007 *******************************************************************************
00008 *
00009 * File uscnnf_p.c
00010 *
00011 * Modification History:
00012 *
00013 *   Date        Name        Description
00014 *   12/02/98    stephen        Creation.
00015 *   03/13/99    stephen     Modified for new C API.
00016 *******************************************************************************
00017 */
00018 
00019 #include "uscanf_p.h"
00020 #include "ufmt_cmn.h"
00021 
00022 /* flag characters for u_scanf */
00023 #define FLAG_ASTERISK 0x002A
00024 #define FLAG_PAREN 0x0028
00025 
00026 #define ISFLAG(s)    (s) == FLAG_ASTERISK || \
00027             (s) == FLAG_PAREN
00028 
00029 /* special characters for u_scanf */
00030 #define SPEC_DOLLARSIGN 0x0024
00031 
00032 /* unicode digits */
00033 #define DIGIT_ZERO 0x0030
00034 #define DIGIT_ONE 0x0031
00035 #define DIGIT_TWO 0x0032
00036 #define DIGIT_THREE 0x0033
00037 #define DIGIT_FOUR 0x0034
00038 #define DIGIT_FIVE 0x0035
00039 #define DIGIT_SIX 0x0036
00040 #define DIGIT_SEVEN 0x0037
00041 #define DIGIT_EIGHT 0x0038
00042 #define DIGIT_NINE 0x0039
00043 
00044 #define ISDIGIT(s)    (s) == DIGIT_ZERO || \
00045             (s) == DIGIT_ONE || \
00046             (s) == DIGIT_TWO || \
00047             (s) == DIGIT_THREE || \
00048             (s) == DIGIT_FOUR || \
00049             (s) == DIGIT_FIVE || \
00050             (s) == DIGIT_SIX || \
00051             (s) == DIGIT_SEVEN || \
00052             (s) == DIGIT_EIGHT || \
00053             (s) == DIGIT_NINE
00054 
00055 /* u_scanf modifiers */
00056 #define MOD_H 0x0068
00057 #define MOD_LOWERL 0x006C
00058 #define MOD_L 0x004C
00059 
00060 #define ISMOD(s)    (s) == MOD_H || \
00061             (s) == MOD_LOWERL || \
00062             (s) == MOD_L
00063 
00064 /* We parse the argument list in Unicode */
00065 int32_t
00066 u_scanf_parse_spec (const UChar     *fmt,
00067             u_scanf_spec    *spec)
00068 {
00069   const UChar *s = fmt;
00070   const UChar *backup;
00071   u_scanf_spec_info *info = &(spec->fInfo);
00072 
00073   /* initialize spec to default values */  
00074   spec->fArgPos             = -1;
00075   spec->fSkipArg            = FALSE;
00076 
00077   info->fSpec         = 0x0000;
00078   info->fWidth        = -1;
00079   info->fPadChar      = 0x0020;
00080   info->fIsLongDouble = FALSE;
00081   info->fIsShort      = FALSE;
00082   info->fIsLong       = FALSE;
00083   info->fIsLongLong   = FALSE;
00084 
00085 
00086   /* skip over the initial '%' */
00087   s++;
00088 
00089   /* Check for positional argument */
00090   if(ISDIGIT(*s)) {
00091 
00092     /* Save the current position */
00093     backup = s;
00094     
00095     /* handle positional parameters */
00096     if(ISDIGIT(*s)) {
00097       spec->fArgPos = (int) (*s++ - DIGIT_ZERO);
00098       
00099       while(ISDIGIT(*s)) {
00100         spec->fArgPos *= 10;
00101         spec->fArgPos += (int) (*s++ - DIGIT_ZERO);
00102       }
00103     }
00104     
00105     /* if there is no '$', don't read anything */
00106     if(*s != SPEC_DOLLARSIGN) {
00107       spec->fArgPos = -1;
00108       s = backup;
00109     }
00110     /* munge the '$' */
00111     else
00112       s++;
00113   }
00114   
00115   /* Get any format flags */
00116   while(ISFLAG(*s)) {
00117     switch(*s++) {
00118       
00119       /* skip argument */
00120     case FLAG_ASTERISK:
00121       spec->fSkipArg = TRUE;
00122       break;
00123 
00124       /* pad character specified */
00125     case FLAG_PAREN:
00126 
00127       /* first four characters are hex values for pad char */
00128       info->fPadChar = (UChar)ufmt_digitvalue(*s++);
00129       info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
00130       info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
00131       info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
00132       
00133       /* final character is ignored */
00134       s++;
00135       
00136       break;
00137     }
00138   }
00139 
00140   /* Get the width */
00141   if(ISDIGIT(*s)){
00142     info->fWidth = (int) (*s++ - DIGIT_ZERO);
00143     
00144     while(ISDIGIT(*s)) {
00145       info->fWidth *= 10;
00146       info->fWidth += (int) (*s++ - DIGIT_ZERO);
00147     }
00148   }
00149   
00150   /* Get any modifiers */
00151   if(ISMOD(*s)) {
00152     switch(*s++) {
00153 
00154       /* short */
00155     case MOD_H:
00156       info->fIsShort = TRUE;
00157       break;
00158 
00159       /* long or long long */
00160     case MOD_LOWERL:
00161       if(*s == MOD_LOWERL) {
00162         info->fIsLongLong = TRUE;
00163         /* skip over the next 'l' */
00164         s++;
00165       }
00166       else
00167         info->fIsLong = TRUE;
00168       break;
00169       
00170       /* long double */
00171     case MOD_L:
00172       info->fIsLongDouble = TRUE;
00173       break;
00174     }
00175   }
00176 
00177   /* finally, get the specifier letter */
00178   info->fSpec = *s++;
00179 
00180   /* return # of characters in this specifier */
00181   return (s - fmt);
00182 }

Generated at Tue Dec 5 10:48:11 2000 for ICU by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000