From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by sourceware.org (Postfix) with ESMTPS id 909353858412; Thu, 16 Dec 2021 20:22:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 909353858412 Received: by mail-wr1-x42e.google.com with SMTP id j9so245890wrc.0; Thu, 16 Dec 2021 12:22:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:mime-version:subject:message-id:date:cc:to; bh=WBCC5HvyPcvJgVKUQYsbFjMXCsaq5YJTsXCz3cluioI=; b=V4BYpXti9GEF1FacJKjUt3gGMjoTMQw9J65kywl95RGaeSweS35duTVz4P2aVxGUop 4WXEhfqZkfLjrOa0Vbkws9stLQUPXcwTGjCJkHyoCSQLYB5ChiGNF4aqJD7eB9Ltu5pg irlNhWV+Njv+OI2I/CEs2/acAulCrI/RRX5MvOk/nhdko9sgfFDC/4gGb4hORfMRj3bh etUW1SH5Un/50YUMI+Tw0Bkr8gMLRCdBSRtaEjGLz24lyrLvL/lcIEpNVx1VxWCdf+jW YIegIusWbXbDnDwKbjhOPO49weJPQ4+fzqWBjieZ3eL3tVNa6lrwvwWku9pDjOhCZu3S Iy/A== X-Gm-Message-State: AOAM532VQc+ZwLrKSMvskSmgXCwp1tRkrQRbgiR+3w+iyuYUhoUeKXkc wdmvaNgX+1kBN8uihY5F4Di67gIAthE= X-Google-Smtp-Source: ABdhPJypWDevyjOkiAHtYJ9Tx2AXMyJ5hXnUak87DnbxxFw3Tmc+Q6AO503WcfKLs1OKVnHURLK9nQ== X-Received: by 2002:adf:de84:: with SMTP id w4mr7800741wrl.67.1639686135459; Thu, 16 Dec 2021 12:22:15 -0800 (PST) Received: from smtpclient.apple ([2a01:e34:ec28:8cb0:a5b9:b62:16cf:26bf]) by smtp.gmail.com with ESMTPSA id t17sm9517803wmq.15.2021.12.16.12.22.14 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Dec 2021 12:22:15 -0800 (PST) From: FX Content-Type: multipart/mixed; boundary="Apple-Mail=_BFACACFB-BD60-4F2B-BA31-23E802E5C4FA" Mime-Version: 1.0 (Mac OS X Mail 15.0 \(3693.40.0.1.81\)) Subject: [patch] Fix PR libfortran/95177, ctype.h functions should not be called with char arguments Message-Id: Date: Thu, 16 Dec 2021 21:22:14 +0100 Cc: gcc-patches@gcc.gnu.org To: fortran@gcc.gnu.org X-Mailer: Apple Mail (2.3693.40.0.1.81) X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: fortran@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Fortran mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Dec 2021 20:22:18 -0000 --Apple-Mail=_BFACACFB-BD60-4F2B-BA31-23E802E5C4FA Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Hi, Functions from should only be called on values that can be = represented by unsigned char. On targets where char is a signed type, = some of libgfortran calls have undefined behaviour. The solution is to cast the argument to unsigned char type. I=E2=80=99ve = defined macros in libgfortran.h to do so, to retain legibility of the = library code. Bootstrapped and regtested on x86_64-pc-linux-gnu. OK to commit? FX --Apple-Mail=_BFACACFB-BD60-4F2B-BA31-23E802E5C4FA Content-Disposition: attachment; filename=pr95177.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="pr95177.patch" Content-Transfer-Encoding: quoted-printable commit=20a3d0045d510707b82d2bd65722d0ca6cec235caa=0AAuthor:=20= Fran=C3=A7ois-Xavier=20Coudert=20=0ADate:=20=20=20= 2021-12-16=2018:38:30=20+0100=0A=0A=20=20=20=20Cast=20arguments=20of=20= =20functions=20to=20unsigned=20char=0A=20=20=20=20=0A=20=20=20=20= PR=20libfortran/95177=0A=20=20=20=20=0A=20=20=20=20libgfortran/ChangeLog=0A= =20=20=20=20=0A=20=20=20=20=20=20=20=20=20=20=20=20*=20libgfortran.h:=20= include=20ctype.h,=20provide=20safe=20macros.=0A=20=20=20=20=20=20=20=20=20= =20=20=20*=20io/format.c:=20use=20safe=20macros.=0A=20=20=20=20=20=20=20=20= =20=20=20=20*=20io/list_read.c:=20use=20safe=20macros.=0A=20=20=20=20=20=20= =20=20=20=20=20=20*=20io/read.c:=20use=20safe=20macros.=0A=20=20=20=20=20= =20=20=20=20=20=20=20*=20io/write.c:=20use=20safe=20macros.=0A=20=20=20=20= =20=20=20=20=20=20=20=20*=20runtime/environ.c:=20use=20safe=20macros.=0A=0A= diff=20--git=20a/libgfortran/io/format.c=20b/libgfortran/io/format.c=0A= index=2056f8dbd858a..927e3785a34=20100644=0A---=20= a/libgfortran/io/format.c=0A+++=20b/libgfortran/io/format.c=0A@@=20-29,7=20= +29,6=20@@=20see=20the=20files=20COPYING3=20and=20COPYING.RUNTIME=20= respectively.=20=20If=20not,=20see=0A=20=0A=20#include=20"io.h"=0A=20= #include=20"format.h"=0A-#include=20=0A=20#include=20=0A= =20=0A=20=0A@@=20-193,7=20+192,7=20@@=20next_char=20(format_data=20*fmt,=20= int=20literal)=0A=20=09return=20-1;=0A=20=0A=20=20=20=20=20=20=20= fmt->format_string_len--;=0A-=20=20=20=20=20=20c=20=3D=20toupper=20= (*fmt->format_string++);=0A+=20=20=20=20=20=20c=20=3D=20safe_toupper=20= (*fmt->format_string++);=0A=20=20=20=20=20=20=20fmt->error_element=20=3D=20= c;=0A=20=20=20=20=20}=0A=20=20=20while=20((c=20=3D=3D=20'=20'=20||=20c=20= =3D=3D=20'\t')=20&&=20!literal);=0A@@=20-328,7=20+327,7=20@@=20= format_lex=20(format_data=20*fmt)=0A=20=0A=20=20=20=20=20case=20'+':=0A=20= =20=20=20=20=20=20c=20=3D=20next_char=20(fmt,=200);=0A-=20=20=20=20=20=20= if=20(!isdigit=20(c))=0A+=20=20=20=20=20=20if=20(!safe_isdigit=20(c))=0A=20= =09{=0A=20=09=20=20token=20=3D=20FMT_UNKNOWN;=0A=20=09=20=20break;=0A@@=20= -339,7=20+338,7=20@@=20format_lex=20(format_data=20*fmt)=0A=20=20=20=20=20= =20=20for=20(;;)=0A=20=09{=0A=20=09=20=20c=20=3D=20next_char=20(fmt,=20= 0);=0A-=09=20=20if=20(!isdigit=20(c))=0A+=09=20=20if=20(!safe_isdigit=20= (c))=0A=20=09=20=20=20=20break;=0A=20=0A=20=09=20=20fmt->value=20=3D=20= 10=20*=20fmt->value=20+=20c=20-=20'0';=0A@@=20-367,7=20+366,7=20@@=20= format_lex=20(format_data=20*fmt)=0A=20=20=20=20=20=20=20for=20(;;)=0A=20= =09{=0A=20=09=20=20c=20=3D=20next_char=20(fmt,=200);=0A-=09=20=20if=20= (!isdigit=20(c))=0A+=09=20=20if=20(!safe_isdigit=20(c))=0A=20=09=20=20=20= =20break;=0A=20=0A=20=09=20=20fmt->value=20=3D=2010=20*=20fmt->value=20+=20= c=20-=20'0';=0Adiff=20--git=20a/libgfortran/io/list_read.c=20= b/libgfortran/io/list_read.c=0Aindex=208cc7ddbe8e2..f902ee4fe1d=20100644=0A= ---=20a/libgfortran/io/list_read.c=0A+++=20b/libgfortran/io/list_read.c=0A= @@=20-29,7=20+29,6=20@@=20see=20the=20files=20COPYING3=20and=20= COPYING.RUNTIME=20respectively.=20=20If=20not,=20see=0A=20#include=20= "fbuf.h"=0A=20#include=20"unix.h"=0A=20#include=20=0A-#include=20= =0A=20=0A=20typedef=20unsigned=20char=20uchar;=0A=20=0A@@=20= -811,7=20+810,7=20@@=20read_logical=20(st_parameter_dt=20*dtp,=20int=20= length)=0A=20=20=20if=20(parse_repeat=20(dtp))=0A=20=20=20=20=20return;=0A= =20=0A-=20=20c=20=3D=20tolower=20(next_char=20(dtp));=0A+=20=20c=20=3D=20= safe_tolower=20(next_char=20(dtp));=0A=20=20=20l_push_char=20(dtp,=20c);=0A= =20=20=20switch=20(c)=0A=20=20=20=20=20{=0A@@=20-837,7=20+836,7=20@@=20= read_logical=20(st_parameter_dt=20*dtp,=20int=20length)=0A=20=20=20=20=20= =20=20break;=0A=20=0A=20=20=20=20=20case=20'.':=0A-=20=20=20=20=20=20c=20= =3D=20tolower=20(next_char=20(dtp));=0A+=20=20=20=20=20=20c=20=3D=20= safe_tolower=20(next_char=20(dtp));=0A=20=20=20=20=20=20=20switch=20(c)=0A= =20=09{=0A=20=09=20=20case=20't':=0A@@=20-1052,7=20+1051,7=20@@=20= read_integer=20(st_parameter_dt=20*dtp,=20int=20length)=0A=20=20=20=20=20= }=0A=20=0A=20=20get_integer:=0A-=20=20if=20(!isdigit=20(c))=0A+=20=20if=20= (!safe_isdigit=20(c))=0A=20=20=20=20=20goto=20bad_integer;=0A=20=20=20= push_char=20(dtp,=20c);=0A=20=0A@@=20-1303,7=20+1302,7=20@@=20parse_real=20= (st_parameter_dt=20*dtp,=20void=20*buffer,=20int=20length)=0A=20=20=20if=20= (c=20=3D=3D=20','=20&&=20dtp->u.p.current_unit->decimal_status=20=3D=3D=20= DECIMAL_COMMA)=0A=20=20=20=20=20c=20=3D=20'.';=0A=20=0A-=20=20if=20= (!isdigit=20(c)=20&&=20c=20!=3D=20'.')=0A+=20=20if=20(!safe_isdigit=20= (c)=20&&=20c=20!=3D=20'.')=0A=20=20=20=20=20{=0A=20=20=20=20=20=20=20if=20= (c=20=3D=3D=20'i'=20||=20c=20=3D=3D=20'I'=20||=20c=20=3D=3D=20'n'=20||=20= c=20=3D=3D=20'N')=0A=20=09goto=20inf_nan;=0A@@=20-1377,7=20+1376,7=20@@=20= parse_real=20(st_parameter_dt=20*dtp,=20void=20*buffer,=20int=20length)=0A= =20=20=20=20=20}=0A=20=0A=20=20exp2:=0A-=20=20if=20(!isdigit=20(c))=0A+=20= =20if=20(!safe_isdigit=20(c))=0A=20=20=20=20=20{=0A=20=20=20=20=20=20=20= /*=20Extension:=20allow=20default=20exponent=20of=200=20when=20omitted.=20= =20*/=0A=20=20=20=20=20=20=20if=20(dtp->common.flags=20&=20= IOPARM_DT_DEC_EXT)=0A@@=20-1748,7=20+1747,7=20@@=20read_real=20= (st_parameter_dt=20*dtp,=20void=20*dest,=20int=20length)=0A=20=20=20if=20= (c=20=3D=3D=20','=20&&=20dtp->u.p.current_unit->decimal_status=20=3D=3D=20= DECIMAL_COMMA)=0A=20=20=20=20=20c=20=3D=20'.';=0A=20=0A-=20=20if=20= (!isdigit=20(c)=20&&=20c=20!=3D=20'.')=0A+=20=20if=20(!safe_isdigit=20= (c)=20&&=20c=20!=3D=20'.')=0A=20=20=20=20=20{=0A=20=20=20=20=20=20=20if=20= (c=20=3D=3D=20'i'=20||=20c=20=3D=3D=20'I'=20||=20c=20=3D=3D=20'n'=20||=20= c=20=3D=3D=20'N')=0A=20=09goto=20inf_nan;=0A@@=20-1828,7=20+1827,7=20@@=20= read_real=20(st_parameter_dt=20*dtp,=20void=20*dest,=20int=20length)=0A=20= =20=20=20=20}=0A=20=0A=20=20exp2:=0A-=20=20if=20(!isdigit=20(c))=0A+=20=20= if=20(!safe_isdigit=20(c))=0A=20=20=20=20=20{=0A=20=20=20=20=20=20=20/*=20= Extension:=20allow=20default=20exponent=20of=200=20when=20omitted.=20=20= */=0A=20=20=20=20=20=20=20if=20(dtp->common.flags=20&=20= IOPARM_DT_DEC_EXT)=0A@@=20-2757,7=20+2756,7=20@@=20nml_match_name=20= (st_parameter_dt=20*dtp,=20const=20char=20*name,=20index_type=20len)=0A=20= =20=20for=20(i=20=3D=200;=20i=20<=20len;=20i++)=0A=20=20=20=20=20{=0A=20=20= =20=20=20=20=20c=20=3D=20next_char=20(dtp);=0A-=20=20=20=20=20=20if=20(c=20= =3D=3D=20EOF=20||=20(tolower=20(c)=20!=3D=20tolower=20(name[i])))=0A+=20=20= =20=20=20=20if=20(c=20=3D=3D=20EOF=20||=20(safe_tolower=20(c)=20!=3D=20= safe_tolower=20(name[i])))=0A=20=09{=0A=20=09=20=20= dtp->u.p.nml_read_error=20=3D=201;=0A=20=09=20=20break;=0A@@=20-3286,7=20= +3285,7=20@@=20get_name:=0A=20=20=20do=0A=20=20=20=20=20{=0A=20=20=20=20=20= =20=20if=20(!is_separator=20(c))=0A-=09push_char_default=20(dtp,=20= tolower(c));=0A+=09push_char_default=20(dtp,=20safe_tolower(c));=0A=20=20= =20=20=20=20=20if=20((c=20=3D=20next_char=20(dtp))=20=3D=3D=20EOF)=0A=20=09= goto=20nml_err_ret;=0A=20=20=20=20=20}=0Adiff=20--git=20= a/libgfortran/io/read.c=20b/libgfortran/io/read.c=0Aindex=20= 7515d912c51..7b3f137d687=20100644=0A---=20a/libgfortran/io/read.c=0A+++=20= b/libgfortran/io/read.c=0A@@=20-28,7=20+28,6=20@@=20see=20the=20files=20= COPYING3=20and=20COPYING.RUNTIME=20respectively.=20=20If=20not,=20see=0A=20= #include=20"format.h"=0A=20#include=20"unix.h"=0A=20#include=20= =0A-#include=20=0A=20#include=20=0A=20= #include=20"async.h"=0A=20=0A@@=20-959,7=20+958,7=20@@=20read_f=20= (st_parameter_dt=20*dtp,=20const=20fnode=20*f,=20char=20*dest,=20int=20= length)=0A=20=09=20between=20"NaN"=20and=20the=20optional=20perenthesis=20= is=20not=20permitted.=20=20*/=0A=20=20=20=20=20=20=20while=20(w=20>=200)=0A= =20=09{=0A-=09=20=20*out=20=3D=20tolower=20(*p);=0A+=09=20=20*out=20=3D=20= safe_tolower=20(*p);=0A=20=09=20=20switch=20(*p)=0A=20=09=20=20=20=20{=0A= =20=09=20=20=20=20case=20'=20':=0A@@=20-981,7=20+980,7=20@@=20read_f=20= (st_parameter_dt=20*dtp,=20const=20fnode=20*f,=20char=20*dest,=20int=20= length)=0A=20=09=09goto=20bad_float;=0A=20=09=20=20=20=20=20=20break;=0A=20= =09=20=20=20=20default:=0A-=09=20=20=20=20=20=20if=20(!isalnum=20(*out))=0A= +=09=20=20=20=20=20=20if=20(!safe_isalnum=20(*out))=0A=20=09=09goto=20= bad_float;=0A=20=09=20=20=20=20}=0A=20=09=20=20--w;=0A@@=20-1109,7=20= +1108,7=20@@=20exponent:=0A=20=0A=20=20=20if=20(dtp->u.p.blank_status=20= =3D=3D=20BLANK_UNSPECIFIED)=0A=20=20=20=20=20{=0A-=20=20=20=20=20=20= while=20(w=20>=200=20&&=20isdigit=20(*p))=0A+=20=20=20=20=20=20while=20= (w=20>=200=20&&=20safe_isdigit=20(*p))=0A=20=09{=0A=20=09=20=20exponent=20= *=3D=2010;=0A=20=09=20=20exponent=20+=3D=20*p=20-=20'0';=0A@@=20-1137,7=20= +1136,7=20@@=20exponent:=0A=20=09=20=20=20=20=20=20else=0A=20=09=09= assert=20(dtp->u.p.blank_status=20=3D=3D=20BLANK_NULL);=0A=20=09=20=20=20= =20}=0A-=09=20=20else=20if=20(!isdigit=20(*p))=0A+=09=20=20else=20if=20= (!safe_isdigit=20(*p))=0A=20=09=20=20=20=20goto=20bad_float;=0A=20=09=20=20= else=0A=20=09=20=20=20=20{=0Adiff=20--git=20a/libgfortran/io/write.c=20= b/libgfortran/io/write.c=0Aindex=20278cd47cabb..b9e92845bcf=20100644=0A= ---=20a/libgfortran/io/write.c=0A+++=20b/libgfortran/io/write.c=0A@@=20= -30,7=20+30,6=20@@=20see=20the=20files=20COPYING3=20and=20= COPYING.RUNTIME=20respectively.=20=20If=20not,=20see=0A=20#include=20= "unix.h"=0A=20#include=20=0A=20#include=20=0A= -#include=20=0A=20=0A=20#define=20star_fill(p,=20n)=20memset(p,=20= '*',=20n)=0A=20=0A@@=20-2101,14=20+2100,14=20@@=20nml_write_obj=20= (st_parameter_dt=20*dtp,=20namelist_info=20*obj,=20index_type=20offset,=0A= =20=09=20=20base_name_len=20=3D=20strlen=20(base_name);=0A=20=09=20=20= for=20(dim_i=20=3D=200;=20dim_i=20<=20base_name_len;=20dim_i++)=0A=20=20=20= =20=20=20=20=20=20=20=20=20=20{=0A-=09=20=20=20=20=20=20cup=20=3D=20= toupper=20((int)=20base_name[dim_i]);=0A+=09=20=20=20=20=20=20cup=20=3D=20= safe_toupper=20(base_name[dim_i]);=0A=20=09=20=20=20=20=20=20= write_character=20(dtp,=20&cup,=201,=201,=20NODELIM);=0A=20=20=20=20=20=20= =20=20=20=20=20=20=20}=0A=20=09}=0A=20=20=20=20=20=20=20clen=20=3D=20= strlen=20(obj->var_name);=0A=20=20=20=20=20=20=20for=20(dim_i=20=3D=20= len;=20dim_i=20<=20clen;=20dim_i++)=0A=20=09{=0A-=09=20=20cup=20=3D=20= toupper=20((int)=20obj->var_name[dim_i]);=0A+=09=20=20cup=20=3D=20= safe_toupper=20(obj->var_name[dim_i]);=0A=20=09=20=20if=20(cup=20=3D=3D=20= '+')=0A=20=09=20=20=20=20cup=20=3D=20'%';=0A=20=09=20=20write_character=20= (dtp,=20&cup,=201,=201,=20NODELIM);=0A@@=20-2426,7=20+2425,7=20@@=20= namelist_write=20(st_parameter_dt=20*dtp)=0A=20=20=20/*=20Write=20= namelist=20name=20in=20upper=20case=20-=20f95=20std.=20=20*/=0A=20=20=20= for=20(gfc_charlen_type=20i=20=3D=200;=20i=20<=20dtp->namelist_name_len;=20= i++=20)=0A=20=20=20=20=20{=0A-=20=20=20=20=20=20c=20=3D=20toupper=20= ((int)=20dtp->namelist_name[i]);=0A+=20=20=20=20=20=20c=20=3D=20= safe_toupper=20(dtp->namelist_name[i]);=0A=20=20=20=20=20=20=20= write_character=20(dtp,=20&c,=201=20,1,=20NODELIM);=0A=20=20=20=20=20}=0A= =20=0Adiff=20--git=20a/libgfortran/libgfortran.h=20= b/libgfortran/libgfortran.h=0Aindex=20285c36a00b5..93e3591b21f=20100644=0A= ---=20a/libgfortran/libgfortran.h=0A+++=20b/libgfortran/libgfortran.h=0A= @@=20-39,6=20+39,7=20@@=20see=20the=20files=20COPYING3=20and=20= COPYING.RUNTIME=20respectively.=20=20If=20not,=20see=0A=20/*=20config.h=20= MUST=20be=20first=20because=20it=20can=20affect=20system=20headers.=20=20= */=0A=20#include=20"config.h"=0A=20=0A+#include=20=0A=20= #include=20=0A=20#include=20=0A=20#include=20= =0A@@=20-103,6=20+104,20=20@@=20typedef=20off_t=20gfc_offset;=0A= =20#endif=0A=20=0A=20=0A+/*=20These=20functions=20from=20=20= should=20only=20be=20used=20on=20values=20that=20can=20be=0A+=20=20=20= represented=20as=20unsigned=20char,=20otherwise=20the=20behavior=20is=20= undefined.=0A+=20=20=20Some=20targets=20have=20a=20char=20type=20that=20= is=20signed,=20so=20we=20cast=20the=20argument=0A+=20=20=20to=20unsigned=20= char.=20See:=0A+=20=20=20=20=20= https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D95177=0A+=20=20=20=20=20= https://wiki.sei.cmu.edu/confluence/x/BNcxBQ=0A+=20*/=0A+=0A+#define=20= safe_isalnum(x)=20isalnum((unsigned=20char)=20(x))=0A+#define=20= safe_isdigit(x)=20isdigit((unsigned=20char)=20(x))=0A+#define=20= safe_tolower(x)=20tolower((unsigned=20char)=20(x))=0A+#define=20= safe_toupper(x)=20toupper((unsigned=20char)=20(x))=0A+=0A+=0A=20/*=20The=20= following=20macros=20can=20be=20used=20to=20annotate=20conditions=20= which=20are=20likely=20or=0A=20=20=20=20unlikely=20to=20be=20true.=20=20= Avoid=20using=20them=20when=20a=20condition=20is=20only=20slightly=0A=20=20= =20=20more=20likely/less=20unlikely=20than=20average=20to=20avoid=20the=20= performance=20penalties=20of=0Adiff=20--git=20= a/libgfortran/runtime/environ.c=20b/libgfortran/runtime/environ.c=0A= index=20fe16c080797..ce408cf11af=20100644=0A---=20= a/libgfortran/runtime/environ.c=0A+++=20b/libgfortran/runtime/environ.c=0A= @@=20-26,7=20+26,6=20@@=20see=20the=20files=20COPYING3=20and=20= COPYING.RUNTIME=20respectively.=20=20If=20not,=20see=0A=20=0A=20#include=20= =0A=20#include=20=0A-#include=20=0A=20=0A=20= #ifdef=20HAVE_UNISTD_H=0A=20#include=20=0A@@=20-91,7=20+90,7=20= @@=20init_integer=20(variable=20*=20v)=0A=20=20=20=20=20return;=0A=20=0A=20= =20=20for=20(q=20=3D=20p;=20*q;=20q++)=0A-=20=20=20=20if=20(!isdigit=20= (*q)=20&&=20(p=20!=3D=20q=20||=20*q=20!=3D=20'-'))=0A+=20=20=20=20if=20= (!safe_isdigit=20(*q)=20&&=20(p=20!=3D=20q=20||=20*q=20!=3D=20'-'))=0A=20= =20=20=20=20=20=20return;=0A=20=0A=20=20=20*v->var=20=3D=20atoi=20(p);=0A= @@=20-344,7=20+343,7=20@@=20static=20int=0A=20match_integer=20(void)=0A=20= {=0A=20=20=20unit_num=20=3D=200;=0A-=20=20while=20(isdigit=20(*p))=0A+=20= =20while=20(safe_isdigit=20(*p))=0A=20=20=20=20=20unit_num=20=3D=20= unit_num=20*=2010=20+=20(*p++=20-=20'0');=0A=20=20=20return=20INTEGER;=0A= =20}=0A= --Apple-Mail=_BFACACFB-BD60-4F2B-BA31-23E802E5C4FA--