xref: /illumos-gate/usr/src/lib/libc/port/fp/file_decim.c (revision 4fe85d41bb4eb0db41934722f4b06c8acec2d25a)
1  /*
2   * CDDL HEADER START
3   *
4   * The contents of this file are subject to the terms of the
5   * Common Development and Distribution License (the "License").
6   * You may not use this file except in compliance with the License.
7   *
8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9   * or http://www.opensolaris.org/os/licensing.
10   * See the License for the specific language governing permissions
11   * and limitations under the License.
12   *
13   * When distributing Covered Code, include this CDDL HEADER in each
14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15   * If applicable, add the following below this CDDL HEADER, with the
16   * fields enclosed by brackets "[]" replaced with your own identifying
17   * information: Portions Copyright [yyyy] [name of copyright owner]
18   *
19   * CDDL HEADER END
20   */
21  
22  /*
23   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24   * Use is subject to license terms.
25   */
26  
27  #pragma ident	"%Z%%M%	%I%	%E% SMI"
28  
29  #include "lint.h"
30  #include "file64.h"
31  #include "mtlib.h"
32  #include <sys/types.h>
33  #include <ctype.h>
34  #include <stdio.h>
35  #include "base_conversion.h"
36  #include <locale.h>
37  #include <thread.h>
38  #include <synch.h>
39  #include "stdiom.h"
40  #include "libc.h"
41  
42  /* if the _IOWRT flag is set, this must be a call from sscanf */
43  #define	mygetc(iop)	((iop->_flag & _IOWRT) ? \
44  				((*iop->_ptr == '\0') ? EOF : *iop->_ptr++) : \
45  				GETC(iop))
46  
47  #define	myungetc(x, iop)	((iop->_flag & _IOWRT) ? *(--iop->_ptr) : \
48  					UNGETC(x, iop))
49  
50  
51  void
52  file_to_decimal(char **ppc, int nmax, int fortran_conventions,
53  		decimal_record *pd, enum decimal_string_form *pform,
54  		char **pechar, FILE *pf, int *pnread)
55  {
56  	char	*cp = *ppc - 1;	/* last character seen */
57  	char	*good = cp;	/* last character accepted */
58  	int	current;	/* *cp or EOF */
59  	int	nread = 0;	/* number of characters read so far */
60  
61  /* if the _IOWRT flag is set, this must be a call from sscanf */
62  #define	NEXT \
63  	if (nread < nmax) { \
64  		current = ((pf->_flag & _IOWRT) ? \
65  		    ((*pf->_ptr == '\0') ? EOF : *pf->_ptr++) : \
66  		    GETC(pf)); \
67  		if (current != EOF) { \
68  			*++cp = (char)current; \
69  			nread++; \
70  		} \
71  	} else { \
72  		current = EOF; \
73  	}
74  
75  	NEXT;
76  
77  #include "char_to_decimal.h"
78  
79  	/*
80  	 * If we read any characters beyond the end of the accepted
81  	 * token, try to push them back.
82  	 */
83  	if (fortran_conventions < 0) {
84  		/* in C99 mode, push back at most one character */
85  		if (cp >= *ppc && current != EOF && myungetc(current, pf)
86  		    != EOF) {
87  			cp--;
88  			nread--;
89  		}
90  	} else {
91  		while (cp >= *ppc) {
92  			if (myungetc((int)(unsigned char)*cp, pf) == EOF)
93  				break;
94  			cp--;
95  			nread--;
96  		}
97  	}
98  
99  	*++cp = '\0';
100  	*pnread = nread;
101  }
102