Beispiel #1
0
BOOL CSerialPDD::Open()
{
    PHYSICAL_ADDRESS	ioPhysicalBase = { S3C6410_BASE_REG_PA_GPIO, 0};
    ULONG				inIoSpace = 0;

    if (InterlockedExchange(&m_lOpenCount,1) !=0)
        return FALSE;
    
    PREFAST_ASSERT(m_PowerHelperHandle!=INVALID_HANDLE_VALUE);
    ASSERT(m_hPowerLock==NULL);
    m_hPowerLock= DDKPwr_RequestLevel( m_PowerHelperHandle, D0 );  
    ASSERT(m_hPowerLock!=NULL);
    
    SetDefaultConfiguration(); 
    InitLine(TRUE);
    InitReceive(TRUE);
    InitXmit(TRUE);

    if(cUart_Index==3)
    {
        if (TranslateBusAddr(m_hParent,Internal,0, ioPhysicalBase,&inIoSpace,&ioPhysicalBase))
    	{
	// Map it if it is Memeory Mapped IO.
	g_pIOPregs = (S3C6410_GPIO_REG *)DrvLib_MapIoSpace(ioPhysicalBase.LowPart , sizeof(S3C6410_GPIO_REG),FALSE);	
	g_pIOPregs->GPCCON &= ~(0xf<<28);	///< Clear Bit
	g_pIOPregs->GPCCON |=  (0x1<<28); 	///< Select UART IP                
	g_pIOPregs->GPCPUD &= ~(0x3<<14);    ///< Pull-Up/Down Disable  
	//g_pIOPregs->GPCDAT |=1<<7;

    	}
    }
    return TRUE;
}
Beispiel #2
0
void CDebug::Initialize()
{
	m_pDevice = _SINGLE(CDevice)->GetDevice();
	if(!m_pDevice)
		return;
	_SINGLE(CTimeManager)->Init();
	//CreateVertexBuffer();

	//memset(&m_tGridMaterial, 0, sizeof(D3DMATERIAL9));
	//m_tGridMaterial.Diffuse.a = 1.f;
	//m_tGridMaterial.Diffuse.r = 1.f;
	//m_tGridMaterial.Diffuse.g = 0.8f;
	//m_tGridMaterial.Diffuse.b = 1.f;
	//m_tGridMaterial.Power = 0.2f;
	//m_tGridMaterial.Specular = m_tGridMaterial.Diffuse;
	//m_tGridMaterial.Ambient = m_tGridMaterial.Diffuse;

	//m_pTerrain = new CTerrainMesh;

	//m_pTerrain->Initialize();

	InitFont();
	InitLog();
	InitLine();

	//AddText3D( D3DXVECTOR3(10, 3, 10), _T("3D텍스트다!") );

}
Beispiel #3
0
LinkComp::LinkComp (Line* line) {
    if (line != nil) {
        Coord x0, y0, x1, y1;
        float fx0, fy0, fx1, fy1;

        line->GetOriginal(x0, y0, x1, y1);
        Transformer* t = line->GetTransformer();
        Graphic* parent = new Picture(line);
        parent->SetTransformer(nil);

        if (t == nil) {
            fx0 = x0; fy0 = y0; fx1 = x1; fy1 = y1;
        } else {
            t->Transform(float(x0), float(y0), fx0, fy0);
            t->Transform(float(x1), float(y1), fx1, fy1);
        }
        delete line;
        line = new Line(0, 0, 1, 1);
        InitLine(line, fx0, fy0, fx1, fy1);

        PinGraphic* pg1 = new PinGraphic;
        PinGraphic* pg2 = new PinGraphic;
        pg1->SetBrush(psnonebr);
        pg2->SetBrush(psnonebr);
        pg1->Translate(fx0, fy0);
        pg2->Translate(fx1, fy1);

        _conn1 = new PinComp(pg1);
        _conn2 = new PinComp(pg2);

        parent->Append(line, pg1, pg2);
        SetGraphic(parent);
    }
}
void CPdd6410Uart::PostInit()
{
    DWORD dwCount=0;
    m_HardwareLock.Lock();
    m_pReg6410Uart->Write_UCON(0); // Set to Default;
    DisableInterrupt(S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM);
    // Mask all interrupt.
    while ((GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM))!=0 && dwCount <MAX_RETRY)
    {
        InitReceive(TRUE);
        InitLine(TRUE);
        ClearInterrupt(S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM);
        dwCount++;
    } 
    ASSERT((GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM))==0);
    m_HardwareLock.Unlock();
    CSerialPDD::PostInit();
    CeSetPriority(m_dwPriority256);
#ifdef DEBUG
    if ( ZONE_INIT )
    {
        m_pReg6410Uart->DumpRegister();
    }
#endif
    ThreadStart();  // Start IST.
}
Beispiel #5
0
static void PreprocessLine (void)
/* Translate one line. */
{
    /* Trim whitespace and remove comments. The function returns the number of
     * identifiers found. If there were any, we will have to check for macros.
     */
    SB_Clear (MLine);
    if (Pass1 (Line, MLine) > 0) {
        MLine = InitLine (MLine);
        SB_Reset (Line);
        SB_Clear (MLine);
        MacroReplacement (Line, MLine);
    }

    /* Read from the new line */
    SB_Reset (MLine);
    MLine = InitLine (MLine);
}
Beispiel #6
0
static void
InitLines (void)
{
  InitReduce (INITLINES1);

  if (ltoken_getCode (nextToken) != LEOFTOKEN)
    {
      InitLine ();
      InitReduce (INITLINES2);
    }

  while (ltoken_getCode (nextToken) != LEOFTOKEN)
    {
      InitLine ();
      InitReduce (INITLINES3);
    }

}
Beispiel #7
0
void CSerialPDD::Reset()
{
    InitialPower(TRUE);
    InitModem(TRUE);
    InitLine(TRUE);
    InitReceive(TRUE);
    InitXmit(TRUE);
    InitialEnableInterrupt(TRUE); 
}
Beispiel #8
0
void LinkComp::Update () {
    float fx0, fy0, fx1, fy1;
    Transformer* t1 = _conn1->GetGraphic()->GetTransformer();
    Transformer* t2 = _conn2->GetGraphic()->GetTransformer();

    t1->Transform(0., 0., fx0, fy0);
    t2->Transform(0., 0., fx1, fy1);

    InitLine(GetLine(), fx0, fy0, fx1, fy1);
    Notify();
}
Beispiel #9
0
static void MacroReplacement (StrBuf* Source, StrBuf* Target)
/* Perform macro replacement. */
{
    ident       Ident;
    Macro*      M;

    /* Remember the current input and switch to Source */
    StrBuf* OldSource = InitLine (Source);

    /* Loop substituting macros */
    while (CurC != '\0') {
        /* If we have an identifier, check if it's a macro */
        if (IsSym (Ident)) {
            /* Check if it's a macro */
            if ((M = FindMacro (Ident)) != 0 && !M->Expanding) {
                /* It's a macro, expand it */
                ExpandMacro (Target, M);
            } else {
                /* An identifier, keep it */
                SB_AppendStr (Target, Ident);
            }
        } else if (IsQuote (CurC)) {
            CopyQuotedString (Target);
        } else if (IsSpace (CurC)) {
            if (!IsSpace (SB_LookAtLast (Target))) {
                SB_AppendChar (Target, CurC);
            }
            NextChar ();
        } else {
            SB_AppendChar (Target, CurC);
            NextChar ();
        }
    }

    /* Switch back the input */
    InitLine (OldSource);
}
void CAdActor::FollowPath()
{
	// skip current position
	m_Path->GetFirst();
	while(m_Path->GetCurrent()!=NULL)
	{
		if(m_Path->GetCurrent()->x != m_PosX || m_Path->GetCurrent()->y != m_PosY) break;
		m_Path->GetNext();
	}

	// are there points to follow?
	if(m_Path->GetCurrent() != NULL)
	{
		m_State = STATE_FOLLOWING_PATH;;
		InitLine(CBPoint(m_PosX, m_PosY), *m_Path->GetCurrent());
	}
	else
	{
		if(m_AfterWalkDir!=DI_NONE) TurnTo(m_AfterWalkDir);
		else m_State = STATE_READY;
	}
}
Beispiel #11
0
static void DoPragma (void)
/* Handle a #pragma line by converting the #pragma preprocessor directive into
 * the _Pragma() compiler operator.
 */
{
    /* Skip blanks following the #pragma directive */
    SkipWhitespace (0);

    /* Copy the remainder of the line into MLine removing comments and ws */
    SB_Clear (MLine);
    Pass1 (Line, MLine);

    /* Convert the directive into the operator */
    SB_CopyStr (Line, "_Pragma (");
    SB_Reset (MLine);
    Stringize (MLine, Line);
    SB_AppendChar (Line, ')');

    /* Initialize reading from line */
    SB_Reset (Line);
    InitLine (Line);
}
Beispiel #12
0
BOOL CSerialPDD::Close()
{
    if (InterlockedExchange(&m_lOpenCount,0) !=1)
        return FALSE;
    InitXmit(FALSE);
    InitReceive(FALSE);
    InitLine(FALSE);
    
    PREFAST_ASSERT(m_PowerHelperHandle!=INVALID_HANDLE_VALUE);
    ASSERT(m_hPowerLock!=NULL);
    DDKPwr_ReleaseLevel(m_PowerHelperHandle, m_hPowerLock);  
    m_hPowerLock=NULL;
    if(cUart_Index==3)
    {
    	//g_pIOPregs->GPCDAT &=~(1<<7);
	if (g_pIOPregs!=NULL)
	{
		DrvLib_UnmapIoSpace((PVOID)g_pIOPregs);
	}

    }

    return TRUE;
}
Beispiel #13
0
static unsigned Pass1 (StrBuf* Source, StrBuf* Target)
/* Preprocessor pass 1. Remove whitespace. Handle old and new style comments
 * and the "defined" operator.
 */
{
    unsigned    IdentCount;
    ident       Ident;
    int         HaveParen;

    /* Switch to the new input source */
    StrBuf* OldSource = InitLine (Source);

    /* Loop removing ws and comments */
    IdentCount = 0;
    while (CurC != '\0') {
        if (SkipWhitespace (0)) {
            /* Squeeze runs of blanks */
            if (!IsSpace (SB_LookAtLast (Target))) {
                SB_AppendChar (Target, ' ');
            }
        } else if (IsSym (Ident)) {
            if (Preprocessing && strcmp (Ident, "defined") == 0) {
                /* Handle the "defined" operator */
                SkipWhitespace (0);
                HaveParen = 0;
                if (CurC == '(') {
                    HaveParen = 1;
                    NextChar ();
                    SkipWhitespace (0);
                }
                if (IsSym (Ident)) {
                    SB_AppendChar (Target, IsMacro (Ident)? '1' : '0');
                    if (HaveParen) {
                        SkipWhitespace (0);
                        if (CurC != ')') {
                            PPError ("`)' expected");
                        } else {
                            NextChar ();
                        }
                    }
                } else {
                    PPError ("Identifier expected");
                    SB_AppendChar (Target, '0');
                }
            } else {
                ++IdentCount;
                SB_AppendStr (Target, Ident);
            }
        } else if (IsQuote (CurC)) {
            CopyQuotedString (Target);
        } else if (CurC == '/' && NextC == '*') {
            if (!IsSpace (SB_LookAtLast (Target))) {
                SB_AppendChar (Target, ' ');
            }
            OldStyleComment ();
        } else if (IS_Get (&Standard) >= STD_C99 && CurC == '/' && NextC == '/') {
            if (!IsSpace (SB_LookAtLast (Target))) {
                SB_AppendChar (Target, ' ');
            }
            NewStyleComment ();
        } else {
            SB_AppendChar (Target, CurC);
            NextChar ();
        }
    }

    /* Switch back to the old source */
    InitLine (OldSource);

    /* Return the number of identifiers found in the line */
    return IdentCount;
}
Beispiel #14
0
static void MacroArgSubst (MacroExp* E)
/* Argument substitution according to ISO/IEC 9899:1999 (E), 6.10.3.1ff */
{
    ident       Ident;
    int         ArgIdx;
    StrBuf*     OldSource;
    StrBuf*     Arg;
    int         HaveSpace;


    /* Remember the current input and switch to the macro replacement. */
    int OldIndex = SB_GetIndex (&E->M->Replacement);
    SB_Reset (&E->M->Replacement);
    OldSource = InitLine (&E->M->Replacement);

    /* Argument handling loop */
    while (CurC != '\0') {

        /* If we have an identifier, check if it's a macro */
        if (IsSym (Ident)) {

            /* Check if it's a macro argument */
            if ((ArgIdx = FindMacroArg (E->M, Ident)) >= 0) {

                /* A macro argument. Get the corresponding actual argument. */
                Arg = ME_GetActual (E, ArgIdx);

                /* Copy any following whitespace */
                HaveSpace = SkipWhitespace (0);

                /* If a ## operator follows, we have to insert the actual
                 * argument as is, otherwise it must be macro replaced.
                 */
                if (CurC == '#' && NextC == '#') {

                    /* ### Add placemarker if necessary */
                    SB_Append (&E->Replacement, Arg);

                } else {

                    /* Replace the formal argument by a macro replaced copy
                     * of the actual.
                     */
                    SB_Reset (Arg);
                    MacroReplacement (Arg, &E->Replacement);

                    /* If we skipped whitespace before, re-add it now */
                    if (HaveSpace) {
                        SB_AppendChar (&E->Replacement, ' ');
                    }
                }


            } else {

                /* An identifier, keep it */
                SB_AppendStr (&E->Replacement, Ident);

            }

        } else if (CurC == '#' && NextC == '#') {

            /* ## operator. */
            NextChar ();
            NextChar ();
            SkipWhitespace (0);

            /* Since we need to concatenate the token sequences, remove
             * any whitespace that was added to target, since it must come
             * from the input.
             */
            while (IsSpace (SB_LookAtLast (&E->Replacement))) {
                SB_Drop (&E->Replacement, 1);
            }

            /* If the next token is an identifier which is a macro argument,
             * replace it, otherwise do nothing.
             */
            if (IsSym (Ident)) {

                /* Check if it's a macro argument */
                if ((ArgIdx = FindMacroArg (E->M, Ident)) >= 0) {

                    /* Get the corresponding actual argument and add it. */
                    SB_Append (&E->Replacement, ME_GetActual (E, ArgIdx));

                } else {

                    /* Just an ordinary identifier - add as is */
                    SB_AppendStr (&E->Replacement, Ident);

                }
            }

        } else if (CurC == '#' && E->M->ArgCount >= 0) {

            /* A # operator within a macro expansion of a function like
             * macro. Read the following identifier and check if it's a
             * macro parameter.
             */
            NextChar ();
            SkipWhitespace (0);
            if (!IsSym (Ident) || (ArgIdx = FindMacroArg (E->M, Ident)) < 0) {
                PPError ("`#' is not followed by a macro parameter");
            } else {
                /* Make a valid string from Replacement */
                Arg = ME_GetActual (E, ArgIdx);
                SB_Reset (Arg);
                Stringize (Arg, &E->Replacement);
            }

        } else if (IsQuote (CurC)) {
            CopyQuotedString (&E->Replacement);
        } else {
            SB_AppendChar (&E->Replacement, CurC);
            NextChar ();
        }
    }

#if 0
    /* Remove whitespace from the end of the line */
    while (IsSpace (SB_LookAtLast (&E->Replacement))) {
        SB_Drop (&E->Replacement, 1);
    }
#endif

    /* Switch back the input */
    InitLine (OldSource);
    SB_SetIndex (&E->M->Replacement, OldIndex);
}
Beispiel #15
0
void ModelClass::SetFromXml(wxXmlNode* ModelNode, bool zeroBased)
{
    wxString tempstr,channelstr;
    wxString customModel,RGBorder;
    long degrees, StartChannel, channel;
    size_t i;

    ModelXml=ModelNode;
    TreeDegrees=0;
    StrobeRate=0;
    Nodes.clear();

    name=ModelNode->GetAttribute("name");
    DisplayAs=ModelNode->GetAttribute("DisplayAs");
    if (ModelNode->HasAttribute("StringType"))
    {
        // post 3.1.4
        StringType=ModelNode->GetAttribute("StringType");
    }
    else
    {
        // 3.1.4 and earlier
        StringType=ModelNode->GetAttribute("Order","RGB")+" Nodes";
    }
    SingleNode=HasSingleNode(StringType);
    SingleChannel=HasSingleChannel(StringType);
    RGBorder=SingleNode ? "RGB" : RGBorder=StringType.Left(3);
    rgbidx[0]=std::max(RGBorder.Find('R'),0);
    rgbidx[1]=std::max(RGBorder.Find('G'),0);
    rgbidx[2]=std::max(RGBorder.Find('B'),0);

    tempstr=ModelNode->GetAttribute("parm1");
    tempstr.ToLong(&parm1);
    tempstr=ModelNode->GetAttribute("parm2");
    tempstr.ToLong(&parm2);
    tempstr=ModelNode->GetAttribute("parm3");
    tempstr.ToLong(&parm3);
    tempstr=ModelNode->GetAttribute("StartChannel","1");
    tempstr.ToLong(&StartChannel);
    tempstr=ModelNode->GetAttribute("Dir");
    IsLtoR=tempstr != "R";
    if (ModelNode->HasAttribute("StartSide"))
    {
        tempstr=ModelNode->GetAttribute("StartSide");
        isBotToTop = (tempstr == "B");
    }
    else
    {
        isBotToTop=true;
    }

    tempstr=ModelNode->GetAttribute("Antialias","0");
    tempstr.ToLong(&Antialias);
    AliasFactor=1 << Antialias;
    MyDisplay=IsMyDisplay(ModelNode);

    tempstr=ModelNode->GetAttribute("offsetXpct","0");
    tempstr.ToDouble(&offsetXpct);
    tempstr=ModelNode->GetAttribute("offsetYpct","0");
    tempstr.ToDouble(&offsetYpct);
    tempstr=ModelNode->GetAttribute("PreviewScale","0.333");
    tempstr.ToDouble(&PreviewScale);
    tempstr=ModelNode->GetAttribute("PreviewRotation","0");
    tempstr.ToLong(&degrees);
    PreviewRotation=degrees;

    // calculate starting channel numbers for each string
    size_t NumberOfStrings= HasOneString(DisplayAs) ? 1 : parm1;
    int ChannelsPerString=parm2*3;
    if (SingleChannel)
        ChannelsPerString=1;
    else if (SingleNode)
        ChannelsPerString=3;

    if (ModelNode->HasAttribute("CustomModel"))
    {
        customModel = ModelNode->GetAttribute("CustomModel");
        int maxval=GetCustomMaxChannel(customModel);
        // fix NumberOfStrings
        if (SingleNode)
        {
            NumberOfStrings=maxval;
        }
        else
        {
            ChannelsPerString=maxval*3;
        }
    }

    tempstr=ModelNode->GetAttribute("Advanced","0");
    bool HasIndividualStartChans=tempstr == "1";
    stringStartChan.clear();
    stringStartChan.resize(NumberOfStrings);
    for (i=0; i<NumberOfStrings; i++)
    {
        tempstr=StartChanAttrName(i);
        if (!zeroBased && HasIndividualStartChans && ModelNode->HasAttribute(tempstr))
        {
            ModelNode->GetAttribute(tempstr, &channelstr);
            channelstr.ToLong(&channel);
            stringStartChan[i] = channel-1;
        }
        else
        {
            stringStartChan[i] = (zeroBased? 0 : StartChannel-1) + i*ChannelsPerString;
        }
    }

    // initialize model based on the DisplayAs value
    wxStringTokenizer tkz(DisplayAs, " ");
    wxString token = tkz.GetNextToken();
    if (token == "Tree")
    {
        InitVMatrix();
        token = tkz.GetNextToken();
        token.ToLong(&degrees);
        SetTreeCoord(degrees);
    }
    else if (DisplayAs == "Custom")
    {
        InitCustomMatrix(customModel);
        CopyBufCoord2ScreenCoord();
    }
    else if (DisplayAs == "Vert Matrix")
    {
        InitVMatrix();
        CopyBufCoord2ScreenCoord();
    }
    else if (DisplayAs == "Horiz Matrix")
    {
        InitHMatrix();
        CopyBufCoord2ScreenCoord();
    }
    else if (DisplayAs == "Single Line")
    {
        InitLine();
        SetLineCoord();
    }
    else if (DisplayAs == "Arches")
    {
        InitHMatrix(); // Old call was InitLine();
        SetArchCoord();
    }
    else if (DisplayAs == "Window Frame")
    {
        InitFrame();
        CopyBufCoord2ScreenCoord();
    }
    else if (DisplayAs == "Star")
    {
        InitStar();
        CopyBufCoord2ScreenCoord();
    }
    else if (DisplayAs == "Wreath")
    {
        InitWreath();
        CopyBufCoord2ScreenCoord();
    }

    size_t NodeCount=GetNodeCount();
    for(size_t i=0; i<NodeCount; i++)
    {
        Nodes[i]->sparkle = rand() % 10000;
    }
}
void CAdActor::GetNextStep()
{
	if(m_WalkSprite)
	{
		m_CurrentSprite = m_WalkSprite->GetSprite(m_Dir);
	}
	else
	{
		CAdSpriteSet* Anim = GetAnimByName(m_WalkAnimName);
		if(Anim) m_CurrentSprite = Anim->GetSprite(m_Dir);
	}
	
	if(!m_CurrentSprite) return;

	m_CurrentSprite->GetCurrentFrame(m_Zoomable?((CAdGame*)Game)->m_Scene->GetZoomAt(m_PosX, m_PosY):100, m_Zoomable?((CAdGame*)Game)->m_Scene->GetZoomAt(m_PosX, m_PosY):100);
	if(!m_CurrentSprite->m_Changed) return;

		
	int MaxStepX, MaxStepY;
	MaxStepX = abs(m_CurrentSprite->m_MoveX);
	MaxStepY = abs(m_CurrentSprite->m_MoveY);

	MaxStepX = max(MaxStepX, MaxStepY);
	MaxStepX = max(MaxStepX, 1);

	while(m_PFCount > 0 && MaxStepX >= 0)
	{
		m_PFX += m_PFStepX;
		m_PFY += m_PFStepY;

		m_PFCount--;
		MaxStepX--;
	}

	if(((CAdGame*)Game)->m_Scene->IsBlockedAt(m_PFX, m_PFY, true, this))
	{
		if(m_PFCount==0)
		{
			m_State = m_NextState;
			m_NextState = STATE_READY;
			return;
		}
		GoTo(m_TargetPoint->x, m_TargetPoint->y);
		return;
	}


	m_PosX = (int)m_PFX;
	m_PosY = (int)m_PFY;

	AfterMove();
	

	if(m_PFCount == 0)
	{
		if(m_Path->GetNext()==NULL)
		{
			m_PosX = m_TargetPoint->x;
			m_PosY = m_TargetPoint->y;

			m_Path->Reset();
			if(m_AfterWalkDir!=DI_NONE) TurnTo(m_AfterWalkDir);
			else
			{
				m_State = m_NextState;
				m_NextState = STATE_READY;
			}
		}
		else InitLine(CBPoint(m_PosX, m_PosY), *m_Path->GetCurrent());
	}
}
Beispiel #17
0
int NextLine (void)
/* Get a line from the current input. Returns 0 on end of file. */
{
    AFile*     	Input;

    /* Clear the current line */
    ClearLine ();

    /* If there is no file open, bail out, otherwise get the current input file */
    if (CollCount (&AFiles) == 0) {
     	return 0;
    }
    Input = CollLast (&AFiles);

    /* Read characters until we have one complete line */
    while (1) {

        /* Read the next character */
        int C = fgetc (Input->F);

        /* Check for EOF */
        if (C == EOF) {

            /* Accept files without a newline at the end */
            if (SB_NotEmpty (Line)) {
                ++Input->Line;
                break;
            }

      	    /* Leave the current file */
      	    CloseIncludeFile ();

            /* If there is no file open, bail out, otherwise get the
             * previous input file and start over.
             */
            if (CollCount (&AFiles) == 0) {
                return 0;
            }
            Input = CollLast (&AFiles);
            continue;
        }

        /* Check for end of line */
        if (C == '\n') {

            /* We got a new line */
            ++Input->Line;

            /* If the \n is preceeded by a \r, remove the \r, so we can read
             * DOS/Windows files under *nix.
             */
            if (SB_LookAtLast (Line) == '\r') {
                SB_Drop (Line, 1);
            }

            /* If we don't have a line continuation character at the end,
             * we're done with this line. Otherwise replace the character
             * by a newline and continue reading.
             */
            if (SB_LookAtLast (Line) == '\\') {
                Line->Buf[Line->Len-1] = '\n';
            } else {
                break;
            }

        } else if (C != '\0') {         /* Ignore embedded NULs */

            /* Just some character, add it to the line */
            SB_AppendChar (Line, C);

        }
    }

    /* Add a termination character to the string buffer */
    SB_Terminate (Line);

    /* Initialize the current and next characters. */
    InitLine (Line);

    /* Create line information for this line */
    UpdateLineInfo (Input->Input, Input->Line, Line);

    /* Done */
    return 1;
}