Ejemplo n.º 1
0
/*=gfunc prefix
 *
 * what:  prefix lines with a string
 * general_use:
 *
 * exparg: prefix, string to insert at start of each line
 * exparg: text, multi-line block of text
 *
 * doc:
 *  Prefix every line in the second string with the first string.
 *
 *  For example, if the first string is "# " and the second contains:
 *  @example
 *  two
 *  lines
 *  @end example
 *  @noindent
 *  The result string will contain:
 *  @example
 *  # two
 *  # lines
 *  @end example
=*/
SCM
ag_scm_prefix(SCM prefix, SCM text)
{
    char*    pzPfx;
    char*    pzText;
    char*    pzDta;
    size_t   out_size, rem_size;
    size_t   pfx_size;
    char*    pzRes;

    pzPfx    = ag_scm2zchars(prefix, "prefix");
    pzDta    = \
    pzText   = ag_scm2zchars(text, "text");
    pfx_size = strlen(pzPfx);
    out_size = pfx_size;

    for (;;) {
        switch (*(pzText++)) {
        case NUL:
            goto exit_count;
        case NL:
            out_size += pfx_size;
            /* FALLTHROUGH */
        default:
            out_size++;
        }
    } exit_count:;

    pzText = pzDta;
    pzRes  = pzDta = ag_scribble(rem_size = out_size);
    strcpy(pzDta, pzPfx);
    pzDta    += pfx_size;
    rem_size -= pfx_size;
    pfx_size++;

    for (;;) {
        char ch = *(pzText++);
        switch (ch) {
        case NUL:
            if (rem_size != 0)
                AG_ABEND(PREFIX_FAIL);

            return AG_SCM_STR2SCM(pzRes, out_size);

        case NL:
            *pzDta    = ch;
            strcpy(pzDta+1, pzPfx);
            pzDta    += pfx_size;
            rem_size -= pfx_size;
            break;

        default:
            rem_size--;
            *(pzDta++) = ch;
            break;
        }
    }
}
Ejemplo n.º 2
0
/**
 *  Could not find the file or could not find the markers.
 *  Either way, emit an empty enclosure.
 */
static SCM
mk_empty_text(char const* pzStart, char const* pzEnd, SCM def)
{
    size_t mlen = strlen(pzStart) + strlen(pzEnd) + 3;
    char* pzOut;

    if (! AG_SCM_STRING_P(def)) {
        pzOut = ag_scribble(mlen);
        sprintf(pzOut, LINE_CONCAT3_FMT+3, pzStart, pzEnd);

    } else {
        char const * pzDef = ag_scm2zchars(def, "dft extr str");
        mlen += AG_SCM_STRLEN(def) + 1;
        pzOut = ag_scribble(mlen);
        sprintf(pzOut, LINE_CONCAT3_FMT, pzStart, pzDef, pzEnd);
    }

    return AG_SCM_STR02SCM(pzOut);
}
Ejemplo n.º 3
0
/**
 *  Replace marker text.
 *
 *  Replace all occurrances of the marker text with the substitution text.
 *  The result is stored in an automatically freed temporary buffer.
 *
 *  @param src_str  The source string
 *  @param str_len  The length of the string
 *  @param match    the SCM-ized marker string
 *  @param repl     the SCM-ized replacement string
 *  @param ppz_res  pointer to the result pointer
 *  @param res_len  pointer to result length
 */
static void
do_substitution(
    char const * src_str,
    ssize_t      str_len,
    SCM          match,
    SCM          repl,
    char **      ppz_res,
    ssize_t *    res_len)
{
    char* pzMatch  = ag_scm2zchars(match, "match text");
    char* rep_str  = ag_scm2zchars(repl,  "repl text");
    int   mark_len = AG_SCM_STRLEN(match);
    int   repl_len = AG_SCM_STRLEN(repl);

    {
        int ct = sub_count(src_str, pzMatch);
        if (ct == 0)
            return; /* No substitutions -- no work. */

        str_len += (repl_len - mark_len) * ct;
    }

    {
        char * dest = ag_scribble(str_len + 1);
        *ppz_res = dest;
        *res_len = str_len;

        for (;;) {
            char const * next = strstr(src_str, pzMatch);
            size_t len;

            if (next == NULL)
                break;
            len = next - src_str;
            if (len != 0) {
                memcpy(dest, src_str, len);
                dest += len;
            }
            memcpy(dest, rep_str, (size_t)repl_len);
            dest   += repl_len;
            src_str = next + mark_len;
        }

        strcpy(dest, src_str);
    }
}
Ejemplo n.º 4
0
/**
 * guts of the template file/line functions
 */
static SCM
do_tpl_file_line(int line_delta, char const * fmt)
{
    void * args[2] = {
        [0] = (void*)pCurTemplate->pzTplFile,
        [1] = (void*)((long)pCurMacro->lineNo + line_delta)
    };
    char * buf = strrchr(args[0], DIRCH);
    if (buf != NULL)
        args[0] = buf + 1;

    {
        size_t sz = strlen(fmt) + strlen(args[0]) + 24;
        buf = ag_scribble(sz);
    }

    sprintfv(buf, fmt, (snv_constpointer*)args);
    return AG_SCM_STR02SCM(buf);
}
Ejemplo n.º 5
0
/*=gfunc def_file_line
 *
 * what:   get a definition file+line number
 *
 * exparg: ag-name, name of AutoGen value
 * exparg: msg-fmt, formatting for line message, optional
 *
 * doc:
 *  Returns the file and line number of a AutoGen defined value, using
 *  either the default format, "from %s line %d", or else the format you
 *  supply.  For example, if you want to insert a "C" language file-line
 *  directive, you would supply the format "# %2$d \"%1$s\"", but that
 *  is also already supplied with the scheme variable
 *  @xref{SCM c-file-line-fmt}.  You may use it thus:
 *
 *  @example
 *  (def-file-line "ag-def-name" c-file-line-fmt)
 *  @end example
 *
 *  It is also safe to use the formatting string, "%2$d".  AutoGen uses
 *  an argument vector version of printf: @xref{snprintfv}.
=*/
SCM
ag_scm_def_file_line(SCM obj, SCM fmt)
{
    static char const zFmt[]  = "from %s line %d";
    char const * pzFmt = zFmt;
    char * buf;
    ag_bool     x;

    tDefEntry * pE = findDefEntry(ag_scm2zchars(obj, "ag value"), &x);

    /*
     *  IF we did not find the entry we are looking for
     *  THEN return UNDEFINED
     */
    if (pE == NULL)
        return SCM_UNDEFINED;

    if (AG_SCM_STRING_P(fmt))
        pzFmt = ag_scm2zchars(fmt, "file/line format");

    {
        void * args[2] = {
            (void*)pE->pzSrcFile,
            (void*)(long)pE->srcLineNum
        };
        size_t maxlen;

        buf = strrchr(args[0], DIRCH);
        if (buf != NULL)
            args[0] = buf + 1;

        maxlen = strlen(args[0]) + strlen(pzFmt) + LOG10_2to32 + 1;
        buf = ag_scribble(maxlen);
        sprintfv(buf, pzFmt, (snv_constpointer*)args);
    }

    return AG_SCM_STR02SCM(buf);
}
Ejemplo n.º 6
0
/*=gfunc hide_email
 *
 * what:  convert eaddr to javascript
 * general_use:
 *
 * exparg: display, display text
 * exparg: eaddr,   email address
 *
 * doc:    Hides an email address as a java scriptlett.
 *         The 'mailto:' tag and the email address are coded bytes
 *         rather than plain text.  They are also broken up.
=*/
SCM
ag_scm_hide_email(SCM display, SCM eaddr)
{
    static char const zFmt[]   = "&#%d;";
    static char const zStrt[]  =
        "<script language=\"JavaScript\" type=\"text/javascript\">\n"
        "<!--\n"
        "var one = 'm&#97;';\n"
        "var two = 'i&#108;t';\n"
        "document.write('<a href=\"' + one + two );\n"
        "document.write('&#111;:";

    static char const zEnd[]   = "');\n"
        "document.write('\" >%s</a>');\n"
        "//-->\n</script>";

    char*  pzDisp = ag_scm2zchars(display, zFormat);
    char*  pzEadr = ag_scm2zchars(eaddr,   zFormat);
    size_t str_size = (strlen(pzEadr) * sizeof(zFmt))
            + sizeof(zStrt) + sizeof(zEnd) + strlen(pzDisp);

    char*  pzRes  = ag_scribble(str_size);
    char*  pzScan = pzRes;

    strcpy(pzScan, zStrt);
    pzScan += sizeof(zStrt) - 1;

    for (;;) {
        if (*pzEadr == NUL)
            break;
        pzScan += sprintf(pzScan, zFmt, *(pzEadr++));
    }

    pzScan += sprintf(pzScan, zEnd, pzDisp);

    return AG_SCM_STR2SCM(pzRes, (size_t)(pzScan - pzRes));
}
Ejemplo n.º 7
0
/*=gfunc join
 *
 * what:   join string list with separator
 * general_use:
 * exparg: separator, string to insert between entries
 * exparg: list, list of strings to join,, list
 *
 * doc:  With the first argument as the separator string,
 *       joins together an a-list of strings into one long string.
 *       The list may contain nested lists, partly because you
 *       cannot always control that.
=*/
SCM
ag_scm_join(SCM sep, SCM list)
{
    int      l_len, sv_l_len;
    SCM      car;
    SCM      alist = list;
    size_t   sep_len;
    size_t   str_len;
    char *   pzRes;
    char const * pzSep;
    char *   pzScan;

    if (! AG_SCM_STRING_P(sep))
        return SCM_UNDEFINED;

    sv_l_len = l_len = scm_ilength(list);
    if (l_len == 0)
        return AG_SCM_STR02SCM(zNil);

    pzSep   = AG_SCM_CHARS(sep);
    sep_len = AG_SCM_STRLEN(sep);
    str_len = 0;

    /*
     *  Count up the lengths of all the strings to be joined.
     */
    for (;;) {
        car  = SCM_CAR(list);
        list = SCM_CDR(list);

        /*
         *  This routine is listed as getting a list as the second
         *  argument.  That means that if someone builds a list and
         *  hands it to us, it magically becomes a nested list.
         *  This unravels that.
         */
        if (! AG_SCM_STRING_P(car)) {
            if (car != SCM_UNDEFINED)
                car = ag_scm_join(sep, car);
            if (! AG_SCM_STRING_P(car))
                return SCM_UNDEFINED;
        }

        str_len += AG_SCM_STRLEN(car);

        if (--l_len <= 0)
            break;

        str_len += sep_len;
    }

    l_len = sv_l_len;
    pzRes = pzScan = ag_scribble(str_len);

    /*
     *  Now, copy each one into the output
     */
    for (;;) {
        size_t cpy_len;

        car   = SCM_CAR(alist);
        alist = SCM_CDR(alist);

        /*
         *  This unravels nested lists.
         */
        if (! AG_SCM_STRING_P(car))
            car = ag_scm_join(sep, car);

        cpy_len = AG_SCM_STRLEN(car);
        memcpy((void*)pzScan, AG_SCM_CHARS(car), cpy_len);
        pzScan += cpy_len;

        /*
         *  IF we reach zero, then do not insert a separation and bail out
         */
        if (--l_len <= 0)
            break;
        memcpy((void*)pzScan, (void*)pzSep, sep_len);
        pzScan += sep_len;
    }

    return AG_SCM_STR2SCM(pzRes, str_len);
}