Ejemplo n.º 1
0
void ParseRepeat (void)
/* Parse and handle the .REPEAT statement */
{
    char* Name;
    TokList* List;

    /* Repeat count follows */
    long RepCount = ConstExpression ();
    if (RepCount < 0) {
	Error ("Range error");
	RepCount = 0;
    }

    /* Optional there is a comma and a counter variable */
    Name = 0;
    if (Tok == TOK_COMMA) {

       	/* Skip the comma */
       	NextTok ();

       	/* Check for an identifier */
       	if (Tok != TOK_IDENT) {
       	    ErrorSkip ("Identifier expected");
       	} else {
       	    /* Remember the name and skip it */
            SB_Terminate (&SVal);
       	    Name = xstrdup (SB_GetConstBuf (&SVal));
       	    NextTok ();
       	}
    }

    /* Separator */
    ConsumeSep ();

    /* Read the token list */
    List = CollectRepeatTokens ();

    /* If we had an error, bail out */
    if (List == 0) {
	xfree (Name);
       	return;
    }

    /* Update the token list for replay */
    List->RepMax = (unsigned) RepCount;
    List->Data   = Name;
    List->Check  = RepeatTokenCheck;

    /* If the list is empty, or repeat count zero, there is nothing
     * to repeat.
     */
    if (List->Count == 0 || RepCount == 0) {
     	FreeTokList (List);
	return;
    }

    /* Read input from the repeat descriptor */
    PushTokList (List, ".REPEAT");
}
Ejemplo n.º 2
0
static TokList* CollectRepeatTokens (void)
/* Collect all tokens inside the .REPEAT body in a token list and return
 * this list. In case of errors, NULL is returned.
 */
{
    /* Create the token list */
    TokList* List = NewTokList ();

    /* Read the token list */
    unsigned Repeats = 0;
    while (Repeats != 0 || Tok != TOK_ENDREP) {

     	/* Check for end of input */
       	if (Tok == TOK_EOF) {
     	    Error ("Unexpected end of file");
	    FreeTokList (List);
     	    return 0;
     	}

	/* If we find a token that is equal to the repeat counter name,
	 * replace it by a REPCOUNTER token. This way we have to do strcmps
	 * only once for each identifier, and not for each expansion.
	 * Note: This will fail for nested repeats using the same repeat
	 * counter name, but
	 */



       	/* Collect all tokens in the list */
	AddCurTok (List);

     	/* Check for and count nested .REPEATs */
     	if (Tok == TOK_REPEAT) {
     	    ++Repeats;
     	} else if (Tok == TOK_ENDREP) {
     	    --Repeats;
     	}

       	/* Get the next token */
     	NextTok ();
    }

    /* Eat the closing .ENDREP */
    NextTok ();

    /* Return the list of collected tokens */
    return List;
}
Ejemplo n.º 3
0
void PushTokList (TokList* List, const char* Desc)
/* Push a token list to be used as input for InputFromStack. This includes
 * several initializations needed in the token list structure, so don't use
 * PushInput directly.
 */
{
    /* If the list is empty, just delete it and bail out */
    if (List->Count == 0) {
	FreeTokList (List);
	return;
    }

    /* Reset the last pointer to the first element */
    List->Last = List->Root;

    /* Insert the list specifying our input function */
    PushInput (ReplayTokList, List, Desc);
}
Ejemplo n.º 4
0
static int ReplayTokList (void* List)
/* Function that gets the next token from a token list and sets it. This
 * function may be used together with the PushInput function from the istack
 * module.
 */
{
    /* Cast the generic pointer to an actual list */
    TokList* L = List;

    /* Last may never be a NULL pointer, otherwise there's a bug in the code */
    CHECK (L->Last != 0);

    /* Set the next token from the list */
    TokSet (L->Last);

    /* If a check function is defined, call it, so it may look at the token
     * just set and changed it as apropriate.
     */
    if (L->Check) {
	L->Check (L);
    }

    /* Set the pointer to the next token */
    L->Last = L->Last->Next;

    /* If this was the last token, decrement the repeat counter. If it goes
     * zero, delete the list and remove the function from the stack.
     */
    if (L->Last == 0) {
	if (++L->RepCount >= L->RepMax) {
	    /* Done with this list */
	    FreeTokList (L);
	    PopInput ();
	} else {
	    /* Replay one more time */
	    L->Last = L->Root;
	}
    }

    /* We have a token */
    return 1;
}
Ejemplo n.º 5
0
static TokList* CollectRepeatTokens (void)
/* Collect all tokens inside the .REPEAT body in a token list and return
 * this list. In case of errors, NULL is returned.
 */
{
    /* Create the token list */
    TokList* List = NewTokList ();

    /* Read the token list */
    unsigned Repeats = 0;
    while (Repeats != 0 || CurTok.Tok != TOK_ENDREP) {

        /* Check for end of input */
        if (CurTok.Tok == TOK_EOF) {
            Error ("Unexpected end of file");
            FreeTokList (List);
            return 0;
        }

        /* Collect all tokens in the list */
        AddCurTok (List);

        /* Check for and count nested .REPEATs */
        if (CurTok.Tok == TOK_REPEAT) {
            ++Repeats;
        } else if (CurTok.Tok == TOK_ENDREP) {
            --Repeats;
        }

        /* Get the next token */
        NextTok ();
    }

    /* Eat the closing .ENDREP */
    NextTok ();

    /* Return the list of collected tokens */
    return List;
}