1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 34*7c478bd9Sstevel@tonic-gate #include <regexpr.h> 35*7c478bd9Sstevel@tonic-gate #include <locale.h> 36*7c478bd9Sstevel@tonic-gate #include <string.h> 37*7c478bd9Sstevel@tonic-gate #include <unistd.h> 38*7c478bd9Sstevel@tonic-gate #include <regex.h> 39*7c478bd9Sstevel@tonic-gate #include <limits.h> 40*7c478bd9Sstevel@tonic-gate #include <stdio.h> 41*7c478bd9Sstevel@tonic-gate #include <ctype.h> 42*7c478bd9Sstevel@tonic-gate #include <errno.h> 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #define A_STRING 258 45*7c478bd9Sstevel@tonic-gate #define NOARG 259 46*7c478bd9Sstevel@tonic-gate #define OR 260 47*7c478bd9Sstevel@tonic-gate #define AND 261 48*7c478bd9Sstevel@tonic-gate #define EQ 262 49*7c478bd9Sstevel@tonic-gate #define LT 263 50*7c478bd9Sstevel@tonic-gate #define GT 264 51*7c478bd9Sstevel@tonic-gate #define GEQ 265 52*7c478bd9Sstevel@tonic-gate #define LEQ 266 53*7c478bd9Sstevel@tonic-gate #define NEQ 267 54*7c478bd9Sstevel@tonic-gate #define ADD 268 55*7c478bd9Sstevel@tonic-gate #define SUBT 269 56*7c478bd9Sstevel@tonic-gate #define MULT 270 57*7c478bd9Sstevel@tonic-gate #define DIV 271 58*7c478bd9Sstevel@tonic-gate #define REM 272 59*7c478bd9Sstevel@tonic-gate #define MCH 273 60*7c478bd9Sstevel@tonic-gate #define MATCH 274 61*7c478bd9Sstevel@tonic-gate #ifdef _iBCS2 62*7c478bd9Sstevel@tonic-gate #define SUBSTR 276 63*7c478bd9Sstevel@tonic-gate #define LENGTH 277 64*7c478bd9Sstevel@tonic-gate #define INDEX 278 65*7c478bd9Sstevel@tonic-gate #endif /* _iBCS2 */ 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* size of subexpression array */ 68*7c478bd9Sstevel@tonic-gate #define MSIZE LINE_MAX 69*7c478bd9Sstevel@tonic-gate #define error(c) errxx() 70*7c478bd9Sstevel@tonic-gate #define EQL(x, y) (strcmp(x, y) == 0) 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate #define ERROR(c) errxx() 73*7c478bd9Sstevel@tonic-gate #define MAX_MATCH 20 74*7c478bd9Sstevel@tonic-gate static int ematch(char *, char *); 75*7c478bd9Sstevel@tonic-gate static void yyerror(char *); 76*7c478bd9Sstevel@tonic-gate static void errxx(); 77*7c478bd9Sstevel@tonic-gate static void *exprmalloc(size_t size); 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate long atol(); 80*7c478bd9Sstevel@tonic-gate char *strcpy(), *strncpy(); 81*7c478bd9Sstevel@tonic-gate void exit(); 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate static char *ltoa(); 84*7c478bd9Sstevel@tonic-gate static char *lltoa(); 85*7c478bd9Sstevel@tonic-gate static char **Av; 86*7c478bd9Sstevel@tonic-gate static char *buf; 87*7c478bd9Sstevel@tonic-gate static int Ac; 88*7c478bd9Sstevel@tonic-gate static int Argi; 89*7c478bd9Sstevel@tonic-gate static int noarg; 90*7c478bd9Sstevel@tonic-gate static int paren; 91*7c478bd9Sstevel@tonic-gate #ifdef _iBCS2 92*7c478bd9Sstevel@tonic-gate char *sysv3_set; 93*7c478bd9Sstevel@tonic-gate #endif /* _iBCS2 */ 94*7c478bd9Sstevel@tonic-gate /* 95*7c478bd9Sstevel@tonic-gate * Array used to store subexpressions in regular expressions 96*7c478bd9Sstevel@tonic-gate * Only one subexpression allowed per regular expression currently 97*7c478bd9Sstevel@tonic-gate */ 98*7c478bd9Sstevel@tonic-gate static char Mstring[1][MSIZE]; 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate static char *operator[] = { 102*7c478bd9Sstevel@tonic-gate "|", "&", "+", "-", "*", "/", "%", ":", 103*7c478bd9Sstevel@tonic-gate "=", "==", "<", "<=", ">", ">=", "!=", 104*7c478bd9Sstevel@tonic-gate "match", 105*7c478bd9Sstevel@tonic-gate #ifdef _iBCS2 106*7c478bd9Sstevel@tonic-gate "substr", "length", "index", 107*7c478bd9Sstevel@tonic-gate #endif /* _iBCS2 */ 108*7c478bd9Sstevel@tonic-gate "\0" }; 109*7c478bd9Sstevel@tonic-gate static int op[] = { 110*7c478bd9Sstevel@tonic-gate OR, AND, ADD, SUBT, MULT, DIV, REM, MCH, 111*7c478bd9Sstevel@tonic-gate EQ, EQ, LT, LEQ, GT, GEQ, NEQ, 112*7c478bd9Sstevel@tonic-gate MATCH 113*7c478bd9Sstevel@tonic-gate #ifdef _iBCS2 114*7c478bd9Sstevel@tonic-gate , SUBSTR, LENGTH, INDEX 115*7c478bd9Sstevel@tonic-gate #endif /* _iBCS2 */ 116*7c478bd9Sstevel@tonic-gate }; 117*7c478bd9Sstevel@tonic-gate static int pri[] = { 118*7c478bd9Sstevel@tonic-gate 1, 2, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6, 7 119*7c478bd9Sstevel@tonic-gate #ifdef _iBCS2 120*7c478bd9Sstevel@tonic-gate , 7, 7, 7 121*7c478bd9Sstevel@tonic-gate #endif /* _iBCS2 */ 122*7c478bd9Sstevel@tonic-gate }; 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate /* 126*7c478bd9Sstevel@tonic-gate * clean_buf - XCU4 mod to remove leading zeros from negative signed 127*7c478bd9Sstevel@tonic-gate * numeric output, e.g., -00001 becomes -1 128*7c478bd9Sstevel@tonic-gate */ 129*7c478bd9Sstevel@tonic-gate static void 130*7c478bd9Sstevel@tonic-gate clean_buf(buf) 131*7c478bd9Sstevel@tonic-gate char *buf; 132*7c478bd9Sstevel@tonic-gate { 133*7c478bd9Sstevel@tonic-gate int i = 0; 134*7c478bd9Sstevel@tonic-gate int is_a_num = 1; 135*7c478bd9Sstevel@tonic-gate int len; 136*7c478bd9Sstevel@tonic-gate long long num; 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate if (buf[0] == '\0') 139*7c478bd9Sstevel@tonic-gate return; 140*7c478bd9Sstevel@tonic-gate len = strlen(buf); 141*7c478bd9Sstevel@tonic-gate if (len <= 0) 142*7c478bd9Sstevel@tonic-gate return; 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate if (buf[0] == '-') { 145*7c478bd9Sstevel@tonic-gate i++; /* Skip the leading '-' see while loop */ 146*7c478bd9Sstevel@tonic-gate if (len <= 1) /* Is it a '-' all by itself? */ 147*7c478bd9Sstevel@tonic-gate return; /* Yes, so return */ 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate while (i < len) { 150*7c478bd9Sstevel@tonic-gate if (! isdigit(buf[i])) { 151*7c478bd9Sstevel@tonic-gate is_a_num = 0; 152*7c478bd9Sstevel@tonic-gate break; 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate i++; 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate if (is_a_num) { 157*7c478bd9Sstevel@tonic-gate (void) sscanf(buf, "%lld", &num); 158*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%lld", num); 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate /* 164*7c478bd9Sstevel@tonic-gate * End XCU4 mods. 165*7c478bd9Sstevel@tonic-gate */ 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate static int 168*7c478bd9Sstevel@tonic-gate yylex() 169*7c478bd9Sstevel@tonic-gate { 170*7c478bd9Sstevel@tonic-gate char *p; 171*7c478bd9Sstevel@tonic-gate int i; 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate if (Argi >= Ac) 174*7c478bd9Sstevel@tonic-gate return (NOARG); 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate p = Av[Argi]; 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate if ((*p == '(' || *p == ')') && p[1] == '\0') 179*7c478bd9Sstevel@tonic-gate return ((int)*p); 180*7c478bd9Sstevel@tonic-gate for (i = 0; *operator[i]; ++i) 181*7c478bd9Sstevel@tonic-gate if (EQL(operator[i], p)) 182*7c478bd9Sstevel@tonic-gate return (op[i]); 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate return (A_STRING); 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate static char 189*7c478bd9Sstevel@tonic-gate *rel(oper, r1, r2) register char *r1, *r2; 190*7c478bd9Sstevel@tonic-gate { 191*7c478bd9Sstevel@tonic-gate long long i; 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate if (ematch(r1, "-\\{0,1\\}[0-9]*$") && 194*7c478bd9Sstevel@tonic-gate ematch(r2, "-\\{0,1\\}[0-9]*$")) { 195*7c478bd9Sstevel@tonic-gate errno = 0; 196*7c478bd9Sstevel@tonic-gate i = strtoll(r1, (char **)NULL, 10) - 197*7c478bd9Sstevel@tonic-gate strtoll(r2, (char **)NULL, 10); 198*7c478bd9Sstevel@tonic-gate if (errno) { 199*7c478bd9Sstevel@tonic-gate #ifdef XPG6 200*7c478bd9Sstevel@tonic-gate /* XPG6: stdout will always contain newline even on error */ 201*7c478bd9Sstevel@tonic-gate (void) write(1, "\n", 1); 202*7c478bd9Sstevel@tonic-gate #endif 203*7c478bd9Sstevel@tonic-gate if (errno == ERANGE) { 204*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 205*7c478bd9Sstevel@tonic-gate "expr: Integer argument too large\n")); 206*7c478bd9Sstevel@tonic-gate exit(3); 207*7c478bd9Sstevel@tonic-gate } else { 208*7c478bd9Sstevel@tonic-gate perror("expr"); 209*7c478bd9Sstevel@tonic-gate exit(3); 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate else 214*7c478bd9Sstevel@tonic-gate i = strcoll(r1, r2); 215*7c478bd9Sstevel@tonic-gate switch (oper) { 216*7c478bd9Sstevel@tonic-gate case EQ: 217*7c478bd9Sstevel@tonic-gate i = i == 0; 218*7c478bd9Sstevel@tonic-gate break; 219*7c478bd9Sstevel@tonic-gate case GT: 220*7c478bd9Sstevel@tonic-gate i = i > 0; 221*7c478bd9Sstevel@tonic-gate break; 222*7c478bd9Sstevel@tonic-gate case GEQ: 223*7c478bd9Sstevel@tonic-gate i = i >= 0; 224*7c478bd9Sstevel@tonic-gate break; 225*7c478bd9Sstevel@tonic-gate case LT: 226*7c478bd9Sstevel@tonic-gate i = i < 0; 227*7c478bd9Sstevel@tonic-gate break; 228*7c478bd9Sstevel@tonic-gate case LEQ: 229*7c478bd9Sstevel@tonic-gate i = i <= 0; 230*7c478bd9Sstevel@tonic-gate break; 231*7c478bd9Sstevel@tonic-gate case NEQ: 232*7c478bd9Sstevel@tonic-gate i = i != 0; 233*7c478bd9Sstevel@tonic-gate break; 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate return (i ? "1": "0"); 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate static char 239*7c478bd9Sstevel@tonic-gate *arith(oper, r1, r2) char *r1, *r2; 240*7c478bd9Sstevel@tonic-gate { 241*7c478bd9Sstevel@tonic-gate long long i1, i2; 242*7c478bd9Sstevel@tonic-gate register char *rv; 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate if (!(ematch(r1, "-\\{0,1\\}[0-9]*$") && 245*7c478bd9Sstevel@tonic-gate ematch(r2, "-\\{0,1\\}[0-9]*$"))) 246*7c478bd9Sstevel@tonic-gate yyerror("non-numeric argument"); 247*7c478bd9Sstevel@tonic-gate errno = 0; 248*7c478bd9Sstevel@tonic-gate i1 = strtoll(r1, (char **)NULL, 10); 249*7c478bd9Sstevel@tonic-gate i2 = strtoll(r2, (char **)NULL, 10); 250*7c478bd9Sstevel@tonic-gate if (errno) { 251*7c478bd9Sstevel@tonic-gate #ifdef XPG6 252*7c478bd9Sstevel@tonic-gate /* XPG6: stdout will always contain newline even on error */ 253*7c478bd9Sstevel@tonic-gate (void) write(1, "\n", 1); 254*7c478bd9Sstevel@tonic-gate #endif 255*7c478bd9Sstevel@tonic-gate if (errno == ERANGE) { 256*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 257*7c478bd9Sstevel@tonic-gate "expr: Integer argument too large\n")); 258*7c478bd9Sstevel@tonic-gate exit(3); 259*7c478bd9Sstevel@tonic-gate } else { 260*7c478bd9Sstevel@tonic-gate perror("expr"); 261*7c478bd9Sstevel@tonic-gate exit(3); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate switch (oper) { 266*7c478bd9Sstevel@tonic-gate case ADD: 267*7c478bd9Sstevel@tonic-gate i1 = i1 + i2; 268*7c478bd9Sstevel@tonic-gate break; 269*7c478bd9Sstevel@tonic-gate case SUBT: 270*7c478bd9Sstevel@tonic-gate i1 = i1 - i2; 271*7c478bd9Sstevel@tonic-gate break; 272*7c478bd9Sstevel@tonic-gate case MULT: 273*7c478bd9Sstevel@tonic-gate i1 = i1 * i2; 274*7c478bd9Sstevel@tonic-gate break; 275*7c478bd9Sstevel@tonic-gate case DIV: 276*7c478bd9Sstevel@tonic-gate if (i2 == 0) 277*7c478bd9Sstevel@tonic-gate yyerror("division by zero"); 278*7c478bd9Sstevel@tonic-gate i1 = i1 / i2; 279*7c478bd9Sstevel@tonic-gate break; 280*7c478bd9Sstevel@tonic-gate case REM: 281*7c478bd9Sstevel@tonic-gate if (i2 == 0) 282*7c478bd9Sstevel@tonic-gate yyerror("division by zero"); 283*7c478bd9Sstevel@tonic-gate i1 = i1 % i2; 284*7c478bd9Sstevel@tonic-gate break; 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate rv = exprmalloc(25); 287*7c478bd9Sstevel@tonic-gate (void) strcpy(rv, lltoa(i1)); 288*7c478bd9Sstevel@tonic-gate return (rv); 289*7c478bd9Sstevel@tonic-gate } 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate static char 292*7c478bd9Sstevel@tonic-gate *conj(oper, r1, r2) 293*7c478bd9Sstevel@tonic-gate char *r1, *r2; 294*7c478bd9Sstevel@tonic-gate { 295*7c478bd9Sstevel@tonic-gate register char *rv; 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate switch (oper) { 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate case OR: 300*7c478bd9Sstevel@tonic-gate if (EQL(r1, "0") || EQL(r1, "")) { 301*7c478bd9Sstevel@tonic-gate if (EQL(r2, "0") || EQL(r2, "")) 302*7c478bd9Sstevel@tonic-gate rv = "0"; 303*7c478bd9Sstevel@tonic-gate else 304*7c478bd9Sstevel@tonic-gate rv = r2; 305*7c478bd9Sstevel@tonic-gate } else 306*7c478bd9Sstevel@tonic-gate rv = r1; 307*7c478bd9Sstevel@tonic-gate break; 308*7c478bd9Sstevel@tonic-gate case AND: 309*7c478bd9Sstevel@tonic-gate if (EQL(r1, "0") || EQL(r1, "")) 310*7c478bd9Sstevel@tonic-gate rv = "0"; 311*7c478bd9Sstevel@tonic-gate else if (EQL(r2, "0") || EQL(r2, "")) 312*7c478bd9Sstevel@tonic-gate rv = "0"; 313*7c478bd9Sstevel@tonic-gate else 314*7c478bd9Sstevel@tonic-gate rv = r1; 315*7c478bd9Sstevel@tonic-gate break; 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate return (rv); 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate #ifdef _iBCS2 321*7c478bd9Sstevel@tonic-gate char * 322*7c478bd9Sstevel@tonic-gate substr(char *v, char *s, char *w) 323*7c478bd9Sstevel@tonic-gate { 324*7c478bd9Sstevel@tonic-gate int si, wi; 325*7c478bd9Sstevel@tonic-gate char *res; 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate si = atol(s); 328*7c478bd9Sstevel@tonic-gate wi = atol(w); 329*7c478bd9Sstevel@tonic-gate while (--si) 330*7c478bd9Sstevel@tonic-gate if (*v) ++v; 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate res = v; 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate while (wi--) 335*7c478bd9Sstevel@tonic-gate if (*v) ++v; 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate *v = '\0'; 338*7c478bd9Sstevel@tonic-gate return (res); 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate char * 342*7c478bd9Sstevel@tonic-gate index(char *s, char *t) 343*7c478bd9Sstevel@tonic-gate { 344*7c478bd9Sstevel@tonic-gate long i, j; 345*7c478bd9Sstevel@tonic-gate char *rv; 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate for (i = 0; s[i]; ++i) 348*7c478bd9Sstevel@tonic-gate for (j = 0; t[j]; ++j) 349*7c478bd9Sstevel@tonic-gate if (s[i] == t[j]) { 350*7c478bd9Sstevel@tonic-gate (void) strcpy(rv = exprmalloc(8), ltoa(++i)); 351*7c478bd9Sstevel@tonic-gate return (rv); 352*7c478bd9Sstevel@tonic-gate } 353*7c478bd9Sstevel@tonic-gate return ("0"); 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate char * 357*7c478bd9Sstevel@tonic-gate length(char *s) 358*7c478bd9Sstevel@tonic-gate { 359*7c478bd9Sstevel@tonic-gate long i = 0; 360*7c478bd9Sstevel@tonic-gate char *rv; 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate while (*s++) ++i; 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate rv = exprmalloc(8); 365*7c478bd9Sstevel@tonic-gate (void) strcpy(rv, ltoa(i)); 366*7c478bd9Sstevel@tonic-gate return (rv); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate #endif /* _iBCS2 */ 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate static char * 371*7c478bd9Sstevel@tonic-gate match(char *s, char *p) 372*7c478bd9Sstevel@tonic-gate { 373*7c478bd9Sstevel@tonic-gate char *rv; 374*7c478bd9Sstevel@tonic-gate long val; /* XCU4 */ 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate (void) strcpy(rv = exprmalloc(8), ltoa(val = (long)ematch(s, p))); 377*7c478bd9Sstevel@tonic-gate if (nbra /* && val != 0 */) { 378*7c478bd9Sstevel@tonic-gate rv = exprmalloc((unsigned)strlen(Mstring[0]) + 1); 379*7c478bd9Sstevel@tonic-gate (void) strcpy(rv, Mstring[0]); 380*7c478bd9Sstevel@tonic-gate } 381*7c478bd9Sstevel@tonic-gate return (rv); 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate 385*7c478bd9Sstevel@tonic-gate /* 386*7c478bd9Sstevel@tonic-gate * ematch - XCU4 mods involve calling compile/advance which simulate 387*7c478bd9Sstevel@tonic-gate * the obsolete compile/advance functions using regcomp/regexec 388*7c478bd9Sstevel@tonic-gate */ 389*7c478bd9Sstevel@tonic-gate static int 390*7c478bd9Sstevel@tonic-gate ematch(char *s, char *p) 391*7c478bd9Sstevel@tonic-gate { 392*7c478bd9Sstevel@tonic-gate static char *expbuf; 393*7c478bd9Sstevel@tonic-gate char *nexpbuf; 394*7c478bd9Sstevel@tonic-gate int num; 395*7c478bd9Sstevel@tonic-gate #ifdef XPG4 396*7c478bd9Sstevel@tonic-gate int nmatch; /* number of matched bytes */ 397*7c478bd9Sstevel@tonic-gate char tempbuf[256]; 398*7c478bd9Sstevel@tonic-gate char *tmptr1 = 0; /* If tempbuf is not large enough */ 399*7c478bd9Sstevel@tonic-gate char *tmptr; 400*7c478bd9Sstevel@tonic-gate int nmbchars; /* number characters in multibyte string */ 401*7c478bd9Sstevel@tonic-gate #endif 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate nexpbuf = compile(p, (char *)0, (char *)0); /* XCU4 regex mod */ 404*7c478bd9Sstevel@tonic-gate if (0 /* XXX nbra > 1*/) 405*7c478bd9Sstevel@tonic-gate yyerror("Too many '\\('s"); 406*7c478bd9Sstevel@tonic-gate if (regerrno) { 407*7c478bd9Sstevel@tonic-gate if (regerrno != 41 || expbuf == NULL) 408*7c478bd9Sstevel@tonic-gate errxx(); 409*7c478bd9Sstevel@tonic-gate } else { 410*7c478bd9Sstevel@tonic-gate if (expbuf) 411*7c478bd9Sstevel@tonic-gate free(expbuf); 412*7c478bd9Sstevel@tonic-gate expbuf = nexpbuf; 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate if (advance(s, expbuf)) { 415*7c478bd9Sstevel@tonic-gate if (nbra > 0) { 416*7c478bd9Sstevel@tonic-gate p = braslist[0]; 417*7c478bd9Sstevel@tonic-gate num = braelist[0] - p; 418*7c478bd9Sstevel@tonic-gate if ((num > MSIZE - 1) || (num < 0)) 419*7c478bd9Sstevel@tonic-gate yyerror("string too long"); 420*7c478bd9Sstevel@tonic-gate (void) strncpy(Mstring[0], p, num); 421*7c478bd9Sstevel@tonic-gate Mstring[0][num] = '\0'; 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate #ifdef XPG4 424*7c478bd9Sstevel@tonic-gate /* 425*7c478bd9Sstevel@tonic-gate * Use mbstowcs to find the number of multibyte characters 426*7c478bd9Sstevel@tonic-gate * in the multibyte string beginning at s, and 427*7c478bd9Sstevel@tonic-gate * ending at loc2. Create a separate string 428*7c478bd9Sstevel@tonic-gate * of the substring, so it can be passed to mbstowcs. 429*7c478bd9Sstevel@tonic-gate */ 430*7c478bd9Sstevel@tonic-gate nmatch = loc2 - s; 431*7c478bd9Sstevel@tonic-gate if (nmatch > ((sizeof (tempbuf) / sizeof (char)) - 1)) { 432*7c478bd9Sstevel@tonic-gate tmptr1 = exprmalloc(nmatch + 1); 433*7c478bd9Sstevel@tonic-gate tmptr = tmptr1; 434*7c478bd9Sstevel@tonic-gate } else { 435*7c478bd9Sstevel@tonic-gate tmptr = tempbuf; 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate memcpy(tmptr, s, nmatch); 438*7c478bd9Sstevel@tonic-gate *(tmptr + nmatch) = '\0'; 439*7c478bd9Sstevel@tonic-gate if ((nmbchars = mbstowcs(NULL, tmptr, NULL)) == -1) { 440*7c478bd9Sstevel@tonic-gate yyerror("invalid multibyte character encountered"); 441*7c478bd9Sstevel@tonic-gate if (tmptr1 != NULL) 442*7c478bd9Sstevel@tonic-gate free(tmptr1); 443*7c478bd9Sstevel@tonic-gate return (0); 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate if (tmptr1 != NULL) 446*7c478bd9Sstevel@tonic-gate free(tmptr1); 447*7c478bd9Sstevel@tonic-gate return (nmbchars); 448*7c478bd9Sstevel@tonic-gate #else 449*7c478bd9Sstevel@tonic-gate return (loc2-s); 450*7c478bd9Sstevel@tonic-gate #endif 451*7c478bd9Sstevel@tonic-gate } 452*7c478bd9Sstevel@tonic-gate return (0); 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate static void 456*7c478bd9Sstevel@tonic-gate errxx() 457*7c478bd9Sstevel@tonic-gate { 458*7c478bd9Sstevel@tonic-gate yyerror("RE error"); 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate static void 462*7c478bd9Sstevel@tonic-gate yyerror(char *s) 463*7c478bd9Sstevel@tonic-gate { 464*7c478bd9Sstevel@tonic-gate #ifdef XPG6 465*7c478bd9Sstevel@tonic-gate /* XPG6: stdout will always contain newline even on error */ 466*7c478bd9Sstevel@tonic-gate (void) write(1, "\n", 1); 467*7c478bd9Sstevel@tonic-gate #endif 468*7c478bd9Sstevel@tonic-gate (void) write(2, "expr: ", 6); 469*7c478bd9Sstevel@tonic-gate (void) write(2, gettext(s), (unsigned)strlen(gettext(s))); 470*7c478bd9Sstevel@tonic-gate (void) write(2, "\n", 1); 471*7c478bd9Sstevel@tonic-gate exit(2); 472*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate static char * 476*7c478bd9Sstevel@tonic-gate ltoa(long l) 477*7c478bd9Sstevel@tonic-gate { 478*7c478bd9Sstevel@tonic-gate static char str[20]; 479*7c478bd9Sstevel@tonic-gate char *sp = &str[18]; /* u370 */ 480*7c478bd9Sstevel@tonic-gate int i; 481*7c478bd9Sstevel@tonic-gate int neg = 0; 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate if ((unsigned long)l == 0x80000000UL) 484*7c478bd9Sstevel@tonic-gate return ("-2147483648"); 485*7c478bd9Sstevel@tonic-gate if (l < 0) 486*7c478bd9Sstevel@tonic-gate ++neg, l = -l; 487*7c478bd9Sstevel@tonic-gate str[19] = '\0'; 488*7c478bd9Sstevel@tonic-gate do { 489*7c478bd9Sstevel@tonic-gate i = l % 10; 490*7c478bd9Sstevel@tonic-gate *sp-- = '0' + i; 491*7c478bd9Sstevel@tonic-gate l /= 10; 492*7c478bd9Sstevel@tonic-gate } while (l); 493*7c478bd9Sstevel@tonic-gate if (neg) 494*7c478bd9Sstevel@tonic-gate *sp-- = '-'; 495*7c478bd9Sstevel@tonic-gate return (++sp); 496*7c478bd9Sstevel@tonic-gate } 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate static char * 499*7c478bd9Sstevel@tonic-gate lltoa(long long l) 500*7c478bd9Sstevel@tonic-gate { 501*7c478bd9Sstevel@tonic-gate static char str[25]; 502*7c478bd9Sstevel@tonic-gate char *sp = &str[23]; 503*7c478bd9Sstevel@tonic-gate int i; 504*7c478bd9Sstevel@tonic-gate int neg = 0; 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate if (l == 0x8000000000000000ULL) 507*7c478bd9Sstevel@tonic-gate return ("-9223372036854775808"); 508*7c478bd9Sstevel@tonic-gate if (l < 0) 509*7c478bd9Sstevel@tonic-gate ++neg, l = -l; 510*7c478bd9Sstevel@tonic-gate str[24] = '\0'; 511*7c478bd9Sstevel@tonic-gate do { 512*7c478bd9Sstevel@tonic-gate i = l % 10; 513*7c478bd9Sstevel@tonic-gate *sp-- = '0' + i; 514*7c478bd9Sstevel@tonic-gate l /= 10; 515*7c478bd9Sstevel@tonic-gate } while (l); 516*7c478bd9Sstevel@tonic-gate if (neg) 517*7c478bd9Sstevel@tonic-gate *sp-- = '-'; 518*7c478bd9Sstevel@tonic-gate return (++sp); 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate static char * 522*7c478bd9Sstevel@tonic-gate expres(int prior, int par) 523*7c478bd9Sstevel@tonic-gate { 524*7c478bd9Sstevel@tonic-gate int ylex, temp, op1; 525*7c478bd9Sstevel@tonic-gate char *r1, *ra, *rb, *rc; 526*7c478bd9Sstevel@tonic-gate ylex = yylex(); 527*7c478bd9Sstevel@tonic-gate if (ylex >= NOARG && ylex < MATCH) { 528*7c478bd9Sstevel@tonic-gate yyerror("syntax error"); 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate if (ylex == A_STRING) { 531*7c478bd9Sstevel@tonic-gate r1 = Av[Argi++]; 532*7c478bd9Sstevel@tonic-gate temp = Argi; 533*7c478bd9Sstevel@tonic-gate } else { 534*7c478bd9Sstevel@tonic-gate if (ylex == '(') { 535*7c478bd9Sstevel@tonic-gate paren++; 536*7c478bd9Sstevel@tonic-gate Argi++; 537*7c478bd9Sstevel@tonic-gate r1 = expres(0, Argi); 538*7c478bd9Sstevel@tonic-gate Argi--; 539*7c478bd9Sstevel@tonic-gate } 540*7c478bd9Sstevel@tonic-gate } 541*7c478bd9Sstevel@tonic-gate lop: 542*7c478bd9Sstevel@tonic-gate ylex = yylex(); 543*7c478bd9Sstevel@tonic-gate if (ylex > NOARG && ylex < MATCH) { 544*7c478bd9Sstevel@tonic-gate op1 = ylex; 545*7c478bd9Sstevel@tonic-gate Argi++; 546*7c478bd9Sstevel@tonic-gate if (pri[op1-OR] <= prior) 547*7c478bd9Sstevel@tonic-gate return (r1); 548*7c478bd9Sstevel@tonic-gate else { 549*7c478bd9Sstevel@tonic-gate switch (op1) { 550*7c478bd9Sstevel@tonic-gate case OR: 551*7c478bd9Sstevel@tonic-gate case AND: 552*7c478bd9Sstevel@tonic-gate r1 = conj(op1, r1, expres(pri[op1-OR], 0)); 553*7c478bd9Sstevel@tonic-gate break; 554*7c478bd9Sstevel@tonic-gate case EQ: 555*7c478bd9Sstevel@tonic-gate case LT: 556*7c478bd9Sstevel@tonic-gate case GT: 557*7c478bd9Sstevel@tonic-gate case LEQ: 558*7c478bd9Sstevel@tonic-gate case GEQ: 559*7c478bd9Sstevel@tonic-gate case NEQ: 560*7c478bd9Sstevel@tonic-gate r1 = rel(op1, r1, expres(pri[op1-OR], 0)); 561*7c478bd9Sstevel@tonic-gate break; 562*7c478bd9Sstevel@tonic-gate case ADD: 563*7c478bd9Sstevel@tonic-gate case SUBT: 564*7c478bd9Sstevel@tonic-gate case MULT: 565*7c478bd9Sstevel@tonic-gate case DIV: 566*7c478bd9Sstevel@tonic-gate case REM: 567*7c478bd9Sstevel@tonic-gate r1 = arith(op1, r1, expres(pri[op1-OR], 0)); 568*7c478bd9Sstevel@tonic-gate break; 569*7c478bd9Sstevel@tonic-gate case MCH: 570*7c478bd9Sstevel@tonic-gate r1 = match(r1, expres(pri[op1-OR], 0)); 571*7c478bd9Sstevel@tonic-gate break; 572*7c478bd9Sstevel@tonic-gate } 573*7c478bd9Sstevel@tonic-gate if (noarg == 1) { 574*7c478bd9Sstevel@tonic-gate return (r1); 575*7c478bd9Sstevel@tonic-gate } 576*7c478bd9Sstevel@tonic-gate Argi--; 577*7c478bd9Sstevel@tonic-gate goto lop; 578*7c478bd9Sstevel@tonic-gate } 579*7c478bd9Sstevel@tonic-gate } 580*7c478bd9Sstevel@tonic-gate ylex = yylex(); 581*7c478bd9Sstevel@tonic-gate if (ylex == ')') { 582*7c478bd9Sstevel@tonic-gate if (par == Argi) { 583*7c478bd9Sstevel@tonic-gate yyerror("syntax error"); 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate if (par != 0) { 586*7c478bd9Sstevel@tonic-gate paren--; 587*7c478bd9Sstevel@tonic-gate Argi++; 588*7c478bd9Sstevel@tonic-gate } 589*7c478bd9Sstevel@tonic-gate Argi++; 590*7c478bd9Sstevel@tonic-gate return (r1); 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate ylex = yylex(); 593*7c478bd9Sstevel@tonic-gate #ifdef _iBCS2 594*7c478bd9Sstevel@tonic-gate if (ylex > MCH && ((sysv3_set && ylex <= INDEX) || ylex <= MATCH)) { 595*7c478bd9Sstevel@tonic-gate #else 596*7c478bd9Sstevel@tonic-gate if (ylex > MCH && ylex <= MATCH) { 597*7c478bd9Sstevel@tonic-gate #endif /* _iBCS2 */ 598*7c478bd9Sstevel@tonic-gate if (Argi == temp) { 599*7c478bd9Sstevel@tonic-gate return (r1); 600*7c478bd9Sstevel@tonic-gate } 601*7c478bd9Sstevel@tonic-gate op1 = ylex; 602*7c478bd9Sstevel@tonic-gate Argi++; 603*7c478bd9Sstevel@tonic-gate switch (op1) { 604*7c478bd9Sstevel@tonic-gate case MATCH: 605*7c478bd9Sstevel@tonic-gate rb = expres(pri[op1-OR], 0); 606*7c478bd9Sstevel@tonic-gate ra = expres(pri[op1-OR], 0); 607*7c478bd9Sstevel@tonic-gate break; 608*7c478bd9Sstevel@tonic-gate #ifdef _iBCS2 609*7c478bd9Sstevel@tonic-gate case SUBSTR: 610*7c478bd9Sstevel@tonic-gate rc = expres(pri[op1-OR], 0); 611*7c478bd9Sstevel@tonic-gate rb = expres(pri[op1-OR], 0); 612*7c478bd9Sstevel@tonic-gate ra = expres(pri[op1-OR], 0); 613*7c478bd9Sstevel@tonic-gate break; 614*7c478bd9Sstevel@tonic-gate case LENGTH: 615*7c478bd9Sstevel@tonic-gate ra = expres(pri[op1-OR], 0); 616*7c478bd9Sstevel@tonic-gate break; 617*7c478bd9Sstevel@tonic-gate case INDEX: 618*7c478bd9Sstevel@tonic-gate rb = expres(pri[op1-OR], 0); 619*7c478bd9Sstevel@tonic-gate ra = expres(pri[op1-OR], 0); 620*7c478bd9Sstevel@tonic-gate break; 621*7c478bd9Sstevel@tonic-gate #endif /* _iBCS2 */ 622*7c478bd9Sstevel@tonic-gate } 623*7c478bd9Sstevel@tonic-gate switch (op1) { 624*7c478bd9Sstevel@tonic-gate case MATCH: 625*7c478bd9Sstevel@tonic-gate r1 = match(rb, ra); 626*7c478bd9Sstevel@tonic-gate break; 627*7c478bd9Sstevel@tonic-gate #ifdef _iBCS2 628*7c478bd9Sstevel@tonic-gate case SUBSTR: 629*7c478bd9Sstevel@tonic-gate r1 = substr(rc, rb, ra); 630*7c478bd9Sstevel@tonic-gate break; 631*7c478bd9Sstevel@tonic-gate case LENGTH: 632*7c478bd9Sstevel@tonic-gate r1 = length(ra); 633*7c478bd9Sstevel@tonic-gate break; 634*7c478bd9Sstevel@tonic-gate case INDEX: 635*7c478bd9Sstevel@tonic-gate r1 = index(rb, ra); 636*7c478bd9Sstevel@tonic-gate break; 637*7c478bd9Sstevel@tonic-gate #endif /* _iBCS2 */ 638*7c478bd9Sstevel@tonic-gate } 639*7c478bd9Sstevel@tonic-gate if (noarg == 1) { 640*7c478bd9Sstevel@tonic-gate return (r1); 641*7c478bd9Sstevel@tonic-gate } 642*7c478bd9Sstevel@tonic-gate Argi--; 643*7c478bd9Sstevel@tonic-gate goto lop; 644*7c478bd9Sstevel@tonic-gate } 645*7c478bd9Sstevel@tonic-gate ylex = yylex(); 646*7c478bd9Sstevel@tonic-gate if (ylex == NOARG) { 647*7c478bd9Sstevel@tonic-gate noarg = 1; 648*7c478bd9Sstevel@tonic-gate } 649*7c478bd9Sstevel@tonic-gate return (r1); 650*7c478bd9Sstevel@tonic-gate } 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate void * 653*7c478bd9Sstevel@tonic-gate exprmalloc(size_t size) 654*7c478bd9Sstevel@tonic-gate { 655*7c478bd9Sstevel@tonic-gate void *rv; 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate if ((rv = malloc(size)) == NULL) { 658*7c478bd9Sstevel@tonic-gate char *s = gettext("malloc error"); 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate (void) write(2, "expr: ", 6); 661*7c478bd9Sstevel@tonic-gate (void) write(2, s, (unsigned)strlen(s)); 662*7c478bd9Sstevel@tonic-gate (void) write(2, "\n", 1); 663*7c478bd9Sstevel@tonic-gate exit(3); 664*7c478bd9Sstevel@tonic-gate } 665*7c478bd9Sstevel@tonic-gate return (rv); 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate int 669*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 670*7c478bd9Sstevel@tonic-gate { 671*7c478bd9Sstevel@tonic-gate /* 672*7c478bd9Sstevel@tonic-gate * XCU4 allow "--" as argument 673*7c478bd9Sstevel@tonic-gate */ 674*7c478bd9Sstevel@tonic-gate if (argc > 1 && strcmp(argv[1], "--") == 0) 675*7c478bd9Sstevel@tonic-gate argv++, argc--; 676*7c478bd9Sstevel@tonic-gate /* 677*7c478bd9Sstevel@tonic-gate * XCU4 - print usage message when invoked without args 678*7c478bd9Sstevel@tonic-gate */ 679*7c478bd9Sstevel@tonic-gate if (argc < 2) { 680*7c478bd9Sstevel@tonic-gate #ifdef XPG6 681*7c478bd9Sstevel@tonic-gate /* XPG6: stdout will always contain newline even on error */ 682*7c478bd9Sstevel@tonic-gate (void) write(1, "\n", 1); 683*7c478bd9Sstevel@tonic-gate #endif 684*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Usage: expr expression\n")); 685*7c478bd9Sstevel@tonic-gate exit(3); 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate Ac = argc; 688*7c478bd9Sstevel@tonic-gate Argi = 1; 689*7c478bd9Sstevel@tonic-gate noarg = 0; 690*7c478bd9Sstevel@tonic-gate paren = 0; 691*7c478bd9Sstevel@tonic-gate Av = argv; 692*7c478bd9Sstevel@tonic-gate #ifdef _iBCS2 693*7c478bd9Sstevel@tonic-gate sysv3_set = getenv("SYSV3"); 694*7c478bd9Sstevel@tonic-gate #endif /* _iBCS2 */ 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 697*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 698*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 699*7c478bd9Sstevel@tonic-gate #endif 700*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 701*7c478bd9Sstevel@tonic-gate buf = expres(0, 1); 702*7c478bd9Sstevel@tonic-gate if (Ac != Argi || paren != 0) { 703*7c478bd9Sstevel@tonic-gate yyerror("syntax error"); 704*7c478bd9Sstevel@tonic-gate } 705*7c478bd9Sstevel@tonic-gate /* 706*7c478bd9Sstevel@tonic-gate * XCU4 - strip leading zeros from numeric output 707*7c478bd9Sstevel@tonic-gate */ 708*7c478bd9Sstevel@tonic-gate clean_buf(buf); 709*7c478bd9Sstevel@tonic-gate (void) write(1, buf, (unsigned)strlen(buf)); 710*7c478bd9Sstevel@tonic-gate (void) write(1, "\n", 1); 711*7c478bd9Sstevel@tonic-gate return ((strcmp(buf, "0") == 0 || buf[0] == 0) ? 1 : 0); 712*7c478bd9Sstevel@tonic-gate } 713