4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
42 #define RECSIZE (5 * 512)
43 wchar_t record
[RECSIZE
];
44 wchar_t fields
[RECSIZE
];
45 wchar_t L_NULL
[] = L
"";
49 int donefld
; /* 1 = implies rec broken into fields */
50 int donerec
; /* 1 = record is valid (no flds have changed) */
51 int mustfld
; /* 1 = NF seen, so always break */
52 static wchar_t L_record
[] = L
"$record";
55 #define FINIT { OCELL, CFLD, 0, L_NULL, 0.0, FLD|STR }
56 CELL fldtab
[MAXFLD
] = { /* room for fields */
57 { OCELL
, CFLD
, L_record
, record
, 0.0, STR
|FLD
},
58 FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
,
59 FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
,
60 FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
,
61 FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
,
62 FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
,
63 FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
,
64 FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
,
65 FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
,
66 FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
,
67 FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
, FINIT
69 int maxfld
= 0; /* last used field */
70 /* pointer to CELL for maximum field assigned to */
71 CELL
*maxmfld
= &fldtab
[0];
73 static int isclvar(wchar_t *);
74 static void setclvar(wchar_t *);
84 extern wchar_t **svargv
;
87 dprintf("**RS=%o, **FS=%o\n", **RS
, **FS
, NULL
);
91 er
= record
+ RECSIZE
;
93 dprintf("svargc=%d, *svargv=%ws\n", svargc
, *svargv
, NULL
);
94 if (infile
== NULL
) { /* have to open a new file */
96 * If the argument contains a '=', determine if the
97 * argument needs to be treated as a variable assignment
98 * or as the pathname of a file.
100 if (isclvar(*svargv
)) {
101 /* it's a var=value argument */
110 *FILENAME
= file
= *svargv
;
111 dprintf("opening file %ws\n", file
, NULL
, NULL
);
112 if (*file
== (wchar_t)L
'-')
114 else if ((infile
= fopen(toeuccode(file
), "r")) == NULL
)
115 error(FATAL
, "can't open %ws", file
);
117 if ((sep
= **RS
) == 0)
120 for (rr
= record
; /* dummy */; /* dummy */) {
121 for (; (c
= getwc(inf
)) != sep
&& c
!= EOF
&& rr
< er
;
125 error(FATAL
, "record `%.20ws...' too long",
127 if (**RS
== sep
|| c
== EOF
)
129 if ((c
= getwc(inf
)) == '\n' || c
== EOF
)
136 error(FATAL
, "record `%.20ws...' too long", record
);
140 if (c
!= EOF
|| rr
> record
) { /* normal record */
141 recloc
->tval
&= ~NUM
;
148 /* EOF arrived on this file; set up next */
155 return (0); /* true end of file */
161 * Returns 1 if the input string, arg, is a variable assignment,
162 * otherwise returns 0.
164 * An argument to awk can be either a pathname of a file, or a variable
165 * assignment. An operand that begins with an undersore or alphabetic
166 * character from the portable character set, followed by a sequence of
167 * underscores, digits, and alphabetics from the portable character set,
168 * followed by the '=' character, shall specify a variable assignment
169 * rather than a pathname.
172 isclvar(wchar_t *arg
)
174 wchar_t *tmpptr
= arg
;
176 if (tmpptr
!= NULL
) {
178 /* Begins with an underscore or alphabetic character */
179 if (iswalpha(*tmpptr
) || *tmpptr
== '_') {
182 * followed by a sequence of underscores, digits,
185 for (tmpptr
++; *tmpptr
; tmpptr
++) {
186 if (!(iswalnum(*tmpptr
) || (*tmpptr
== '_'))) {
190 return (*tmpptr
== '=');
198 setclvar(wchar_t *s
) /* set var=value from s */
204 for (p
= s
; *p
!= '='; p
++)
207 q
= setsymtab(s
, tostring(p
), 0.0, STR
, symtab
);
209 dprintf("command line set %ws to |%ws|\n", s
, p
, NULL
);
216 wchar_t *r
, *fr
, sep
, c
;
217 static wchar_t L_NF
[] = L
"NF";
224 i
= 0; /* number of fields accumulated here */
225 if ((sep
= **FS
) == ' ')
226 for (i
= 0; /* dummy */; /* dummy */) {
228 while (iswblank(c
) || c
== '\t' || c
== '\n')
235 "record `%.20ws...' has too many fields", record
);
236 if (!(fldtab
[i
].tval
&FLD
))
237 xfree(fldtab
[i
].sval
);
239 fldtab
[i
].tval
= FLD
| STR
;
243 } while (! iswblank(c
) && c
!= '\t' &&
244 c
!= '\n' && c
!= '\0');
249 } else if (*r
!= 0) /* if 0, it's a null field */
254 "record `%.20ws...' has too many fields", record
);
255 if (!(fldtab
[i
].tval
&FLD
))
256 xfree(fldtab
[i
].sval
);
258 fldtab
[i
].tval
= FLD
| STR
;
259 while ((c
= *r
) != sep
&& c
!= '\n' && c
!= '\0')
260 /* \n always a separator */
267 /* clean out junk from previous record */
268 for (p
= maxmfld
, q
= &fldtab
[i
]; p
> q
; p
--) {
275 maxmfld
= &fldtab
[i
];
277 for (i
= 1; i
<= maxfld
; i
++)
278 if (isanumber(fldtab
[i
].sval
)) {
279 fldtab
[i
].fval
= watof(fldtab
[i
].sval
);
280 fldtab
[i
].tval
|= NUM
;
282 setfval(lookup(L_NF
, symtab
, 0), (awkfloat
) maxfld
);
284 for (i
= 0; i
<= maxfld
; i
++)
285 printf("field %d: |%ws|\n", i
, fldtab
[i
].sval
);
296 if (donefld
== 0 || donerec
== 1)
299 for (i
= 1; i
<= *NF
; i
++) {
300 p
= getsval(&fldtab
[i
]);
306 dprintf("in recbld FS=%o, recloc=%o\n", **FS
, recloc
, NULL
);
307 recloc
->tval
= STR
| FLD
;
308 dprintf("in recbld FS=%o, recloc=%o\n", **FS
, recloc
, NULL
);
309 if (r
> record
+RECSIZE
)
310 error(FATAL
, "built giant record `%.20ws...'", record
);
311 dprintf("recbld = |%ws|\n", record
, NULL
, NULL
);
318 if (n
< 0 || n
>= MAXFLD
)
319 error(FATAL
, "trying to access field %d", n
);
331 gettext("awk: %s near line %lld\n"), gettext(s
), lineno
);
338 error(f
, s
, a1
, a2
, a3
, a4
, a5
, a6
, a7
)
340 fprintf(stderr
, "awk: ");
341 fprintf(stderr
, gettext((char *)s
), a1
, a2
, a3
, a4
, a5
, a6
, a7
);
342 fprintf(stderr
, "\n");
344 fprintf(stderr
, gettext(" record number %g\n"), *NR
);
353 dprintf("%s\n", s
, NULL
, NULL
);
357 #define MAXEXPON 38 /* maximum exponenet for fp number */
361 isanumber(wchar_t *s
)
366 extern wchar_t radixpoint
;
369 while (*s
== ' ' || *s
== '\t' || *s
== '\n')
372 return (0); /* empty stuff isn't number */
373 if (*s
== '+' || *s
== '-')
376 * Since, iswdigit() will include digit from other than code set 0,
377 * we have to check it from code set 0 or not.
379 if (!(iswdigit(*s
) && iswascii(*s
)) && *s
!= radixpoint
)
381 if (iswdigit(*s
) && iswascii(*s
)) {
385 } while (iswdigit(*s
) && iswascii(*s
));
388 return (0); /* too many digits to convert */
389 if (*s
== radixpoint
) {
393 if (iswdigit(*s
) && iswascii(*s
)) {
397 } while (iswdigit(*s
) && iswascii(*s
));
401 if (!(d1
|| point
&& d2
))
403 if (*s
== 'e' || *s
== 'E') {
405 if (*s
== '+' || *s
== '-')
407 if (!(iswdigit(*s
) && iswascii(*s
)))
412 } while (iswdigit(*s
) && iswascii(*s
));
417 else if (s
- es
== 2 &&
418 10 * (*es
-'0') + *(es
+1)-'0' >= MAXEXPON
)
421 while (*s
== ' ' || *s
== '\t' || *s
== '\n')
432 static char euccode
[RECSIZE
];
434 (void) wcstombs(euccode
, str
, RECSIZE
);