2
/* $Header: /cvsroot/nco/nco/src/nco++/ncoGrammer.g,v 1.191 2012/02/13 17:42:00 hmb Exp $ */
2
/* $Header: /cvsroot/nco/nco/src/nco++/ncoGrammer.g,v 1.205 2014/02/17 23:12:39 zender Exp $ */
4
4
/* Purpose: ANTLR Grammar and support files for ncap2 */
6
/* Copyright (C) 2005--2012 Charlie Zender
6
/* Copyright (C) 2005--2012 Henry Butowsky and Charlie Zender
7
7
License: GNU General Public License (GPL) Version 3
8
8
See http://www.gnu.org/copyleft/gpl.html for full license text */
10
10
// C Standard Headers
11
11
#include <assert.h>
15
15
#if !(defined __xlC__) && !(defined SGIMP64) // C++ compilers that do not allow stdint.h
16
16
#include <stdint.h> // Required by g++ for LLONG_MAX, ULLONG_MAX, by icpc for int64_t
73
73
ATAN2; //Used indirectly
75
75
MISS2ZERO; //used only in VarOp -sets all missing values to zero
76
VSORT; // only used outside of grammer to sort in VarOp
76
VSORT; // ascending sort only used outside of grammer to sort in VarOp
77
VRSORT; // reverse sort only used outside of grammer to sort in VarOp
77
78
VABS; // imaginary token used in VarOp to return absolute value
78
79
VSQR2; // imaginary token used in VarOp to return square of number
84
84
std::vector<std::string> inc_vtr;
124
123
| PRINT^ LPAREN! (VAR_ID|ATT_ID|NSTRING) (COMMA! NSTRING)? RPAREN! SEMI!
132
128
// a bracketed block
134
130
LCURL! (statement)* RCURL!
135
131
{ #block = #( [BLOCK, "block"], #block ); }
140
135
FOR^ LPAREN! (e1:expr)? SEMI! (e2:expr)? SEMI! (e3:expr)? RPAREN! st:statement
141
136
/* { if(#e1==NULL) #e1 = #([ NULL_NODE, "null_stmt"]);
149
143
lmt: (expr)? (COLON (expr)?)*
150
144
{ #lmt = #( [LMT, "lmt"], #lmt ); }
155
147
lmt_list: LPAREN! lmt (COMMA! lmt)* RPAREN!
156
148
{ #lmt_list = #( [LMT_LIST, "lmt_list"], #lmt_list ); }
160
151
// Use vars in dimension list so dims in [] can
161
152
// be used with or with out $ prefix. ie "$lon" or "lon"
162
153
// So parser is compatible with ncap1
497
462
// Whitespace -- ignored
498
463
WS options {paraphrase="white space"; }
499
464
: ( ' ' |'\t' { tab(); } | '\f' |'\n' { newline(); })
500
465
{ $setType(antlr::Token::SKIP);}
505
468
CXX_COMMENT options {paraphrase="a C++-style comment"; }
506
469
: "//" (~'\n')* '\n'
507
470
{ $setType(antlr::Token::SKIP); newline(); }
511
473
C_COMMENT options {paraphrase="a C-style comment"; }
522
484
// Numbers like .123, .2e3 ,.123f, 0.23d
523
485
// csz: Treat "l" or "L" following decimal point as "long double" as per C++
524
486
NUMBER_DOT options {paraphrase="a floating point number"; }
526
488
'.' (DGT)+ (XPN)? { $setType(DOUBLE); }
527
489
( ('D'|'d')! { $setType(DOUBLE);}
528
490
|('F'|'f')! { $setType(FLOAT);}
553
513
// Return var or att (var_nm@att_nm)
554
VAR_ATT options {testLiterals=true; paraphrase="variable or attribute identifier"; }
514
VAR_ATT options {testLiterals=true; paraphrase="variable or function or attribute identifier"; }
557
// check function/method vector
558
if( std::binary_search(prs_arg->fmc_vtr.begin(),prs_arg->fmc_vtr.end(),fmc_cls($getText)))
517
// try to intelligently guess the type to avoid un-necessary function search
536
string fnc_nm=$getText;
537
std::vector<fmc_cls>::iterator we=std::lower_bound(prs_arg->fmc_vtr.begin(),prs_arg->fmc_vtr.end(),fmc_cls(fnc_nm));
538
if(we!=prs_arg->fmc_vtr.end() && we->fnm()==fnc_nm){
539
int idx=we-prs_arg->fmc_vtr.begin();
541
sprintf(buff,"%d",idx);
542
// VERY IMPORTANT - append the index in fmc_vtr to the function name - (name#idx)
543
$setText(fnc_nm+"#"+buff);
564
548
('@'(LPH)(LPH|DGT)* {$setType(ATT_ID); })?
568
551
// Return a quoted var or att (var_nm@att_nm)
569
552
VAR_ATT_QT :( '\''!)
595
// Shorthand for naming dims in method e.g $0,$1, $2 etc
573
// Shorthand for naming dims in method e.g., $0,$1, $2 etc
597
575
options{paraphrase="dimension identifier";}
603
580
options{paraphrase="a string";}
604
581
: '"'! ( ~('"'|'\n'))* '"'!
769
735
lmt_sct *lmt_ptr;
772
738
vector<ast_lmt_sct> ast_lmt_vtr;
775
740
// populate ast_lmt_vtr
776
741
nbr_dmn=lmt_init(lmt,ast_lmt_vtr);
778
743
for(idx=0 ; idx <nbr_dmn ; idx++){
781
lcl_ind[0]=-2; lcl_ind[1]=-2; lcl_ind[2]=0;
783
for(jdx=0 ; jdx <3 ; jdx++){
785
aRef=ast_lmt_vtr[idx].ind[jdx];
788
continue; //do nothing - use default lcl_ind values
789
else if( aRef->getType() == COLON){
790
if(jdx <2) lcl_ind[jdx]=-1;
792
// Calculate number using out()
795
// convert result to type int
796
var_out=nco_var_cnf_typ(NC_INT,var_out);
797
(void)cast_void_nctype((nc_type)NC_INT,&var_out->val);
799
// only interested in the first value.
800
lcl_ind[jdx]=var_out->val.ip[0];
802
var_out=nco_var_free(var_out);
806
745
// fill out lmt structure
807
746
// use same logic as nco_lmt_prs
808
747
lmt_ptr=(lmt_sct*)nco_calloc((size_t)1,sizeof(lmt_sct));
810
748
lmt_ptr->nm=NULL;
811
749
//lmt_ptr->lmt_typ=-1;
812
750
lmt_ptr->is_usr_spc_lmt=True; /* True if any part of limit is user-specified, else False */
815
753
lmt_ptr->srd_sng=NULL;
816
754
lmt_ptr->is_usr_spc_min=False;
817
755
lmt_ptr->is_usr_spc_max=False;
819
/* rec_skp_nsh_spf is used for record dimension in multi-file operators */
820
lmt_ptr->rec_skp_nsh_spf=0L; /* Number of records skipped in initial superfluous files */
822
/* Fill-in structure */
823
if( lcl_ind[0] >= 0){
824
lmt_ptr->is_usr_spc_min=True;
825
lmt_ptr->srt=lcl_ind[0];
828
/* Fill-in structure */
829
if( lcl_ind[1] >= 0) {
830
lmt_ptr->is_usr_spc_max=True;
831
lmt_ptr->end=lcl_ind[1];
834
/* Fill-in structure */
835
if( lcl_ind[2] > 0) {
836
lmt_ptr->srd_sng=strdup("~fill_in");
837
lmt_ptr->srd=lcl_ind[2];
756
/* rec_skp_ntl_spf is used for record dimension in multi-file operators */
757
lmt_ptr->rec_skp_ntl_spf=0L; /* Number of records skipped in initial superfluous files */
759
for(jdx=0 ; jdx <3 ; jdx++){
763
aRef=ast_lmt_vtr[idx].ind[jdx];
765
if(aRef && aRef->getType() != COLON ){
766
// Calculate number using out()
768
// convert result to type int
769
var_out=nco_var_cnf_typ(NC_INT,var_out);
770
(void)cast_void_nctype((nc_type)NC_INT,&var_out->val);
771
// only interested in the first value.
772
ldx=var_out->val.ip[0];
773
var_out=nco_var_free(var_out);
775
// switch jdx 0-srt,1-end,2-srd
778
lmt_ptr->is_usr_spc_min=True;
782
lmt_ptr->is_usr_spc_max=True;
786
lmt_ptr->srd_sng=strdup("~fill_in");
840
793
/* need to deal with situation where only start is defined -- ie picking only a single value */
841
if(lcl_ind[0] >=0 && lcl_ind[1]==-2){
842
lmt_ptr->is_usr_spc_max=True;
843
lmt_ptr->end=lcl_ind[0];
794
if( lmt_ptr->is_usr_spc_min==True && lmt_ptr->is_usr_spc_max==False && lmt_ptr->srd_sng==NULL){
795
lmt_ptr->is_usr_spc_max=True;
796
lmt_ptr->end=lmt_ptr->srt;
846
799
lmt_vtr.push_back(lmt_ptr);
850
803
} /* end lmt_mk */
1254
1193
std::string va_nm(pvid->getText());
1258
1196
if(prs_arg->ntl_scn) goto end2;
1259
1197
Nvar=prs_arg->var_vtr.find(va_nm);
1262
1199
if(Nvar && Nvar->flg_mem){
1263
1200
wrn_prn(fnc_nm,"Cannot print out RAM variables at the moment!");
1291
1228
(void)nco_prn_var_val_lmt(fl_id,va_nm.c_str(),(lmt_sct*)NULL,0L,fmt_sng,prs_arg->FORTRAN_IDX_CNV,False,False);
1293
1230
if(fmt_sng) fmt_sng=(char*)nco_free(fmt_sng);
1299
1234
| (#(PRINT ATT_ID))=> #(PRINT patt:ATT_ID){
1358
1293
prn_sng=strdup(pstr->getText().c_str());
1359
1294
(void)sng_ascii_trn(prn_sng);
1361
fprintf(stdout,prn_sng);
1296
fprintf(stdout,"%s",prn_sng);
1362
1297
prn_sng=(char*)nco_free(prn_sng);
1381
1315
var_nm=vid->getText();
1385
if(dbg_lvl_get() > 0)
1386
dbg_prn(fnc_nm,var_nm+"(limits)");
1317
if(nco_dbg_lvl_get() >= nco_dbg_scl) dbg_prn(fnc_nm,var_nm+"(limits)");
1388
1319
// evaluate rhs for side effects eg new dims or lvalues
1389
1320
var_rhs=out(vid->getNextSibling());
1390
1321
var_rhs=nco_var_free(var_rhs);
1393
1323
var_lhs=prs_arg->ncap_var_init(var_nm,false);
1395
1325
var=nco_var_dpl(var_lhs);
1396
1326
(void)prs_arg->ncap_var_write(var_lhs,bram);
1399
1328
// set var to udf
1400
1329
var_lhs=ncap_var_udf(var_nm.c_str());
1401
1330
var=nco_var_dpl(var_lhs);
1457
1381
var_cst=nco_var_cnf_typ(var1->type,var_cst);
1458
1382
var_cst->typ_dsk=var1->type;
1459
1383
var=nco_var_dpl(var_cst);
1462
1385
var1=nco_var_free(var1);
1467
1389
var1=ncap_var_udf(var_nm.c_str());
1468
1390
Nvar=new NcapVar(var1);
1573
1487
var_nm=vid->getText();
1575
if(dbg_lvl_get() > 0)
1576
dbg_prn(fnc_nm,var_nm+"(limits)");
1489
if(nco_dbg_lvl_get() >= nco_dbg_var) dbg_prn(fnc_nm,var_nm+"(limits)");
1579
1491
// check to see if we are dealing with a single
1580
1492
// index in limit -- i.e hyperslab a mult-dimensional var
1624
1532
if( lmt_mk(lmt_Ref,lmt_vtr) == 0)
1625
1533
err_prn(fnc_nm,"Invalid hyperslab limits for variable "+ var_nm);
1628
1535
if( lmt_vtr.size() != nbr_dmn)
1629
1536
err_prn(fnc_nm,"Number of hyperslab limits for variable "+ var_nm+" doesn't match number of dimensions");
1632
1538
// add dim names to dimension list
1633
1539
for(idx=0 ; idx < nbr_dmn;idx++)
1634
1540
lmt_vtr[idx]->nm=strdup(var_lhs->dim[idx]->nm);
1638
1543
// fill out limit structure
1650
1555
if(var_rhs->sz == 1)
1651
1556
(void)ncap_att_stretch(var_rhs,slb_sz);
1654
1558
// make sure var_lhs and var_rhs are the same size
1655
1559
// and that they are the same shape (ie they conform!!)
1656
1560
if(var_rhs->sz != slb_sz){
1660
1564
(void)nco_put_var_mem(var_rhs,var_lhs,lmt_vtr);
1662
1566
(void)prs_arg->ncap_var_write(var_lhs,true);
1666
1568
// deal with Regular Vars
1670
1571
// if var undefined in O or defined but not populated
1671
1572
if(!Nvar || ( Nvar && Nvar->flg_stt==1)){
1672
1573
// if var isn't in ouptut then copy it there
1689
1590
if( lmt_mk(lmt_Ref,lmt_vtr) == 0)
1690
1591
err_prn(fnc_nm,"Invalid hyperslab limits for variable "+ var_nm);
1693
1593
if( lmt_vtr.size() != nbr_dmn)
1694
1594
err_prn(fnc_nm,"Number of hyperslab limits for variable "+ var_nm+" doesn't match number of dimensions");
1697
1596
// add dim names to dimension list
1698
1597
for(idx=0 ; idx < nbr_dmn;idx++)
1699
1598
lmt_vtr[idx]->nm=strdup(var_lhs->dim[idx]->nm);
1703
1601
// fill out limit structure
1777
1668
var_nm=vid1->getText();
1779
if(dbg_lvl_get() > 0)
1780
dbg_prn(fnc_nm,var_nm+"[dims]");
1670
if(nco_dbg_lvl_get() >= nco_dbg_var) dbg_prn(fnc_nm,var_nm+"[dims]");
1783
1672
// set class wide variables
1785
1674
var_cst=NULL_CEWI;
1788
1676
//aRef=vid->getFirstChild()->getFirstChild();
1789
1677
aRef=dmn->getFirstChild();
1806
1694
// If the RHS has size one or is an attribute or an irregular hyperslab
1807
1695
// then we neet to use the var_cst as the shape of the written variable.
1808
1696
// It is possible for the cast on the LHS to have a size of one and the RHS
1809
// to have a size of one e.g if the dim(s) in the list have a size of one
1697
// to have a size of one e.g., if the dim(s) in the list have a size of one
1810
1698
bool br1=(var_cst->sz >=1 && var1->sz==1);
1811
1699
bool br2=(var_cst->sz==var1->sz && ( ncap_var_is_att(var1) ||var1->has_dpl_dmn==-1 ));
1815
1701
// The code rebuilds var1 with the shape from the casting variable
1816
1702
if( br1 || br2){
1833
1719
//blow out if vars not the same size
1834
1720
if(var1->sz != var_cst->sz)
1835
err_prn(fnc_nm, "LHS cast for "+var_nm+" - cannot make RHS "+ std::string(var1->nm) + " conform.");
1721
err_prn(fnc_nm, "LHS cast for "+var_nm+" - cannot make RHS "+ std::string(var1->nm) + " conform.");
1837
1722
var1->nm=(char*)nco_free(var1->nm);
1839
1723
var1->nm =strdup(var_nm.c_str());
1843
1725
// See If we have to return something
1844
1726
if(dmn->getNextSibling() && dmn->getNextSibling()->getType()==NORET)
1847
1729
var=nco_var_dpl(var1);
1851
1731
//call to nco_var_get() in ncap_var_init() uses this property
1852
1732
var1->typ_dsk=var1->type;
1853
1733
(void)prs_arg->ncap_var_write(var1,bram);
1907
1783
(void)prs_arg->ncap_var_write(var1,bram);
1908
1784
//(void)ncap_var_write_omp(var1,bram,prs_arg);
1911
1786
// See If we have to return something
1912
1787
if(vid2->getFirstChild() && vid2->getFirstChild()->getType()==NORET)
1915
1790
var=prs_arg->ncap_var_init(var_nm,true); ;
1918
1792
} // end action
1950
1823
NcapVar *Nvar=new NcapVar(var1,sa);
1951
1824
prs_arg->var_vtr.push_ow(Nvar);
1954
1826
// See If we have to return something
1955
1827
if(att2->getFirstChild() && att2->getFirstChild()->getType()==NORET)
1996
1867
{var=ncap_var_var_op(var1,var2, MOD);}
1997
1868
| #(CARET var1=out var2=out)
1998
1869
{var=ncap_var_var_op(var1,var2, CARET);}
2000
1870
//unary Operators
2001
1871
| #(LNOT var1=out )
2002
1872
{ var=ncap_var_var_op(var1,NULL_CEWI, LNOT );}
2015
1885
| #(POST_DEC var1=out_asn ){
2016
1886
var=ncap_var_var_inc(var1,NULL_CEWI,POST_DEC,false,prs_arg);
2019
1888
// Logical Operators
2020
1889
| #(LAND var1=out var2=out)
2021
1890
{ var=ncap_var_var_op(var1,var2, LAND );}
2034
1903
{ var=ncap_var_var_op(var1,var2, EQ );}
2035
1904
| #(NEQ var1=out var2=out)
2036
1905
{ var=ncap_var_var_op(var1,var2, NEQ );}
2038
1906
// Fortran style Comparison Operators
2039
1907
| #(FLTHAN var1=out var2=out)
2040
1908
{ var=ncap_var_var_op(var1,var2, FLTHAN );}
2041
1909
| #(FGTHAN var1=out var2=out)
2042
1910
{ var=ncap_var_var_op(var1,var2, FGTHAN );}
2044
1911
// Assign Operators
2045
1912
| #(PLUS_ASSIGN pls_asn:. var2=out) {
2046
1913
var1=out_asn(pls_asn);
2119
1983
var1=nco_var_free(var1);
2124
1987
| #(m:FUNC args:FUNC_ARG) {
2126
std::string sfnm(m->getText());
2127
std::vector<fmc_cls>::iterator we=std::lower_bound(prs_arg->fmc_vtr.begin(),prs_arg->fmc_vtr.end(),fmc_cls(sfnm));
2128
// see if string found
2129
if( we->fnm() == sfnm){
2131
var=we->vfnc()->fnd(tr ,args, *we,*this);
2133
std::cout << "Function " << sfnm << " not found" <<std::endl;
1988
// The lexer has appended the index of the function to the function name m - (name#index)
1989
// the index is into fmc_vtr
1990
string sm(m->getText());
1991
string sdx(sm,sm.find("#")+1,sm.length()-1) ;
1992
int idx=atoi(sdx.c_str());
1994
var=prs_arg->fmc_vtr[idx].vfnc()->fnd(tr ,args, prs_arg->fmc_vtr[idx],*this);
2138
1997
// Deal with methods
2139
1998
| #(DOT mtd:. mfnc:FUNC margs:FUNC_ARG ){
2140
std::string sfnm(mfnc->getText());
2141
std::vector<fmc_cls>::iterator we=std::lower_bound(prs_arg->fmc_vtr.begin(),prs_arg->fmc_vtr.end(),fmc_cls(sfnm));
2142
// see if string found
2143
if( we->fnm() == sfnm){
2145
var=we->vfnc()->fnd(mtd ,margs, *we,*this);
2147
std::cout << "Method " << sfnm << " not found" <<std::endl;
1999
// The lexer has appended the index of the function to the function name m - (name#index)
2000
// the index is into fmc_vtr
2001
string sm(mfnc->getText());
2002
string sdx(sm,sm.find("#")+1,sm.length()-1) ;
2003
int idx=atoi(sdx.c_str());
2004
var=prs_arg->fmc_vtr[idx].vfnc()->fnd(mtd ,margs, prs_arg->fmc_vtr[idx],*this);
2152
2007
| dval:DIM_ID_SIZE
2313
2160
var->val.sngp[0]=strdup(tsng);
2315
2162
(void)cast_nctype_void((nc_type)NC_STRING,&var->val);
2319
2164
tsng=(char*)nco_free(tsng);
2324
2167
// Naked numbers: Cast is not applied to these numbers
2325
2168
| val_float:FLOAT
2326
2169
{if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~float"),(nc_type)NC_FLOAT,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~float"),static_cast<float>(std::strtod(val_float->getText().c_str(),(char **)NULL)));} // end FLOAT
2417
2257
// if att not found return undefined
2418
2258
if(prs_arg->ntl_scn && var==NULL_CEWI )
2419
2259
var=ncap_var_udf(att->getText().c_str());
2422
2261
if(prs_arg->ntl_scn && var->val.vp !=NULL)
2423
2262
var->val.vp=(void*)nco_free(var->val.vp);
2430
2267
value_list returns [var_sct *var]
2432
2269
const std::string fnc_nm("value_list");
2514
2348
cp=(char*)(var_ret->val.vp)+ (ptrdiff_t)(idx*tsz);
2515
2349
memcpy(cp,exp_vtr[idx]->val.vp,tsz);
2520
2353
end_val: for(idx=0 ; idx < nbr_lst ; idx++)
2521
2354
(void)nco_var_free(exp_vtr[idx]);
2566
2392
for(idx=0; idx<nbr_lst ; idx++)
2567
2393
if( exp_vtr[idx]->type != NC_STRING)
2568
2394
err_prn(fnc_nm," error processing value list string: to successfully parse value list of strings all elements must be of type NC_STRING");
2571
2396
// from here on deal with final scan
2572
2397
tsz=nco_typ_lng((nc_type)NC_STRING);
2573
2398
var_ret->val.vp=(void*)nco_malloc(nbr_lst*tsz);
2576
2400
(void)cast_void_nctype((nc_type)NC_STRING,&var_ret->val);
2577
2401
cp=var_ret->val.sngp;
2735
2554
prs_arg->ncap_var_write(var_lhs,false);
2742
2559
//Calculate scalar hyperslab where there is a single limit for a possibly
2743
2560
// multi-dimensional variable
2744
2561
var_lmt_one returns [var_sct *var]
2787
2601
srt=var_nbr->val.ip[0];
2788
2602
(void)cast_nctype_void(NC_INT,&var_nbr->val);
2791
2604
// fortran index convention
2792
2605
if(prs_arg->FORTRAN_IDX_CNV)
2608
srt+=var_rhs->sz-1; // deal with negative index
2795
2610
// do some bounds checking
2796
2611
if(srt >= var_rhs->sz || srt<0 )
2797
2612
err_prn(fnc_nm,"Limit of "+ nbr2sng(srt) +" for variable \""+ var_nm+"\" with size="+nbr2sng(var_rhs->sz)+" is out of bounds\n");
2845
2659
// copy missing value if any over
2846
2660
nco_mss_val_cp(var_rhs,var);
2849
2662
} // end else !prs_arg->ntl_scn
2854
2664
end0: var_nbr=nco_var_free(var_nbr);
2855
2665
var_rhs=nco_var_free(var_rhs);
2863
2669
//Calculate scalar LHS hyperslab where there is a single limit for a possibly
2864
2670
// multi-dimensional variable
2865
2671
var_lmt_one_lhs[bool bram] returns [var_sct *var]
2879
2685
var_sct *var_lhs=NULL_CEWI;
2880
2686
var_sct *var_rhs=NULL_CEWI;
2884
2689
var_nm=vid->getText();
2886
if(dbg_lvl_get() > 1)
2887
dbg_prn(fnc_nm,var_nm+"(limit)");
2691
if(nco_dbg_lvl_get() > nco_dbg_var) dbg_prn(fnc_nm,var_nm+"(limit)");
2889
2693
Nvar=prs_arg->var_vtr.find(var_nm);
2894
2698
srt=var_nbr->val.ip[0];
2895
2699
(void)cast_nctype_void(NC_INT,&var_nbr->val);
2897
// fortran index convention
2898
if(prs_arg->FORTRAN_IDX_CNV)
2903
2701
// Overwrite bram possibly
2905
2703
bram=Nvar->flg_mem;
2908
2705
// Deal with RAM variables
2926
2723
var_lhs=prs_arg->ncap_var_init(var_nm,true);
2726
// fortran index convention
2727
if(prs_arg->FORTRAN_IDX_CNV)
2729
else if(srt<0) srt+=var_lhs->sz-1; //deal with negative index convention
2930
2731
// do some bounds checking on single limits
2931
2732
if(srt >= var_lhs->sz || srt<0 )
2932
2733
err_prn(fnc_nm,"Limit of "+ nbr2sng(srt) +" for variable \""+ var_nm+"\" with size="+nbr2sng(var_lhs->sz)+" is out of bounds\n");
2966
2765
var_lhs=prs_arg->ncap_var_init(var_nm,false);
2767
// fortran index convention
2768
if(prs_arg->FORTRAN_IDX_CNV)
2770
else if(srt<0) srt+=var_lhs->sz-1; //deal with negative index convention
2969
2772
// do some bounds checking on single limits
2970
2773
if(srt >= var_lhs->sz || srt<0 )
2999
2802
srt1[idx]=srt/sz_dim;
3000
2803
srt-=srt1[idx]*sz_dim;
3004
2806
for(idx=0;idx<nbr_dim;idx++){
3005
2807
var_lhs->srt[idx]=srt1[idx];
3006
2808
var_lhs->cnt[idx]=1L;
3007
2809
var_lhs->srd[idx]=1L;
3008
2810
} /* end loop over idx */
3011
2812
// write slab to O contains call to Open MP critical region
3012
2813
// routine also frees up var_lhs
3045
2844
NcapVector<lmt_sct*> lmt_vtr;
3046
2845
NcapVector<dmn_sct*> dmn_vtr;
3047
2846
NcapVector<std::string> dmn_nrm_vtr; // list of dimension names
3050
2848
var_nm=vid->getText();
3051
2849
var_rhs=prs_arg->ncap_var_init(var_nm,false);
3079
2876
if( lmt_vtr.size() != nbr_dmn)
3080
2877
err_prn(fnc_nm,"Number of hyperslab limits for variable "+ var_nm+" doesn't match number of dimensions");
3083
2879
// add dim names to dimension list
3084
2880
for(idx=0 ; idx < nbr_dmn;idx++)
3088
2884
for(idx=0 ; idx < nbr_dmn ;idx++)
3089
2885
(void)ncap_lmt_evl(var_rhs->nc_id,lmt_vtr[idx],prs_arg);
3092
2887
// See if var can be normalized
3093
2888
for(idx=0; idx<nbr_dmn ; idx++){
3094
2889
if(lmt_vtr[idx]->cnt==1) continue;
3118
2911
// apply LHS cast if necessary
3119
2912
if(var->sz>1 && bcst)
3120
2913
var=ncap_cst_do(var,var_cst,prs_arg->ntl_scn);
3123
2915
var=ncap_var_udf("~rhs_undefined");
3130
2920
/**** From here on we are dealing with a final scan ****/
3132
2921
// copy lmt_sct to dmn_sct;
3133
2922
for(idx=0 ;idx <nbr_dmn ; idx++){
3134
2923
dmn_sct *dmn_nw;
3193
2981
} // end if(nbram)
3196
2983
// copy missing value over
3197
2984
nco_mss_val_cp(var_rhs,var);
3200
2986
/* a hack - we set var->has_dpl_dmn=-1 so we know we are dealing with
3201
a hyperslabed var and not a regular var -- It shouldn't cause
2987
a hyperslabbed var and not a regular var -- It shouldn't cause
3202
2988
any abberant behaviour!! */
3203
2989
var->has_dpl_dmn=-1;
3208
2991
// if variable is scalar re-organize in a new var
3209
2992
// loose extraneous material so it looks like a
3210
2993
// plain scalar variable
3213
2996
var1=ncap_sclr_var_mk(var_nm,var->type,true);
3214
2997
(void)memcpy( (void*)var1->val.vp,var->val.vp,nco_typ_lng(var1->type));
3217
2999
// copy missing value if any from var_rhs to var1
3218
3000
nco_mss_val_cp(var_rhs,var1);
3233
3012
var1=ncap_cst_mk(dmn_nrm_vtr,prs_arg);
3234
3013
(void)nco_free(var1->nm);
3237
3015
var1->nm=strdup(var_nm.c_str());
3238
3016
var1=nco_var_cnf_typ(var_rhs->type,var1);
3274
3052
var->dim[idx]=prs_arg->dmn_out_vtr.find(dmn_vtr[idx]->nm);
3283
3057
for(idx=0 ; idx < nbr_dmn ; idx++)
3284
3058
(void)nco_dmn_free(dmn_vtr[idx]);
3289
3062
for(idx=0 ; idx < nbr_dmn ; idx++)
3290
3063
(void)nco_lmt_free(lmt_vtr[idx]);
3293
3065
end2: var_rhs=nco_var_free(var_rhs);