/* --COPYRIGHT--,ESD
 *  Copyright (c) 2008 Texas Instruments. All rights reserved. 
 *  This program and the accompanying materials are made available under the 
 *  terms of the Eclipse Public License v1.0 and Eclipse Distribution License
 *  v. 1.0 which accompanies this distribution. The Eclipse Public License is
 *  available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
 *  Distribution License is available at 
 *  http://www.eclipse.org/org/documents/edl-v10.php.
 *
 *  Contributors:
 *      Texas Instruments - initial implementation
 * --/COPYRIGHT--*/
/*
 *  ======== Text.c ========
 */

#include <xdc/runtime/System.h>
#include <xdc/runtime/Types.h>

#include <string.h>
#include <stdarg.h>

#include "package/internal/Text.xdc.h"

/*
 *  ======== cordText ========
 */
String Text_cordText(Text_CordAddr cord)
{
    Char *p = (Char *)cord;

    if (p >= Text_charTab && p < Text_charTab + Text_charCnt
        && !Text_isLoaded) {
        return (NULL);
    }

    return ((String)cord);
}

/*
 *  ======== matchRope ========
 */
Int Text_matchRope(Types_RopeId rope, String pat, Int *lenp)
{
    Text_MatchVisState state;

    state.pat = pat;
    state.lenp = lenp;

    /*
     * Text_visitRopeFxn is a config parameter that references a function
     * generated by the template Text.xdt and initialized in Text.xdc.
     * It's visitRope2() with a stack large enough for all ropes in the
     * application.
     */
    Text_visitRopeFxn(rope, (Fxn)Text_matchVisFxn, &state);

    return (state.res);
}

/*
 *  ======== matchVisFxn ========
 */
Bool Text_matchVisFxn(Ptr obj, String src)
{
    Text_MatchVisState *state;
    String pat;
    Int *lenp;

    state = obj;
    pat = state->pat;
    lenp = state->lenp;

    /* compare pat to src and return if pat != src or wildcard matches */
    for (; *lenp && *src; src++, pat++, *lenp -= 1) {
        if (*src != *pat) {
            state->res = *pat == '%' ? 1 : -1;
            return (TRUE);
        }
    }

    /* if src[0] != 0, we reached the end of pat */
    if (*src) {
        state->res = -1;
        return (TRUE);
    }
    else {
        /* we reached end of src, we need to get next part of rope */
        state->res = 0;
        state->pat = pat;
        return (FALSE);
    }
}

/*
 *  ======== printVisFxn ========
 */
Bool Text_printVisFxn(Ptr obj, String src)
{
    static const Char STR_FMT[] = "%.*s";

    Text_PrintVisState *state = obj;

    if (state->len == 0) {
        return (TRUE);
    }
    else {
        Int oc = Text_xprintf(state->bufp, STR_FMT, state->len, src);
        state->res += oc;
        if (state->len > 0) {
            state->len -= oc;
        }
        return (FALSE);
    }
}

/*
 *  ======== putLab ========
 *  len == -1 => infinite output 
 */
Int Text_putLab(Types_Label *lab, Char **bufp, Int len)
{
    static const Char STR_FMT1[] = "%p";
    static const Char STR_FMT2[] = "('%s')";

    Int res;

    res = Text_putMod(lab->modId, bufp, len);
    if (len < 0 || (len - res) > 8) {  /* need at most 9 characters for "%p" */
        res += Text_xprintf(bufp, STR_FMT1, lab->handle);
    }
    
    if (lab->named
        && (len < 0 || (len - res) >= (4 + (Int)strlen(lab->iname))) ) {

        res += Text_xprintf(bufp, STR_FMT2, lab->iname);
    }

    return (res);
}

/*
 *  ======== putMod ========
 */
Int Text_putMod(Types_ModuleId mid, Char **bufp, Int len)
{
    static const Char STR_FMT1[] = "{module#%d}";
    static const Char STR_FMT2[] = "{module-rope:%x}";

    Text_PrintVisState state;

    if (mid < 0x8000) {
        return (Text_xprintf(bufp, STR_FMT1, mid));
    }

    if (!Text_isLoaded) {
        return (Text_xprintf(bufp, STR_FMT2, mid));
    }
    
    state.bufp = bufp;
    state.len = len < 0 ? 0x7fff : len;   /* 0x7fff == infinite, almost */;
    state.res = 0;
    
    Text_visitRopeFxn(mid, (Fxn)Text_printVisFxn, &state);
    
    return (state.res);
}

/*
 *  ======== putSite ========
 *  len == -1 => infinite output
 */
Int Text_putSite(Types_Site *site, Char **bufp, Int len)
{
    static const Char STR_FMT1[] = ": ";
    static const Char STR_FMT2[] = "\"%s\"";
    static const Char STR_FMT3[] = "line %d: ";

    Int res;
    Int max = len < 0 ? 0x7fff : len;   /* 0x7fff == infinite, well almost */

    if (!site) {
        return (0);
    }

    res = Text_putMod(site->mod, bufp, max);
    max -= (res + 2);     /* +2 for the ": " string below */

    if (max > 0) {
        res += Text_xprintf(bufp, STR_FMT1);

        if (site->line == 0) {
            return (res);
        }
    
        if (site->file && (max >= ((Int)strlen(site->file) + 4))) {
            Int oc = Text_xprintf(bufp, STR_FMT2, site->file);
            res += oc;
            max -= oc;
        }
        
        /* 7 = length of "line : ", 10 = max decimal digits in 32-bit number */
        if (max >= (7 + 10)) {
            res += Text_xprintf(bufp, STR_FMT3, site->line);
        }
    }

    return (res);
}

/*
 *  ======== ropeText ========
 */
String Text_ropeText(Text_RopeId rope)
{
    return (rope & 0x8000 ? NULL : Text_charTab + rope);
}

/*
 *  ======== visitRope2 ========
 *  Call visFxn on each "part" of the rope until visFxn returns TRUE or we
 *  reach the end of our rope.
 *
 *  The stack array must be large enough to hold the maximum number of
 *  nodes "in" rope.
 */
Void Text_visitRope2(Text_RopeId rope, Fxn visFxn, Ptr visState, String stack[])
{
    Int tos = 0;

    for (;;) {
        Text_Node *node;
        String s = Text_ropeText(rope);
        if (s) {
            stack[tos++] = s;
            break;
        }
        node = Text_nodeTab + (Bits32)(rope & 0x00007FFF);
        stack[tos++] = Text_ropeText(node->right);
        rope = node->left;
    }

    do {
        String s = stack[--tos];
        if (((Text_RopeVisitor)visFxn)(visState, s)) {
            return;
        }
    } while (tos);
}

/*
 *  ======== xprintf ========
 */
Int Text_xprintf(Char **bufp, String fmt, ...)
{
    va_list va;
    Char *b;
    Int res;

    va_start(va, fmt);
    b = bufp && *bufp ? *bufp : NULL;

    res = System_vsprintf(b, fmt, va);

    if (b) {
        *bufp += res;
    }

    va_end(va);

    return (res);
}

/*
 *! Revision History
 *! ================
 *! 13-Feb-2008 sasha	changed the names of the members of Types_Label
 *! 03-Dec-2007 sasha	implemented code review changes
 */
