CORE_PROC(int, RelayOutput)( PDATAPATH pdp , PTEXT (CPROC *Datacallback)( PDATAPATH pdp, PTEXT pLine ) ) { extern int gbTrace; if( pdp->pPrior ) { int moved = 0; PTEXT p; //if( gbTrace ) // lprintf( WIDE("Relay output from %s to %s..........") // , GetText( pdp->pName ) // , GetText( pdp->pPrior->pName ) // ); while( ( p = (PTEXT)DequeLink( &pdp->Output ) ) ) { //if( gbTrace ) // lprintf( WIDE("Data is: %s"), GetText( p ) ); if( Datacallback && !( ( p->flags & TF_RELAY ) == TF_RELAY ) ) { for( p = Datacallback( pdp, p ); p; p = Datacallback( pdp, NULL ) ) { EnqueLink( &pdp->pPrior->Output, p ); } } else { #ifdef _DEBUG //PTEXT out = BuildLine( p ); //Log1( WIDE("Relay Out: %s"), GetText( out ) ); //LineRelease( out ); #endif EnqueLink( &pdp->pPrior->Output, p ); } } // stop relaying closes at datasource points //if( !pdp->pPrior->flags.Data_Source ) pdp->flags.Closed |= pdp->pPrior->flags.Closed; if( pdp->pPrior->Write ) moved = pdp->pPrior->Write( pdp->pPrior ); return moved; } else { PTEXT p; while( ( p = (PTEXT)DequeLink( &pdp->Output ) ) ) { if( gbTrace ) { PTEXT pLine = BuildLine( p ); lprintf( WIDE("Relay to dev NULL... Data is: %s"), GetText( pLine ) ); LineRelease( pLine ); } LineRelease( p ); } } return 0; }
CORE_PROC(int, RelayInput)( PDATAPATH pdp , PTEXT (CPROC *Datacallback)( PDATAPATH pdp, PTEXT pLine ) ) { extern int gbTrace; if( pdp->pPrior ) { PTEXT p; int moved = 0; if( gbTrace ) xlprintf(LOG_NOISE+1)( WIDE("Relay input from %s to %s..........") , GetText( pdp->pPrior->pName ) , GetText( pdp->pName ) ); do { if( pdp->pPrior->Read ) { pdp->pPrior->Read( pdp->pPrior ); } if( IsQueueEmpty( &pdp->pPrior->Input ) ) break; //Log( WIDE("Has some input to handle...") ); while( ( p = (PTEXT)DequeLink( &pdp->pPrior->Input ) ) ) { if( gbTrace ) lprintf( WIDE("Data is: %s"), GetText( p ) ); if( Datacallback && !( ( p->flags & TF_RELAY ) == TF_RELAY ) ) { //lprintf( WIDE("Data callback...") ); for( p = Datacallback( pdp, p ); p; p = Datacallback( pdp, NULL ) ) { moved++; if( p != (POINTER)1 ) EnqueLink( &pdp->Input, p ); else lprintf( WIDE("Data was consumed by datapath.") ); } } else { PTEXT out = BuildLine( p ); Log1( WIDE("Relay In: %s"), GetText( out ) ); LineRelease( out ); moved++; EnqueLink( &pdp->Input, p ); } } if( gbTrace && !moved && !pdp->pPrior->flags.Closed ) { lprintf( WIDE("Did not result in data, try reading source again, rerelay. %s %s"), GetText( pdp->pName ), GetText( pdp->pPrior->pName ) ); } } while( !moved && !pdp->pPrior->flags.Closed ); // stop relaying closes at datasource points //if( !pdp->pPrior->flags.Data_Source ) pdp->flags.Closed |= pdp->pPrior->flags.Closed; return moved; } return 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 ); }
int GetInputData( int bWord, PSENTIENT ps, PTEXT parameters ) { if( ps->Data ) { PTEXT pSave, temp; PTEXT *pInd = NULL; pSave = parameters; lprintf( WIDE("Get data from datapath...") ); if( !( ( temp = GetParam( ps, ¶meters ) ) ) ) { lprintf( WIDE("No parameters specified to get line") ); LineRelease( ps->pLastResult ); ps->pLastResult = NULL; pInd = &ps->pLastResult; } else { if( temp == pSave ) { DECLTEXT( msg, WIDE("is not a valid variable reference.") ); EnqueLink( &ps->Command->Output, SegAppend( SegDuplicate( temp ), (PTEXT)&msg ) ); return FALSE; } if( temp->flags & TF_INDIRECT ) { LineRelease( GetIndirect( temp ) ); SetIndirect( temp, NULL ); pInd = (PTEXT*)&temp->data.size; } else { DECLTEXT( msg, WIDE("is not a valid variable reference(not indirect).") ); EnqueLink( &ps->Command->Output, SegAppend( SegDuplicate( temp ), (PTEXT)&msg ) ); return FALSE; } } if( !pInd ) { DECLTEXT( msg, WIDE("FATAL ERROR: Did not set pInd (GetLine)") ); EnqueLink( &ps->Command->Output, (PTEXT)&msg ); return FALSE; } // try grabbing an existing line - could be put there from BURST of prior... if( !ps->Data->CurrentWord ) // just got last word off line... { if( ps->Data->CurrentLine ) { LineRelease( ps->Data->CurrentLine ); ps->Data->CurrentLine = NULL; } } if( !ps->Data->CurrentLine ) { // Gather Data from input source.... // data from HT_CLIENT 'appears' asynchrous // to scripting.... if( ps->Data->Read ) ps->Data->Read( ps->Data ); // this returns a completeline... ps->Data->CurrentLine = (PTEXT)DequeLink( &ps->Data->Input ); } if( ps->Data->CurrentLine ) if( !ps->Data->CurrentWord ) ps->Data->CurrentWord = ps->Data->CurrentLine; if( ps->Data->CurrentWord ) { // indirect pointer will be null. if( bWord ) { *pInd = SegDuplicate( ps->Data->CurrentWord ); ps->Data->CurrentWord = NEXTLINE( ps->Data->CurrentWord ); } else { // duplicate to end of line... which may be whole - or // may be partial because of prior GETWORD from the line... // then release the data input line... // must duplicate the data in either case cause // it will be deleted with additional setting of the // variable... *pInd = TextDuplicate( ps->Data->CurrentWord, FALSE ); LineRelease( ps->Data->CurrentWord ); ps->Data->CurrentLine = NULL; // do NOT release this line... ps->Data->CurrentWord = NULL; // no word on line } } if( ps->CurrentMacro && *pInd ) ps->CurrentMacro->state.flags.bSuccess = TRUE; } return FALSE; }
//-------------------------------------- int CPROC COMMAND( PSENTIENT ps, PTEXT parameters ) { PTEXT temp; PTEXT devname; if( ( devname = GetParam( ps, ¶meters ) ) ) { // find device to see if it's already open... // by name! // but - this causes a problem for nested scripts // which are going to have to be artificiailly inceminated // with a unique name maybe something like script_##### PDATAPATH pdp = FindOpenDevice( ps, devname ); if( pdp ) { if( !ps->CurrentMacro ) { PVARTEXT pvt; pvt = VarTextCreate(); vtprintf( pvt, WIDE("Device named %s is already open."), GetText( devname ) ); EnqueLink( &ps->Command->Output, (POINTER)VarTextGet( pvt ) ); VarTextDestroy( &pvt ); } return -1; } if( ( temp = GetParam( ps, ¶meters ) ) ) { PDATAPATH pdp; //lprintf( WIDE("Opening device handle named: %s"), GetText( devname ) ); if( ( pdp = OpenDevice( &ps->Command, ps, temp, parameters ) ) ) { PTEXT pCommand; PDATAPATH pOldPath; while( devname->flags & TF_INDIRECT ) devname = GetIndirect( devname ); pdp->pName = SegDuplicate( devname ); if( ps->Command ) { // remove old command queue so close won't remove // ps->Command->Input = NULL; // close the command queue... // update to the new queue in the sentience // if the new one is a data source, then we // need to move old commands to new path - // otherwise they may/will get lost. if( ps->Command->flags.Data_Source && !ps->Command->flags.Dont_Relay_Prior) { pOldPath = ps->Command->pPrior; // move all commands from old queue to new queue while( ( pCommand = (PTEXT)DequeLink( &pOldPath->Input ) ) ) { EnqueLink( &ps->Command->Input, pCommand ); } while( ( pCommand = (PTEXT)DequeLink( &pOldPath->Output ) ) ) { EnqueLink( &ps->Command->Output, pCommand ); } } } if( ps->CurrentMacro ) ps->CurrentMacro->state.flags.bSuccess = TRUE; } } else { DECLTEXT( msg, WIDE("Command must specify a name (/command <name> <device> <options...)") ); EnqueLink( &ps->Command->Output, (PTEXT)&msg ); } } return FALSE; }