/******************************************************************** StrAllocPrefix - allocates or reuses dynamic string memory and prefixes a string NOTE: caller is responsible for freeing ppwz even if function fails NOTE: cchPrefix does not have to equal the length of wzPrefix NOTE: if cchPrefix == 0, length of wzPrefix is used instead ********************************************************************/ extern "C" HRESULT DAPI StrAllocPrefix( __inout LPWSTR* ppwz, __in LPCWSTR wzPrefix, __in DWORD_PTR cchPrefix ) { Assert(ppwz && wzPrefix); HRESULT hr = S_OK; DWORD_PTR cch = 0; DWORD_PTR cchLen = 0; if (*ppwz) { cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1) if (-1 == cch) ExitOnFailure(hr = E_INVALIDARG, "failed to get size of destination string"); cch /= sizeof(WCHAR); //convert the count in bytes to count in characters StringCchLengthW(*ppwz, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen)); } Assert(cchLen <= cch); if (0 == cchPrefix) { StringCchLengthW(wzPrefix, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchPrefix)); } if (cch - cchLen < cchPrefix + 1) { cch = cchPrefix + cchLen + 1; hr = StrAlloc(ppwz, cch); ExitOnFailure1(hr, "failed to allocate string from string: %S", wzPrefix); } if (*ppwz) { DWORD_PTR cb = cch * sizeof(WCHAR); DWORD_PTR cbPrefix = cchPrefix * sizeof(WCHAR); memmove(*ppwz + cchPrefix, *ppwz, cb - cbPrefix); memcpy(*ppwz, wzPrefix, cbPrefix); } else { ExitOnFailure(hr = E_UNEXPECTED, "for some reason our buffer is still null"); } LExit: return hr; }
/******************************************************************** StrSize - returns count of bytes in dynamic string p ********************************************************************/ extern "C" HRESULT DAPI StrSize( __in LPVOID p, __out DWORD_PTR* pcb ) { Assert(p && pcb); HRESULT hr = S_OK; *pcb = MemSize(p); if (-1 == *pcb) { hr = E_FAIL; } return hr; }
/******************************************************************** StrAllocConcat - allocates or reuses dynamic string memory and adds an existing string NOTE: caller is responsible for freeing ppwz even if function fails NOTE: cchSource does not have to equal the length of wzSource NOTE: if cchSource == 0, length of wzSource is used instead ********************************************************************/ extern "C" HRESULT DAPI StrAllocConcat( __inout LPWSTR* ppwz, __in LPCWSTR wzSource, __in DWORD_PTR cchSource ) { Assert(ppwz && wzSource); // && *wzSource); HRESULT hr = S_OK; DWORD_PTR cch = 0; DWORD_PTR cchLen = 0; if (*ppwz) { cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1) if (-1 == cch) ExitOnFailure(hr = E_INVALIDARG, "failed to get size of destination string"); cch /= sizeof(WCHAR); //convert the count in bytes to count in characters StringCchLengthW(*ppwz, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen)); } Assert(cchLen <= cch); if (0 == cchSource) StringCchLengthW(wzSource, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchSource)); if (cch - cchLen < cchSource + 1) { cch = (cchSource + cchLen + 1) * 2; hr = StrAlloc(ppwz, cch); ExitOnFailure1(hr, "failed to allocate string from string: %S", wzSource); } if (*ppwz) hr = StringCchCatNExW(*ppwz, cch, wzSource, cchSource, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); else ExitOnFailure(hr = E_UNEXPECTED, "for some reason our buffer is still null"); LExit: return hr; }
/* * doInitializeEditor - do just that */ static void doInitializeEditor( int argc, char *argv[] ) { int i, arg, cnt, ocnt, startcnt = 0; srcline sline; int k, j; char tmp[FILENAME_MAX], c[1]; char buff[MAX_STR], file[MAX_STR], **list; char cmd[MAX_STR * 2]; char *parm; char *startup[MAX_STARTUP]; char *startup_parms[MAX_STARTUP]; vi_rc rc; vi_rc rc1; /* * Make sure WATCOM is setup and if it is not, make a best guess. */ watcom_setup_env(); /* * If EDPATH is not set, use system default %WATCOM%\EDDAT. */ if( getenv( "EDPATH" ) == NULL ) { char *watcom; watcom = getenv( "WATCOM" ); if( watcom != NULL ) { char edpath[FILENAME_MAX]; sprintf( edpath, "%s%c%s", watcom, FILE_SEP, "eddat" ); if( setenv( "EDPATH", edpath, 0 ) != 0 ) { /* * Bail out silently on error, as we will get error message later on. */ } } } /* * misc. set up */ MaxMemFree = MemSize(); StaticStart(); FTSInit(); BoundDataInit(); EditFlags.Starting = true; InitCommandLine(); ChkExtendedKbd(); SSInitBeforeConfig(); GetCWD1( &HomeDirectory ); GetCWD1( &CurrentDirectory ); SetCWD( HomeDirectory ); if( cfgFN == NULL ){ cfgFN = DupString( CFG_NAME ); } checkFlags( &argc, argv, startup, startup_parms, &startcnt ); ScreenInit(); SetWindowSizes(); EditFlags.ClockActive = false; SetInterrupts(); #ifdef __WIN__ InitClrPick(); InitFtPick(); SubclassGenericInit(); CursorOp( COP_INIT ); #else InitColors(); #endif InitSavebufs(); InitKeyMaps(); /* * initial configuration */ EditVars.Majick = MemStrDup( "()~@" ); EditVars.FileEndString = MemStrDup( "[END_OF_FILE]" ); MatchInit(); SetGadgetString( NULL ); WorkLine = MemAlloc( sizeof( line ) + EditVars.MaxLine + 2 ); WorkLine->len = -1; sline = 0; if( cfgFN[0] != 0 ) { c[0] = 0; rc = Source( cfgFN, c, &sline ); if( rc == ERR_FILE_NOT_FOUND ) { #ifdef __WIN__ CloseStartupDialog(); MessageBox( (HWND)NULLHANDLE, "Could not locate configuration information; please make sure your EDPATH environment variable is set correctly", EditorName, MB_OK ); ExitEditor( -1 ); #else rc = ERR_NO_ERR; #endif } } else { rc = ERR_NO_ERR; } if( wantNoReadEntireFile ) { EditFlags.ReadEntireFile = false; } VerifyTmpDir(); while( LostFileCheck() ); HookScriptCheck(); if( EditFlags.Quiet ) { EditFlags.Spinning = false; EditFlags.Clock = false; } ExtendedMemoryInit(); /* * more misc. setup */ if( EditVars.WordDefn == NULL ) { EditVars.WordDefn = DupString( &WordDefnDefault[6] ); InitWordSearch( EditVars.WordDefn ); } if( EditVars.WordAltDefn == NULL ) { EditVars.WordAltDefn = DupString( WordDefnDefault ); } if( EditVars.TagFileName == NULL ) { EditVars.TagFileName = DupString( "tags" ); } DotBuffer = MemAlloc( (maxdotbuffer + 2) * sizeof( vi_key ) ); AltDotBuffer = MemAlloc( (maxdotbuffer + 2) * sizeof( vi_key ) ); DotCmd = MemAlloc( (maxdotbuffer + 2) * sizeof( vi_key ) ); SwapBlockInit( EditVars.MaxSwapBlocks ); ReadBuffer = MemAlloc( MAX_IO_BUFFER + 6 ); WriteBuffer = MemAlloc( MAX_IO_BUFFER + 6 ); FindHistInit( EditVars.FindHist.max ); FilterHistInit( EditVars.FilterHist.max ); CLHistInit( EditVars.CLHist.max ); LastFilesHistInit( EditVars.LastFilesHist.max ); GetClockStart(); GetSpinStart(); SelRgnInit(); SSInitAfterConfig(); #if defined( VI_RCS ) ViRCSInit(); #endif /* * create windows */ StartWindows(); InitMouse(); rc1 = NewMessageWindow(); if( rc1 != ERR_NO_ERR ) { FatalError( rc1 ); } DoVersion(); rc1 = InitMenu(); if( rc1 != ERR_NO_ERR ) { FatalError( rc1 ); } EditFlags.SpinningOurWheels = true; EditFlags.ClockActive = true; EditFlags.DisplayHold = true; rc1 = NewStatusWindow(); if( rc1 != ERR_NO_ERR ) { FatalError( rc1 ); } EditFlags.DisplayHold = false; MaxMemFreeAfterInit = MemSize(); /* * look for a tag: if there is one, set it up as the file to start */ EditFlags.WatchForBreak = true; if( cTag != NULL && !EditFlags.NoInitialFileLoad ) { #if defined( __NT__ ) && !defined( __WIN__ ) { if( !EditFlags.Quiet ) { SetConsoleActiveScreenBuffer( OutputHandle ); } } #endif rc1 = LocateTag( cTag, file, buff ); cFN = file; if( rc1 != ERR_NO_ERR ) { if( rc1 == ERR_TAG_NOT_FOUND ) { Error( GetErrorMsg( rc1 ), cTag ); ExitEditor( 0 ); } FatalError( rc1 ); } } /* * start specified file(s) */ cmd[0] = 'e'; cmd[1] = 0; arg = argc - 1; k = 1; while( !EditFlags.NoInitialFileLoad ) { if( cFN == nullFN && !EditFlags.UseNoName ) { break; } #ifdef __NT__ { int k2; int arg2; char path[_MAX_PATH]; int found; int fd; size_t len; size_t len1; char *p; /* * check for the existence of a file name containing spaces, and open it if * there is one */ len = _MAX_PATH - 1; found = 0; p = path; arg2 = arg; for( k2 = k; argv[k2] != NULL; ) { len1 = strlen( argv[k2] ); if( len1 > len ) break; memcpy( p, argv[k2], len1 ); p += len1; *p = '\0'; len -= len1; --arg2; ++k2; fd = open( path, O_RDONLY ); if( fd != -1 ) { close( fd ); k = k2; arg = arg2; found = 1; break; } *p++ = ' '; } if( found ) { #ifndef __UNIX__ len1 = strlen( path ); if( path[len1 - 1] == '.' ) path[len1 - 1] = '\0'; #endif rc1 = NewFile( path, false ); if( rc1 != ERR_NO_ERR ) { FatalError( rc1 ); } cFN = argv[k]; if( arg < 1 ) { break; } continue; } } #endif strcat( cmd, SingleBlank ); strcat( cmd, cFN ); ocnt = cnt = ExpandFileNames( cFN, &list ); if( cnt == 0 ) { cnt = 1; } else { cFN = list[0]; } for( j = 0; j < cnt; j++ ) { rc1 = NewFile( cFN, false ); if( rc1 != ERR_NO_ERR && rc1 != NEW_FILE ) { FatalError( rc1 ); } if( EditFlags.BreakPressed ) { break; } if( cnt > 0 && j < cnt - 1 ) { cFN = list[j + 1]; } } if( ocnt > 0 ) { MemFreeList( ocnt, list ); } if( EditFlags.BreakPressed ) { ClearBreak(); break; } k++; arg--; if( cTag != NULL || arg < 1 ) { break; } cFN = argv[k]; } if( EditFlags.StdIOMode ) { rc1 = NewFile( "stdio", false ); if( rc1 != ERR_NO_ERR ) { FatalError( rc1 ); } } EditFlags.WatchForBreak = false; EditFlags.Starting = false; /* * if there was a tag, do the appropriate search */ if( cTag != NULL && !EditFlags.NoInitialFileLoad ) { if( buff[0] != '/' ) { i = atoi( buff ); rc1 = GoToLineNoRelCurs( i ); } else { rc1 = FindTag( buff ); } if( rc1 > 0 ) { Error( GetErrorMsg( rc1 ) ); } } /* * try to run startup file */ if( EditFlags.RecoverLostFiles ) { startcnt = 0; } for( i = 0; i < startcnt; i++ ) { GetFromEnv( startup[i], tmp ); ReplaceString( &cfgFN, tmp ); if( cfgFN[0] != 0 ) { if( startup_parms[i] != NULL ) { parm = startup_parms[i]; } else { c[0] = 0; parm = c; } #if defined( __NT__ ) && !defined( __WIN__ ) { if( !EditFlags.Quiet ) { SetConsoleActiveScreenBuffer( OutputHandle ); } } #endif sline = 0; rc = Source( cfgFN, parm, &sline ); } } if( rc > ERR_NO_ERR ) { Error( "%s on line %u of \"%s\"", GetErrorMsg( rc ), sline, cfgFN ); } if( argc == 1 ) { LoadHistory( NULL ); } else { LoadHistory( cmd ); } if( EditVars.GrepDefault == NULL ) { EditVars.GrepDefault = DupString( "*.(c|h)" ); } if( goCmd[0] != 0 ) { KeyAddString( goCmd ); } if( keysToPush != NULL ) { KeyAddString( keysToPush ); } #ifdef __WIN__ if( lineToGoTo != 0 ) { SetCurrentLine( lineToGoTo ); NewCursor( CurrentWindow, EditVars.NormalCursorType ); } #endif AutoSaveInit(); HalfPageLines = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES ) / 2 - 1; #if defined( _M_X64 ) VarAddGlobalStr( "OSX64", "1" ); #elif defined( _M_IX86 ) && !defined( _M_I86 ) VarAddGlobalStr( "OS386", "1" ); #endif if( EditVars.StatusString == NULL ) { EditVars.StatusString = DupString( "L:$6L$nC:$6C" ); } UpdateStatusWindow(); #ifdef __WIN__ if( CurrentInfo == NULL ) { // no file loaded - screen is disconcertenly empty - reassure DisplayFileStatus(); } #endif NewCursor( CurrentWindow, EditVars.NormalCursorType ); #if defined( __NT__ ) && !defined( __WIN__ ) { SetConsoleActiveScreenBuffer( OutputHandle ); } #endif } /* doInitializeEditor */
/******************************************************************** StrAllocStringAnsi - allocates or reuses dynamic string memory and copies in an existing ANSI string NOTE: caller is responsible for freeing ppwz even if function fails NOTE: cchSource must equal the length of wzSource (not including the NULL terminator) NOTE: if cchSource == 0, length of wzSource is used instead ********************************************************************/ extern "C" HRESULT DAPI StrAllocStringAnsi( __inout LPWSTR* ppwz, __in LPCSTR szSource, __in DWORD_PTR cchSource, __in UINT uiCodepage ) { Assert(ppwz && szSource); HRESULT hr = S_OK; LPWSTR pwz = NULL; DWORD_PTR cch = 0; DWORD_PTR cchDest = cchSource; // at least enough if (*ppwz) { cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1) if (-1 == cch) { ExitOnFailure(hr = E_INVALIDARG, "failed to get size of destination string"); } cch /= sizeof(WCHAR); //convert the count in bytes to count in characters } if (0 == cchSource) { cchDest = ::MultiByteToWideChar(uiCodepage, 0, szSource, -1, NULL, 0); if (0 == cchDest) { ExitWithLastError1(hr, "failed to get required size for conversion to unicode: %s", szSource); } --cchDest; //subtract one because MultiByteToWideChar includes space for the NULL terminator that we track below } else if (L'\0' == szSource[cchSource]) // if the source already had a null terminator, don't count that in the character count because we track it below { cchDest = cchSource - 1; } if (cch < cchDest + 1) { cch = cchDest + 1; if (cch >= MAXDWORD / sizeof(WCHAR)) { ExitOnFailure1(hr = E_OUTOFMEMORY, "Not enough memory to allocate string of size: %d", cch); } if (*ppwz) { pwz = static_cast<LPWSTR>(MemReAlloc(*ppwz, sizeof(WCHAR) * cch, TRUE)); } else { pwz = static_cast<LPWSTR>(MemAlloc(sizeof(WCHAR) * cch, TRUE)); } ExitOnNull1(pwz, hr, E_OUTOFMEMORY, "failed to allocate string, len: %d", cch); *ppwz = pwz; } if (0 == ::MultiByteToWideChar(uiCodepage, 0, szSource, 0 == cchSource ? -1 : (int)cchSource, *ppwz, (int)cch)) { ExitWithLastError1(hr, "failed to convert to unicode: %s", szSource); } (*ppwz)[cchDest] = L'\0'; LExit: return hr; }