diff --git a/dvm/fdvm/trunk/Sage/lib/include/libSage++.h b/dvm/fdvm/trunk/Sage/lib/include/libSage++.h index 28b4cee..a41beb6 100644 --- a/dvm/fdvm/trunk/Sage/lib/include/libSage++.h +++ b/dvm/fdvm/trunk/Sage/lib/include/libSage++.h @@ -1787,6 +1787,8 @@ public: inline SgSymbol *construct_name(); inline void replaceTrueBody(SgStatement &s);// new body=s and lex successors. inline void replaceFalseBody(SgStatement &s);//new body=s and lex successors. +// added by A.S. Kolganov 12.12.2024 + inline void setConditional(SgExpression* cond) { BIF_LL1(thebif) = cond->thellnd; } inline ~SgIfStmt(); }; diff --git a/dvm/fdvm/trunk/fdvm/acc.cpp b/dvm/fdvm/trunk/fdvm/acc.cpp index 57290d6..26a145e 100644 --- a/dvm/fdvm/trunk/fdvm/acc.cpp +++ b/dvm/fdvm/trunk/fdvm/acc.cpp @@ -21,7 +21,7 @@ static int has_region, in_arg_list, analyzing, has_max_minloc, for_shadow_comput static SgStatement *cur_in_block, *cur_in_source, *mod_gpu_end; static SgStatement *call_kernel; -static SgExpression *dvm_array_list, *do_st_list, *indexing_info_list; +static SgExpression *dvm_array_list, *do_st_list, *indexing_info_list, *acc_declared_list; static SgExpression *argument_list, *base_mem_list, *coeff_list, *gpu_coeff_list, *registered_uses_list; static SgExpression *red_var_list, *formal_red_offset_list, *red_offset_list, *copy_uses_list; static SgConstantSymb *device_const[Ndev], *const_LONG, *intent_const[Nintent], *handler_const[Nhandler]; @@ -288,6 +288,7 @@ void InitializeInFuncACC() acc_return_list = NULL; /*ACC*/ acc_registered_list = NULL; /*ACC*/ registered_uses_list = NULL; /*ACC*/ + acc_declared_list = NULL; /*ACC*/ } int GeneratedForCuda() @@ -977,6 +978,8 @@ void DeclareVarGPU(SgStatement *lstat, SgType *tlen) /************************************************************************************/ void EnterDataRegionForAllocated(SgStatement *stmt) {SgExpression *al; + if(!ACC_program) + return; for(al=stmt->expr(0); al; al=al->rhs()) EnterDataRegion(al->lhs(),stmt); @@ -1044,7 +1047,7 @@ void UnregisterVariables(int begin_block) { stmt_list *stl; int is; - if (IN_MAIN_PROGRAM) + if (!ACC_program || IN_MAIN_PROGRAM) return; for (stl = acc_return_list; stl; stl = stl->next) { @@ -1101,6 +1104,15 @@ void DeclareDataRegionSaveVariables(SgStatement *lstat, SgType *tlen) if (attr) DeclareVariableWithInitialization (*attr, tlen, lstat); } + for (el = acc_declared_list; el; el = el->rhs()) + { + symb = el->lhs()->symbol(); + if (!(IS_ARRAY(symb)) || isInExprList(el->lhs(), registered_uses_list) || isInSymbList(symb, acc_registered_list)) + continue; + SgSymbol **attr = (SgSymbol **)(symb)->attributeValue(0,DATA_REGION_SYMB); + if (attr) + DeclareVariableWithInitialization (*attr, tlen, lstat); + } } SgSymbol *DataRegionVar(SgSymbol *symb) @@ -1124,9 +1136,9 @@ void EnterDataRegionForLocalVariables(SgStatement *st, SgStatement *first_exec, { if (!el->lhs()) continue; SgSymbol *sym = el->lhs()->symbol(); - if (sym->variant() != CONST_NAME && IS_LOCAL_VAR(sym) && !IS_ALLOCATABLE(sym) && !IS_POINTER_F90(sym) && !(sym->attributes() & HEAP_BIT)) // //!(el->lhs()->symbol()->attributes() & PARAMETER_BIT) ) + if (IS_ARRAY(sym) && sym->variant() != CONST_NAME && IS_LOCAL_VAR(sym) && !IS_ALLOCATABLE(sym) && !IS_POINTER_F90(sym) && !(sym->attributes() & HEAP_BIT)) // //!(el->lhs()->symbol()->attributes() & PARAMETER_BIT) ) { - if ((HAS_SAVE_ATTR(sym) || IN_DATA(sym)) && IS_ARRAY(sym)) + if (HAS_SAVE_ATTR(sym) || IN_DATA(sym)) newst = doIfThenForDataRegion(DataRegionVar(sym), st, DataEnter(new SgVarRefExp(sym),ConstRef(0))); else st->insertStmtAfter(*(newst=DataEnter(new SgVarRefExp(sym),ConstRef(0))),*st->controlParent()); @@ -1134,14 +1146,30 @@ void EnterDataRegionForLocalVariables(SgStatement *st, SgStatement *first_exec, } for (sl = acc_registered_list; sl; sl = sl->next) { - if (sl->symb->variant() != CONST_NAME && IS_LOCAL_VAR(sl->symb) && !IS_ALLOCATABLE(sl->symb) && !IS_POINTER_F90(sl->symb) && !HEADER(sl->symb)) //!(sl->symb->attributes() & PARAMETER_BIT)) + if (IS_ARRAY(sl->symb) && sl->symb->variant() != CONST_NAME && IS_LOCAL_VAR(sl->symb) && !IS_ALLOCATABLE(sl->symb) && !IS_POINTER_F90(sl->symb) && !HEADER(sl->symb)) //!(sl->symb->attributes() & PARAMETER_BIT)) { - if ((HAS_SAVE_ATTR(sl->symb) || IN_DATA(sl->symb)) && IS_ARRAY(sl->symb)) + if (HAS_SAVE_ATTR(sl->symb) || IN_DATA(sl->symb)) newst = doIfThenForDataRegion(DataRegionVar(sl->symb), st, DataEnter(new SgVarRefExp(sl->symb),ConstRef(0))); else st->insertStmtAfter(*(newst=DataEnter(new SgVarRefExp(sl->symb),ConstRef(0))),*st->controlParent()); } } + + for (el = acc_declared_list; el; el = el->rhs()) + { + SgSymbol *sym = el->lhs()->symbol(); + if (!IS_ARRAY(sym) || isInExprList(el->lhs(), registered_uses_list) || isInSymbList(sym, acc_registered_list)) + continue; + + if (sym->variant() != CONST_NAME && IS_LOCAL_VAR(sym) && !IS_ALLOCATABLE(sym) && !IS_POINTER_F90(sym) && !(sym->attributes() & HEAP_BIT) && !HEADER(sym)) + { + if (HAS_SAVE_ATTR(sym) || IN_DATA(sym)) + newst = doIfThenForDataRegion(DataRegionVar(sym), st, DataEnter(new SgVarRefExp(sym),ConstRef(0))); + else + st->insertStmtAfter(*(newst=DataEnter(new SgVarRefExp(sym),ConstRef(0))),*st->controlParent()); + } + } + if (newst && !begin_block) LINE_NUMBER_AFTER(first_exec,st); } @@ -1155,9 +1183,9 @@ void ExitDataRegionForLocalVariables(SgStatement *st, int is) { if (!el->lhs()) continue; SgSymbol *sym = el->lhs()->symbol(); - if (sym->variant() != CONST_NAME && IS_LOCAL_VAR(sym) && !IS_ALLOCATABLE(sym) && !IS_POINTER_F90(sym) && !(sym->attributes() & HEAP_BIT)) // //!(el->lhs()->symbol()->attributes() & PARAMETER_BIT) ) + if (IS_ARRAY(sym) && sym->variant() != CONST_NAME && IS_LOCAL_VAR(sym) && !IS_ALLOCATABLE(sym) && !IS_POINTER_F90(sym) && !(sym->attributes() & HEAP_BIT)) // //!(el->lhs()->symbol()->attributes() & PARAMETER_BIT) ) { - if ((HAS_SAVE_ATTR(sym) || IN_DATA(sym)) && IS_ARRAY(sym)) + if (HAS_SAVE_ATTR(sym) || IN_DATA(sym)) continue; if (!is++) LINE_NUMBER_BEFORE(st,st); @@ -1166,18 +1194,71 @@ void ExitDataRegionForLocalVariables(SgStatement *st, int is) } for (sl = acc_registered_list; sl; sl = sl->next) { - if (sl->symb->variant() != CONST_NAME && IS_LOCAL_VAR(sl->symb) && !IS_ALLOCATABLE(sl->symb) && !IS_POINTER_F90(sl->symb) && !HEADER(sl->symb)) //!(sl->symb->attributes() & PARAMETER_BIT)) + if (IS_ARRAY(sl->symb) && sl->symb->variant() != CONST_NAME && IS_LOCAL_VAR(sl->symb) && !IS_ALLOCATABLE(sl->symb) && !IS_POINTER_F90(sl->symb) && !HEADER(sl->symb)) //!(sl->symb->attributes() & PARAMETER_BIT)) { - if ((HAS_SAVE_ATTR(sl->symb) || IN_DATA(sl->symb)) && IS_ARRAY(sl->symb)) + if (HAS_SAVE_ATTR(sl->symb) || IN_DATA(sl->symb)) continue; if (!is++) LINE_NUMBER_BEFORE(st,st); InsertNewStatementBefore(DataExit(new SgVarRefExp(sl->symb),0),st); } } + for (el = acc_declared_list; el; el = el->rhs()) + { + if (!el->lhs()) continue; + SgSymbol *sym = el->lhs()->symbol(); + if (!IS_ARRAY(sym) || isInExprList(el->lhs(), registered_uses_list) || isInSymbList(sym, acc_registered_list)) + continue; + if (sym->variant() != CONST_NAME && IS_LOCAL_VAR(sym) && !IS_ALLOCATABLE(sym) && !IS_POINTER_F90(sym) && !(sym->attributes() & HEAP_BIT) && !HEADER(sym)) + { + if (HAS_SAVE_ATTR(sym) || IN_DATA(sym)) + continue; + if (!is++) + LINE_NUMBER_BEFORE(st,st); + InsertNewStatementBefore(DataExit(new SgVarRefExp(sym),0),st); + } + } } +void testScopeOfDeclaredVariables(SgStatement *stmt) +{ + SgExpression *el; + for (el = stmt->expr(0); el; el = el->rhs()) + { + SgSymbol *sym = el->lhs()->symbol(); + if (!IS_LOCAL_VAR(sym)) + Error("Non-local data object in DECLARE directive: %s", sym->identifier(), 668, stmt); + continue; + } +} + +void testDeclareDirectives(SgStatement *first_dvm_exec) +{ + SgStatement *stmt; + for (stmt = cur_func->lexNext(); stmt && (stmt != first_dvm_exec); stmt = stmt->lastNodeOfStmt()->lexNext()) + { + if (stmt->variant()==ACC_DECLARE_DIR) + { + if (IN_MODULE) + err("Illegal directive in module", 632, stmt); + else if (!IN_MAIN_PROGRAM) + testScopeOfDeclaredVariables(stmt); + } + continue; + } + // eliminating duplicate objects from the acc_declared_list + SgExpression *el, *el2, *prev; + for (el = acc_declared_list; el; el = el->rhs()) + { + for (el2 = el->rhs(), prev = el; el2; ) + if (ORIGINAL_SYMBOL(el->lhs()->symbol()) == ORIGINAL_SYMBOL(el2->lhs()->symbol())) + { prev->setRhs(el2->rhs()); el2 = el2->rhs(); } + else + { prev = el2; el2 = el2->rhs(); } + } +} + void ExtractCopy(SgExpression *elist) { SgExpression *el; @@ -1204,6 +1285,8 @@ void CleanAllocatedList() int ExitDataRegionForAllocated(SgStatement *st,int begin_block) { SgExpression *el; + if (!ACC_program) + return(0); if (TestLocal(allocated_list)) { @@ -1250,7 +1333,8 @@ int hasSameOriginalName(SgSymbol *s) } void EnterDataRegionForVariablesInMainProgram(SgStatement *st) -{ +{ +/* symb_list *sl; SgSymbol *s; for(sl=registration; sl; sl=sl->next) @@ -1265,11 +1349,35 @@ void EnterDataRegionForVariablesInMainProgram(SgStatement *st) if (!is_deleted_module_symbol(s) && IS_ARRAY(s) && !hasSameOriginalName(s) && s->variant() == VARIABLE_NAME && !IS_ALLOCATABLE(s) && !IS_POINTER_F90(s) && !HEADER(s) ) st->insertStmtAfter(*DataEnter(new SgVarRefExp(s),ConstRef(0)),*st->controlParent()); s = s->next(); - } + } +*/ + SgExpression *el; + symb_list *sl; + for (el = registered_uses_list; el; el = el->rhs()) + { + SgSymbol *sym = el->lhs()->symbol(); + if (IS_ARRAY(sym) && sym->variant() != CONST_NAME && !IS_ALLOCATABLE(sym) && !IS_POINTER_F90(sym) && !(sym->attributes() & HEAP_BIT)) + st->insertStmtAfter(*DataEnter(new SgVarRefExp(sym),ConstRef(0)),*st->controlParent()); + } + for (sl = acc_registered_list; sl; sl = sl->next) + { + if (sl->symb->variant() != CONST_NAME && !IS_ALLOCATABLE(sl->symb) && !IS_POINTER_F90(sl->symb) && !HEADER(sl->symb)) + st->insertStmtAfter(*DataEnter(new SgVarRefExp(sl->symb),ConstRef(0)),*st->controlParent()); + } + for (el = acc_declared_list; el; el = el->rhs()) + { + SgSymbol *sym = el->lhs()->symbol(); + if (!IS_ARRAY(sym) || isInExprList(el->lhs(), registered_uses_list) || isInSymbList(sym, acc_registered_list)) + continue; + + if (sym->variant() == VARIABLE_NAME && !IS_ALLOCATABLE(sym) && !IS_POINTER_F90(sym) && !HEADER(sym) && !(sym->attributes() & HEAP_BIT)) + st->insertStmtAfter(*DataEnter(new SgVarRefExp(sym),ConstRef(0)),*st->controlParent()); + } } void ExitDataRegionForVariablesInMainProgram(SgStatement *st) { +/* symb_list *sl; SgSymbol *s; for(sl=registration; sl; sl=sl->next) @@ -1286,6 +1394,37 @@ void ExitDataRegionForVariablesInMainProgram(SgStatement *st) InsertNewStatementBefore(DataExit(new SgVarRefExp(s),0),st); s = s->next(); } + SgSymbol *s; + SgExpression *el; + for (el = acc_declared_list; el; el = el->rhs()) + { + s = el->lhs()->symbol(); + if (IS_ARRAY(s) && s->variant() == VARIABLE_NAME && !IS_ALLOCATABLE(s) && !IS_POINTER_F90(s) && !HEADER(s) && !(s->attributes() & HEAP_BIT)) + InsertNewStatementBefore(DataExit(new SgVarRefExp(s),0),st); + } +*/ + SgExpression *el; + symb_list *sl; + for (el = registered_uses_list; el; el = el->rhs()) + { + SgSymbol *sym = el->lhs()->symbol(); + if (IS_ARRAY(sym) && sym->variant() != CONST_NAME && !IS_ALLOCATABLE(sym) && !IS_POINTER_F90(sym) && !(sym->attributes() & HEAP_BIT)) + InsertNewStatementBefore(DataExit(new SgVarRefExp(sym),0),st); + } + for (sl = acc_registered_list; sl; sl = sl->next) + { + if (sl->symb->variant() != CONST_NAME && !IS_ALLOCATABLE(sl->symb) && !IS_POINTER_F90(sl->symb) && !HEADER(sl->symb)) + InsertNewStatementBefore(DataExit(new SgVarRefExp(sl->symb),0),st); + } + for (el = acc_declared_list; el; el = el->rhs()) + { + SgSymbol *sym = el->lhs()->symbol(); + if (!IS_ARRAY(sym) || isInExprList(el->lhs(), registered_uses_list) || isInSymbList(sym, acc_registered_list)) + continue; + + if (sym->variant() == VARIABLE_NAME && !IS_ALLOCATABLE(sym) && !IS_POINTER_F90(sym) && !HEADER(sym) && !(sym->attributes() & HEAP_BIT)) + InsertNewStatementBefore(DataExit(new SgVarRefExp(sym),0),st); + } } /**********************************************************************************/ @@ -1345,9 +1484,15 @@ SgStatement *ACC_Directive(SgStatement *stmt) } +void ACC_DECLARE_Directive(SgStatement *stmt) +{ + if (ACC_program) + acc_declared_list = ExpressionListsUnion(acc_declared_list, &(stmt->expr(0)->copy())); +} + void ACC_ROUTINE_Directive(SgStatement *stmt) { - if( options.isOn(NO_CUDA) ) + if(!ACC_program || options.isOn(NO_CUDA) ) return; int control_variant = stmt->controlParent()->controlParent()->variant(); if (control_variant == INTERFACE_STMT || control_variant == INTERFACE_OPERATOR || control_variant == INTERFACE_ASSIGNMENT) @@ -1658,11 +1803,8 @@ SgStatement *ACC_REGION_Directive(SgStatement *stmt) // creating lists of registered variables in procedure - if (!IN_MAIN_PROGRAM) - { acc_registered_list = SymbolListsUnion(acc_registered_list, acc_array_list); registered_uses_list = ExpressionListsUnion(registered_uses_list, uses_list); - } return(cur_st); } @@ -10664,7 +10806,18 @@ void ReductionBlockInKernel_On_C_Cuda(SgStatement *stat, SgSymbol *i_var, SgExpr stat->insertStmtBefore(*new SgCExpStmt(*fun_ref), *stat->controlParent()); if (across) + { newst = AssignStatement(new SgArrayRefExp(*rsl->red_grid, *ex), new SgVarRefExp(rsl->redvar)); + + SgExpression* cond = if_st->conditional(); + int redVar = RedFuncNumber(ered->lhs()); + if (redVar == 9) // maxloc + cond = &(*cond && (*new SgVarRefExp(rsl->redvar) > *new SgArrayRefExp(*rsl->red_grid, *ex))); + else if (redVar == 10) // minloc + cond = &(*cond && (*new SgVarRefExp(rsl->redvar) < *new SgArrayRefExp(*rsl->red_grid, *ex))); + + if_st->setConditional(cond); + } else newst = AssignStatement(new SgArrayRefExp(*rsl->red_grid, *BlockIdxRefExpr("x") * *ex1 + *ex), new SgVarRefExp(rsl->redvar)); diff --git a/dvm/fdvm/trunk/fdvm/acc_across.cpp b/dvm/fdvm/trunk/fdvm/acc_across.cpp index 95f7ec1..6ab4e28 100644 --- a/dvm/fdvm/trunk/fdvm/acc_across.cpp +++ b/dvm/fdvm/trunk/fdvm/acc_across.cpp @@ -5923,7 +5923,11 @@ SgStatement *CreateLoopKernelAcross(SgSymbol *skernel, ArgsForKernel* argsKer, i else if (num == 9 || num == 10) { st = AssignStatement(*new SgArrayRefExp(*redGrid, *e1), red_expr_ref->copy()); - ifSt = new SgIfStmt(red_expr_ref->copy() > *new SgArrayRefExp(*redGrid, *e1), *st); + if (num == 9) + ifSt = new SgIfStmt(red_expr_ref->copy() > *new SgArrayRefExp(*redGrid, *e1), *st); + else + ifSt = new SgIfStmt(red_expr_ref->copy() < *new SgArrayRefExp(*redGrid, *e1), *st); + for (int i = loc_el_num - 1; i >= 0; i--) { SgSymbol *locGrid = new SgSymbol(VARIABLE_NAME, tmp_list->loc_grid->identifier()); diff --git a/dvm/fdvm/trunk/fdvm/dvm.cpp b/dvm/fdvm/trunk/fdvm/dvm.cpp index cd46e92..7447afc 100644 --- a/dvm/fdvm/trunk/fdvm/dvm.cpp +++ b/dvm/fdvm/trunk/fdvm/dvm.cpp @@ -2191,6 +2191,9 @@ void TransFunc(SgStatement *func,SgStatement* &end_of_unit) { case(ACC_ROUTINE_DIR): ACC_ROUTINE_Directive(stmt); continue; + case(ACC_DECLARE_DIR): + ACC_DECLARE_Directive(stmt); + continue; case(HPF_TEMPLATE_STAT): if(IN_MODULE && stmt->expr(1)) err("Illegal directive in module",632,stmt); @@ -2678,7 +2681,9 @@ void TransFunc(SgStatement *func,SgStatement* &end_of_unit) { // current statement is executable (F77/DVM) break; - } + } + // checking semantics of DECLARE directives + testDeclareDirectives(stmt); if(pstmt && (stmt != last)) pstmt = pstmt->next; //deleting first executable statement from @@ -4238,8 +4243,7 @@ END_: // end of program unit cur_st = first_dvm_exec; if(last_dvm_entry) lentry = last_dvm_entry->lexNext(); // lentry - statement following first_dvm_exec or last generated dvm-initialization statement(before first_exec) - // before first_exec may be new statements generated for first_exec - + // before first_exec may be new statements generated for first_exec if(!IN_MODULE) { if(has_contains) MarkCoeffsAsUsed(); @@ -5294,7 +5298,8 @@ void DEALLOCATEf90_arrays(SgStatement *stmt) } else { apr = al; - InsertNewStatementAfter(DataExit(&al->lhs()->copy(),0),cur_st,stmt->controlParent()); /*26.10.17*/ + if(ACC_program) /*ACC*/ + InsertNewStatementAfter(DataExit(&al->lhs()->copy(),0),cur_st,stmt->controlParent()); /*26.10.17*/ //if(ACC_program) /*ACC*/ // InsertNewStatementAfter(DestroyScalar(&al->lhs()->copy()),cur_st,stmt->controlParent()); //doCallAfter(DataExit(&al->lhs()->copy(),0)); /*ACC*/ @@ -10599,7 +10604,8 @@ void InsertDebugStat(SgStatement *func, SgStatement* &end_of_unit) //including the DVM specification directive to list pstmt = addToStmtList(pstmt, stmt); continue; - case(ACC_ROUTINE_DIR): + case(ACC_ROUTINE_DIR): + case(ACC_DECLARE_DIR): case(HPF_PROCESSORS_STAT): case(HPF_TEMPLATE_STAT): case(DVM_DYNAMIC_DIR): @@ -13760,6 +13766,7 @@ SgStatement *InterfaceBody(SgStatement *hedr) case (DVM_POINTER_DIR): case (DVM_HEAP_DIR): case (DVM_ASYNCID_DIR): + case (ACC_DECLARE_DIR): dvm_pred = stmt; default: continue; diff --git a/dvm/fdvm/trunk/include/dvm.h b/dvm/fdvm/trunk/include/dvm.h index 31e51aa..d3cca27 100644 --- a/dvm/fdvm/trunk/include/dvm.h +++ b/dvm/fdvm/trunk/include/dvm.h @@ -1453,6 +1453,8 @@ SgExpression *CreatePrivateDummyList(); char *PointerNameForPrivateArray(SgSymbol *symb); void GetMemoryForPrivateArrays(SgSymbol *private_first, SgSymbol *s_loop_ref, int nump, SgStatement *st_end, SgStatement *st_hedr, SgExpression *e_totalThreads); SgSymbol *LocRedVariableSymbolInKernel(reduction_operation_list *rsl); +void testDeclareDirectives(SgStatement *first_dvm_exec); +void ACC_DECLARE_Directive(SgStatement *stmt); /* acc_analyzer.cpp */ //void Private_Vars_Analyzer(SgStatement *firstSt, SgStatement *lastSt); diff --git a/dvm/fdvm/trunk/parser/lexfdvm.c b/dvm/fdvm/trunk/parser/lexfdvm.c index 8b78023..540cb37 100644 --- a/dvm/fdvm/trunk/parser/lexfdvm.c +++ b/dvm/fdvm/trunk/parser/lexfdvm.c @@ -1345,11 +1345,16 @@ body:/* if(newname) { { prefix[5]=BLANKC; *endcd++ = '\0';} else *endcd++ = '\0'; /* put NULL char in buffer as end marker */ - if((c==';') && (char_cntx==0)) { +stmt_end: if((c==';') && (char_cntx==0)) { restcd = bend - endcd; while( ((c = getc(infile)) == ';') || (c == ' ')) restcd--; - (void) ungetc(c,infile); + if(c == '!') { /* delimiter ';' is ignored before comment */ + restcd = 0; + goto stmt_end; + } + else + (void) ungetc(c,infile); } else if((c=='!') && (char_cntx==0)) { cmt = tempbuf; @@ -1615,11 +1620,16 @@ body: /* Read body of line */ /*('\r\n' is end line marker in Windows) */ else *endcd++ = '\0'; /* put NULL char in buffer as end marker */ - if((c==';') && (char_cntx==0)) { +stmt_end: if((c==';') && (char_cntx==0)) { restcd = 1; while( ((c = getc(infile)) == ';') || (c == ' ')) ; - (void) ungetc(c,infile); + if(c == '!') { /* delimiter ';' is ignored before comment */ + restcd = 0; + goto stmt_end; + } + else + (void) ungetc(c,infile); } else if((c=='!') && (char_cntx==0)) { cmt = tempbuf; diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/version.h b/sapfor/experts/Sapfor_2017/_src/Utils/version.h index 5e465ae..2584b43 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/version.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2374" +#define VERSION_SPF "2375"