mirror of https://github.com/ecmwf/eccodes.git
Merge branch 'develop' into feature/memfs
This commit is contained in:
commit
16663de49a
52
.cproject
52
.cproject
|
@ -1,52 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
|
||||||
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.117388601">
|
|
||||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.117388601" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
|
||||||
<externalSettings/>
|
|
||||||
<extensions>
|
|
||||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
|
||||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
|
||||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
|
||||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
|
||||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
|
||||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
|
||||||
</extensions>
|
|
||||||
</storageModule>
|
|
||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
|
||||||
<configuration buildProperties="" id="cdt.managedbuild.toolchain.gnu.base.117388601" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
|
|
||||||
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.117388601.793025112" name="/" resourcePath="">
|
|
||||||
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1462179316" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
|
|
||||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.860211140" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
|
|
||||||
<builder id="cdt.managedbuild.target.gnu.builder.base.1272978155" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.base"/>
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1052361218" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.963458311" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1182912071" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
|
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.944880334" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
|
||||||
</tool>
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1829431036" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base">
|
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.619958332" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
|
||||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
|
||||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
|
||||||
</inputType>
|
|
||||||
</tool>
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1695886808" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.assembler.base.2103226257" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
|
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.742915453" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
|
||||||
</tool>
|
|
||||||
</toolChain>
|
|
||||||
</folderInfo>
|
|
||||||
</configuration>
|
|
||||||
</storageModule>
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
|
||||||
</cconfiguration>
|
|
||||||
</storageModule>
|
|
||||||
<storageModule moduleId="scannerConfiguration">
|
|
||||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
|
||||||
</storageModule>
|
|
||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
|
||||||
<project id="ecCodes.null.1772218298" name="ecCodes"/>
|
|
||||||
</storageModule>
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
|
||||||
</cproject>
|
|
|
@ -1,12 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<project>
|
|
||||||
<configuration id="cdt.managedbuild.toolchain.gnu.base.117388601" name="Default">
|
|
||||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
|
||||||
<provider class="org.eclipse.cdt.core.language.settings.providers.LanguageSettingsGenericProvider" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider" name="CDT User Setting Entries" prefer-non-shared="true"/>
|
|
||||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
|
||||||
<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
|
|
||||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" ref="shared-provider"/>
|
|
||||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
|
||||||
</extension>
|
|
||||||
</configuration>
|
|
||||||
</project>
|
|
|
@ -298,7 +298,7 @@ add_subdirectory( ifs_samples ) # must come after samples
|
||||||
ecbuild_dont_pack( DIRS
|
ecbuild_dont_pack( DIRS
|
||||||
concepts tests.ecmwf doxygen confluence examples.dev templates parameters java
|
concepts tests.ecmwf doxygen confluence examples.dev templates parameters java
|
||||||
gaussian_experimental gribex examples/F77
|
gaussian_experimental gribex examples/F77
|
||||||
examples/extra bamboo fortran/fortranCtypes tigge/tools share/eccodes grib_api_for_mars
|
examples/extra bamboo fortran/fortranCtypes tigge/tools share/eccodes
|
||||||
src/.deps tests/.deps tools/.deps tigge/.deps examples/C/.deps examples/python/.deps
|
src/.deps tests/.deps tools/.deps tigge/.deps examples/C/.deps examples/python/.deps
|
||||||
python/.deps fortran/.deps
|
python/.deps fortran/.deps
|
||||||
)
|
)
|
||||||
|
|
|
@ -384,3 +384,4 @@ uegabe.bufr.num.ref
|
||||||
syno.bufr.out.ref
|
syno.bufr.out.ref
|
||||||
airep.bufr.out.ref
|
airep.bufr.out.ref
|
||||||
new_replication.bufr.ref
|
new_replication.bufr.ref
|
||||||
|
get_string_array.ref
|
||||||
|
|
|
@ -38,7 +38,6 @@ do
|
||||||
tar="full_${files[i]}"
|
tar="full_${files[i]}"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
p4 edit ${files[i]}
|
|
||||||
if [[ ${precision[i]} -gt 0 ]]
|
if [[ ${precision[i]} -gt 0 ]]
|
||||||
then
|
then
|
||||||
grib_set -r -s bitsPerValue=0,decimalScaleFactor=${precision[i]} full_${files[i]} ${files[i]}
|
grib_set -r -s bitsPerValue=0,decimalScaleFactor=${precision[i]} full_${files[i]} ${files[i]}
|
||||||
|
@ -53,4 +52,3 @@ EOF
|
||||||
grib_dump ${grib2} > /dev/null
|
grib_dump ${grib2} > /dev/null
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,9 @@ prov=$1
|
||||||
dest=$2
|
dest=$2
|
||||||
|
|
||||||
mkdir -p $dest
|
mkdir -p $dest
|
||||||
p4 edit $dest/*.html
|
|
||||||
|
|
||||||
for file in $prov/*.html
|
for file in $prov/*.html
|
||||||
do
|
do
|
||||||
f=`basename $file`
|
f=`basename $file`
|
||||||
cat head.html $file tail.html > $dest/$f
|
cat head.html $file tail.html > $dest/$f
|
||||||
done
|
done
|
||||||
|
|
||||||
p4 add $dest/*.html
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
cd ../tools
|
cd ../tools
|
||||||
./make_dox.ksh
|
./make_dox.ksh
|
||||||
cd ../doxygen
|
cd ../doxygen
|
||||||
p4 edit ../html/*
|
|
||||||
rm -f ../html/*
|
rm -f ../html/*
|
||||||
touch ../html/Makefile.am
|
touch ../html/Makefile.am
|
||||||
doxygen grib_api_wiz.cfg
|
doxygen grib_api_wiz.cfg
|
||||||
|
|
|
@ -36,6 +36,7 @@ list( APPEND tests
|
||||||
bufr_clone
|
bufr_clone
|
||||||
bufr_expanded
|
bufr_expanded
|
||||||
bufr_get_keys
|
bufr_get_keys
|
||||||
|
bufr_get_string_array
|
||||||
bufr_keys_iterator
|
bufr_keys_iterator
|
||||||
bufr_read_header
|
bufr_read_header
|
||||||
bufr_read_scatterometer
|
bufr_read_scatterometer
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
!
|
||||||
|
!Copyright 2005-2016 ECMWF.
|
||||||
|
!
|
||||||
|
! This software is licensed under the terms of the Apache Licence Version 2.0
|
||||||
|
!which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
!
|
||||||
|
! In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
||||||
|
! virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
||||||
|
!
|
||||||
|
!
|
||||||
|
! FOTRAN 90 Implementation: bufr_get_string_array
|
||||||
|
!
|
||||||
|
! Description: how to get an array of strings from a BUFR message.
|
||||||
|
|
||||||
|
program bufr_get_string_array
|
||||||
|
use eccodes
|
||||||
|
implicit none
|
||||||
|
integer :: ifile
|
||||||
|
integer :: iret,i,n
|
||||||
|
integer :: ibufr
|
||||||
|
integer :: strsize
|
||||||
|
integer, parameter :: max_strsize = 20
|
||||||
|
character(len=max_strsize) , dimension(:),allocatable :: stationOrSiteName
|
||||||
|
|
||||||
|
call codes_open_file(ifile,'../../data/bufr/pgps_110.bufr','r')
|
||||||
|
|
||||||
|
call codes_bufr_new_from_file(ifile,ibufr,iret)
|
||||||
|
|
||||||
|
|
||||||
|
! unpack the data values
|
||||||
|
call codes_set(ibufr,'unpack',1)
|
||||||
|
call codes_get(ibufr,'stationOrSiteName->width',strsize)
|
||||||
|
strsize=strsize/8
|
||||||
|
if (strsize > max_strsize) then
|
||||||
|
print *,'stationOrSiteName array dimension is ',max_strsize,' and should be ',strsize
|
||||||
|
call exit(1)
|
||||||
|
end if
|
||||||
|
|
||||||
|
call codes_get_size(ibufr,'stationOrSiteName',n)
|
||||||
|
allocate(stationOrSiteName(n))
|
||||||
|
! passing an array of strings stationOrSiteName which must be allocated beforehand
|
||||||
|
call codes_get_string_array(ibufr,'stationOrSiteName',stationOrSiteName)
|
||||||
|
do i=1,n
|
||||||
|
write(*,'(A)')trim(stationOrSiteName(i))
|
||||||
|
end do
|
||||||
|
|
||||||
|
!remember to deallocate what was allocated by codes_get_string_array
|
||||||
|
deallocate(stationOrSiteName)
|
||||||
|
|
||||||
|
! release the bufr message
|
||||||
|
call codes_release(ibufr)
|
||||||
|
|
||||||
|
! close file
|
||||||
|
call codes_close_file(ifile)
|
||||||
|
|
||||||
|
|
||||||
|
end program bufr_get_string_array
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright 2005-2016 ECMWF.
|
||||||
|
#
|
||||||
|
# This software is licensed under the terms of the Apache Licence Version 2.0
|
||||||
|
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
#
|
||||||
|
# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
||||||
|
# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
||||||
|
|
||||||
|
. ./include.sh
|
||||||
|
set -x
|
||||||
|
#Define a common label for all the tmp files
|
||||||
|
label="bufr_get_string_array_test_f"
|
||||||
|
|
||||||
|
#Prepare tmp file
|
||||||
|
fTmp=${label}.tmp.txt
|
||||||
|
rm -f $fTmp | true
|
||||||
|
|
||||||
|
#-----------------------------------------------------
|
||||||
|
# Test get string array from a BUFR
|
||||||
|
#----------------------------------------------------
|
||||||
|
|
||||||
|
fRef=${data_dir}/bufr/get_string_array.ref
|
||||||
|
|
||||||
|
REDIRECT=/dev/null
|
||||||
|
|
||||||
|
#Write the values into a file and compare with reference
|
||||||
|
${examples_dir}/eccodes_f_bufr_get_string_array $f > $fTmp
|
||||||
|
|
||||||
|
#We compare output to the reference by ignoring the whitespaces
|
||||||
|
diff -w $fRef $fTmp
|
||||||
|
|
||||||
|
#cat $fRes
|
||||||
|
|
||||||
|
#Clean up
|
||||||
|
rm -f ${fTmp} | true
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -96,8 +96,8 @@
|
||||||
codes_get_real4, &
|
codes_get_real4, &
|
||||||
codes_get_real8, &
|
codes_get_real8, &
|
||||||
codes_get_string, &
|
codes_get_string, &
|
||||||
codes_get_int_array, &
|
|
||||||
codes_get_byte_array, &
|
codes_get_byte_array, &
|
||||||
|
codes_get_int_array, &
|
||||||
codes_get_real4_array, &
|
codes_get_real4_array, &
|
||||||
codes_get_real8_array
|
codes_get_real8_array
|
||||||
end interface codes_get
|
end interface codes_get
|
||||||
|
|
|
@ -100,8 +100,8 @@
|
||||||
codes_get_real4, &
|
codes_get_real4, &
|
||||||
codes_get_real8, &
|
codes_get_real8, &
|
||||||
codes_get_string, &
|
codes_get_string, &
|
||||||
codes_get_int_array, &
|
|
||||||
codes_get_byte_array, &
|
codes_get_byte_array, &
|
||||||
|
codes_get_int_array, &
|
||||||
codes_get_real4_array, &
|
codes_get_real4_array, &
|
||||||
codes_get_real8_array
|
codes_get_real8_array
|
||||||
end interface codes_get
|
end interface codes_get
|
||||||
|
|
|
@ -828,6 +828,43 @@ subroutine codes_get_string ( gribid, key, value, status )
|
||||||
call grib_get_string ( gribid, key, value, status )
|
call grib_get_string ( gribid, key, value, status )
|
||||||
end subroutine codes_get_string
|
end subroutine codes_get_string
|
||||||
|
|
||||||
|
subroutine codes_get_string_array ( gribid, key, value, status )
|
||||||
|
integer(kind=kindOfInt), intent(in) :: gribid
|
||||||
|
character(len=*), intent(in) :: key
|
||||||
|
character(len=*), dimension(:),allocatable,intent(inout) :: value
|
||||||
|
integer(kind=kindOfInt),optional, intent(out) :: status
|
||||||
|
|
||||||
|
character :: cvalue(size(value)*len(value(0)))
|
||||||
|
integer(kind=kindOfInt) :: iret
|
||||||
|
integer(kind=kindOfInt) :: nb_values
|
||||||
|
integer(kind=kindOfInt) :: slen
|
||||||
|
integer(kind=kindOfInt) :: i,s,j
|
||||||
|
|
||||||
|
if (allocated(value) .eqv. .false.) then
|
||||||
|
iret=CODES_NULL_POINTER
|
||||||
|
if (present(status)) then
|
||||||
|
status = iret
|
||||||
|
else
|
||||||
|
call grib_check(iret,'grib_get',key)
|
||||||
|
endif
|
||||||
|
end if
|
||||||
|
|
||||||
|
nb_values=size(value)
|
||||||
|
slen=len(value(0))
|
||||||
|
iret=grib_f_get_string_array ( gribid, key, cvalue , nb_values, slen )
|
||||||
|
value=transfer(cvalue,value)
|
||||||
|
|
||||||
|
if (iret /= 0) then
|
||||||
|
call grib_f_write_on_fail(gribid)
|
||||||
|
endif
|
||||||
|
if (present(status)) then
|
||||||
|
status = iret
|
||||||
|
else
|
||||||
|
call grib_check(iret,'grib_get',key)
|
||||||
|
endif
|
||||||
|
|
||||||
|
end subroutine codes_get_string_array
|
||||||
|
|
||||||
! Note: This function supports the allocatable array attribute
|
! Note: This function supports the allocatable array attribute
|
||||||
! -------------------------------------------------------------
|
! -------------------------------------------------------------
|
||||||
subroutine codes_get_int_array ( gribid, key, value, status )
|
subroutine codes_get_int_array ( gribid, key, value, status )
|
||||||
|
@ -926,7 +963,6 @@ subroutine codes_get_byte_array ( gribid, key, value, length, status )
|
||||||
integer(kind=kindOfInt), optional, intent(out) :: status
|
integer(kind=kindOfInt), optional, intent(out) :: status
|
||||||
integer(kind=kindOfInt) :: iret
|
integer(kind=kindOfInt) :: iret
|
||||||
integer(kind=kindOfInt) :: nb_values
|
integer(kind=kindOfInt) :: nb_values
|
||||||
character :: bytes(size(value))
|
|
||||||
|
|
||||||
call grib_get_byte_array ( gribid, key, value, length, status )
|
call grib_get_byte_array ( gribid, key, value, length, status )
|
||||||
end subroutine codes_get_byte_array
|
end subroutine codes_get_byte_array
|
||||||
|
@ -1144,7 +1180,6 @@ subroutine codes_set_byte_array ( gribid, key, value, length, status )
|
||||||
integer(kind=kindOfInt), optional, intent(out) :: status
|
integer(kind=kindOfInt), optional, intent(out) :: status
|
||||||
integer(kind=kindOfInt) :: iret
|
integer(kind=kindOfInt) :: iret
|
||||||
integer(kind=kindOfInt) :: nb_values
|
integer(kind=kindOfInt) :: nb_values
|
||||||
character :: bytes(size(value))
|
|
||||||
|
|
||||||
call grib_set_byte_array ( gribid, key, value, length, status )
|
call grib_set_byte_array ( gribid, key, value, length, status )
|
||||||
end subroutine codes_set_byte_array
|
end subroutine codes_set_byte_array
|
||||||
|
|
|
@ -32,7 +32,8 @@ integer, external :: grib_f_get_int, grib_f_get_long,grib_f_get_int_array, &
|
||||||
grib_f_get_real8, grib_f_get_real8_array, &
|
grib_f_get_real8, grib_f_get_real8_array, &
|
||||||
grib_f_get_real4_element, grib_f_get_real8_element, &
|
grib_f_get_real4_element, grib_f_get_real8_element, &
|
||||||
grib_f_get_real4_elements, grib_f_get_real8_elements, &
|
grib_f_get_real4_elements, grib_f_get_real8_elements, &
|
||||||
grib_f_get_string,grib_f_is_missing,grib_f_is_defined
|
grib_f_get_string,grib_f_get_string_array, &
|
||||||
|
grib_f_is_missing,grib_f_is_defined
|
||||||
integer, external :: grib_f_new_from_index, &
|
integer, external :: grib_f_new_from_index, &
|
||||||
grib_f_index_new_from_file, &
|
grib_f_index_new_from_file, &
|
||||||
grib_f_index_add_file, &
|
grib_f_index_add_file, &
|
||||||
|
|
|
@ -162,6 +162,16 @@ static void czstr_to_fortran(char* str,int len)
|
||||||
*p=' ';
|
*p=' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static void czstr_to_fortran_replace0(char* str,int len)
|
||||||
|
{
|
||||||
|
char *p,*end;
|
||||||
|
p=str; end=str+len-1;
|
||||||
|
while (p != end) {
|
||||||
|
if (*p=='\0') *p=' ';
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
static void fort_char_clean(char* str,int len)
|
static void fort_char_clean(char* str,int len)
|
||||||
{
|
{
|
||||||
char *p,*end;
|
char *p,*end;
|
||||||
|
@ -2697,6 +2707,43 @@ int grib_f_set_real8_array(int* gid, char* key, double *val, int* size, int len)
|
||||||
return grib_f_set_real8_array_( gid, key, val, size, len);
|
return grib_f_set_real8_array_( gid, key, val, size, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
int grib_f_get_string_array_(int* gid, char* key, char* val,int* nvals,int* slen,int len)
|
||||||
|
{
|
||||||
|
grib_handle *h = get_handle(*gid);
|
||||||
|
int err = GRIB_SUCCESS;
|
||||||
|
size_t i;
|
||||||
|
char buf[1024];
|
||||||
|
size_t lsize = *nvals;
|
||||||
|
char** cval=0;
|
||||||
|
char* p=val;
|
||||||
|
|
||||||
|
if(!h) return GRIB_INVALID_GRIB;
|
||||||
|
|
||||||
|
cval=(char**)grib_context_malloc_clear(h->context,sizeof(char*)*lsize);
|
||||||
|
err = grib_get_string_array(h, cast_char(buf,key,len), cval, &lsize);
|
||||||
|
if (err) return err;
|
||||||
|
|
||||||
|
if (strlen(cval[0])>*slen) err=GRIB_ARRAY_TOO_SMALL;
|
||||||
|
|
||||||
|
for (i=0;i<lsize;i++) {
|
||||||
|
strcpy(p,cval[i]);
|
||||||
|
czstr_to_fortran(p,*slen);
|
||||||
|
p+= *slen;
|
||||||
|
}
|
||||||
|
grib_context_free(h->context,cval);
|
||||||
|
/*remember to deallocate each string*/
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int grib_f_get_string_array__(int* gid, char* key, char* val,int* nvals,int* slen, int len){
|
||||||
|
return grib_f_get_string_array_( gid, key, val,nvals,slen,len);
|
||||||
|
}
|
||||||
|
int grib_f_get_string_array(int* gid, char* key, char* val,int* nvals,int* slen, int len){
|
||||||
|
return grib_f_get_string_array_( gid, key, val, nvals, slen, len);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int grib_f_get_string_(int* gid, char* key, char* val,int len, int len2){
|
int grib_f_get_string_(int* gid, char* key, char* val,int len, int len2){
|
||||||
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
# Copyright 2005-2016 ECMWF.
|
|
||||||
#
|
|
||||||
# This software is licensed under the terms of the Apache Licence Version 2.0
|
|
||||||
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
#
|
|
||||||
# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
|
||||||
# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
|
||||||
#
|
|
||||||
constant GRIBEXSection1Problem = 120 - section1Length ;
|
|
||||||
|
|
||||||
template mars_labeling "grib1/mars_labeling.def";
|
|
||||||
|
|
||||||
unsigned[1] yearOfReference = yearOfCentury : dump;
|
|
||||||
unsigned[1] monthOfReference = month : dump;
|
|
||||||
unsigned[1] dayOfReference = day : dump;
|
|
||||||
unsigned[1] hourOfReference = hour : dump;
|
|
||||||
unsigned[1] minuteOfReference = minute : dump;
|
|
||||||
unsigned[1] centuryOfReference = centuryOfReferenceTimeOfData : dump;
|
|
||||||
transient secondsOfReference = 0 ;
|
|
||||||
|
|
||||||
unsigned[1] numberOfForcasts=0 : dump;
|
|
||||||
unsigned[1] numberOfAnalysis=1 : dump;
|
|
||||||
|
|
||||||
if (numberOfForcasts) {
|
|
||||||
unsigned[3] forecastSteps[numberOfForcasts] : dump;
|
|
||||||
}
|
|
||||||
if (numberOfAnalysis) {
|
|
||||||
signed[3] analysisOffsets[numberOfAnalysis] : dump;
|
|
||||||
}
|
|
||||||
|
|
||||||
padto padding_local_35(offsetSection1 + 120);
|
|
||||||
|
|
||||||
meta dateOfReference g1date(centuryOfReference,yearOfReference,monthOfReference,dayOfReference) : dump;
|
|
||||||
meta timeOfReference time(hourOfReference,minuteOfReference,secondsOfReference) : dump;
|
|
||||||
|
|
||||||
if (indicatorOfTypeOfLevel==160) {
|
|
||||||
alias mars.levelist = level;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,160 +0,0 @@
|
||||||
# Copyright 2005-2016 ECMWF.
|
|
||||||
#
|
|
||||||
# This software is licensed under the terms of the Apache Licence Version 2.0
|
|
||||||
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
#
|
|
||||||
# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
|
||||||
# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
|
||||||
#
|
|
||||||
# START grib1::section
|
|
||||||
# SECTION 4, Binary data section
|
|
||||||
# Length of section
|
|
||||||
# (octets)
|
|
||||||
position offsetSection4;
|
|
||||||
|
|
||||||
# Due to a trick done by GRIBEX to support large GRIBs, we need a special treatment
|
|
||||||
# of the message length and of the section4 lenth, so instead of
|
|
||||||
# length[3] section4Length ;
|
|
||||||
# we get:
|
|
||||||
g1_section4_length[3] section4Length(totalLength);
|
|
||||||
|
|
||||||
meta section4Pointer section_pointer(offsetSection4,section4Length,4);
|
|
||||||
|
|
||||||
g1_half_byte_codeflag halfByte;
|
|
||||||
flags[1] dataFlag "grib1/11.table" = 0 : read_only;
|
|
||||||
signed[2] binaryScaleFactor = 0 : read_only,dump;
|
|
||||||
ibmfloat referenceValue : read_only,dump;
|
|
||||||
unsigned[1] bitsPerValue : dump ;
|
|
||||||
alias numberOfBitsContainingEachPackedValue = bitsPerValue;
|
|
||||||
|
|
||||||
meta referenceValueError reference_value_error(referenceValue,ibm);
|
|
||||||
|
|
||||||
flagbit sphericalHarmonics(dataFlag,7) : dump;
|
|
||||||
flagbit complexPacking(dataFlag,6) : dump;
|
|
||||||
flagbit integerPointValues(dataFlag,5) : dump;
|
|
||||||
flagbit additionalFlagPresent(dataFlag,4) : edition_specific,dump;
|
|
||||||
|
|
||||||
transient hideThis=0;
|
|
||||||
|
|
||||||
concept packingType {
|
|
||||||
#set uses the last one
|
|
||||||
#get returns the first match
|
|
||||||
"grid_simple" = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
|
|
||||||
"grid_ieee" = { sphericalHarmonics = 0; complexPacking = 0;
|
|
||||||
integerPointValues=1; additionalFlagPresent=1;}
|
|
||||||
"spectral_complex" = { sphericalHarmonics = 1; complexPacking = 1;
|
|
||||||
additionalFlagPresent = 0; }
|
|
||||||
"spectral_simple" = { sphericalHarmonics = 1; complexPacking = 0; additionalFlagPresent = 0;
|
|
||||||
representationMode=1;}
|
|
||||||
"spectral_ieee" = { sphericalHarmonics = 1; complexPacking = 1;
|
|
||||||
additionalFlagPresent = 0; hideThis=1; }
|
|
||||||
"grid_simple_matrix" = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 1;}
|
|
||||||
"grid_second_order" = { sphericalHarmonics = 0; complexPacking = 1; }
|
|
||||||
"grid_complex" = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
|
|
||||||
"grid_complex_spatial_differencing" = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
|
|
||||||
"grid_jpeg" = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
|
|
||||||
"grid_png" = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
|
|
||||||
"grid_simple_log_preprocessing"= { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
|
|
||||||
} : dump;
|
|
||||||
|
|
||||||
|
|
||||||
alias ls.packingType=packingType;
|
|
||||||
alias typeOfPacking=packingType;
|
|
||||||
|
|
||||||
if( binaryScaleFactor == -32767) {
|
|
||||||
constant dataRepresentationTemplateNumber = 0;
|
|
||||||
constant bitMapIndicator = 0;
|
|
||||||
# For grib 1 -> 2
|
|
||||||
position offsetBeforeData;
|
|
||||||
transient numberOfCodedValues=numberOfPoints;
|
|
||||||
meta values data_dummy_field(
|
|
||||||
section4Length,
|
|
||||||
offsetBeforeData,
|
|
||||||
offsetSection4,
|
|
||||||
unitsFactor,
|
|
||||||
unitsBias,
|
|
||||||
changingPrecision,
|
|
||||||
numberOfCodedValues,
|
|
||||||
bitsPerValue,
|
|
||||||
referenceValue,
|
|
||||||
binaryScaleFactor,
|
|
||||||
decimalScaleFactor,
|
|
||||||
halfByte,
|
|
||||||
packingType,
|
|
||||||
grid_ieee,precision,
|
|
||||||
missingValue,
|
|
||||||
numberOfPoints,
|
|
||||||
bitmap
|
|
||||||
) : dump;
|
|
||||||
} else {
|
|
||||||
template dataValues "grib1/data.[packingType:s].def";
|
|
||||||
}
|
|
||||||
|
|
||||||
position offsetAfterData;
|
|
||||||
|
|
||||||
transient dataLength=(offsetAfterData-offsetBeforeData)/8;
|
|
||||||
|
|
||||||
if (bitmapPresent==1) {
|
|
||||||
alias numberOfEffectiveValues=numberOfDataPoints;
|
|
||||||
} else {
|
|
||||||
alias numberOfEffectiveValues=numberOfCodedValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
_if (sphericalHarmonics) {
|
|
||||||
alias numberOfEffectiveValues=numberOfValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
#meta setDecimalPrecision suppressed(decimalPrecision,changeDecimalPrecision);
|
|
||||||
meta changeDecimalPrecision decimal_precision(bitsPerValue,decimalScaleFactor,changingPrecision,values) : edition_specific;
|
|
||||||
meta decimalPrecision decimal_precision(bitsPerValue,decimalScaleFactor,changingPrecision) : edition_specific;
|
|
||||||
alias setDecimalPrecision=changeDecimalPrecision;
|
|
||||||
|
|
||||||
meta bitsPerValueAndRepack bits_per_value(values,bitsPerValue) : edition_specific;
|
|
||||||
alias setBitsPerValue=bitsPerValueAndRepack;
|
|
||||||
|
|
||||||
meta scaleValuesBy scale_values(values,missingValue) : edition_specific;
|
|
||||||
meta offsetValuesBy offset_values(values,missingValue) : edition_specific;
|
|
||||||
|
|
||||||
concept gridType {
|
|
||||||
#set uses the last one
|
|
||||||
#get returns the first match
|
|
||||||
"regular_ll" = {dataRepresentationType = 0; sphericalHarmonics = 0; PLPresent=0;}
|
|
||||||
"reduced_ll" = {dataRepresentationType = 0; sphericalHarmonics = 0; PLPresent=1; Ni=missing(); }
|
|
||||||
"mercator" = {dataRepresentationType = 1; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"lambert" = {dataRepresentationType = 3; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"polar_stereographic" = {dataRepresentationType = 5; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"UTM" = {dataRepresentationType = 6; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"simple_polyconic" = {dataRepresentationType = 7; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"albers" = {dataRepresentationType = 8; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"miller" = {dataRepresentationType = 8; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"rotated_ll" = {dataRepresentationType = 10; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"stretched_ll" = {dataRepresentationType = 20; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"stretched_rotated_ll" = {dataRepresentationType = 30; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"regular_gg" = {dataRepresentationType = 4; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"rotated_gg" = {dataRepresentationType = 14; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"stretched_gg" = {dataRepresentationType = 24; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"stretched_rotated_gg" = {dataRepresentationType = 34; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"reduced_gg" = {dataRepresentationType = 4; sphericalHarmonics = 0;
|
|
||||||
PLPresent=1; numberOfPointsAlongAParallel = missing();
|
|
||||||
iDirectionIncrement = missing(); ijDirectionIncrementGiven=0;}
|
|
||||||
"sh" = {dataRepresentationType = 50; sphericalHarmonics = 1; PLPresent=0; }
|
|
||||||
"rotated_sh" = {dataRepresentationType = 60; sphericalHarmonics = 1; PLPresent=0; }
|
|
||||||
"stretched_sh" = {dataRepresentationType = 70; sphericalHarmonics = 1; PLPresent=0; }
|
|
||||||
"stretched_rotated_sh" = {dataRepresentationType = 80; sphericalHarmonics = 1; PLPresent=0; }
|
|
||||||
"space_view" = {dataRepresentationType = 90; sphericalHarmonics = 0; PLPresent=0; }
|
|
||||||
"unknown" = {PLPresent=0;}
|
|
||||||
"unknown_PLPresent" = {PLPresent=1;}
|
|
||||||
} : dump;
|
|
||||||
|
|
||||||
alias ls.gridType=gridType;
|
|
||||||
alias geography.gridType=gridType;
|
|
||||||
alias typeOfGrid=gridType;
|
|
||||||
|
|
||||||
meta getNumberOfValues size(values) : edition_specific,dump ;
|
|
||||||
|
|
||||||
padtoeven padding_sec4_1(offsetSection4,section4Length) ;
|
|
||||||
|
|
||||||
meta md5Section4 md5(offsetSection4,section4Length);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
if WITH_MARS_TESTS
|
|
||||||
TESTS = ls.sh
|
|
||||||
|
|
||||||
noinst_PROGRAMS =
|
|
||||||
|
|
||||||
LDADD = $(top_builddir)/src/libgrib_api.a $(EMOS_LIB)
|
|
||||||
|
|
||||||
INCLUDES = -I$(top_builddir)/src
|
|
||||||
|
|
||||||
EXTRA_DIST = $(TESTS)
|
|
||||||
|
|
||||||
endif
|
|
|
@ -1,50 +0,0 @@
|
||||||
# Copyright 2005-2016 ECMWF.
|
|
||||||
#
|
|
||||||
# This software is licensed under the terms of the Apache Licence Version 2.0
|
|
||||||
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
#
|
|
||||||
# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
|
||||||
# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
|
||||||
|
|
||||||
set -ea
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "TEST: $0"
|
|
||||||
|
|
||||||
data_dir=""
|
|
||||||
|
|
||||||
# save current working dir
|
|
||||||
save=`pwd`
|
|
||||||
|
|
||||||
if [ -z "${data_dir}" ]
|
|
||||||
then
|
|
||||||
cd ../
|
|
||||||
cpath=`pwd`
|
|
||||||
ECCODES_DEFINITION_PATH=$cpath/definitions
|
|
||||||
export ECCODES_DEFINITION_PATH
|
|
||||||
ECCODES_SAMPLES_PATH=$cpath/samples
|
|
||||||
export ECCODES_SAMPLES_PATH
|
|
||||||
tools_dir=$cpath/tools/
|
|
||||||
tigge_dir=$cpath/tigge/
|
|
||||||
data_dir=$cpath/data
|
|
||||||
test_dir=$cpath/tests
|
|
||||||
def_dir=$cpath/definitions
|
|
||||||
else
|
|
||||||
tools_dir=""
|
|
||||||
tigge_dir=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "${GRIB_API_INCLUDE}" ]
|
|
||||||
then
|
|
||||||
GRIB_API_INCLUDE=`pwd`/src
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "${GRIB_API_LIB}" ]
|
|
||||||
then
|
|
||||||
GRIB_API_LIB=`pwd`/src
|
|
||||||
fi
|
|
||||||
|
|
||||||
# go back to current working dir
|
|
||||||
cd $save
|
|
||||||
|
|
||||||
set -u
|
|
|
@ -1,60 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Copyright 2005-2016 ECMWF.
|
|
||||||
#
|
|
||||||
# This software is licensed under the terms of the Apache Licence Version 2.0
|
|
||||||
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
#
|
|
||||||
# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
|
||||||
# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
|
||||||
|
|
||||||
. ./include.sh
|
|
||||||
|
|
||||||
rm -f log | true
|
|
||||||
workdir=`pwd`
|
|
||||||
|
|
||||||
cd ${data_dir}
|
|
||||||
infile=regular_gaussian_model_level.grib1
|
|
||||||
|
|
||||||
${tools_dir}grib_ls -P count $infile > log
|
|
||||||
${tools_dir}grib_ls -p count,step $infile >> log
|
|
||||||
${tools_dir}grib_ls $infile >> log
|
|
||||||
${tools_dir}grib_ls -l 0,0,1 $infile >> log
|
|
||||||
${tools_dir}grib_get -l 0,0,1 $infile >> log
|
|
||||||
${tools_dir}grib_get -p count,step $infile >> log
|
|
||||||
${tools_dir}grib_get -P count $infile >> log
|
|
||||||
|
|
||||||
files=" reduced_gaussian_lsm.grib1
|
|
||||||
reduced_gaussian_model_level.grib1
|
|
||||||
reduced_gaussian_model_level.grib2
|
|
||||||
reduced_gaussian_pressure_level.grib1
|
|
||||||
reduced_gaussian_pressure_level.grib2
|
|
||||||
reduced_gaussian_pressure_level_constant.grib1
|
|
||||||
reduced_gaussian_pressure_level_constant.grib2
|
|
||||||
reduced_gaussian_sub_area.grib1
|
|
||||||
reduced_gaussian_sub_area.grib2
|
|
||||||
reduced_gaussian_surface.grib1
|
|
||||||
reduced_gaussian_surface.grib2
|
|
||||||
reduced_latlon_surface.grib1
|
|
||||||
reduced_latlon_surface.grib2
|
|
||||||
regular_gaussian_model_level.grib1
|
|
||||||
regular_gaussian_model_level.grib2
|
|
||||||
regular_gaussian_pressure_level.grib1
|
|
||||||
regular_gaussian_pressure_level.grib2
|
|
||||||
regular_gaussian_pressure_level_constant.grib1
|
|
||||||
regular_gaussian_pressure_level_constant.grib2
|
|
||||||
regular_gaussian_surface.grib1
|
|
||||||
regular_gaussian_surface.grib2
|
|
||||||
regular_latlon_surface.grib1
|
|
||||||
regular_latlon_surface.grib2
|
|
||||||
"
|
|
||||||
|
|
||||||
for file in $files
|
|
||||||
do
|
|
||||||
echo $file >> log
|
|
||||||
${tools_dir}grib_ls -l 40,28 $file | grep index | awk '{print $4;}' >> log
|
|
||||||
done
|
|
||||||
|
|
||||||
diff log ls.log
|
|
||||||
rm -f log
|
|
||||||
|
|
||||||
cd $workdir
|
|
|
@ -490,6 +490,7 @@ static grib_darray* decode_double_array(grib_context* c,unsigned char* data,long
|
||||||
} else {
|
} else {
|
||||||
dval=localReference*modifiedFactor;
|
dval=localReference*modifiedFactor;
|
||||||
}
|
}
|
||||||
|
grib_context_log(c, GRIB_LOG_DEBUG," modifiedWidth=%ld lval=%ld dval=%g", modifiedWidth,lval,dval);
|
||||||
grib_darray_push(c,ret,dval);
|
grib_darray_push(c,ret,dval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,6 @@ static void init_class(grib_iterator_class* c)
|
||||||
|
|
||||||
static int next(grib_iterator* i, double *lat, double *lon, double *val)
|
static int next(grib_iterator* i, double *lat, double *lon, double *val)
|
||||||
{
|
{
|
||||||
|
|
||||||
grib_iterator_lambert_conformal* self = (grib_iterator_lambert_conformal*)i;
|
grib_iterator_lambert_conformal* self = (grib_iterator_lambert_conformal*)i;
|
||||||
|
|
||||||
if((long)i->e >= (long)(i->nv-1))
|
if((long)i->e >= (long)(i->nv-1))
|
||||||
|
@ -208,7 +207,8 @@ static int init(grib_iterator* iter,grib_handle* h,grib_arguments* args)
|
||||||
x0 = rho * sin(angle);
|
x0 = rho * sin(angle);
|
||||||
y0 = rho0 - rho * cos(angle);
|
y0 = rho0 - rho * cos(angle);
|
||||||
Dx = iScansNegatively == 0 ? Dx : -Dx;
|
Dx = iScansNegatively == 0 ? Dx : -Dx;
|
||||||
Dy = jScansPositively == 1 ? Dy : -Dy;
|
/* GRIB-405: Don't change sign of Dy. Latitudes ALWAYS increase from latitudeOfFirstGridPoint */
|
||||||
|
/*Dy = jScansPositively == 1 ? Dy : -Dy;*/
|
||||||
|
|
||||||
/* No support (yet) for jPointsAreConsecutive */
|
/* No support (yet) for jPointsAreConsecutive */
|
||||||
if (jPointsAreConsecutive) {
|
if (jPointsAreConsecutive) {
|
||||||
|
@ -271,4 +271,3 @@ static int destroy(grib_iterator* i)
|
||||||
grib_context_free(c,self->lons);
|
grib_context_free(c,self->lons);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,30 +3,26 @@ set -ex
|
||||||
set -A tools grib_dump grib_ls grib_get grib_copy grib_set grib_filter grib_compare grib_get_data grib_keys grib_index_build
|
set -A tools grib_dump grib_ls grib_get grib_copy grib_set grib_filter grib_compare grib_get_data grib_keys grib_index_build
|
||||||
export DOXYGEN_USAGE=1
|
export DOXYGEN_USAGE=1
|
||||||
|
|
||||||
p4 edit tools.dox
|
|
||||||
|
|
||||||
cat tools_head.dox > tools.dox
|
cat tools_head.dox > tools.dox
|
||||||
|
|
||||||
for tool in ${tools[@]}
|
for tool in ${tools[@]}
|
||||||
do
|
do
|
||||||
p4 edit ${tool}.dox
|
set +e
|
||||||
|
|
||||||
set +e
|
|
||||||
./$tool > ${tool}.dox
|
./$tool > ${tool}.dox
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
cat >> ${tool}.dox <<EOF
|
cat >> ${tool}.dox <<EOF
|
||||||
|
|
||||||
\section ${tool}_examples ${tool} examples
|
\section ${tool}_examples ${tool} examples
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
./${tool}.sh >> ${tool}.dox
|
./${tool}.sh >> ${tool}.dox
|
||||||
|
|
||||||
cat >> ${tool}.dox <<EOF
|
cat >> ${tool}.dox <<EOF
|
||||||
*/
|
*/
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat >> tools.dox <<EOF
|
cat >> tools.dox <<EOF
|
||||||
- \ref ${tool}
|
- \ref ${tool}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue