예제 #1
0
PTEXT SplitLine( PTEXT pLine, INDEX nPos )
{
	PTEXT newseg, end;
	if( !nPos )
	{
		if( PRIORLINE( pLine ) )
			return PRIORLINE( pLine ); 
		// otherwise we'll have to insert a new segment 
		// in front of this....
		newseg = SegCreate( BUILD_LINE_OUTPUT_SIZE );
		newseg->data.size = 0;
		pLine->format.position.offset.spaces = 0;
		SegAppend( newseg, pLine );
		return newseg;
	}
	else if( pLine->data.size == nPos )
	{
		// if the point to split is not in the middle of
		// this segment....
		return pLine;
	}

	newseg = SegCreate( BUILD_LINE_OUTPUT_SIZE );

	end = NEXTLINE( pLine );
	SegBreak( end );

	// fill in new segment with trailing data
	newseg->data.size = pLine->data.size - nPos;
	MemCpy( newseg->data.data, pLine->data.data + nPos, newseg->data.size );

	pLine->data.size = nPos; 
	pLine->data.data[nPos] = 0; // terminate with null also...
	SegAppend( pLine
				, SegAppend( newseg, end ) 
				);

	return pLine;
}
예제 #2
0
PTEXT win_get_line(HANDLE hFile)
{
//   extern HANDLE hStdin;
   #define WORKSPACE 1024  // character for workspace
   PTEXT workline=(PTEXT)NULL;
   uint32_t length = 0;
   do
   {
      // create a workspace to read input from the file.
      workline=SegAppend(workline,SegCreate(WORKSPACE));
      SetEnd( workline );
      // read a line of input from the file.
      if( !ReadConsole( hFile
                           , GetText(workline)
                           , WORKSPACE
                           , &length
                           , NULL) ) // if no input read.
      {
         if (PRIORLINE(workline)) // if we've read some.
         {
            PTEXT t;
            workline=PRIORLINE(workline); // go back one.
            SegBreak(t = NEXTLINE(workline));
            LineRelease(t);  // destroy the current segment.
         }
         else
         {
            LineRelease(workline);            // destory only segment.
            workline = NULL;
         }
         break;  // get out of the loop- there is no more to read.
      }
   }
   while (GetText(workline)[length-1]!='\n'); //while not at the end of the line.
   if (workline&&length)  // if I got a line, and there was some length to it.
      SetStart(workline);   // set workline to the beginning.
   return(workline);      // return the line read from the file.
}
예제 #3
0
static uintptr_t CPROC HandleTaskOutput(PTHREAD thread )
{
	PTASK_INFO task = (PTASK_INFO)GetThreadParam( thread );
	{
		task->pOutputThread = thread;
		// read input from task, montiro close and dispatch TaskEnd Notification also.
		{
			PHANDLEINFO phi = &task->hStdOut;
			PTEXT pInput = SegCreate( 4096 );
			int done, lastloop;
			Hold( task );
			done = lastloop = FALSE;
			do
			{
				uint32_t dwRead, dwAvail;
				if( done )
					lastloop = TRUE;
#ifdef _WIN32
				//while(  )
				{

#else
					while( CanRead( phi->handle ) )
#endif
					{
						if( task->flags.log_input )
							lprintf( WIDE( "Go to read task's stdout." ) );
#ifdef _WIN32
						if( !task->flags.process_ended &&
							 ReadFile( phi->handle
										, GetText( pInput ), (DWORD)(GetTextSize( pInput ) - 1)
										, (LPDWORD)&dwRead, NULL ) )  //read the  pipe
						{
#else
							dwRead = read( phi->handle
											 , GetText( pInput )
											 , GetTextSize( pInput ) - 1 );
							if( !dwRead )
							{
#ifdef _DEBUG
												//lprintf( WIDE( "Ending system thread because of broke pipe! %d" ), errno );
#endif
#ifdef WIN32
								continue;
#else
												//lprintf( WIDE( "0 read = pipe failure." ) );
								break;
#endif
							}
#endif
							if( task->flags.log_input )
								lprintf( WIDE( "got read on task's stdout: %d" ), dwRead );
							if( task->flags.bSentIoTerminator )
							{
								if( dwRead > 1 )
									dwRead--;
								else
								{
									if( task->flags.log_input )
										lprintf( WIDE( "Finished, no more data, task has ended; no need for once more around" ) );
									lastloop = 1;
									break; // we're done; task ended, and we got an io terminator on XP
								}
							}
							//lprintf( WIDE( "result %d" ), dwRead );
							GetText( pInput )[dwRead] = 0;
							pInput->data.size = dwRead;
							//LogBinary( GetText( pInput ), GetTextSize( pInput ) );
							if( task->OutputEvent )
							{
								task->OutputEvent( task->psvEnd, task, GetText( pInput ), GetTextSize( pInput ) );
							}
							pInput->data.size = 4096;
#ifdef _WIN32
						}
						else
						{
							DWORD dwError = GetLastError();
							if( ( dwError == ERROR_OPERATION_ABORTED ) && task->flags.process_ended )
							{
								if( PeekNamedPipe( phi->handle, NULL, 0, NULL, (LPDWORD)&dwAvail, NULL ) )
								{
									if( dwAvail > 0 )
									{
										lprintf( WIDE( "caught data" ) );
										// there is still data in the pipe, just that the process closed
										// and we got the sync even before getting the data.
									}
									else
										break;
								}
							}
						}
#endif
					}
#ifdef _WIN32
				}
#endif
				//allow a minor time for output to be gathered before sending
				// partial gathers...
				if( task->flags.process_ended )
#ifdef _WIN32
				{
					// Ending system thread because of process exit!
					done = TRUE;
				}
#else
				//if( !dwRead )
				//	break;
				if( task->pid == waitpid( task->pid, NULL, WNOHANG ) )
				{
					Log( WIDE( "Setting done event on system reader." ) );
					done = TRUE; // do one pass to make sure we completed read
				}
				else
				{
					//lprintf( WIDE( "process active..." ) );
					Relinquish();
				}
#endif
			}
			while( !lastloop );
#ifdef _DEBUG
			if( lastloop )
			{
				//DECLTEXT( msg, WIDE( "Ending system thread because of process exit!" ) );
				//EnqueLink( phi->pdp->&ps->Command->Output, &msg );
			}
			else
			{
				//DECLTEXT( msg, WIDE( "Guess we exited from broken pipe" ) );
				//EnqueLink( phi->pdp->&ps->Command->Output, &msg );
			}
#endif
			LineRelease( pInput );
#ifdef _WIN32
			CloseHandle( task->hReadIn );
			CloseHandle( task->hReadOut );
			CloseHandle( task->hWriteIn );
			CloseHandle( task->hWriteOut );
			//lprintf( WIDE( "Closing process handle %p" ), task->pi.hProcess );
			phi->hThread = 0;
#else
			//close( phi->handle );
			close( task->hStdIn.pair[1] );
			close( task->hStdOut.pair[0] );
         //close( task->hStdErr.pair[0] );
#define INVALID_HANDLE_VALUE -1
#endif
			if( phi->handle == task->hStdIn.handle )
				task->hStdIn.handle = INVALID_HANDLE_VALUE;
			phi->handle = INVALID_HANDLE_VALUE;
			task->pOutputThread = NULL;

			Release( task );
			//WakeAThread( phi->pdp->common.Owner );
			return 0xdead;
		}
	}
}
예제 #4
0
static PTEXT CPROC ParseCommand( PMYDATAPATH pdp, PTEXT buffer )
{
	if( buffer )
	{
		PTEXT pCommand;
     	//Log2( WIDE("buffer: %s(%d)"), GetText( buffer ), GetTextSize( buffer ) );
     	//LogBinary( buffer );
      pCommand = burst( buffer );
      LineRelease( buffer );
      if( pCommand )
      {
         PTEXT pTemp, pStart;
         int bEscaped = FALSE;
         pStart = pTemp = pCommand;
         while( pTemp )
         {
            if( TextIs( pTemp, WIDE("\\") ) )
            {
               if( !bEscaped )
               {
                  PTEXT pNext;
                  pNext = NEXTLINE( pTemp );
                  pNext->format.position.offset.spaces = pTemp->format.position.offset.spaces;
                  LineRelease( SegGrab( pTemp ) );
                  bEscaped = TRUE;
                  pTemp = pNext;
                  continue;
               }
            }
            if( !bEscaped && TextIs( pTemp, WIDE(";") ) )
            {
               PTEXT pPrior;
	           	//Log( WIDE("Splitting the line and enqueing it...") );
               pPrior = pTemp;
               SegBreak( pTemp );
               if( pStart != pTemp )
               {
               	// end of line included!
               	pStart = SegAppend( pStart, SegCreate(0) ); 
                  EnqueLink( &pdp->output, pStart );
               }
               pStart = pTemp = NEXTLINE( pTemp );
               SegBreak( pTemp );
               LineRelease( pPrior ); // remove ';'
               bEscaped = FALSE;
               continue;
            }
            bEscaped = FALSE;
            pTemp = NEXTLINE( pTemp );
         }
         if( pStart )
         {
         	PTEXT line;
         	line = BuildLine( pStart );
         	//Log1( WIDE("Enqueu: %s"), GetText( line ) );
         	LineRelease( line );
            EnqueLink( &pdp->output, pStart );
         }
      }
      else
      {
         // well what now?  I guess pLine got put into Partial...
         // next pass through this all for command recall will blow...
         Log( WIDE("No information from the burst!") );
      }
	}
	return (PTEXT)DequeLink( &pdp->output );
}
예제 #5
0
CORE_PROC( PTEXT, GatherLineEx )( PTEXT *pOutput, INDEX *pIndex, int bInsert, int bSaveCR, int bData, PTEXT pInput )
// if data - assume data is coming from a preformatted source
// otherwise use escape as command entry and clear buffer...
{
	// this routine should be used to process user type character
	// input into a legible line buffer....
	// results in a complete line....
	// the line returned must be used - the output buffer
	// is an accumulator and will contain any partial input buffer
	// which remaineder if an EOL sequence was found....

	// build line in buffer using standard console
	// behavior... 

	INDEX pos
       , len = 0
       , size
       , maxlen = 0;
	PTEXT pReturn = NULL;
	PTEXT pDelete = NULL;
	TEXTCHAR character;
	TEXTSTR output;

	if( !pOutput ) // must supply a holder for partial collection...
		return NULL;

	if( !pInput ) // nothing new input - just using previous collection...
	{
		if( *pOutput )
		{
			// use prior partial as new input....
			pInput = *pOutput;
			pDelete = pInput; // this is never deleted if we use prior...
			SetStart( pInput );
			*pOutput = NULL;
		}
		else
			return NULL;
	}
	// probably first pass of gathering...
	if( !*pOutput )
	{
		*pOutput = SegCreate( BUILD_LINE_OUTPUT_SIZE );
		if( pIndex )
			*pIndex = 0;
		SetTextSize( *pOutput, 0 );
		output = GetText( *pOutput );
		len = 0;
	}
	else if( pIndex )
	{
		output = GetText( *pOutput );
		len = *pIndex;
		if( (*pOutput)->data.size != len )
		{
			if( bInsert )
			{
				// creates a new segment inbetween here.....
				*pOutput = SplitLine( *pOutput, *pIndex );
				output = GetText( *pOutput );
				len = *pIndex = GetTextSize( *pOutput );
			}
			else
			{
				maxlen = (*pOutput)->data.size;
			}
		}
	}
	else
	{
		output = GetText( *pOutput );
		len = GetTextSize( *pOutput );
	}

	while( pInput )
	{
		size = GetTextSize( pInput );
		for( pos = 0; pos < size; pos++ )
		{
			switch( character = GetText( pInput )[pos] )
			{
			case '\x1b':
				if( !bData )
				{
					SetEnd( *pOutput );
					SetStart( *pOutput )
					{
						SetTextSize( *pOutput, 0 );
					}
					SetTextSize( *pOutput, 0 );
					output = GetText( *pOutput );
					len = 0;
				}
				else
					goto defaultcase;
				break;
			case '\x7f': // handle unix type delete too ? perhaps...
				if( !bInsert )
				{
					PTEXT pNext;
					// this will slide from the middle to the end...
					// if bInsert - then prior to entrying this switch
					// the data was split and THIS segment is set to zero.
					pNext = *pOutput;
					if( len != (maxlen = GetTextSize( *pOutput )) )
					{
						MemCpy( output + len, output+len+1, maxlen - len );
						SetTextSize( *pOutput, --maxlen );
					}
					else
					{
						PTEXT pDel;
						pNext = *pOutput;
						do {
							pDel = pNext;
							pNext = NEXTLINE( pNext );
							if( pDel != *pOutput )
							{
								SegGrab( pDel );
								LineRelease( pDel );
							}
						} while( pNext && !GetTextSize( pNext ) );
						if( pNext )
						{
							size_t len2;
							output = GetText( pNext );
							len2 = GetTextSize( pNext ) - 1;
							*pOutput = pNext;
							len = 0;
							MemCpy( output, output+1, len2 );
							SetTextSize( pNext, len2 );
						}
					}
				}
				else // was insert is either at end....
				{
					// I dunno perform sliding delete operation...
					// must refresh the output string....
					{
						PTEXT pNext, pDel;
						pNext = *pOutput;
						do {
							pDel = pNext;
							pNext = NEXTLINE( pNext );
							if( pDel != *pOutput )
							{
								SegGrab( pDel );
								LineRelease( pDel );
							}
						} while( pNext && !GetTextSize( pNext ) );
						if( pNext )
						{
							size_t len2;
							TEXTCHAR *data;
							data = GetText( pNext );
							MemCpy( data, data+1, len2 = (GetTextSize( pNext ) - 1 ));
							SetTextSize( pNext, len2 );
						}
					}
				}
				break;
			case '\b':
				/* perhaps consider using split for backspace in a line...*/
				if( !bInsert )
				{
					PTEXT pNext;
					size_t maxlen;
					// this will slide from the middle to the end...
					// if bInsert - then prior to entrying this switch
					// the data was split and THIS segment is set to zero.
					pNext = *pOutput;
					maxlen = GetTextSize( *pOutput );
					while( !maxlen && PRIORLINE( *pOutput ) )
					{
						*pOutput = PRIORLINE( *pOutput );
						len = maxlen = GetTextSize( *pOutput );
					}
					if( maxlen )
					{
						if( len != maxlen )
						{
							size_t sz;
							sz = maxlen - len;
							MemCpy( output + len - 1, output + len, sz );
							SetTextSize( *pOutput, maxlen - 1 );
							len--;
						}
						else
						{
							SetTextSize( *pOutput, --len );
						}
					}
				}
				else // was insert is either at end....
				{
					if( len )
					{
						SetTextSize( *pOutput, --len );
					}
					else
					{
						if( PRIORLINE( *pOutput ) )
						{
							*pOutput = PRIORLINE( *pOutput );
							len = GetTextSize( *pOutput );
						}

						if( len )
							SetTextSize( *pOutput, --len );
					}
				}
				break;
			case '\r': // ignore this character...
				if( !bSaveCR )
					break;
				// falls through .. past this and saves the return...
				if(0)
			case '\n':
				if( !pReturn )
				{
					// transfer *pOutput to pReturn....
					pReturn = *pOutput;
					SetEnd( pReturn );
					output = GetText( pReturn );
					len = GetTextSize( pReturn );
					output[len] = character;
					SetTextSize( pReturn, ++len );
					// begin next collection in case more data is in the input...
					*pOutput = SegCreate( BUILD_LINE_OUTPUT_SIZE );
					SetTextSize( *pOutput, 0 );
					output = GetText( *pOutput );
					len = 0;
					break;
				}
				// store carriage return... 
			default:
    defaultcase:
				output[len++] = character;

				if( (maxlen && len == maxlen ) ||
                len == BUILD_LINE_OUTPUT_SIZE )
				{
					PTEXT pTemp;
					SetTextSize( *pOutput, len );
					if( !NEXTLINE( *pOutput ) )
					{
						SegAppend( *pOutput, pTemp = SegCreate( BUILD_LINE_OUTPUT_SIZE ) );
						SetTextSize( pTemp, 0 );
					}
					else
					{
						pTemp = NEXTLINE( *pOutput );
						maxlen = GetTextSize( pTemp );
					}
					*pOutput = pTemp;
					output = GetText( *pOutput );
					len = 0;
				}
				else
				{
					if( bInsert ) // insertion happens at end of segment
                             // and the segment is broken...
					{
						if( !pIndex || ( len > *pIndex ) )
							SetTextSize( *pOutput, len );
					}
					else
						if( len > GetTextSize( *pOutput ) )
						{
							SetTextSize( *pOutput, len );
						}
				}

				break;
			}
		}