TEXTCHAR NextCharEx( PTEXT input, INDEX idx ) { if( ( ++idx ) >= input->data.size ) { idx -= input->data.size; input = NEXTLINE( input ); } if( input ) return input->data.data[idx]; return 0; }
static size_t GetInputIndex( PUSER_INPUT_BUFFER pci ) { PTEXT start = pci->CollectionBuffer; size_t index = 0; SetStart( start ); while( start != pci->CollectionBuffer ) { index += GetTextSize( start ); start = NEXTLINE( start ); } index += pci->CollectionIndex; return index; }
int Widget_DoStroke( PCHAT_LIST list, PTEXT stroke ) { INDEX i; int bOutput = FALSE; DECLTEXT( key, " " ); //Log1( "Do Stroke with %c", stroke->data.data[0] ); if( list->input.command_mark_start != list->input.command_mark_end ) { int n; SetUserInputPosition( list->input.CommandInfo, list->input.command_mark_start, COMMAND_POS_SET ); for( n = 0; n < ( list->input.command_mark_end - list->input.command_mark_start ); n++ ) DeleteUserInput( list->input.CommandInfo ); list->input.command_mark_start = list->input.command_mark_end = 0; } { PTEXT seg; size_t outchar; int had_cr = 0; seg = stroke; while( seg ) { outchar = 0; for( i = 0; i < seg->data.size; i++ ) { if( seg->data.data[i] == '\n' ) { if( !had_cr ) seg->data.data[outchar++] = '\n'; // carriage return = linefeed else had_cr = FALSE; } else if( seg->data.data[i] == '\r' ) { had_cr = TRUE; seg->data.data[outchar++] = '\n'; // carriage return = linefeed } else seg->data.data[outchar++] = seg->data.data[i]; // save any other character } if( outchar != i ) seg->data.size = outchar; seg = NEXTLINE( seg ); } GatherUserInput( list->input.CommandInfo , (PTEXT)stroke ); } return TRUE; }
void StoreMacros( FILE *pFile, PSENTIENT ps ) { { INDEX idx; PLIST pVars; PTEXT pVar, pVal; pVars = ps->Current->pVars; fprintf( pFile, WIDE("\n## Begin Variables\n") ); LIST_FORALL( pVars, idx, PTEXT, pVar ) { fprintf( pFile, WIDE("/Declare %s "), GetText( pVar ) ); pVal = BuildLine( GetIndirect( NEXTLINE( pVar ) ) ); if( pVal ) fprintf( pFile, WIDE("%s\n"), GetText( pVal ) ); else fprintf( pFile, WIDE("\n") ); } fprintf( pFile, WIDE("\n## Begin Macros\n") ); }
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; }
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. }
void Menu_Process() { // Handle Menu Display depending on user input switch (menuState) { case HOMEMENU: lcd_4line(); display_1 = home[HOMEITEMBEGIN]; display_2 = home[HOMEITEMFIRST]; display_3 = home[HOMEITEMSECOND]; display_4 = home[HOMEITEMTHIRD]; // get next menuIDX if (NEWHOMEIDX != menuIDX) { unselALL(); menuIDX = NEWHOMEIDX; sel(); } break; // IP Address case IPADDR: lcd_4line(); showIPAddress(); display_1 = "IP:"; display_2 = (char*)ip_address; display_3 = NEXTLINE((char*)ip_address); display_4 = ""; break; // HOME Config case HOMECONFIG: if (!HAVE_SET_UP_HOME) { startConfig(); configHome(); DONE(ONCE_HOME); endConfig(); } else deviceConfigured(); break; // NCSU Config case NCSUCONFIG: if (!HAVE_SET_UP_NCSU) { startConfig(); configNCSU(); DONE(ONCE_NCSU); endConfig(); } else deviceConfigured(); break; default: return; } }
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 ); }
void HTTPCollapse( PTEXT *ppText ) { PTEXT output; PTEXT input = *ppText; while( input ) { if( GetText( input )[0] == '+' ) { PTEXT subst; // sometimes a + can be attached to a number // so much for the natural language parser dealing with // a machine oriented protocol... if( GetTextSize( input ) > 1 ) { SegSplit( &input, 1 ); } subst = GetSubst( '+' ); SegInsert( subst, input ); LineRelease( SegGrab( input ) ); input = subst; if( !PRIORLINE( input ) ) (*ppText) = input; } else if( TextIs( input, WIDE("%") ) ) { PTEXT next = NEXTLINE( input ); if( next ) { PTEXT subst; SegSplit( &next, 2 ); subst = GetSubst( *(unsigned short*)GetText( next ) ); if( subst ) { PTEXT nextnext = NEXTLINE( next ); PTEXT prior = SegBreak( input ); if( !prior ) { *ppText = SegAppend( subst, nextnext ); } if( nextnext ) { SegBreak( nextnext ); if( !prior ) *ppText = nextnext; else SegAppend( prior, nextnext ); SegInsert( subst, nextnext ); input = nextnext; continue; } else { SegAppend( prior, (PTEXT)&subst ); input = NULL; continue; } } // if not subst... just continue stepping, no replacement nessecary? } } input = NEXTLINE( input ); } output = BuildLine( *ppText ); LineRelease( *ppText ); (*ppText) = output; }
void ParseURI( CTEXTSTR string ) { int state; PTEXT words; PTEXT delete_seg = NULL; PTEXT line = SegCreateFromText( string ); PTEXT filename = NULL; PTEXT varname = NULL; PTEXT varvalue = NULL; PTEXT content = NULL; int content_length; struct { uint32_t bInvalid : 1; uint32_t bGet : 1; uint32_t bPost : 1; uint32_t bBinary : 1; // reading the content... uint32_t bValue : 1; } flags; // we got a line, therefore we can process it... // only thing then is the last line in the block ... state = GET_FILENAME; words = burst( line ); delete_seg = words; // though... LineRelease( line ); flags.bValue = 0; while( words ) { DECLTEXT( page, WIDE("page") ); DECLTEXT( CGI, WIDE("CGI") ); //printf( "state:%d word:%s \r\n",state, GetText(words ) ); // what does stuff have now? the whole thign? a line? if( !GetTextSize( words ) ) switch( state ) { case GET_HTTP_EOL: state = GET_HTTP_METAVAR; break; case GET_HTTP_METAVAR: case GET_CGI: goto AddCGIVariable; break; } else switch( state ) { case RESET: state = GET_COMMAND; continue; // skip ahead and try new state; break; case GET_COMMAND: if( TextLike( words, WIDE("GET") ) ) { state = GET_FILENAME; //flags.bGet = TRUE; } else if( TextLike( words, WIDE("POST") ) ) { state = GET_FILENAME; //flags.bPost = TRUE; } else { flags.bInvalid = TRUE; } break; case GET_FILENAME: if( !filename && TextIs( words, WIDE("/") ) ) { // this is rude, and should never be done, // however this filter consumes all data anyhow, SO // mangling this will not hurt much... words->format.position.offset.spaces = 0; } if( TextIs( words, WIDE("?") ) || words->format.position.offset.spaces ) { if( !words->format.position.offset.spaces ) state = GET_CGI; else state = GET_HTTP_VERSION; filename = NEXTLINE( filename ); LineRelease( SegBreak( filename ) ); HTTPCollapse( &filename ); //AddVariableExxx( ps, ps->Current, (PTEXT)&page, filename, FALSE,TRUE,TRUE DBG_SRC ); //AddVariable( ps, ps->Current, (PTEXT)&CGI, TextDuplicate( NEXTLINE( words ), FALSE ) ); LineRelease( filename ); filename = NULL; } else { filename = SegAppend( filename, SegDuplicate( words ) ); } break; case GET_CGI: if( words->format.position.offset.spaces ) { state = GET_HTTP_VERSION; goto AddCGIVariable; } else { if( TextIs( words, WIDE("=") ) ) { HTTPCollapse( &varname ); flags.bValue = 1; } else if( TextIs( words, WIDE("&") ) ) { AddCGIVariable: HTTPCollapse( &varvalue ); HTTPCollapse( &varname ); if( TextLike( varname, WIDE("content-length") ) ) { content_length= IntCreateFromText( GetText( varvalue ) ); } { struct VAR *v = New( struct VAR ); v->varname = varname; varname = NULL; v->varvalue = varvalue; varvalue = NULL; AddLink( &l.vars, v ); } //AddVariableExxx( ps, ps->Current, pmdp->varname, pmdp->varvalue, FALSE,TRUE,TRUE DBG_SRC ); //LineRelease( varname ); //LineRelease( varvalue ); //varname = NULL; //varvalue = NULL; flags.bValue = 0; } else { if( flags.bValue ) { varvalue = SegAppend( varvalue, SegDuplicate( words ) ); } else { //printf( "add var" ); varname = SegAppend( varname, SegDuplicate( words ) ); } } } break; case GET_HTTP_VERSION: if( TextIs( words, WIDE("HTTP") ) ) { // okay - don't really do anything... next word is the version... } else { // TextIs( words, "/" ); // this is a token before the number... // Version better be something like 1.1 1.0? // well wait for EOL... state = GET_HTTP_EOL; } break; case GET_HTTP_EOL: if( !GetTextSize( words ) ) { state = GET_HTTP_METAVAR; } break; case GET_HTTP_METAVAR: { if( !flags.bValue && TextIs( words, WIDE(":") ) ) { flags.bValue = TRUE; } else { if( flags.bValue ) { varvalue = SegAppend( varvalue, SegDuplicate( words ) ); } else { varname = SegAppend( varname, SegDuplicate( words ) ); } } } break; case GET_HTTP_CONTENT: if( !content_length ) { DebugBreak(); state = RESET; } else { // hmm we've parsed everything up to here, but now we need blocks, binary blocks. content = SegAppend( content, words ); if( LineLength( content ) == content_length ) { //ProcessPostCGI( common.Owner, content ); //AddVariableExxx( ps, ps->Current, (PTEXT)&CGI, content, FALSE,TRUE,TRUE DBG_SRC ); //AddVariable( ps, ps->Current, (PTEXT)&CGI, content ); LineRelease( content ); //InvokeBehavior( "http.request", common.Owner->Current, common.Owner, NULL ); //InvokeBehavior( "http_request", common.Owner->Current, common.Owner, NULL ); state = RESET; } words = NULL; } break; }
if( LineLength( content ) == content_length ) { //ProcessPostCGI( common.Owner, content ); //AddVariableExxx( ps, ps->Current, (PTEXT)&CGI, content, FALSE,TRUE,TRUE DBG_SRC ); //AddVariable( ps, ps->Current, (PTEXT)&CGI, content ); LineRelease( content ); //InvokeBehavior( "http.request", common.Owner->Current, common.Owner, NULL ); //InvokeBehavior( "http_request", common.Owner->Current, common.Owner, NULL ); state = RESET; } words = NULL; } break; } words = NEXTLINE( words ); } LineRelease( delete_seg ); if( varname && varvalue ) { HTTPCollapse( &varvalue ); HTTPCollapse( &varname ); { struct VAR *v = New( struct VAR ); v->varname = varname; varname = NULL; v->varvalue = varvalue; varvalue = NULL; AddLink( &l.vars, v ); } }
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; } }
void ProcessEnum( void ) { PTEXT pLine = GetCurrentWord(); char *text; // look for enum keyword.... while( pLine ) { text = GetText( pLine ); if( TextIs( pLine, WIDE("enum") ) ) { if( g.current_enum ) { fprintf( stderr, WIDE("%s(%d): Syntax error enumeration within enum?\n") , GetCurrentFileName(), GetCurrentLine() ); } g.current_enum = Allocate( sizeof( ENUM_TABLE ) ); g.current_enum->entries = NULL; g.current_enum->name = NULL; if( g.current_entry ) { fprintf( stderr, WIDE("Coding error - uncommited enumeration value. Lost memory.\n") ); g.current_entry = NULL; } g.flags.get_identifier = 1; } else { if( g.flags.get_identifier ) { if( text[0] != '{' ) { if( g.current_enum->name ) { fprintf( stderr, WIDE("%s(%d): Error multiple identifers for enum\n") , GetCurrentFileName(), GetCurrentLine() ); } else g.current_enum->name = SegDuplicate( pLine ); } else { // well whether or not there was an identifier (name) // we're done getting it.... g.flags.get_identifier = 0; } } else // collecting enumeration values... { if( text[0] == '}' ) { } else if( text[0] == ',' ) { } else if( text[0] == '=' ) { } else if( g.current_entry ) { if( text[0] == ',' ) { if( !g.flags.current_value_set ) { if( g.current_enum->last_entry ) g.current_entry->value = g.current_enum->last_entry->value + 1; else g.current_entry->value = 0; } if( g.current_enum->last_entry ) g.current_enum->last_entry->next = g.current_entry; else g.current_enum->entries = g.current_entry; g.current_enum->last_entry = g.current_entry; g.current_entry = NULL; } else { } } else { if( text[0] == ',' ) { fprintf( stderr, WIDE("Error - unexpected comma sepeartor enumeration.\n") ); } if( text[0] == '=' ) { fprintf( stderr, WIDE("Error - unexpected comma sepeartor enumeration.\n") ); } g.current_entry = Allocate( sizeof( ENUM_ENTRY ) ); g.flags.current_value_set = 0; g.current_entry->next = NULL; g.current_entry->name = SegDuplicate( pLine ); } } } pLine = NEXTLINE( pLine ); } }
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; }