// edit or display a file with vertical & horizontal scrolling & text searching int _near List_Cmd( LPTSTR pszCmdLine ) { int nFVal, nReturn = 0, argc; TCHAR szSource[MAXFILENAME+1], szFileName[MAXFILENAME+1], *pszArg; FILESEARCH dir; memset( &dir, '\0', sizeof(FILESEARCH) ); // check for and remove switches if ( GetRange( pszCmdLine, &(dir.aRanges), 0 ) != 0 ) return ERROR_EXIT; // check for /T"search string" GetMultiCharSwitch( pszCmdLine, _TEXT("T"), szSource, 255 ); if ( szSource[0] == _TEXT('"') ) sscanf( szSource+1, _TEXT("%79[^\"]"), szListFindWhat ); else if ( szSource[0] ) sprintf( szListFindWhat, FMT_PREC_STR, 79, szSource ); if ( GetSwitches( pszCmdLine, _TEXT("*HIRSWX"), &lListFlags, 0 ) != 0 ) return ( Usage( LIST_USAGE )); if ( szSource[0] ) lListFlags |= LIST_SEARCH; // check for pipe to LIST w/o explicit /S switch if ( first_arg( pszCmdLine ) == NULL ) { if ( _isatty( STDIN ) == 0 ) lListFlags |= LIST_STDIN; else if (( lListFlags & LIST_STDIN ) == 0 ) return ( Usage( LIST_USAGE )); } // initialize buffers & globals if ( ListInit() ) return ERROR_EXIT; nCurrent = nStart = 0; // ^C handling if ( setjmp( cv.env ) == -1 ) { list_abort: FindClose( dir.hdir ); Cls_Cmd( NULL ); nReturn = CTRLC; goto list_bye; } RestartFileSearch: for ( argc = 0; ; argc++ ) { // break if at end of arg list, & not listing STDIN if (( pszArg = ntharg( pszCmdLine, argc )) == NULL ) { if (( lListFlags & LIST_STDIN ) == 0 ) break; } else strcpy( szSource, pszArg ); for ( nFVal = FIND_FIRST; ; ) { szClip[0] = _TEXT('\0'); // if not reading from STDIN, get the next matching file if (( lListFlags & LIST_STDIN ) == 0 ) { // qualify filename if ( nFVal == FIND_FIRST ) { mkfname( szSource, 0 ); if ( is_dir( szSource )) mkdirname( szSource, WILD_FILE ); } if ( stricmp( szSource, CLIP ) == 0 ) { RedirToClip( szClip, 99 ); if ( CopyFromClipboard( szClip ) != 0 ) break; strcpy( szFileName, szClip ); } else if ( QueryIsPipeName( szSource )) { // only look for pipe once if ( nFVal == FIND_NEXT ) break; copy_filename( szFileName, szSource ); } else if ( find_file( nFVal, szSource, ( FIND_BYATTS | FIND_RANGE | FIND_EXCLUDE | 0x07), &dir, szFileName ) == NULL ) { nReturn = (( nFVal == FIND_FIRST ) ? ERROR_EXIT : 0 ); break; } else if ( nStart < nCurrent ) { nStart++; nFVal = FIND_NEXT; continue; } else if ( dir.ulSize > 0L ) LFile.lSize = dir.ulSize; } // clear the screen (scrolling the buffer first to save the current screen) Cls_Cmd( NULL ); if (( nReturn = _list( szFileName )) == CTRLC ) goto list_abort; if ( szClip[0] ) remove( szClip ); if ( nReturn != 0 ) break; SetCurPos( nScreenRows, 0 ); if (( szClip[0] ) || ( lListFlags & LIST_STDIN )) break; if ( LFile.hHandle > 0 ) _close( LFile.hHandle ); LFile.hHandle = -1; // increment index to current file if ( nCurrent < nStart ) { FindClose( dir.hdir ); nStart = 0; goto RestartFileSearch; } else { nFVal = FIND_NEXT; nCurrent++; nStart++; } } // we can only read STDIN once! lListFlags &= ~LIST_STDIN; } crlf(); list_bye: FreeMem( LFile.lpBufferStart ); if ( LFile.hHandle > 0 ) _close( LFile.hHandle ); LFile.hHandle = -1; return nReturn; }
void RangeCheck::OptimizeRangeCheck(BasicBlock* block, GenTreePtr stmt, GenTreePtr treeParent) { // Check if we are dealing with a bounds check node. if (treeParent->OperGet() != GT_COMMA) { return; } // If we are not looking at array bounds check, bail. GenTreePtr tree = treeParent->gtOp.gtOp1; if (!tree->OperIsBoundsCheck()) { return; } GenTreeBoundsChk* bndsChk = tree->AsBoundsChk(); m_pCurBndsChk = bndsChk; GenTreePtr treeIndex = bndsChk->gtIndex; // Take care of constant index first, like a[2], for example. ValueNum idxVn = treeIndex->gtVNPair.GetConservative(); ValueNum arrLenVn = bndsChk->gtArrLen->gtVNPair.GetConservative(); int arrSize = 0; if (m_pCompiler->vnStore->IsVNConstant(arrLenVn)) { ssize_t constVal = -1; unsigned iconFlags = 0; if (m_pCompiler->optIsTreeKnownIntValue(true, bndsChk->gtArrLen, &constVal, &iconFlags)) { arrSize = (int)constVal; } } else #ifdef FEATURE_SIMD if (tree->gtOper != GT_SIMD_CHK) #endif // FEATURE_SIMD { arrSize = GetArrLength(arrLenVn); } JITDUMP("ArrSize for lengthVN:%03X = %d\n", arrLenVn, arrSize); if (m_pCompiler->vnStore->IsVNConstant(idxVn) && arrSize > 0) { ssize_t idxVal = -1; unsigned iconFlags = 0; if (!m_pCompiler->optIsTreeKnownIntValue(true, treeIndex, &idxVal, &iconFlags)) { return; } JITDUMP("[RangeCheck::OptimizeRangeCheck] Is index %d in <0, arrLenVn VN%X sz:%d>.\n", idxVal, arrLenVn, arrSize); if (arrSize > 0 && idxVal < arrSize && idxVal >= 0) { JITDUMP("Removing range check\n"); m_pCompiler->optRemoveRangeCheck(treeParent, stmt, true, GTF_ASG, true /* force remove */); return; } } GetRangeMap()->RemoveAll(); GetOverflowMap()->RemoveAll(); // Get the range for this index. SearchPath* path = new (m_pCompiler->getAllocator()) SearchPath(m_pCompiler->getAllocator()); Range range = GetRange(block, stmt, treeIndex, path, false DEBUGARG(0)); // If upper or lower limit is found to be unknown (top), or it was found to // be unknown because of over budget or a deep search, then return early. if (range.UpperLimit().IsUnknown() || range.LowerLimit().IsUnknown()) { // Note: If we had stack depth too deep in the GetRange call, we'd be // too deep even in the DoesOverflow call. So return early. return; } if (DoesOverflow(block, stmt, treeIndex, path)) { JITDUMP("Method determined to overflow.\n"); return; } JITDUMP("Range value %s\n", range.ToString(m_pCompiler->getAllocatorDebugOnly())); path->RemoveAll(); Widen(block, stmt, treeIndex, path, &range); // If upper or lower limit is unknown, then return. if (range.UpperLimit().IsUnknown() || range.LowerLimit().IsUnknown()) { return; } // Is the range between the lower and upper bound values. if (BetweenBounds(range, 0, bndsChk->gtArrLen)) { JITDUMP("[RangeCheck::OptimizeRangeCheck] Between bounds\n"); m_pCompiler->optRemoveRangeCheck(treeParent, stmt, true, GTF_ASG, true /* force remove */); } return; }