From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: lloda Newsgroups: gmane.lisp.guile.devel Subject: [PATCH] Support C99 complex types in (system foreign) Date: Thu, 11 Nov 2021 18:15:07 +0100 Message-ID: <2ACECB92-AF5C-4712-824D-779B3C824D81@sarc.name> Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.7\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_B8174C50-5D5E-484B-A56B-318C5941C07F" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="38806"; mail-complaints-to="usenet@ciao.gmane.io" To: guile-devel Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Thu Nov 11 18:15:43 2021 Return-path: Envelope-to: guile-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mlDfq-0009ob-OQ for guile-devel@m.gmane-mx.org; Thu, 11 Nov 2021 18:15:42 +0100 Original-Received: from localhost ([::1]:37868 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mlDfo-000524-OV for guile-devel@m.gmane-mx.org; Thu, 11 Nov 2021 12:15:40 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:40836) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mlDfc-000518-G9 for guile-devel@gnu.org; Thu, 11 Nov 2021 12:15:28 -0500 Original-Received: from mta-13-4.privateemail.com ([198.54.127.109]:41157) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mlDfa-0002hq-Qu for guile-devel@gnu.org; Thu, 11 Nov 2021 12:15:28 -0500 Original-Received: from mta-13.privateemail.com (localhost [127.0.0.1]) by mta-13.privateemail.com (Postfix) with ESMTP id B087818000A3 for ; Thu, 11 Nov 2021 12:15:10 -0500 (EST) Original-Received: from [192.168.1.105] (unknown [10.20.151.219]) by mta-13.privateemail.com (Postfix) with ESMTPA id EF5AA18000B7 for ; Thu, 11 Nov 2021 12:15:09 -0500 (EST) X-Mailer: Apple Mail (2.3608.120.23.2.7) X-Virus-Scanned: ClamAV using ClamSMTP Received-SPF: pass client-ip=198.54.127.109; envelope-from=lloda@sarc.name; helo=MTA-13-4.privateemail.com X-Spam_score_int: -4 X-Spam_score: -0.5 X-Spam_bar: / X-Spam_report: (-0.5 / 5.0 requ) BAYES_00=-1.9, PYZOR_CHECK=1.392, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Original-Sender: "guile-devel" Xref: news.gmane.io gmane.lisp.guile.devel:20934 Archived-At: --Apple-Mail=_B8174C50-5D5E-484B-A56B-318C5941C07F Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=us-ascii --Apple-Mail=_B8174C50-5D5E-484B-A56B-318C5941C07F Content-Disposition: attachment; filename=0001-Support-C99-complex-types-in-system-foreign.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Support-C99-complex-types-in-system-foreign.patch" Content-Transfer-Encoding: quoted-printable =46rom=202a95a47be9d431fbcb3fe65c1d02a9926441bbaf=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Daniel=20Llorens=20=0ADate:=20= Thu,=2011=20Nov=202021=2015:47:42=20+0100=0ASubject:=20[PATCH]=20Support=20= C99=20complex=20types=20in=20(system=20foreign)=0A=0A*=20= libguile/foreign.h=20(SCM_FOREIGN_TYPE_COMPLEX_FLOAT,=0A=20=20= SCM_FOREIGN_TYPE_COMPLEX_DOUBLE):=20New=20enums.=0A*=20= module/system/foreign.scm=20(complex-float,=20complex-double):=20Export=20= new=20types.=0A=20=20(make-c-struct,=20parse-c-struct):=20Support=20the=20= new=20types.=0A*=20libguile/foreign.c=20(complex-float,=20= complex-double):=20Define=20new=20types.=0A=20=20(alignof,=20sizeof,=20= pack,=20unpack):=20Support=20the=20new=20types.=0A---=0A=20NEWS=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20=205=20+++=0A=20= doc/ref/api-foreign.texi=20=20|=20=205=20++-=0A=20libguile/foreign.c=20=20= =20=20=20=20=20=20|=2066=20+++++++++++++++++++++++++++++++++++++++=0A=20= libguile/foreign.h=20=20=20=20=20=20=20=20|=20=206=20++++=0A=20= module/system/foreign.scm=20|=2016=20++++++++++=0A=205=20files=20= changed,=2097=20insertions(+),=201=20deletion(-)=0A=0Adiff=20--git=20= a/NEWS=20b/NEWS=0Aindex=20f41e772ad..710b8ddda=20100644=0A---=20a/NEWS=0A= +++=20b/NEWS=0A@@=20-49,6=20+49,11=20@@=20Bytevectors"=20in=20the=20= manual.=0A=20Compared=20to=20the=20previous=20versions,=20these=20accept=20= range=20arguments.=20See=0A=20"Accessing=20and=20Modifying=20Vector=20= Contents"=20in=20the=20manual.=0A=20=0A+**=20(system=20foreign)=20= supports=20C99=20complex=20types=0A+=0A+The=20types=20`complex-float'=20= and=20`complex-double'=20stand=20for=20C99=20`float=0A+_Complex'=20and=20= `double=20_Complex`=20respectively.=0A+=0A=20=0C=0A=20Changes=20in=20= 3.0.7=20(since=203.0.6)=0A=20=0Adiff=20--git=20= a/doc/ref/api-foreign.texi=20b/doc/ref/api-foreign.texi=0Aindex=20= a1a1016b0..540fbbaf5=20100644=0A---=20a/doc/ref/api-foreign.texi=0A+++=20= b/doc/ref/api-foreign.texi=0A@@=20-465,8=20+465,11=20@@=20C=20types.=0A=20= @defvrx=20{Scheme=20Variable}=20int64=0A=20@defvrx=20{Scheme=20Variable}=20= float=0A=20@defvrx=20{Scheme=20Variable}=20double=0A+@defvrx=20{Scheme=20= Variable}=20complex-double=0A+@defvrx=20{Scheme=20Variable}=20= complex-float=0A=20These=20values=20represent=20the=20C=20numeric=20= types=20of=20the=20specified=20sizes=20and=0A-signednesses.=0A= +signednesses.=20@code{complex-float}=20and=20@code{complex-double}=20= stand=20for=0A+C99=20@code{float=20_Complex}=20and=20@code{double=20= _Complex}=20respecively.=0A=20@end=20defvr=0A=20=0A=20In=20addition=20= there=20are=20some=20convenience=20bindings=20for=20indicating=20types=20= of=0Adiff=20--git=20a/libguile/foreign.c=20b/libguile/foreign.c=0Aindex=20= 1368cc9da..fdf1001dc=20100644=0A---=20a/libguile/foreign.c=0A+++=20= b/libguile/foreign.c=0A@@=20-29,6=20+29,10=20@@=0A=20=0A=20#include=20= =0A=20=0A+#ifdef=20FFI_TARGET_HAS_COMPLEX_TYPE=0A+#include=20= =0A+#endif=0A+=0A=20#include=20"boolean.h"=0A=20#include=20= "bytevectors.h"=0A=20#include=20"dynwind.h"=0A@@=20-63,6=20+67,10=20@@=0A= =20SCM_SYMBOL=20(sym_void,=20"void");=0A=20SCM_SYMBOL=20(sym_float,=20= "float");=0A=20SCM_SYMBOL=20(sym_double,=20"double");=0A+#ifdef=20= FFI_TARGET_HAS_COMPLEX_TYPE=0A+SCM_SYMBOL=20(sym_complex_float,=20= "complex-float");=0A+SCM_SYMBOL=20(sym_complex_double,=20= "complex-double");=0A+#endif=0A=20SCM_SYMBOL=20(sym_uint8,=20"uint8");=0A= =20SCM_SYMBOL=20(sym_int8,=20"int8");=0A=20SCM_SYMBOL=20(sym_uint16,=20= "uint16");=0A@@=20-470,6=20+478,12=20@@=20SCM_DEFINE=20(scm_alignof,=20= "alignof",=201,=200,=200,=20(SCM=20type),=0A=20=20=20=20=20=20=20=20=20=20= =20return=20scm_from_size_t=20(alignof_type=20(float));=0A=20=20=20=20=20= =20=20=20=20case=20SCM_FOREIGN_TYPE_DOUBLE:=0A=20=20=20=20=20=20=20=20=20= =20=20return=20scm_from_size_t=20(alignof_type=20(double));=0A+#ifdef=20= FFI_TARGET_HAS_COMPLEX_TYPE=20=20=20=20=20=20=20=0A+=20=20=20=20=20=20=20= =20case=20SCM_FOREIGN_TYPE_COMPLEX_FLOAT:=0A+=20=20=20=20=20=20=20=20=20=20= return=20scm_from_size_t=20(alignof_type=20(float=20_Complex));=0A+=20=20= =20=20=20=20=20=20case=20SCM_FOREIGN_TYPE_COMPLEX_DOUBLE:=0A+=20=20=20=20= =20=20=20=20=20=20return=20scm_from_size_t=20(alignof_type=20(double=20= _Complex));=0A+#endif=0A=20=20=20=20=20=20=20=20=20case=20= SCM_FOREIGN_TYPE_UINT8:=0A=20=20=20=20=20=20=20=20=20=20=20return=20= scm_from_size_t=20(alignof_type=20(uint8_t));=0A=20=20=20=20=20=20=20=20=20= case=20SCM_FOREIGN_TYPE_INT8:=0A@@=20-534,6=20+548,12=20@@=20SCM_DEFINE=20= (scm_sizeof,=20"sizeof",=201,=200,=200,=20(SCM=20type),=0A=20=20=20=20=20= =20=20=20=20=20=20return=20scm_from_size_t=20(sizeof=20(float));=0A=20=20= =20=20=20=20=20=20=20case=20SCM_FOREIGN_TYPE_DOUBLE:=0A=20=20=20=20=20=20= =20=20=20=20=20return=20scm_from_size_t=20(sizeof=20(double));=0A+#ifdef=20= FFI_TARGET_HAS_COMPLEX_TYPE=20=20=20=20=20=20=20=0A+=20=20=20=20=20=20=20= =20case=20SCM_FOREIGN_TYPE_COMPLEX_FLOAT:=0A+=20=20=20=20=20=20=20=20=20=20= return=20scm_from_size_t=20(sizeof=20(float=20_Complex));=0A+=20=20=20=20= =20=20=20=20case=20SCM_FOREIGN_TYPE_COMPLEX_DOUBLE:=0A+=20=20=20=20=20=20= =20=20=20=20return=20scm_from_size_t=20(sizeof=20(double=20_Complex));=0A= +#endif=0A=20=20=20=20=20=20=20=20=20case=20SCM_FOREIGN_TYPE_UINT8:=0A=20= =20=20=20=20=20=20=20=20=20=20return=20scm_from_size_t=20(sizeof=20= (uint8_t));=0A=20=20=20=20=20=20=20=20=20case=20SCM_FOREIGN_TYPE_INT8:=0A= @@=20-626,6=20+646,14=20@@=20fill_ffi_type=20(SCM=20type,=20ffi_type=20= *ftype,=20ffi_type=20***type_ptrs,=0A=20=20=20=20=20=20=20=20=20case=20= SCM_FOREIGN_TYPE_DOUBLE:=0A=20=20=20=20=20=20=20=20=20=20=20*ftype=20=3D=20= ffi_type_double;=0A=20=20=20=20=20=20=20=20=20=20=20return;=0A+#ifdef=20= FFI_TARGET_HAS_COMPLEX_TYPE=0A+=20=20=20=20=20=20=20=20case=20= SCM_FOREIGN_TYPE_COMPLEX_FLOAT:=0A+=20=20=20=20=20=20=20=20=20=20*ftype=20= =3D=20ffi_type_complex_float;=0A+=20=20=20=20=20=20=20=20=20=20return;=0A= +=20=20=20=20=20=20=20=20case=20SCM_FOREIGN_TYPE_COMPLEX_DOUBLE:=0A+=20=20= =20=20=20=20=20=20=20=20*ftype=20=3D=20ffi_type_complex_double;=0A+=20=20= =20=20=20=20=20=20=20=20return;=0A+#endif=0A=20=20=20=20=20=20=20=20=20= case=20SCM_FOREIGN_TYPE_UINT8:=0A=20=20=20=20=20=20=20=20=20=20=20*ftype=20= =3D=20ffi_type_uint8;=0A=20=20=20=20=20=20=20=20=20=20=20return;=0A@@=20= -882,6=20+910,22=20@@=20unpack=20(const=20ffi_type=20*type,=20void=20= *loc,=20SCM=20x,=20int=20return_value_p)=0A=20=20=20=20=20=20=20*(double=20= *)=20loc=20=3D=20scm_to_double=20(x);=0A=20=20=20=20=20=20=20break;=0A=20= =0A+=20=20=20=20=20=20/*=20no=20FFI_TYPE_xxx_COMPLEX=20or=20= (FFI_TYPE_COMPLEX_xxx)=20:-|=20*/=0A+=20=20=20=20=20=20=0A+#ifdef=20= FFI_TARGET_HAS_COMPLEX_TYPE=0A+=20=20=20=20case=20FFI_TYPE_COMPLEX:=20{=0A= +=20=20=20=20=20=20double=20re=20=3D=20scm_to_double=20= (scm_real_part(x));=0A+=20=20=20=20=20=20double=20im=20=3D=20= scm_to_double=20(scm_imag_part(x));=0A+=20=20=20=20=20=20if=20(sizeof=20= (float=20_Complex)=20=3D=3D=20type->size)=20{=0A+=20=20=20=20=20=20=20=20= *(float=20_Complex=20*)=20loc=20=3D=20(float)re=20+=20_Complex_I=20*=20= (float)im;=0A+=20=20=20=20=20=20}=20else=20if=20(sizeof=20(double=20= _Complex)=20=3D=3D=20type->size)=20{=0A+=20=20=20=20=20=20=20=20*(double=20= _Complex=20*)=20loc=20=3D=20re=20+=20_Complex_I=20*=20im;=0A+=20=20=20=20= =20=20}=20else=20{=0A+=20=20=20=20=20=20=20=20abort();=0A+=20=20=20=20=20= =20}=0A+=20=20=20=20}=20break;=0A+#endif=0A+=20=20=20=20=20=20=0A=20=20=20= =20=20/*=20For=20integer=20return=20values=20smaller=20than=20`int',=20= libffi=20expects=20the=0A=20=20=20=20=20=20=20=20result=20in=20an=20= `ffi_arg'-long=20buffer.=20=20*/=0A=20=0A@@=20-960,6=20+1004,24=20@@=20= pack=20(const=20ffi_type=20*=20type,=20const=20void=20*loc,=20int=20= return_value_p)=0A=20=20=20=20=20case=20FFI_TYPE_DOUBLE:=0A=20=20=20=20=20= =20=20return=20scm_from_double=20(*(double=20*)=20loc);=0A=20=0A+=20=20=20= =20=20=20/*=20no=20FFI_TYPE_xxx_COMPLEX=20or=20(FFI_TYPE_COMPLEX_xxx)=20= :-|=20*/=0A+=20=20=20=20=20=20=0A+#ifdef=20FFI_TARGET_HAS_COMPLEX_TYPE=0A= +=20=20=20=20case=20FFI_TYPE_COMPLEX:=20{=0A+=20=20=20=20=20=20double=20= re,=20im;=0A+=20=20=20=20=20=20if=20(sizeof=20(float=20_Complex)=20=3D=3D=20= type->size)=20{=0A+=20=20=20=20=20=20=20=20re=20=3D=20crealf(*(float=20= _Complex=20*)=20loc);=0A+=20=20=20=20=20=20=20=20im=20=3D=20= cimagf(*(float=20_Complex=20*)=20loc);=0A+=20=20=20=20=20=20}=20else=20= if=20(sizeof=20(double=20_Complex)=20=3D=3D=20type->size)=20{=0A+=20=20=20= =20=20=20=20=20re=20=3D=20creal(*(double=20_Complex=20*)=20loc);=0A+=20=20= =20=20=20=20=20=20im=20=3D=20cimag(*(double=20_Complex=20*)=20loc);=0A+=20= =20=20=20=20=20}=20else=20{=0A+=20=20=20=20=20=20=20=20abort=20();=0A+=20= =20=20=20=20=20}=0A+=20=20=20=20=20=20return=20scm_make_rectangular=20= (scm_from_double=20(re),=20scm_from_double=20(im));=0A+=20=20=20=20}=0A= +#endif=0A+=0A=20=20=20=20=20=20=20/*=20For=20integer=20return=20values=20= smaller=20than=20`int',=20libffi=20stores=20the=0A=20=09=20result=20in=20= an=20`ffi_arg'-long=20buffer,=20of=20which=20only=20the=0A=20=09=20= significant=20bits=20must=20be=20kept---hence=20the=20pair=20of=20casts=20= below.=0A@@=20-1172,6=20+1234,10=20@@=20scm_init_foreign=20(void)=0A=20=20= =20scm_define=20(sym_void,=20scm_from_uint8=20(SCM_FOREIGN_TYPE_VOID));=0A= =20=20=20scm_define=20(sym_float,=20scm_from_uint8=20= (SCM_FOREIGN_TYPE_FLOAT));=0A=20=20=20scm_define=20(sym_double,=20= scm_from_uint8=20(SCM_FOREIGN_TYPE_DOUBLE));=0A+#ifdef=20= FFI_TARGET_HAS_COMPLEX_TYPE=0A+=20=20scm_define=20(sym_complex_float,=20= scm_from_uint8=20(SCM_FOREIGN_TYPE_COMPLEX_FLOAT));=0A+=20=20scm_define=20= (sym_complex_double,=20scm_from_uint8=20= (SCM_FOREIGN_TYPE_COMPLEX_DOUBLE));=0A+#endif=0A=20=20=20scm_define=20= (sym_uint8,=20scm_from_uint8=20(SCM_FOREIGN_TYPE_UINT8));=0A=20=20=20= scm_define=20(sym_int8,=20scm_from_uint8=20(SCM_FOREIGN_TYPE_INT8));=0A=20= =20=20scm_define=20(sym_uint16,=20scm_from_uint8=20= (SCM_FOREIGN_TYPE_UINT16));=0Adiff=20--git=20a/libguile/foreign.h=20= b/libguile/foreign.h=0Aindex=2041f26b335..33ce6311a=20100644=0A---=20= a/libguile/foreign.h=0A+++=20b/libguile/foreign.h=0A@@=20-43,7=20+43,13=20= @@=20enum=20scm_t_foreign_type=0A=20=20=20=20=20SCM_FOREIGN_TYPE_INT32,=0A= =20=20=20=20=20SCM_FOREIGN_TYPE_UINT64,=0A=20=20=20=20=20= SCM_FOREIGN_TYPE_INT64,=0A+#ifdef=20FFI_TARGET_HAS_COMPLEX_TYPE=0A+=20=20= =20=20SCM_FOREIGN_TYPE_COMPLEX_FLOAT,=0A+=20=20=20=20= SCM_FOREIGN_TYPE_COMPLEX_DOUBLE,=0A+=20=20=20=20SCM_FOREIGN_TYPE_LAST=20= =3D=20SCM_FOREIGN_TYPE_COMPLEX_DOUBLE=0A+#else=0A=20=20=20=20=20= SCM_FOREIGN_TYPE_LAST=20=3D=20SCM_FOREIGN_TYPE_INT64=0A+#endif=0A=20=20=20= };=0A=20=0A=20typedef=20enum=20scm_t_foreign_type=20scm_t_foreign_type;=0A= diff=20--git=20a/module/system/foreign.scm=20b/module/system/foreign.scm=0A= index=20d1c2ceb96..24e14a0cd=20100644=0A---=20= a/module/system/foreign.scm=0A+++=20b/module/system/foreign.scm=0A@@=20= -23,6=20+23,7=20@@=0A=20=20=20#:use-module=20(srfi=20srfi-9=20gnu)=0A=20=20= =20#:export=20(void=0A=20=20=20=20=20=20=20=20=20=20=20=20=20float=20= double=0A+=20=20=20=20=20=20=20=20=20=20=20=20complex-float=20= complex-double=0A=20=20=20=20=20=20=20=20=20=20=20=20=20short=0A=20=20=20= =20=20=20=20=20=20=20=20=20=20unsigned-short=0A=20=20=20=20=20=20=20=20=20= =20=20=20=20int=20unsigned-int=20long=20unsigned-long=20size_t=20ssize_t=20= ptrdiff_t=0A@@=20-93,9=20+94,22=20@@=0A=20=20=20=20=20=20=20=20=20=20=20=20= (bytevector-u32-native-set!=20bv=20offset=20(pointer-address=20ptr))))=0A= =20=20=20=20=20(else=20(error=20"what=20machine=20is=20this?"))))=0A=20=0A= +(define=20(writer-complex=20set=20size)=0A+=20=20(lambda=20(bv=20i=20= val)=0A+=20=20=20=20(set=20bv=20i=20(real-part=20val))=0A+=20=20=20=20= (set=20bv=20(+=20i=20size)=20(imag-part=20val))))=0A+=0A+(define=20= (reader-complex=20ref=20size)=0A+=20=20(lambda=20(bv=20i)=0A+=20=20=20=20= (make-rectangular=20=0A+=20=20=20=20=20(ref=20bv=20i)=0A+=20=20=20=20=20= (ref=20bv=20(+=20i=20size)))))=0A+=0A=20(define=20*writers*=0A=20=20=20= `((,float=20.=20,bytevector-ieee-single-native-set!)=0A=20=20=20=20=20= (,double=20.=20,bytevector-ieee-double-native-set!)=0A+=20=20=20=20= (,complex-float=20.=20,(writer-complex=20= bytevector-ieee-single-native-set!=20(sizeof=20float)))=0A+=20=20=20=20= (,complex-double=20.=20,(writer-complex=20= bytevector-ieee-double-native-set!=20(sizeof=20double)))=0A=20=20=20=20=20= (,int8=20.=20,bytevector-s8-set!)=0A=20=20=20=20=20(,uint8=20.=20= ,bytevector-u8-set!)=0A=20=20=20=20=20(,int16=20.=20= ,bytevector-s16-native-set!)=0A@@=20-109,6=20+123,8=20@@=0A=20(define=20= *readers*=0A=20=20=20`((,float=20.=20,bytevector-ieee-single-native-ref)=0A= =20=20=20=20=20(,double=20.=20,bytevector-ieee-double-native-ref)=0A+=20=20= =20=20(,complex-float=20.=20,(reader-complex=20= bytevector-ieee-single-native-ref=20(sizeof=20float)))=0A+=20=20=20=20= (,complex-double=20.=20,(reader-complex=20= bytevector-ieee-double-native-ref=20(sizeof=20double)))=0A=20=20=20=20=20= (,int8=20.=20,bytevector-s8-ref)=0A=20=20=20=20=20(,uint8=20.=20= ,bytevector-u8-ref)=0A=20=20=20=20=20(,int16=20.=20= ,bytevector-s16-native-ref)=0A--=20=0A2.30.2=0A=0A= --Apple-Mail=_B8174C50-5D5E-484B-A56B-318C5941C07F--