Fahad Mirza
/
Nucleo_HXC900
A demo application for HXC900 LoRaWAN module using Nucleo-L053R8.
Utilities/tiny_sscanf.c@5:53302861bfea, 2018-07-16 (annotated)
- Committer:
- fahadmirza
- Date:
- Mon Jul 16 20:12:42 2018 +0000
- Revision:
- 5:53302861bfea
- Parent:
- tiny_sscanf.c@0:a0c5877bd360
Updated directories;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fahadmirza | 0:a0c5877bd360 | 1 | /****************************************************************************** |
fahadmirza | 0:a0c5877bd360 | 2 | * @file tiny_sscanf.c |
fahadmirza | 0:a0c5877bd360 | 3 | * @author MCD Application Team |
fahadmirza | 0:a0c5877bd360 | 4 | * @version V1.1.4 |
fahadmirza | 0:a0c5877bd360 | 5 | * @date 08-January-2018 |
fahadmirza | 0:a0c5877bd360 | 6 | * @brief Tiny implementation of sscanf |
fahadmirza | 0:a0c5877bd360 | 7 | ****************************************************************************** |
fahadmirza | 0:a0c5877bd360 | 8 | * @attention |
fahadmirza | 0:a0c5877bd360 | 9 | * |
fahadmirza | 0:a0c5877bd360 | 10 | * <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V. |
fahadmirza | 0:a0c5877bd360 | 11 | * All rights reserved.</center></h2> |
fahadmirza | 0:a0c5877bd360 | 12 | * |
fahadmirza | 0:a0c5877bd360 | 13 | * Copyright (c) 1990, 1993 |
fahadmirza | 0:a0c5877bd360 | 14 | * The Regents of the University of California. All rights reserved. |
fahadmirza | 0:a0c5877bd360 | 15 | * |
fahadmirza | 0:a0c5877bd360 | 16 | * This code is derived from software contributed to Berkeley by |
fahadmirza | 0:a0c5877bd360 | 17 | * Chris Torek. |
fahadmirza | 0:a0c5877bd360 | 18 | * Redistribution and use in source and binary forms, with or without |
fahadmirza | 0:a0c5877bd360 | 19 | * modification, are permitted, provided that the following conditions are met: |
fahadmirza | 0:a0c5877bd360 | 20 | * |
fahadmirza | 0:a0c5877bd360 | 21 | * 1. Redistribution of source code must retain the above copyright notice, |
fahadmirza | 0:a0c5877bd360 | 22 | * this list of conditions and the following disclaimer. |
fahadmirza | 0:a0c5877bd360 | 23 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
fahadmirza | 0:a0c5877bd360 | 24 | * this list of conditions and the following disclaimer in the documentation |
fahadmirza | 0:a0c5877bd360 | 25 | * and/or other materials provided with the distribution. |
fahadmirza | 0:a0c5877bd360 | 26 | * 3. Neither the name of STMicroelectronics nor the names of other |
fahadmirza | 0:a0c5877bd360 | 27 | * contributors to this software may be used to endorse or promote products |
fahadmirza | 0:a0c5877bd360 | 28 | * derived from this software without specific written permission. |
fahadmirza | 0:a0c5877bd360 | 29 | * 4. This software, including modifications and/or derivative works of this |
fahadmirza | 0:a0c5877bd360 | 30 | * software, must execute solely and exclusively on microcontroller or |
fahadmirza | 0:a0c5877bd360 | 31 | * microprocessor devices manufactured by or for STMicroelectronics. |
fahadmirza | 0:a0c5877bd360 | 32 | * 5. Redistribution and use of this software other than as permitted under |
fahadmirza | 0:a0c5877bd360 | 33 | * this license is void and will automatically terminate your rights under |
fahadmirza | 0:a0c5877bd360 | 34 | * this license. |
fahadmirza | 0:a0c5877bd360 | 35 | * |
fahadmirza | 0:a0c5877bd360 | 36 | * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" |
fahadmirza | 0:a0c5877bd360 | 37 | * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT |
fahadmirza | 0:a0c5877bd360 | 38 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
fahadmirza | 0:a0c5877bd360 | 39 | * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
fahadmirza | 0:a0c5877bd360 | 40 | * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT |
fahadmirza | 0:a0c5877bd360 | 41 | * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
fahadmirza | 0:a0c5877bd360 | 42 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
fahadmirza | 0:a0c5877bd360 | 43 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, |
fahadmirza | 0:a0c5877bd360 | 44 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
fahadmirza | 0:a0c5877bd360 | 45 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
fahadmirza | 0:a0c5877bd360 | 46 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
fahadmirza | 0:a0c5877bd360 | 47 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
fahadmirza | 0:a0c5877bd360 | 48 | * |
fahadmirza | 0:a0c5877bd360 | 49 | ****************************************************************************** |
fahadmirza | 0:a0c5877bd360 | 50 | */ |
fahadmirza | 0:a0c5877bd360 | 51 | /* $OpenBSD: sscanf.c,v 1.12 2005/08/08 08:05:36 espie Exp $ */ |
fahadmirza | 0:a0c5877bd360 | 52 | /*- |
fahadmirza | 0:a0c5877bd360 | 53 | * Copyright (c) 1990, 1993 |
fahadmirza | 0:a0c5877bd360 | 54 | * The Regents of the University of California. All rights reserved. |
fahadmirza | 0:a0c5877bd360 | 55 | * |
fahadmirza | 0:a0c5877bd360 | 56 | * This code is derived from software contributed to Berkeley by |
fahadmirza | 0:a0c5877bd360 | 57 | * Chris Torek. |
fahadmirza | 0:a0c5877bd360 | 58 | * |
fahadmirza | 0:a0c5877bd360 | 59 | * Redistribution and use in source and binary forms, with or without |
fahadmirza | 0:a0c5877bd360 | 60 | * modification, are permitted provided that the following conditions |
fahadmirza | 0:a0c5877bd360 | 61 | * are met: |
fahadmirza | 0:a0c5877bd360 | 62 | * 1. Redistributions of source code must retain the above copyright |
fahadmirza | 0:a0c5877bd360 | 63 | * notice, this list of conditions and the following disclaimer. |
fahadmirza | 0:a0c5877bd360 | 64 | * 2. Redistributions in binary form must reproduce the above copyright |
fahadmirza | 0:a0c5877bd360 | 65 | * notice, this list of conditions and the following disclaimer in the |
fahadmirza | 0:a0c5877bd360 | 66 | * documentation and/or other materials provided with the distribution. |
fahadmirza | 0:a0c5877bd360 | 67 | * 3. Neither the name of the University nor the names of its contributors |
fahadmirza | 0:a0c5877bd360 | 68 | * may be used to endorse or promote products derived from this software |
fahadmirza | 0:a0c5877bd360 | 69 | * without specific prior written permission. |
fahadmirza | 0:a0c5877bd360 | 70 | * |
fahadmirza | 0:a0c5877bd360 | 71 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
fahadmirza | 0:a0c5877bd360 | 72 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
fahadmirza | 0:a0c5877bd360 | 73 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
fahadmirza | 0:a0c5877bd360 | 74 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
fahadmirza | 0:a0c5877bd360 | 75 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
fahadmirza | 0:a0c5877bd360 | 76 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
fahadmirza | 0:a0c5877bd360 | 77 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
fahadmirza | 0:a0c5877bd360 | 78 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
fahadmirza | 0:a0c5877bd360 | 79 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
fahadmirza | 0:a0c5877bd360 | 80 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
fahadmirza | 0:a0c5877bd360 | 81 | * SUCH DAMAGE. |
fahadmirza | 0:a0c5877bd360 | 82 | */ |
fahadmirza | 0:a0c5877bd360 | 83 | |
fahadmirza | 0:a0c5877bd360 | 84 | |
fahadmirza | 0:a0c5877bd360 | 85 | /* |
fahadmirza | 0:a0c5877bd360 | 86 | * This code is derived from |
fahadmirza | 0:a0c5877bd360 | 87 | * https://github.com/rapid7/metasploit-payloads/, in c/meterpreter/source/bionic/libc/stdio/sscanf.c |
fahadmirza | 0:a0c5877bd360 | 88 | * It has been derived in order to optimize code size. In this context |
fahadmirza | 0:a0c5877bd360 | 89 | * all the formats are not supported. Current supported formats are |
fahadmirza | 0:a0c5877bd360 | 90 | * %hx, %hhx, %ul, %d,... |
fahadmirza | 0:a0c5877bd360 | 91 | * when TINY_SSCANF is defined |
fahadmirza | 0:a0c5877bd360 | 92 | * |
fahadmirza | 0:a0c5877bd360 | 93 | * When TINY_NO_OX is defined, this is not possible to sscanf("%x") of "0xab", |
fahadmirza | 0:a0c5877bd360 | 94 | * only "ab" is possible |
fahadmirza | 0:a0c5877bd360 | 95 | * |
fahadmirza | 0:a0c5877bd360 | 96 | * When TINY_SPACE_NOT_SPECIALCASE is defined, "space" is not a special character. |
fahadmirza | 0:a0c5877bd360 | 97 | * That means that we expect a single space, and not any of ispace() character |
fahadmirza | 0:a0c5877bd360 | 98 | * (space, tabs,...) |
fahadmirza | 0:a0c5877bd360 | 99 | */ |
fahadmirza | 0:a0c5877bd360 | 100 | |
fahadmirza | 0:a0c5877bd360 | 101 | #include <stdio.h> |
fahadmirza | 0:a0c5877bd360 | 102 | #include <string.h> |
fahadmirza | 0:a0c5877bd360 | 103 | #include <stdarg.h> |
fahadmirza | 0:a0c5877bd360 | 104 | #include <stdint.h> |
fahadmirza | 0:a0c5877bd360 | 105 | #include <stdlib.h> |
fahadmirza | 0:a0c5877bd360 | 106 | #include <inttypes.h> |
fahadmirza | 0:a0c5877bd360 | 107 | #include "tiny_sscanf.h" |
fahadmirza | 0:a0c5877bd360 | 108 | |
fahadmirza | 0:a0c5877bd360 | 109 | /* Private typedef -----------------------------------------------------------*/ |
fahadmirza | 0:a0c5877bd360 | 110 | /* Private define ------------------------------------------------------------*/ |
fahadmirza | 0:a0c5877bd360 | 111 | #define TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 112 | #define TINY_NO_OX |
fahadmirza | 0:a0c5877bd360 | 113 | #define TINY_SPACE_NOT_SPECIALCASE |
fahadmirza | 0:a0c5877bd360 | 114 | |
fahadmirza | 0:a0c5877bd360 | 115 | /* Private macro -------------------------------------------------------------*/ |
fahadmirza | 0:a0c5877bd360 | 116 | /* Private variables ---------------------------------------------------------*/ |
fahadmirza | 0:a0c5877bd360 | 117 | /* Functions Definition ------------------------------------------------------*/ |
fahadmirza | 0:a0c5877bd360 | 118 | |
fahadmirza | 0:a0c5877bd360 | 119 | #ifdef FLOATING_POINT |
fahadmirza | 0:a0c5877bd360 | 120 | #include "floatio.h" |
fahadmirza | 0:a0c5877bd360 | 121 | #endif |
fahadmirza | 0:a0c5877bd360 | 122 | |
fahadmirza | 0:a0c5877bd360 | 123 | #define BUF 513 /* Maximum length of numeric string. */ |
fahadmirza | 0:a0c5877bd360 | 124 | |
fahadmirza | 0:a0c5877bd360 | 125 | /* |
fahadmirza | 0:a0c5877bd360 | 126 | * Flags used during conversion. |
fahadmirza | 0:a0c5877bd360 | 127 | */ |
fahadmirza | 0:a0c5877bd360 | 128 | #define LONG 0x00001 /* l: long or double */ |
fahadmirza | 0:a0c5877bd360 | 129 | #define SHORT 0x00004 /* h: short */ |
fahadmirza | 0:a0c5877bd360 | 130 | #define SHORTSHORT 0x00008 /* hh: 8 bit integer */ |
fahadmirza | 0:a0c5877bd360 | 131 | #define UNSIGNED 0x00800 /* %[oupxX] conversions */ |
fahadmirza | 0:a0c5877bd360 | 132 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 133 | #else |
fahadmirza | 0:a0c5877bd360 | 134 | #define LONGDBL 0x00002 /* L: long double; unimplemented */ |
fahadmirza | 0:a0c5877bd360 | 135 | #define LLONG 0x00010 /* ll: long long (+ deprecated q: quad) */ |
fahadmirza | 0:a0c5877bd360 | 136 | #define POINTER 0x00020 /* p: void * (as hex) */ |
fahadmirza | 0:a0c5877bd360 | 137 | #define SIZEINT 0x00040 /* z: (signed) size_t */ |
fahadmirza | 0:a0c5877bd360 | 138 | #define MAXINT 0x00080 /* j: intmax_t */ |
fahadmirza | 0:a0c5877bd360 | 139 | #define PTRINT 0x00100 /* t: ptrdiff_t */ |
fahadmirza | 0:a0c5877bd360 | 140 | #define NOSKIP 0x00200 /* [ or c: do not skip blanks */ |
fahadmirza | 0:a0c5877bd360 | 141 | #define SUPPRESS 0x00400 /* *: suppress assignment */ |
fahadmirza | 0:a0c5877bd360 | 142 | #endif |
fahadmirza | 0:a0c5877bd360 | 143 | |
fahadmirza | 0:a0c5877bd360 | 144 | /* |
fahadmirza | 0:a0c5877bd360 | 145 | * The following are used in numeric conversions only: |
fahadmirza | 0:a0c5877bd360 | 146 | * SIGNOK, HAVESIGN, NDIGITS, DPTOK, and EXPOK are for floating point; |
fahadmirza | 0:a0c5877bd360 | 147 | * SIGNOK, HAVESIGN, NDIGITS, PFXOK, and NZDIGITS are for integral. |
fahadmirza | 0:a0c5877bd360 | 148 | */ |
fahadmirza | 0:a0c5877bd360 | 149 | #define SIGNOK 0x01000 /* +/- is (still) legal */ |
fahadmirza | 0:a0c5877bd360 | 150 | #define HAVESIGN 0x02000 /* sign detected */ |
fahadmirza | 0:a0c5877bd360 | 151 | #define NDIGITS 0x04000 /* no digits detected */ |
fahadmirza | 0:a0c5877bd360 | 152 | |
fahadmirza | 0:a0c5877bd360 | 153 | #define DPTOK 0x08000 /* (float) decimal point is still legal */ |
fahadmirza | 0:a0c5877bd360 | 154 | #define EXPOK 0x10000 /* (float) exponent (e+3, etc) still legal */ |
fahadmirza | 0:a0c5877bd360 | 155 | |
fahadmirza | 0:a0c5877bd360 | 156 | #ifdef TINY_NO_OX |
fahadmirza | 0:a0c5877bd360 | 157 | #else |
fahadmirza | 0:a0c5877bd360 | 158 | #define PFXOK 0x08000 /* 0x prefix is (still) legal */ |
fahadmirza | 0:a0c5877bd360 | 159 | #define NZDIGITS 0x10000 /* no zero digits detected */ |
fahadmirza | 0:a0c5877bd360 | 160 | #endif |
fahadmirza | 0:a0c5877bd360 | 161 | |
fahadmirza | 0:a0c5877bd360 | 162 | /* |
fahadmirza | 0:a0c5877bd360 | 163 | * Conversion types. |
fahadmirza | 0:a0c5877bd360 | 164 | */ |
fahadmirza | 0:a0c5877bd360 | 165 | #define CT_INT 3 /* integer, i.e., strtoimax or strtoumax */ |
fahadmirza | 0:a0c5877bd360 | 166 | #define CT_FLOAT 4 /* floating, i.e., strtod */ |
fahadmirza | 0:a0c5877bd360 | 167 | |
fahadmirza | 0:a0c5877bd360 | 168 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 169 | #else |
fahadmirza | 0:a0c5877bd360 | 170 | #define CT_CHAR 0 /* %c conversion */ |
fahadmirza | 0:a0c5877bd360 | 171 | #define CT_CCL 1 /* %[...] conversion */ |
fahadmirza | 0:a0c5877bd360 | 172 | #define CT_STRING 2 /* %s conversion */ |
fahadmirza | 0:a0c5877bd360 | 173 | #endif |
fahadmirza | 0:a0c5877bd360 | 174 | |
fahadmirza | 0:a0c5877bd360 | 175 | #define u_char unsigned char |
fahadmirza | 0:a0c5877bd360 | 176 | #define u_long unsigned long |
fahadmirza | 0:a0c5877bd360 | 177 | |
fahadmirza | 0:a0c5877bd360 | 178 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 179 | #else |
fahadmirza | 0:a0c5877bd360 | 180 | static u_char *__sccl(char *, u_char *); |
fahadmirza | 0:a0c5877bd360 | 181 | #endif |
fahadmirza | 0:a0c5877bd360 | 182 | |
fahadmirza | 0:a0c5877bd360 | 183 | #define VFSCANF tiny_vfscanf |
fahadmirza | 0:a0c5877bd360 | 184 | |
fahadmirza | 0:a0c5877bd360 | 185 | #if !defined(VFSCANF) |
fahadmirza | 0:a0c5877bd360 | 186 | #define VFSCANF vfscanf |
fahadmirza | 0:a0c5877bd360 | 187 | #endif |
fahadmirza | 0:a0c5877bd360 | 188 | |
fahadmirza | 0:a0c5877bd360 | 189 | |
fahadmirza | 0:a0c5877bd360 | 190 | #define __srefill(_x) 1 |
fahadmirza | 0:a0c5877bd360 | 191 | #define ungetc(_c, _fp) do { (_c), fp_p--; fp_r++; } while (0) |
fahadmirza | 0:a0c5877bd360 | 192 | |
fahadmirza | 0:a0c5877bd360 | 193 | /* |
fahadmirza | 0:a0c5877bd360 | 194 | * vfscanf |
fahadmirza | 0:a0c5877bd360 | 195 | */ |
fahadmirza | 0:a0c5877bd360 | 196 | static inline int |
fahadmirza | 0:a0c5877bd360 | 197 | VFSCANF(const char *str, const char *fmt0, __va_list ap) |
fahadmirza | 0:a0c5877bd360 | 198 | { |
fahadmirza | 0:a0c5877bd360 | 199 | u_char *fmt = (u_char *)fmt0; |
fahadmirza | 0:a0c5877bd360 | 200 | int c; /* character from format, or conversion */ |
fahadmirza | 0:a0c5877bd360 | 201 | size_t width; /* field width, or 0 */ |
fahadmirza | 0:a0c5877bd360 | 202 | char *p; /* points into all kinds of strings */ |
fahadmirza | 0:a0c5877bd360 | 203 | int flags; /* flags as defined above */ |
fahadmirza | 0:a0c5877bd360 | 204 | int nassigned; /* number of fields assigned */ |
fahadmirza | 0:a0c5877bd360 | 205 | int nread; /* number of characters consumed from fp */ |
fahadmirza | 0:a0c5877bd360 | 206 | int base; /* base argument to strtoimax/strtouimax */ |
fahadmirza | 0:a0c5877bd360 | 207 | char buf[BUF]; /* buffer for numeric conversions */ |
fahadmirza | 0:a0c5877bd360 | 208 | const char *fp_p; |
fahadmirza | 0:a0c5877bd360 | 209 | int fp_r; |
fahadmirza | 0:a0c5877bd360 | 210 | uintmax_t value; |
fahadmirza | 0:a0c5877bd360 | 211 | int sign_minus; |
fahadmirza | 0:a0c5877bd360 | 212 | |
fahadmirza | 0:a0c5877bd360 | 213 | |
fahadmirza | 0:a0c5877bd360 | 214 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 215 | #else |
fahadmirza | 0:a0c5877bd360 | 216 | int n; /* handy integer */ |
fahadmirza | 0:a0c5877bd360 | 217 | char *p0; /* saves original value of p when necessary */ |
fahadmirza | 0:a0c5877bd360 | 218 | char ccltab[256]; /* character class table for %[...] */ |
fahadmirza | 0:a0c5877bd360 | 219 | #endif |
fahadmirza | 0:a0c5877bd360 | 220 | |
fahadmirza | 0:a0c5877bd360 | 221 | /* `basefix' is used to avoid `if' tests in the integer scanner */ |
fahadmirza | 0:a0c5877bd360 | 222 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 223 | /* basefix[] can be removed as we do not support %i */ |
fahadmirza | 0:a0c5877bd360 | 224 | #else |
fahadmirza | 0:a0c5877bd360 | 225 | static short basefix[17] = |
fahadmirza | 0:a0c5877bd360 | 226 | { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; |
fahadmirza | 0:a0c5877bd360 | 227 | #endif |
fahadmirza | 0:a0c5877bd360 | 228 | |
fahadmirza | 0:a0c5877bd360 | 229 | fp_p = str; |
fahadmirza | 0:a0c5877bd360 | 230 | fp_r = strlen(str); |
fahadmirza | 0:a0c5877bd360 | 231 | |
fahadmirza | 0:a0c5877bd360 | 232 | nassigned = 0; |
fahadmirza | 0:a0c5877bd360 | 233 | nread = 0; |
fahadmirza | 0:a0c5877bd360 | 234 | base = 0; /* XXX just to keep gcc happy */ |
fahadmirza | 0:a0c5877bd360 | 235 | for (;;) { |
fahadmirza | 0:a0c5877bd360 | 236 | c = *fmt++; |
fahadmirza | 0:a0c5877bd360 | 237 | if (c == 0) |
fahadmirza | 0:a0c5877bd360 | 238 | return (nassigned); |
fahadmirza | 0:a0c5877bd360 | 239 | #ifdef TINY_SPACE_NOT_SPECIALCASE |
fahadmirza | 0:a0c5877bd360 | 240 | #else |
fahadmirza | 0:a0c5877bd360 | 241 | if (isspace(c)) { |
fahadmirza | 0:a0c5877bd360 | 242 | while ((fp_r > 0 || __srefill(fp) == 0) && |
fahadmirza | 0:a0c5877bd360 | 243 | isspace(*fp_p)) |
fahadmirza | 0:a0c5877bd360 | 244 | nread++, fp_r--, fp_p++; |
fahadmirza | 0:a0c5877bd360 | 245 | continue; |
fahadmirza | 0:a0c5877bd360 | 246 | } |
fahadmirza | 0:a0c5877bd360 | 247 | #endif |
fahadmirza | 0:a0c5877bd360 | 248 | if (c != '%') |
fahadmirza | 0:a0c5877bd360 | 249 | goto literal; |
fahadmirza | 0:a0c5877bd360 | 250 | width = 0; |
fahadmirza | 0:a0c5877bd360 | 251 | flags = 0; |
fahadmirza | 0:a0c5877bd360 | 252 | /* |
fahadmirza | 0:a0c5877bd360 | 253 | * switch on the format. continue if done; |
fahadmirza | 0:a0c5877bd360 | 254 | * break once format type is derived. |
fahadmirza | 0:a0c5877bd360 | 255 | */ |
fahadmirza | 0:a0c5877bd360 | 256 | again: c = *fmt++; |
fahadmirza | 0:a0c5877bd360 | 257 | switch (c) { |
fahadmirza | 0:a0c5877bd360 | 258 | case '%': |
fahadmirza | 0:a0c5877bd360 | 259 | literal: |
fahadmirza | 0:a0c5877bd360 | 260 | if (fp_r <= 0 && __srefill(fp)) |
fahadmirza | 0:a0c5877bd360 | 261 | goto input_failure; |
fahadmirza | 0:a0c5877bd360 | 262 | if (*fp_p != c) |
fahadmirza | 0:a0c5877bd360 | 263 | goto match_failure; |
fahadmirza | 0:a0c5877bd360 | 264 | fp_r--, fp_p++; |
fahadmirza | 0:a0c5877bd360 | 265 | nread++; |
fahadmirza | 0:a0c5877bd360 | 266 | continue; |
fahadmirza | 0:a0c5877bd360 | 267 | |
fahadmirza | 0:a0c5877bd360 | 268 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 269 | #else |
fahadmirza | 0:a0c5877bd360 | 270 | case '*': |
fahadmirza | 0:a0c5877bd360 | 271 | flags |= SUPPRESS; |
fahadmirza | 0:a0c5877bd360 | 272 | goto again; |
fahadmirza | 0:a0c5877bd360 | 273 | case 'j': |
fahadmirza | 0:a0c5877bd360 | 274 | flags |= MAXINT; |
fahadmirza | 0:a0c5877bd360 | 275 | goto again; |
fahadmirza | 0:a0c5877bd360 | 276 | case 'L': |
fahadmirza | 0:a0c5877bd360 | 277 | flags |= LONGDBL; |
fahadmirza | 0:a0c5877bd360 | 278 | goto again; |
fahadmirza | 0:a0c5877bd360 | 279 | #endif |
fahadmirza | 0:a0c5877bd360 | 280 | case 'h': |
fahadmirza | 0:a0c5877bd360 | 281 | if (*fmt == 'h') { |
fahadmirza | 0:a0c5877bd360 | 282 | fmt++; |
fahadmirza | 0:a0c5877bd360 | 283 | flags |= SHORTSHORT; |
fahadmirza | 0:a0c5877bd360 | 284 | } else { |
fahadmirza | 0:a0c5877bd360 | 285 | flags |= SHORT; |
fahadmirza | 0:a0c5877bd360 | 286 | } |
fahadmirza | 0:a0c5877bd360 | 287 | goto again; |
fahadmirza | 0:a0c5877bd360 | 288 | case 'l': |
fahadmirza | 0:a0c5877bd360 | 289 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 290 | /* %ll not supported */ |
fahadmirza | 0:a0c5877bd360 | 291 | flags |= LONG; |
fahadmirza | 0:a0c5877bd360 | 292 | goto again; |
fahadmirza | 0:a0c5877bd360 | 293 | #else |
fahadmirza | 0:a0c5877bd360 | 294 | if (*fmt == 'l') { |
fahadmirza | 0:a0c5877bd360 | 295 | fmt++; |
fahadmirza | 0:a0c5877bd360 | 296 | flags |= LLONG; |
fahadmirza | 0:a0c5877bd360 | 297 | } else { |
fahadmirza | 0:a0c5877bd360 | 298 | flags |= LONG; |
fahadmirza | 0:a0c5877bd360 | 299 | } |
fahadmirza | 0:a0c5877bd360 | 300 | goto again; |
fahadmirza | 0:a0c5877bd360 | 301 | #endif |
fahadmirza | 0:a0c5877bd360 | 302 | |
fahadmirza | 0:a0c5877bd360 | 303 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 304 | #else |
fahadmirza | 0:a0c5877bd360 | 305 | case 'q': |
fahadmirza | 0:a0c5877bd360 | 306 | flags |= LLONG; /* deprecated */ |
fahadmirza | 0:a0c5877bd360 | 307 | goto again; |
fahadmirza | 0:a0c5877bd360 | 308 | case 't': |
fahadmirza | 0:a0c5877bd360 | 309 | flags |= PTRINT; |
fahadmirza | 0:a0c5877bd360 | 310 | goto again; |
fahadmirza | 0:a0c5877bd360 | 311 | case 'z': |
fahadmirza | 0:a0c5877bd360 | 312 | flags |= SIZEINT; |
fahadmirza | 0:a0c5877bd360 | 313 | goto again; |
fahadmirza | 0:a0c5877bd360 | 314 | #endif |
fahadmirza | 0:a0c5877bd360 | 315 | case '0': case '1': case '2': case '3': case '4': |
fahadmirza | 0:a0c5877bd360 | 316 | case '5': case '6': case '7': case '8': case '9': |
fahadmirza | 0:a0c5877bd360 | 317 | width = width * 10 + c - '0'; |
fahadmirza | 0:a0c5877bd360 | 318 | goto again; |
fahadmirza | 0:a0c5877bd360 | 319 | |
fahadmirza | 0:a0c5877bd360 | 320 | /* |
fahadmirza | 0:a0c5877bd360 | 321 | * Conversions. |
fahadmirza | 0:a0c5877bd360 | 322 | * Those marked `compat' are for 4.[123]BSD compatibility. |
fahadmirza | 0:a0c5877bd360 | 323 | * |
fahadmirza | 0:a0c5877bd360 | 324 | * (According to ANSI, E and X formats are supposed |
fahadmirza | 0:a0c5877bd360 | 325 | * to the same as e and x. Sorry about that.) |
fahadmirza | 0:a0c5877bd360 | 326 | */ |
fahadmirza | 0:a0c5877bd360 | 327 | case 'D': /* compat */ |
fahadmirza | 0:a0c5877bd360 | 328 | flags |= LONG; |
fahadmirza | 0:a0c5877bd360 | 329 | /* FALLTHROUGH */ |
fahadmirza | 0:a0c5877bd360 | 330 | case 'd': |
fahadmirza | 0:a0c5877bd360 | 331 | c = CT_INT; |
fahadmirza | 0:a0c5877bd360 | 332 | base = 10; |
fahadmirza | 0:a0c5877bd360 | 333 | break; |
fahadmirza | 0:a0c5877bd360 | 334 | |
fahadmirza | 0:a0c5877bd360 | 335 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 336 | /* |
fahadmirza | 0:a0c5877bd360 | 337 | * We do not support %i to remove potential base=8 in the following |
fahadmirza | 0:a0c5877bd360 | 338 | * Hence basefix can be removed |
fahadmirza | 0:a0c5877bd360 | 339 | */ |
fahadmirza | 0:a0c5877bd360 | 340 | #else |
fahadmirza | 0:a0c5877bd360 | 341 | case 'i': |
fahadmirza | 0:a0c5877bd360 | 342 | c = CT_INT; |
fahadmirza | 0:a0c5877bd360 | 343 | base = 0; |
fahadmirza | 0:a0c5877bd360 | 344 | break; |
fahadmirza | 0:a0c5877bd360 | 345 | #endif |
fahadmirza | 0:a0c5877bd360 | 346 | |
fahadmirza | 0:a0c5877bd360 | 347 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 348 | #else |
fahadmirza | 0:a0c5877bd360 | 349 | case 'O': /* compat */ |
fahadmirza | 0:a0c5877bd360 | 350 | flags |= LONG; |
fahadmirza | 0:a0c5877bd360 | 351 | /* FALLTHROUGH */ |
fahadmirza | 0:a0c5877bd360 | 352 | case 'o': |
fahadmirza | 0:a0c5877bd360 | 353 | c = CT_INT; |
fahadmirza | 0:a0c5877bd360 | 354 | flags |= UNSIGNED; |
fahadmirza | 0:a0c5877bd360 | 355 | base = 8; |
fahadmirza | 0:a0c5877bd360 | 356 | break; |
fahadmirza | 0:a0c5877bd360 | 357 | #endif |
fahadmirza | 0:a0c5877bd360 | 358 | |
fahadmirza | 0:a0c5877bd360 | 359 | case 'u': |
fahadmirza | 0:a0c5877bd360 | 360 | c = CT_INT; |
fahadmirza | 0:a0c5877bd360 | 361 | flags |= UNSIGNED; |
fahadmirza | 0:a0c5877bd360 | 362 | base = 10; |
fahadmirza | 0:a0c5877bd360 | 363 | break; |
fahadmirza | 0:a0c5877bd360 | 364 | |
fahadmirza | 0:a0c5877bd360 | 365 | case 'X': |
fahadmirza | 0:a0c5877bd360 | 366 | case 'x': |
fahadmirza | 0:a0c5877bd360 | 367 | #ifdef TINY_NO_OX |
fahadmirza | 0:a0c5877bd360 | 368 | #else |
fahadmirza | 0:a0c5877bd360 | 369 | flags |= PFXOK; /* enable 0x prefixing */ |
fahadmirza | 0:a0c5877bd360 | 370 | #endif |
fahadmirza | 0:a0c5877bd360 | 371 | c = CT_INT; |
fahadmirza | 0:a0c5877bd360 | 372 | flags |= UNSIGNED; |
fahadmirza | 0:a0c5877bd360 | 373 | base = 16; |
fahadmirza | 0:a0c5877bd360 | 374 | break; |
fahadmirza | 0:a0c5877bd360 | 375 | |
fahadmirza | 0:a0c5877bd360 | 376 | #ifdef FLOATING_POINT |
fahadmirza | 0:a0c5877bd360 | 377 | case 'E': |
fahadmirza | 0:a0c5877bd360 | 378 | case 'G': |
fahadmirza | 0:a0c5877bd360 | 379 | case 'e': |
fahadmirza | 0:a0c5877bd360 | 380 | case 'f': |
fahadmirza | 0:a0c5877bd360 | 381 | case 'g': |
fahadmirza | 0:a0c5877bd360 | 382 | c = CT_FLOAT; |
fahadmirza | 0:a0c5877bd360 | 383 | break; |
fahadmirza | 0:a0c5877bd360 | 384 | #endif |
fahadmirza | 0:a0c5877bd360 | 385 | |
fahadmirza | 0:a0c5877bd360 | 386 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 387 | #else |
fahadmirza | 0:a0c5877bd360 | 388 | case 's': |
fahadmirza | 0:a0c5877bd360 | 389 | c = CT_STRING; |
fahadmirza | 0:a0c5877bd360 | 390 | break; |
fahadmirza | 0:a0c5877bd360 | 391 | |
fahadmirza | 0:a0c5877bd360 | 392 | case '[': |
fahadmirza | 0:a0c5877bd360 | 393 | fmt = __sccl(ccltab, fmt); |
fahadmirza | 0:a0c5877bd360 | 394 | flags |= NOSKIP; |
fahadmirza | 0:a0c5877bd360 | 395 | c = CT_CCL; |
fahadmirza | 0:a0c5877bd360 | 396 | break; |
fahadmirza | 0:a0c5877bd360 | 397 | |
fahadmirza | 0:a0c5877bd360 | 398 | case 'c': |
fahadmirza | 0:a0c5877bd360 | 399 | flags |= NOSKIP; |
fahadmirza | 0:a0c5877bd360 | 400 | c = CT_CHAR; |
fahadmirza | 0:a0c5877bd360 | 401 | break; |
fahadmirza | 0:a0c5877bd360 | 402 | |
fahadmirza | 0:a0c5877bd360 | 403 | case 'p': /* pointer format is like hex */ |
fahadmirza | 0:a0c5877bd360 | 404 | flags |= POINTER | PFXOK; |
fahadmirza | 0:a0c5877bd360 | 405 | c = CT_INT; |
fahadmirza | 0:a0c5877bd360 | 406 | flags |= UNSIGNED; |
fahadmirza | 0:a0c5877bd360 | 407 | base = 16; |
fahadmirza | 0:a0c5877bd360 | 408 | break; |
fahadmirza | 0:a0c5877bd360 | 409 | |
fahadmirza | 0:a0c5877bd360 | 410 | case 'n': |
fahadmirza | 0:a0c5877bd360 | 411 | if (flags & SUPPRESS) |
fahadmirza | 0:a0c5877bd360 | 412 | continue; |
fahadmirza | 0:a0c5877bd360 | 413 | if (flags & SHORTSHORT) |
fahadmirza | 0:a0c5877bd360 | 414 | *va_arg(ap, char *) = nread; |
fahadmirza | 0:a0c5877bd360 | 415 | else if (flags & SHORT) |
fahadmirza | 0:a0c5877bd360 | 416 | *va_arg(ap, short *) = nread; |
fahadmirza | 0:a0c5877bd360 | 417 | else if (flags & LONG) |
fahadmirza | 0:a0c5877bd360 | 418 | *va_arg(ap, long *) = nread; |
fahadmirza | 0:a0c5877bd360 | 419 | else if (flags & SIZEINT) |
fahadmirza | 0:a0c5877bd360 | 420 | *va_arg(ap, size_t *) = nread; |
fahadmirza | 0:a0c5877bd360 | 421 | else if (flags & PTRINT) |
fahadmirza | 0:a0c5877bd360 | 422 | *va_arg(ap, ptrdiff_t *) = nread; |
fahadmirza | 0:a0c5877bd360 | 423 | else if (flags & LLONG) |
fahadmirza | 0:a0c5877bd360 | 424 | *va_arg(ap, long long *) = nread; |
fahadmirza | 0:a0c5877bd360 | 425 | else if (flags & MAXINT) |
fahadmirza | 0:a0c5877bd360 | 426 | *va_arg(ap, intmax_t *) = nread; |
fahadmirza | 0:a0c5877bd360 | 427 | else |
fahadmirza | 0:a0c5877bd360 | 428 | *va_arg(ap, int *) = nread; |
fahadmirza | 0:a0c5877bd360 | 429 | continue; |
fahadmirza | 0:a0c5877bd360 | 430 | #endif |
fahadmirza | 0:a0c5877bd360 | 431 | |
fahadmirza | 0:a0c5877bd360 | 432 | /* |
fahadmirza | 0:a0c5877bd360 | 433 | * Disgusting backwards compatibility hacks. XXX |
fahadmirza | 0:a0c5877bd360 | 434 | */ |
fahadmirza | 0:a0c5877bd360 | 435 | case '\0': /* compat */ |
fahadmirza | 0:a0c5877bd360 | 436 | return (EOF); |
fahadmirza | 0:a0c5877bd360 | 437 | |
fahadmirza | 0:a0c5877bd360 | 438 | default: /* compat */ |
fahadmirza | 0:a0c5877bd360 | 439 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 440 | #else |
fahadmirza | 0:a0c5877bd360 | 441 | if (isupper(c)) |
fahadmirza | 0:a0c5877bd360 | 442 | flags |= LONG; |
fahadmirza | 0:a0c5877bd360 | 443 | c = CT_INT; |
fahadmirza | 0:a0c5877bd360 | 444 | base = 10; |
fahadmirza | 0:a0c5877bd360 | 445 | #endif |
fahadmirza | 0:a0c5877bd360 | 446 | break; |
fahadmirza | 0:a0c5877bd360 | 447 | } |
fahadmirza | 0:a0c5877bd360 | 448 | |
fahadmirza | 0:a0c5877bd360 | 449 | /* |
fahadmirza | 0:a0c5877bd360 | 450 | * We have a conversion that requires input. |
fahadmirza | 0:a0c5877bd360 | 451 | */ |
fahadmirza | 0:a0c5877bd360 | 452 | if (fp_r <= 0 && __srefill(fp)) |
fahadmirza | 0:a0c5877bd360 | 453 | goto input_failure; |
fahadmirza | 0:a0c5877bd360 | 454 | |
fahadmirza | 0:a0c5877bd360 | 455 | |
fahadmirza | 0:a0c5877bd360 | 456 | /* |
fahadmirza | 0:a0c5877bd360 | 457 | * Consume leading white space, except for formats |
fahadmirza | 0:a0c5877bd360 | 458 | * that suppress this. |
fahadmirza | 0:a0c5877bd360 | 459 | */ |
fahadmirza | 0:a0c5877bd360 | 460 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 461 | #else |
fahadmirza | 0:a0c5877bd360 | 462 | if ((flags & NOSKIP) == 0) { |
fahadmirza | 0:a0c5877bd360 | 463 | while (isspace(*fp_p)) { |
fahadmirza | 0:a0c5877bd360 | 464 | nread++; |
fahadmirza | 0:a0c5877bd360 | 465 | if (--fp_r > 0) |
fahadmirza | 0:a0c5877bd360 | 466 | fp_p++; |
fahadmirza | 0:a0c5877bd360 | 467 | else if (__srefill(fp)) |
fahadmirza | 0:a0c5877bd360 | 468 | goto input_failure; |
fahadmirza | 0:a0c5877bd360 | 469 | } |
fahadmirza | 0:a0c5877bd360 | 470 | /* |
fahadmirza | 0:a0c5877bd360 | 471 | * Note that there is at least one character in |
fahadmirza | 0:a0c5877bd360 | 472 | * the buffer, so conversions that do not set NOSKIP |
fahadmirza | 0:a0c5877bd360 | 473 | * ca no longer result in an input failure. |
fahadmirza | 0:a0c5877bd360 | 474 | */ |
fahadmirza | 0:a0c5877bd360 | 475 | } |
fahadmirza | 0:a0c5877bd360 | 476 | #endif |
fahadmirza | 0:a0c5877bd360 | 477 | |
fahadmirza | 0:a0c5877bd360 | 478 | /* |
fahadmirza | 0:a0c5877bd360 | 479 | * Do the conversion. |
fahadmirza | 0:a0c5877bd360 | 480 | */ |
fahadmirza | 0:a0c5877bd360 | 481 | switch (c) { |
fahadmirza | 0:a0c5877bd360 | 482 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 483 | #else |
fahadmirza | 0:a0c5877bd360 | 484 | case CT_CHAR: |
fahadmirza | 0:a0c5877bd360 | 485 | /* scan arbitrary characters (sets NOSKIP) */ |
fahadmirza | 0:a0c5877bd360 | 486 | if (width == 0) |
fahadmirza | 0:a0c5877bd360 | 487 | width = 1; |
fahadmirza | 0:a0c5877bd360 | 488 | if (flags & SUPPRESS) { |
fahadmirza | 0:a0c5877bd360 | 489 | size_t sum = 0; |
fahadmirza | 0:a0c5877bd360 | 490 | for (;;) { |
fahadmirza | 0:a0c5877bd360 | 491 | if ((n = fp_r) < (int)width) { |
fahadmirza | 0:a0c5877bd360 | 492 | sum += n; |
fahadmirza | 0:a0c5877bd360 | 493 | width -= n; |
fahadmirza | 0:a0c5877bd360 | 494 | fp_p += n; |
fahadmirza | 0:a0c5877bd360 | 495 | if (__srefill(fp)) { |
fahadmirza | 0:a0c5877bd360 | 496 | if (sum == 0) |
fahadmirza | 0:a0c5877bd360 | 497 | goto input_failure; |
fahadmirza | 0:a0c5877bd360 | 498 | break; |
fahadmirza | 0:a0c5877bd360 | 499 | } |
fahadmirza | 0:a0c5877bd360 | 500 | } else { |
fahadmirza | 0:a0c5877bd360 | 501 | sum += width; |
fahadmirza | 0:a0c5877bd360 | 502 | fp_r -= width; |
fahadmirza | 0:a0c5877bd360 | 503 | fp_p += width; |
fahadmirza | 0:a0c5877bd360 | 504 | break; |
fahadmirza | 0:a0c5877bd360 | 505 | } |
fahadmirza | 0:a0c5877bd360 | 506 | } |
fahadmirza | 0:a0c5877bd360 | 507 | nread += sum; |
fahadmirza | 0:a0c5877bd360 | 508 | } else { |
fahadmirza | 0:a0c5877bd360 | 509 | size_t r = fread((void *)va_arg(ap, char *), 1, |
fahadmirza | 0:a0c5877bd360 | 510 | width, fp); |
fahadmirza | 0:a0c5877bd360 | 511 | |
fahadmirza | 0:a0c5877bd360 | 512 | if (r == 0) |
fahadmirza | 0:a0c5877bd360 | 513 | goto input_failure; |
fahadmirza | 0:a0c5877bd360 | 514 | nread += r; |
fahadmirza | 0:a0c5877bd360 | 515 | nassigned++; |
fahadmirza | 0:a0c5877bd360 | 516 | } |
fahadmirza | 0:a0c5877bd360 | 517 | break; |
fahadmirza | 0:a0c5877bd360 | 518 | #endif |
fahadmirza | 0:a0c5877bd360 | 519 | |
fahadmirza | 0:a0c5877bd360 | 520 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 521 | #else |
fahadmirza | 0:a0c5877bd360 | 522 | case CT_CCL: |
fahadmirza | 0:a0c5877bd360 | 523 | /* scan a (nonempty) character class (sets NOSKIP) */ |
fahadmirza | 0:a0c5877bd360 | 524 | if (width == 0) |
fahadmirza | 0:a0c5877bd360 | 525 | width = (size_t)~0; /* `infinity' */ |
fahadmirza | 0:a0c5877bd360 | 526 | /* take only those things in the class */ |
fahadmirza | 0:a0c5877bd360 | 527 | if (flags & SUPPRESS) { |
fahadmirza | 0:a0c5877bd360 | 528 | n = 0; |
fahadmirza | 0:a0c5877bd360 | 529 | while (ccltab[*fp_p]) { |
fahadmirza | 0:a0c5877bd360 | 530 | n++, fp_r--, fp_p++; |
fahadmirza | 0:a0c5877bd360 | 531 | if (--width == 0) |
fahadmirza | 0:a0c5877bd360 | 532 | break; |
fahadmirza | 0:a0c5877bd360 | 533 | if (fp_r <= 0 && __srefill(fp)) { |
fahadmirza | 0:a0c5877bd360 | 534 | if (n == 0) |
fahadmirza | 0:a0c5877bd360 | 535 | goto input_failure; |
fahadmirza | 0:a0c5877bd360 | 536 | break; |
fahadmirza | 0:a0c5877bd360 | 537 | } |
fahadmirza | 0:a0c5877bd360 | 538 | } |
fahadmirza | 0:a0c5877bd360 | 539 | if (n == 0) |
fahadmirza | 0:a0c5877bd360 | 540 | goto match_failure; |
fahadmirza | 0:a0c5877bd360 | 541 | } else { |
fahadmirza | 0:a0c5877bd360 | 542 | p0 = p = va_arg(ap, char *); |
fahadmirza | 0:a0c5877bd360 | 543 | while (ccltab[*fp_p]) { |
fahadmirza | 0:a0c5877bd360 | 544 | fp_r--; |
fahadmirza | 0:a0c5877bd360 | 545 | *p++ = *fp_p++; |
fahadmirza | 0:a0c5877bd360 | 546 | if (--width == 0) |
fahadmirza | 0:a0c5877bd360 | 547 | break; |
fahadmirza | 0:a0c5877bd360 | 548 | if (fp_r <= 0 && __srefill(fp)) { |
fahadmirza | 0:a0c5877bd360 | 549 | if (p == p0) |
fahadmirza | 0:a0c5877bd360 | 550 | goto input_failure; |
fahadmirza | 0:a0c5877bd360 | 551 | break; |
fahadmirza | 0:a0c5877bd360 | 552 | } |
fahadmirza | 0:a0c5877bd360 | 553 | } |
fahadmirza | 0:a0c5877bd360 | 554 | n = p - p0; |
fahadmirza | 0:a0c5877bd360 | 555 | if (n == 0) |
fahadmirza | 0:a0c5877bd360 | 556 | goto match_failure; |
fahadmirza | 0:a0c5877bd360 | 557 | *p = '\0'; |
fahadmirza | 0:a0c5877bd360 | 558 | nassigned++; |
fahadmirza | 0:a0c5877bd360 | 559 | } |
fahadmirza | 0:a0c5877bd360 | 560 | nread += n; |
fahadmirza | 0:a0c5877bd360 | 561 | break; |
fahadmirza | 0:a0c5877bd360 | 562 | #endif |
fahadmirza | 0:a0c5877bd360 | 563 | |
fahadmirza | 0:a0c5877bd360 | 564 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 565 | #else |
fahadmirza | 0:a0c5877bd360 | 566 | case CT_STRING: |
fahadmirza | 0:a0c5877bd360 | 567 | /* like CCL, but zero-length string OK, & no NOSKIP */ |
fahadmirza | 0:a0c5877bd360 | 568 | if (width == 0) |
fahadmirza | 0:a0c5877bd360 | 569 | width = (size_t)~0; |
fahadmirza | 0:a0c5877bd360 | 570 | if (flags & SUPPRESS) { |
fahadmirza | 0:a0c5877bd360 | 571 | n = 0; |
fahadmirza | 0:a0c5877bd360 | 572 | while (!isspace(*fp_p)) { |
fahadmirza | 0:a0c5877bd360 | 573 | n++, fp_r--, fp_p++; |
fahadmirza | 0:a0c5877bd360 | 574 | if (--width == 0) |
fahadmirza | 0:a0c5877bd360 | 575 | break; |
fahadmirza | 0:a0c5877bd360 | 576 | if (fp_r <= 0 && __srefill(fp)) |
fahadmirza | 0:a0c5877bd360 | 577 | break; |
fahadmirza | 0:a0c5877bd360 | 578 | } |
fahadmirza | 0:a0c5877bd360 | 579 | nread += n; |
fahadmirza | 0:a0c5877bd360 | 580 | } else { |
fahadmirza | 0:a0c5877bd360 | 581 | p0 = p = va_arg(ap, char *); |
fahadmirza | 0:a0c5877bd360 | 582 | while (!isspace(*fp_p)) { |
fahadmirza | 0:a0c5877bd360 | 583 | fp_r--; |
fahadmirza | 0:a0c5877bd360 | 584 | *p++ = *fp_p++; |
fahadmirza | 0:a0c5877bd360 | 585 | if (--width == 0) |
fahadmirza | 0:a0c5877bd360 | 586 | break; |
fahadmirza | 0:a0c5877bd360 | 587 | if (fp_r <= 0 && __srefill(fp)) |
fahadmirza | 0:a0c5877bd360 | 588 | break; |
fahadmirza | 0:a0c5877bd360 | 589 | } |
fahadmirza | 0:a0c5877bd360 | 590 | *p = '\0'; |
fahadmirza | 0:a0c5877bd360 | 591 | nread += p - p0; |
fahadmirza | 0:a0c5877bd360 | 592 | nassigned++; |
fahadmirza | 0:a0c5877bd360 | 593 | } |
fahadmirza | 0:a0c5877bd360 | 594 | continue; |
fahadmirza | 0:a0c5877bd360 | 595 | #endif |
fahadmirza | 0:a0c5877bd360 | 596 | |
fahadmirza | 0:a0c5877bd360 | 597 | case CT_INT: |
fahadmirza | 0:a0c5877bd360 | 598 | /* scan an integer as if by strtoimax/strtoumax */ |
fahadmirza | 0:a0c5877bd360 | 599 | #ifdef hardway |
fahadmirza | 0:a0c5877bd360 | 600 | if (width == 0 || width > sizeof(buf) - 1) |
fahadmirza | 0:a0c5877bd360 | 601 | width = sizeof(buf) - 1; |
fahadmirza | 0:a0c5877bd360 | 602 | #else |
fahadmirza | 0:a0c5877bd360 | 603 | /* size_t is unsigned, hence this optimisation */ |
fahadmirza | 0:a0c5877bd360 | 604 | if (--width > sizeof(buf) - 2) |
fahadmirza | 0:a0c5877bd360 | 605 | width = sizeof(buf) - 2; |
fahadmirza | 0:a0c5877bd360 | 606 | width++; |
fahadmirza | 0:a0c5877bd360 | 607 | #endif |
fahadmirza | 0:a0c5877bd360 | 608 | |
fahadmirza | 0:a0c5877bd360 | 609 | #ifdef TINY_NO_OX |
fahadmirza | 0:a0c5877bd360 | 610 | flags |= SIGNOK | NDIGITS; |
fahadmirza | 0:a0c5877bd360 | 611 | #else |
fahadmirza | 0:a0c5877bd360 | 612 | flags |= SIGNOK | NDIGITS | NZDIGITS; |
fahadmirza | 0:a0c5877bd360 | 613 | #endif |
fahadmirza | 0:a0c5877bd360 | 614 | |
fahadmirza | 0:a0c5877bd360 | 615 | sign_minus = 0; |
fahadmirza | 0:a0c5877bd360 | 616 | value = 0; |
fahadmirza | 0:a0c5877bd360 | 617 | for (p = buf; width; width--) { |
fahadmirza | 0:a0c5877bd360 | 618 | c = *fp_p; |
fahadmirza | 0:a0c5877bd360 | 619 | /* |
fahadmirza | 0:a0c5877bd360 | 620 | * Switch on the character; `goto ok' |
fahadmirza | 0:a0c5877bd360 | 621 | * if we accept it as a part of number. |
fahadmirza | 0:a0c5877bd360 | 622 | */ |
fahadmirza | 0:a0c5877bd360 | 623 | switch (c) { |
fahadmirza | 0:a0c5877bd360 | 624 | |
fahadmirza | 0:a0c5877bd360 | 625 | /* |
fahadmirza | 0:a0c5877bd360 | 626 | * The digit 0 is always legal, but is |
fahadmirza | 0:a0c5877bd360 | 627 | * special. For %i conversions, if no |
fahadmirza | 0:a0c5877bd360 | 628 | * digits (zero or nonzero) have been |
fahadmirza | 0:a0c5877bd360 | 629 | * scanned (only signs), we will have |
fahadmirza | 0:a0c5877bd360 | 630 | * base==0. In that case, we should set |
fahadmirza | 0:a0c5877bd360 | 631 | * it to 8 and enable 0x prefixing. |
fahadmirza | 0:a0c5877bd360 | 632 | * Also, if we have not scanned zero digits |
fahadmirza | 0:a0c5877bd360 | 633 | * before this, do not turn off prefixing |
fahadmirza | 0:a0c5877bd360 | 634 | * (someone else will turn it off if we |
fahadmirza | 0:a0c5877bd360 | 635 | * have scanned any nonzero digits). |
fahadmirza | 0:a0c5877bd360 | 636 | */ |
fahadmirza | 0:a0c5877bd360 | 637 | case '0': |
fahadmirza | 0:a0c5877bd360 | 638 | #ifdef TINY_NO_OX |
fahadmirza | 0:a0c5877bd360 | 639 | /* FALLTHROUGH */ |
fahadmirza | 0:a0c5877bd360 | 640 | #else |
fahadmirza | 0:a0c5877bd360 | 641 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 642 | #else |
fahadmirza | 0:a0c5877bd360 | 643 | if (base == 0) { |
fahadmirza | 0:a0c5877bd360 | 644 | base = 8; |
fahadmirza | 0:a0c5877bd360 | 645 | flags |= PFXOK; |
fahadmirza | 0:a0c5877bd360 | 646 | } |
fahadmirza | 0:a0c5877bd360 | 647 | #endif |
fahadmirza | 0:a0c5877bd360 | 648 | if (!(flags & NDIGITS)) { |
fahadmirza | 0:a0c5877bd360 | 649 | value = value * base; |
fahadmirza | 0:a0c5877bd360 | 650 | } |
fahadmirza | 0:a0c5877bd360 | 651 | |
fahadmirza | 0:a0c5877bd360 | 652 | if (flags & NZDIGITS) |
fahadmirza | 0:a0c5877bd360 | 653 | flags &= ~(SIGNOK|NZDIGITS|NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 654 | else |
fahadmirza | 0:a0c5877bd360 | 655 | flags &= ~(SIGNOK|PFXOK|NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 656 | goto ok; |
fahadmirza | 0:a0c5877bd360 | 657 | #endif |
fahadmirza | 0:a0c5877bd360 | 658 | |
fahadmirza | 0:a0c5877bd360 | 659 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 660 | /* we only support base 10 and 16 */ |
fahadmirza | 0:a0c5877bd360 | 661 | case '1': case '2': case '3': |
fahadmirza | 0:a0c5877bd360 | 662 | case '4': case '5': case '6': case '7': |
fahadmirza | 0:a0c5877bd360 | 663 | case '8': case '9': |
fahadmirza | 0:a0c5877bd360 | 664 | #ifdef TINY_NO_OX |
fahadmirza | 0:a0c5877bd360 | 665 | flags &= ~(SIGNOK | NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 666 | #else |
fahadmirza | 0:a0c5877bd360 | 667 | flags &= ~(SIGNOK | PFXOK | NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 668 | #endif |
fahadmirza | 0:a0c5877bd360 | 669 | value = value * base + c - '0'; |
fahadmirza | 0:a0c5877bd360 | 670 | goto ok; |
fahadmirza | 0:a0c5877bd360 | 671 | #else |
fahadmirza | 0:a0c5877bd360 | 672 | /* 1 through 7 always legal */ |
fahadmirza | 0:a0c5877bd360 | 673 | case '1': case '2': case '3': |
fahadmirza | 0:a0c5877bd360 | 674 | case '4': case '5': case '6': case '7': |
fahadmirza | 0:a0c5877bd360 | 675 | base = basefix[base]; |
fahadmirza | 0:a0c5877bd360 | 676 | flags &= ~(SIGNOK | PFXOK | NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 677 | value = value * base + c - '0'; |
fahadmirza | 0:a0c5877bd360 | 678 | goto ok; |
fahadmirza | 0:a0c5877bd360 | 679 | |
fahadmirza | 0:a0c5877bd360 | 680 | /* digits 8 and 9 ok iff decimal or hex */ |
fahadmirza | 0:a0c5877bd360 | 681 | case '8': case '9': |
fahadmirza | 0:a0c5877bd360 | 682 | base = basefix[base]; |
fahadmirza | 0:a0c5877bd360 | 683 | if (base <= 8) |
fahadmirza | 0:a0c5877bd360 | 684 | break; /* not legal here */ |
fahadmirza | 0:a0c5877bd360 | 685 | flags &= ~(SIGNOK | PFXOK | NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 686 | value = value * base + c - '0'; |
fahadmirza | 0:a0c5877bd360 | 687 | goto ok; |
fahadmirza | 0:a0c5877bd360 | 688 | #endif |
fahadmirza | 0:a0c5877bd360 | 689 | |
fahadmirza | 0:a0c5877bd360 | 690 | /* letters ok iff hex */ |
fahadmirza | 0:a0c5877bd360 | 691 | case 'A': case 'B': case 'C': |
fahadmirza | 0:a0c5877bd360 | 692 | case 'D': case 'E': case 'F': |
fahadmirza | 0:a0c5877bd360 | 693 | /* no need to fix base here */ |
fahadmirza | 0:a0c5877bd360 | 694 | if (base <= 10) |
fahadmirza | 0:a0c5877bd360 | 695 | break; /* not legal here */ |
fahadmirza | 0:a0c5877bd360 | 696 | #ifdef TINY_NO_OX |
fahadmirza | 0:a0c5877bd360 | 697 | flags &= ~(SIGNOK | NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 698 | #else |
fahadmirza | 0:a0c5877bd360 | 699 | flags &= ~(SIGNOK | PFXOK | NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 700 | #endif |
fahadmirza | 0:a0c5877bd360 | 701 | value = value * base + c - 'A' + 10; |
fahadmirza | 0:a0c5877bd360 | 702 | goto ok; |
fahadmirza | 0:a0c5877bd360 | 703 | |
fahadmirza | 0:a0c5877bd360 | 704 | case 'a': case 'b': case 'c': |
fahadmirza | 0:a0c5877bd360 | 705 | case 'd': case 'e': case 'f': |
fahadmirza | 0:a0c5877bd360 | 706 | /* no need to fix base here */ |
fahadmirza | 0:a0c5877bd360 | 707 | if (base <= 10) |
fahadmirza | 0:a0c5877bd360 | 708 | break; /* not legal here */ |
fahadmirza | 0:a0c5877bd360 | 709 | #ifdef TINY_NO_OX |
fahadmirza | 0:a0c5877bd360 | 710 | flags &= ~(SIGNOK | NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 711 | #else |
fahadmirza | 0:a0c5877bd360 | 712 | flags &= ~(SIGNOK | PFXOK | NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 713 | #endif |
fahadmirza | 0:a0c5877bd360 | 714 | value = value * base + c - 'a' + 10; |
fahadmirza | 0:a0c5877bd360 | 715 | goto ok; |
fahadmirza | 0:a0c5877bd360 | 716 | |
fahadmirza | 0:a0c5877bd360 | 717 | /* sign ok only as first character */ |
fahadmirza | 0:a0c5877bd360 | 718 | case '-': |
fahadmirza | 0:a0c5877bd360 | 719 | if (!(flags & HAVESIGN)) { |
fahadmirza | 0:a0c5877bd360 | 720 | sign_minus = 1; |
fahadmirza | 0:a0c5877bd360 | 721 | } |
fahadmirza | 0:a0c5877bd360 | 722 | /* FALLTHROUGH */ |
fahadmirza | 0:a0c5877bd360 | 723 | case '+': |
fahadmirza | 0:a0c5877bd360 | 724 | if (flags & SIGNOK) { |
fahadmirza | 0:a0c5877bd360 | 725 | flags &= ~SIGNOK; |
fahadmirza | 0:a0c5877bd360 | 726 | flags |= HAVESIGN; |
fahadmirza | 0:a0c5877bd360 | 727 | goto ok; |
fahadmirza | 0:a0c5877bd360 | 728 | } |
fahadmirza | 0:a0c5877bd360 | 729 | break; |
fahadmirza | 0:a0c5877bd360 | 730 | |
fahadmirza | 0:a0c5877bd360 | 731 | /* |
fahadmirza | 0:a0c5877bd360 | 732 | * x ok iff flag still set and 2nd char (or |
fahadmirza | 0:a0c5877bd360 | 733 | * 3rd char if we have a sign). |
fahadmirza | 0:a0c5877bd360 | 734 | */ |
fahadmirza | 0:a0c5877bd360 | 735 | #ifdef TINY_NO_OX |
fahadmirza | 0:a0c5877bd360 | 736 | #else |
fahadmirza | 0:a0c5877bd360 | 737 | case 'x': case 'X': |
fahadmirza | 0:a0c5877bd360 | 738 | if ((flags & PFXOK) && p == |
fahadmirza | 0:a0c5877bd360 | 739 | buf + 1 + !!(flags & HAVESIGN)) { |
fahadmirza | 0:a0c5877bd360 | 740 | base = 16; /* if %i */ |
fahadmirza | 0:a0c5877bd360 | 741 | flags &= ~PFXOK; |
fahadmirza | 0:a0c5877bd360 | 742 | goto ok; |
fahadmirza | 0:a0c5877bd360 | 743 | } |
fahadmirza | 0:a0c5877bd360 | 744 | break; |
fahadmirza | 0:a0c5877bd360 | 745 | #endif |
fahadmirza | 0:a0c5877bd360 | 746 | } |
fahadmirza | 0:a0c5877bd360 | 747 | |
fahadmirza | 0:a0c5877bd360 | 748 | /* |
fahadmirza | 0:a0c5877bd360 | 749 | * If we got here, c is not a legal character |
fahadmirza | 0:a0c5877bd360 | 750 | * for a number. Stop accumulating digits. |
fahadmirza | 0:a0c5877bd360 | 751 | */ |
fahadmirza | 0:a0c5877bd360 | 752 | break; |
fahadmirza | 0:a0c5877bd360 | 753 | ok: |
fahadmirza | 0:a0c5877bd360 | 754 | /* |
fahadmirza | 0:a0c5877bd360 | 755 | * c is legal: store it and look at the next. |
fahadmirza | 0:a0c5877bd360 | 756 | */ |
fahadmirza | 0:a0c5877bd360 | 757 | *p++ = c; |
fahadmirza | 0:a0c5877bd360 | 758 | if (--fp_r > 0) |
fahadmirza | 0:a0c5877bd360 | 759 | fp_p++; |
fahadmirza | 0:a0c5877bd360 | 760 | else if (__srefill(fp)) |
fahadmirza | 0:a0c5877bd360 | 761 | break; /* EOF */ |
fahadmirza | 0:a0c5877bd360 | 762 | } |
fahadmirza | 0:a0c5877bd360 | 763 | /* |
fahadmirza | 0:a0c5877bd360 | 764 | * If we had only a sign, it is no good; push |
fahadmirza | 0:a0c5877bd360 | 765 | * back the sign. If the number ends in `x', |
fahadmirza | 0:a0c5877bd360 | 766 | * it was [sign] '0' 'x', so push back the x |
fahadmirza | 0:a0c5877bd360 | 767 | * and treat it as [sign] '0'. |
fahadmirza | 0:a0c5877bd360 | 768 | */ |
fahadmirza | 0:a0c5877bd360 | 769 | if (flags & NDIGITS) { |
fahadmirza | 0:a0c5877bd360 | 770 | if (p > buf) |
fahadmirza | 0:a0c5877bd360 | 771 | { |
fahadmirza | 0:a0c5877bd360 | 772 | --c; |
fahadmirza | 0:a0c5877bd360 | 773 | --p; |
fahadmirza | 0:a0c5877bd360 | 774 | ungetc(c++, fp); |
fahadmirza | 0:a0c5877bd360 | 775 | /* There is a dummy post-increment to |
fahadmirza | 0:a0c5877bd360 | 776 | avoid an unused value warning */ |
fahadmirza | 0:a0c5877bd360 | 777 | } |
fahadmirza | 0:a0c5877bd360 | 778 | goto match_failure; |
fahadmirza | 0:a0c5877bd360 | 779 | } |
fahadmirza | 0:a0c5877bd360 | 780 | #ifdef TINY_NO_OX |
fahadmirza | 0:a0c5877bd360 | 781 | #else |
fahadmirza | 0:a0c5877bd360 | 782 | c = ((u_char *)p)[-1]; |
fahadmirza | 0:a0c5877bd360 | 783 | if (c == 'x' || c == 'X') { |
fahadmirza | 0:a0c5877bd360 | 784 | --p; |
fahadmirza | 0:a0c5877bd360 | 785 | ungetc(c, fp); |
fahadmirza | 0:a0c5877bd360 | 786 | } |
fahadmirza | 0:a0c5877bd360 | 787 | #endif |
fahadmirza | 0:a0c5877bd360 | 788 | |
fahadmirza | 0:a0c5877bd360 | 789 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 790 | { |
fahadmirza | 0:a0c5877bd360 | 791 | #else |
fahadmirza | 0:a0c5877bd360 | 792 | if ((flags & SUPPRESS) == 0) { |
fahadmirza | 0:a0c5877bd360 | 793 | #endif |
fahadmirza | 0:a0c5877bd360 | 794 | |
fahadmirza | 0:a0c5877bd360 | 795 | *p = '\0'; |
fahadmirza | 0:a0c5877bd360 | 796 | if (sign_minus) |
fahadmirza | 0:a0c5877bd360 | 797 | value = -value; |
fahadmirza | 0:a0c5877bd360 | 798 | |
fahadmirza | 0:a0c5877bd360 | 799 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 800 | #else |
fahadmirza | 0:a0c5877bd360 | 801 | if (flags & POINTER) |
fahadmirza | 0:a0c5877bd360 | 802 | *va_arg(ap, void **) = |
fahadmirza | 0:a0c5877bd360 | 803 | (void *)(uintptr_t)value; |
fahadmirza | 0:a0c5877bd360 | 804 | else if (flags & MAXINT) |
fahadmirza | 0:a0c5877bd360 | 805 | *va_arg(ap, intmax_t *) = value; |
fahadmirza | 0:a0c5877bd360 | 806 | else if (flags & LLONG) |
fahadmirza | 0:a0c5877bd360 | 807 | *va_arg(ap, long long *) = value; |
fahadmirza | 0:a0c5877bd360 | 808 | else if (flags & SIZEINT) |
fahadmirza | 0:a0c5877bd360 | 809 | *va_arg(ap, size_t *) = value; |
fahadmirza | 0:a0c5877bd360 | 810 | else if (flags & PTRINT) |
fahadmirza | 0:a0c5877bd360 | 811 | *va_arg(ap, ptrdiff_t *) = value; |
fahadmirza | 0:a0c5877bd360 | 812 | else |
fahadmirza | 0:a0c5877bd360 | 813 | #endif |
fahadmirza | 0:a0c5877bd360 | 814 | if (flags & LONG) |
fahadmirza | 0:a0c5877bd360 | 815 | *va_arg(ap, long *) = value; |
fahadmirza | 0:a0c5877bd360 | 816 | else if (flags & SHORT) |
fahadmirza | 0:a0c5877bd360 | 817 | *va_arg(ap, short *) = value; |
fahadmirza | 0:a0c5877bd360 | 818 | else if (flags & SHORTSHORT) |
fahadmirza | 0:a0c5877bd360 | 819 | *va_arg(ap, char *) = value; |
fahadmirza | 0:a0c5877bd360 | 820 | else |
fahadmirza | 0:a0c5877bd360 | 821 | *va_arg(ap, int *) = value; |
fahadmirza | 0:a0c5877bd360 | 822 | nassigned++; |
fahadmirza | 0:a0c5877bd360 | 823 | } |
fahadmirza | 0:a0c5877bd360 | 824 | nread += p - buf; |
fahadmirza | 0:a0c5877bd360 | 825 | break; |
fahadmirza | 0:a0c5877bd360 | 826 | |
fahadmirza | 0:a0c5877bd360 | 827 | #ifdef FLOATING_POINT |
fahadmirza | 0:a0c5877bd360 | 828 | case CT_FLOAT: |
fahadmirza | 0:a0c5877bd360 | 829 | /* scan a floating point number as if by strtod */ |
fahadmirza | 0:a0c5877bd360 | 830 | #ifdef hardway |
fahadmirza | 0:a0c5877bd360 | 831 | if (width == 0 || width > sizeof(buf) - 1) |
fahadmirza | 0:a0c5877bd360 | 832 | width = sizeof(buf) - 1; |
fahadmirza | 0:a0c5877bd360 | 833 | #else |
fahadmirza | 0:a0c5877bd360 | 834 | /* size_t is unsigned, hence this optimisation */ |
fahadmirza | 0:a0c5877bd360 | 835 | if (--width > sizeof(buf) - 2) |
fahadmirza | 0:a0c5877bd360 | 836 | width = sizeof(buf) - 2; |
fahadmirza | 0:a0c5877bd360 | 837 | width++; |
fahadmirza | 0:a0c5877bd360 | 838 | #endif |
fahadmirza | 0:a0c5877bd360 | 839 | flags |= SIGNOK | NDIGITS | DPTOK | EXPOK; |
fahadmirza | 0:a0c5877bd360 | 840 | for (p = buf; width; width--) { |
fahadmirza | 0:a0c5877bd360 | 841 | c = *fp->_p; |
fahadmirza | 0:a0c5877bd360 | 842 | /* |
fahadmirza | 0:a0c5877bd360 | 843 | * This code mimicks the integer conversion |
fahadmirza | 0:a0c5877bd360 | 844 | * code, but is much simpler. |
fahadmirza | 0:a0c5877bd360 | 845 | */ |
fahadmirza | 0:a0c5877bd360 | 846 | switch (c) { |
fahadmirza | 0:a0c5877bd360 | 847 | |
fahadmirza | 0:a0c5877bd360 | 848 | case '0': case '1': case '2': case '3': |
fahadmirza | 0:a0c5877bd360 | 849 | case '4': case '5': case '6': case '7': |
fahadmirza | 0:a0c5877bd360 | 850 | case '8': case '9': |
fahadmirza | 0:a0c5877bd360 | 851 | flags &= ~(SIGNOK | NDIGITS); |
fahadmirza | 0:a0c5877bd360 | 852 | goto fok; |
fahadmirza | 0:a0c5877bd360 | 853 | |
fahadmirza | 0:a0c5877bd360 | 854 | case '+': case '-': |
fahadmirza | 0:a0c5877bd360 | 855 | if (flags & SIGNOK) { |
fahadmirza | 0:a0c5877bd360 | 856 | flags &= ~SIGNOK; |
fahadmirza | 0:a0c5877bd360 | 857 | goto fok; |
fahadmirza | 0:a0c5877bd360 | 858 | } |
fahadmirza | 0:a0c5877bd360 | 859 | break; |
fahadmirza | 0:a0c5877bd360 | 860 | case '.': |
fahadmirza | 0:a0c5877bd360 | 861 | if (flags & DPTOK) { |
fahadmirza | 0:a0c5877bd360 | 862 | flags &= ~(SIGNOK | DPTOK); |
fahadmirza | 0:a0c5877bd360 | 863 | goto fok; |
fahadmirza | 0:a0c5877bd360 | 864 | } |
fahadmirza | 0:a0c5877bd360 | 865 | break; |
fahadmirza | 0:a0c5877bd360 | 866 | case 'e': case 'E': |
fahadmirza | 0:a0c5877bd360 | 867 | /* no exponent without some digits */ |
fahadmirza | 0:a0c5877bd360 | 868 | if ((flags&(NDIGITS|EXPOK)) == EXPOK) { |
fahadmirza | 0:a0c5877bd360 | 869 | flags = |
fahadmirza | 0:a0c5877bd360 | 870 | (flags & ~(EXPOK|DPTOK)) | |
fahadmirza | 0:a0c5877bd360 | 871 | SIGNOK | NDIGITS; |
fahadmirza | 0:a0c5877bd360 | 872 | goto fok; |
fahadmirza | 0:a0c5877bd360 | 873 | } |
fahadmirza | 0:a0c5877bd360 | 874 | break; |
fahadmirza | 0:a0c5877bd360 | 875 | } |
fahadmirza | 0:a0c5877bd360 | 876 | break; |
fahadmirza | 0:a0c5877bd360 | 877 | fok: |
fahadmirza | 0:a0c5877bd360 | 878 | *p++ = c; |
fahadmirza | 0:a0c5877bd360 | 879 | if (--fp->_r > 0) |
fahadmirza | 0:a0c5877bd360 | 880 | fp->_p++; |
fahadmirza | 0:a0c5877bd360 | 881 | else if (__srefill(fp)) |
fahadmirza | 0:a0c5877bd360 | 882 | break; /* EOF */ |
fahadmirza | 0:a0c5877bd360 | 883 | } |
fahadmirza | 0:a0c5877bd360 | 884 | /* |
fahadmirza | 0:a0c5877bd360 | 885 | * If no digits, might be missing exponent digits |
fahadmirza | 0:a0c5877bd360 | 886 | * (just give back the exponent) or might be missing |
fahadmirza | 0:a0c5877bd360 | 887 | * regular digits, but had sign and/or decimal point. |
fahadmirza | 0:a0c5877bd360 | 888 | */ |
fahadmirza | 0:a0c5877bd360 | 889 | if (flags & NDIGITS) { |
fahadmirza | 0:a0c5877bd360 | 890 | if (flags & EXPOK) { |
fahadmirza | 0:a0c5877bd360 | 891 | /* no digits at all */ |
fahadmirza | 0:a0c5877bd360 | 892 | while (p > buf) |
fahadmirza | 0:a0c5877bd360 | 893 | ungetc(*(u_char *)--p, fp); |
fahadmirza | 0:a0c5877bd360 | 894 | goto match_failure; |
fahadmirza | 0:a0c5877bd360 | 895 | } |
fahadmirza | 0:a0c5877bd360 | 896 | /* just a bad exponent (e and maybe sign) */ |
fahadmirza | 0:a0c5877bd360 | 897 | c = *(u_char *)--p; |
fahadmirza | 0:a0c5877bd360 | 898 | if (c != 'e' && c != 'E') { |
fahadmirza | 0:a0c5877bd360 | 899 | (void) ungetc(c, fp);/* sign */ |
fahadmirza | 0:a0c5877bd360 | 900 | c = *(u_char *)--p; |
fahadmirza | 0:a0c5877bd360 | 901 | } |
fahadmirza | 0:a0c5877bd360 | 902 | (void) ungetc(c, fp); |
fahadmirza | 0:a0c5877bd360 | 903 | } |
fahadmirza | 0:a0c5877bd360 | 904 | if ((flags & SUPPRESS) == 0) { |
fahadmirza | 0:a0c5877bd360 | 905 | double res; |
fahadmirza | 0:a0c5877bd360 | 906 | |
fahadmirza | 0:a0c5877bd360 | 907 | *p = '\0'; |
fahadmirza | 0:a0c5877bd360 | 908 | res = strtod(buf, (char **) NULL); |
fahadmirza | 0:a0c5877bd360 | 909 | if (flags & LONGDBL) |
fahadmirza | 0:a0c5877bd360 | 910 | *va_arg(ap, long double *) = res; |
fahadmirza | 0:a0c5877bd360 | 911 | else if (flags & LONG) |
fahadmirza | 0:a0c5877bd360 | 912 | *va_arg(ap, double *) = res; |
fahadmirza | 0:a0c5877bd360 | 913 | else |
fahadmirza | 0:a0c5877bd360 | 914 | *va_arg(ap, float *) = res; |
fahadmirza | 0:a0c5877bd360 | 915 | nassigned++; |
fahadmirza | 0:a0c5877bd360 | 916 | } |
fahadmirza | 0:a0c5877bd360 | 917 | nread += p - buf; |
fahadmirza | 0:a0c5877bd360 | 918 | break; |
fahadmirza | 0:a0c5877bd360 | 919 | #endif /* FLOATING_POINT */ |
fahadmirza | 0:a0c5877bd360 | 920 | } |
fahadmirza | 0:a0c5877bd360 | 921 | } |
fahadmirza | 0:a0c5877bd360 | 922 | input_failure: |
fahadmirza | 0:a0c5877bd360 | 923 | return (nassigned ? nassigned : -1); |
fahadmirza | 0:a0c5877bd360 | 924 | match_failure: |
fahadmirza | 0:a0c5877bd360 | 925 | return (nassigned); |
fahadmirza | 0:a0c5877bd360 | 926 | } |
fahadmirza | 0:a0c5877bd360 | 927 | |
fahadmirza | 0:a0c5877bd360 | 928 | #ifdef TINY_SSCANF |
fahadmirza | 0:a0c5877bd360 | 929 | #else |
fahadmirza | 0:a0c5877bd360 | 930 | /* |
fahadmirza | 0:a0c5877bd360 | 931 | * Fill in the given table from the scanset at the given format |
fahadmirza | 0:a0c5877bd360 | 932 | * (just after `['). Return a pointer to the character past the |
fahadmirza | 0:a0c5877bd360 | 933 | * closing `]'. The table has a 1 wherever characters should be |
fahadmirza | 0:a0c5877bd360 | 934 | * considered part of the scanset. |
fahadmirza | 0:a0c5877bd360 | 935 | */ |
fahadmirza | 0:a0c5877bd360 | 936 | static u_char * |
fahadmirza | 0:a0c5877bd360 | 937 | __sccl(char *tab, u_char *fmt) |
fahadmirza | 0:a0c5877bd360 | 938 | { |
fahadmirza | 0:a0c5877bd360 | 939 | int c, n, v; |
fahadmirza | 0:a0c5877bd360 | 940 | |
fahadmirza | 0:a0c5877bd360 | 941 | /* first `clear' the whole table */ |
fahadmirza | 0:a0c5877bd360 | 942 | c = *fmt++; /* first char hat => negated scanset */ |
fahadmirza | 0:a0c5877bd360 | 943 | if (c == '^') { |
fahadmirza | 0:a0c5877bd360 | 944 | v = 1; /* default => accept */ |
fahadmirza | 0:a0c5877bd360 | 945 | c = *fmt++; /* get new first char */ |
fahadmirza | 0:a0c5877bd360 | 946 | } else |
fahadmirza | 0:a0c5877bd360 | 947 | v = 0; /* default => reject */ |
fahadmirza | 0:a0c5877bd360 | 948 | /* should probably use memset here */ |
fahadmirza | 0:a0c5877bd360 | 949 | for (n = 0; n < 256; n++) |
fahadmirza | 0:a0c5877bd360 | 950 | tab[n] = v; |
fahadmirza | 0:a0c5877bd360 | 951 | if (c == 0) |
fahadmirza | 0:a0c5877bd360 | 952 | return (fmt - 1);/* format ended before closing ] */ |
fahadmirza | 0:a0c5877bd360 | 953 | |
fahadmirza | 0:a0c5877bd360 | 954 | /* |
fahadmirza | 0:a0c5877bd360 | 955 | * Now set the entries corresponding to the actual scanset |
fahadmirza | 0:a0c5877bd360 | 956 | * to the opposite of the above. |
fahadmirza | 0:a0c5877bd360 | 957 | * |
fahadmirza | 0:a0c5877bd360 | 958 | * The first character may be ']' (or '-') without being special; |
fahadmirza | 0:a0c5877bd360 | 959 | * the last character may be '-'. |
fahadmirza | 0:a0c5877bd360 | 960 | */ |
fahadmirza | 0:a0c5877bd360 | 961 | v = 1 - v; |
fahadmirza | 0:a0c5877bd360 | 962 | for (;;) { |
fahadmirza | 0:a0c5877bd360 | 963 | tab[c] = v; /* take character c */ |
fahadmirza | 0:a0c5877bd360 | 964 | doswitch: |
fahadmirza | 0:a0c5877bd360 | 965 | n = *fmt++; /* and examine the next */ |
fahadmirza | 0:a0c5877bd360 | 966 | switch (n) { |
fahadmirza | 0:a0c5877bd360 | 967 | |
fahadmirza | 0:a0c5877bd360 | 968 | case 0: /* format ended too soon */ |
fahadmirza | 0:a0c5877bd360 | 969 | return (fmt - 1); |
fahadmirza | 0:a0c5877bd360 | 970 | |
fahadmirza | 0:a0c5877bd360 | 971 | case '-': |
fahadmirza | 0:a0c5877bd360 | 972 | /* |
fahadmirza | 0:a0c5877bd360 | 973 | * A scanset of the form |
fahadmirza | 0:a0c5877bd360 | 974 | * [01+-] |
fahadmirza | 0:a0c5877bd360 | 975 | * is defined as `the digit 0, the digit 1, |
fahadmirza | 0:a0c5877bd360 | 976 | * the character +, the character -', but |
fahadmirza | 0:a0c5877bd360 | 977 | * the effect of a scanset such as |
fahadmirza | 0:a0c5877bd360 | 978 | * [a-zA-Z0-9] |
fahadmirza | 0:a0c5877bd360 | 979 | * is implementation defined. The V7 Unix |
fahadmirza | 0:a0c5877bd360 | 980 | * scanf treats `a-z' as `the letters a through |
fahadmirza | 0:a0c5877bd360 | 981 | * z', but treats `a-a' as `the letter a, the |
fahadmirza | 0:a0c5877bd360 | 982 | * character -, and the letter a'. |
fahadmirza | 0:a0c5877bd360 | 983 | * |
fahadmirza | 0:a0c5877bd360 | 984 | * For compatibility, the `-' is not considerd |
fahadmirza | 0:a0c5877bd360 | 985 | * to define a range if the character following |
fahadmirza | 0:a0c5877bd360 | 986 | * it is either a close bracket (required by ANSI) |
fahadmirza | 0:a0c5877bd360 | 987 | * or is not numerically greater than the character |
fahadmirza | 0:a0c5877bd360 | 988 | * we just stored in the table (c). |
fahadmirza | 0:a0c5877bd360 | 989 | */ |
fahadmirza | 0:a0c5877bd360 | 990 | n = *fmt; |
fahadmirza | 0:a0c5877bd360 | 991 | if (n == ']' || n < c) { |
fahadmirza | 0:a0c5877bd360 | 992 | c = '-'; |
fahadmirza | 0:a0c5877bd360 | 993 | break; /* resume the for(;;) */ |
fahadmirza | 0:a0c5877bd360 | 994 | } |
fahadmirza | 0:a0c5877bd360 | 995 | fmt++; |
fahadmirza | 0:a0c5877bd360 | 996 | do { /* fill in the range */ |
fahadmirza | 0:a0c5877bd360 | 997 | tab[++c] = v; |
fahadmirza | 0:a0c5877bd360 | 998 | } while (c < n); |
fahadmirza | 0:a0c5877bd360 | 999 | #if 1 /* XXX another disgusting compatibility hack */ |
fahadmirza | 0:a0c5877bd360 | 1000 | /* |
fahadmirza | 0:a0c5877bd360 | 1001 | * Alas, the V7 Unix scanf also treats formats |
fahadmirza | 0:a0c5877bd360 | 1002 | * such as [a-c-e] as `the letters a through e'. |
fahadmirza | 0:a0c5877bd360 | 1003 | * This too is permitted by the standard.... |
fahadmirza | 0:a0c5877bd360 | 1004 | */ |
fahadmirza | 0:a0c5877bd360 | 1005 | goto doswitch; |
fahadmirza | 0:a0c5877bd360 | 1006 | #else |
fahadmirza | 0:a0c5877bd360 | 1007 | c = *fmt++; |
fahadmirza | 0:a0c5877bd360 | 1008 | if (c == 0) |
fahadmirza | 0:a0c5877bd360 | 1009 | return (fmt - 1); |
fahadmirza | 0:a0c5877bd360 | 1010 | if (c == ']') |
fahadmirza | 0:a0c5877bd360 | 1011 | return (fmt); |
fahadmirza | 0:a0c5877bd360 | 1012 | #endif |
fahadmirza | 0:a0c5877bd360 | 1013 | break; |
fahadmirza | 0:a0c5877bd360 | 1014 | |
fahadmirza | 0:a0c5877bd360 | 1015 | case ']': /* end of scanset */ |
fahadmirza | 0:a0c5877bd360 | 1016 | return (fmt); |
fahadmirza | 0:a0c5877bd360 | 1017 | |
fahadmirza | 0:a0c5877bd360 | 1018 | default: /* just another character */ |
fahadmirza | 0:a0c5877bd360 | 1019 | c = n; |
fahadmirza | 0:a0c5877bd360 | 1020 | break; |
fahadmirza | 0:a0c5877bd360 | 1021 | } |
fahadmirza | 0:a0c5877bd360 | 1022 | } |
fahadmirza | 0:a0c5877bd360 | 1023 | /* NOTREACHED */ |
fahadmirza | 0:a0c5877bd360 | 1024 | } |
fahadmirza | 0:a0c5877bd360 | 1025 | #endif |
fahadmirza | 0:a0c5877bd360 | 1026 | |
fahadmirza | 0:a0c5877bd360 | 1027 | int |
fahadmirza | 0:a0c5877bd360 | 1028 | tiny_sscanf(const char *str, const char *fmt, ...) |
fahadmirza | 0:a0c5877bd360 | 1029 | { |
fahadmirza | 0:a0c5877bd360 | 1030 | int ret; |
fahadmirza | 0:a0c5877bd360 | 1031 | va_list ap; |
fahadmirza | 0:a0c5877bd360 | 1032 | |
fahadmirza | 0:a0c5877bd360 | 1033 | va_start(ap, fmt); |
fahadmirza | 0:a0c5877bd360 | 1034 | ret = tiny_vfscanf(str, fmt, ap); |
fahadmirza | 0:a0c5877bd360 | 1035 | va_end(ap); |
fahadmirza | 0:a0c5877bd360 | 1036 | return (ret); |
fahadmirza | 0:a0c5877bd360 | 1037 | } |
fahadmirza | 0:a0c5877bd360 | 1038 | |
fahadmirza | 0:a0c5877bd360 | 1039 | |
fahadmirza | 0:a0c5877bd360 | 1040 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
fahadmirza | 0:a0c5877bd360 | 1041 |