Exemplo n.º 1
0
static SCM
shell_stringify(SCM obj, uint_t qt)
{
    char * pzNew;
    size_t dtaSize = 3;
    char * pzDta   = ag_scm2zchars(obj, "AG Object");
    char * pz      = pzDta;

    for (;;) {
        char c = *(pz++);

        switch (c) {
        case NUL:
            goto loopDone1;

        case '"': case '`': case '\\':
            dtaSize += 2;
            break;

        default:
            dtaSize++;
        }
    } loopDone1:;

    pzNew = AGALOC(dtaSize, "shell string");
    dtaSize = stringify_for_sh(pzNew, qt, pzDta);

    {
        SCM res = AG_SCM_STR2SCM(pzNew, dtaSize);
        AGFREE(pzNew);
        return res;
    }
}
Exemplo n.º 2
0
/*=gfunc string_tr
 *
 * what:  convert characters with new result
 * general_use:
 *
 *  exparg:  source, string to transform
 *  exparg:  match,  characters to be converted
 *  exparg:  translation, conversion list
 *
 * doc: This is identical to @code{string-tr!}, except that it does not
 *      over-write the previous value.
=*/
SCM
ag_scm_string_tr(SCM Str, SCM From, SCM To)
{
    size_t lenz  = AG_SCM_STRLEN(Str);
    SCM    res   = AG_SCM_STR2SCM(scm_i_string_chars(Str), lenz);
    return ag_scm_string_tr_x(res, From, To);
}
Exemplo n.º 3
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;
        }
    }
}
Exemplo n.º 4
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.
 *  This includes empty lines, though trailing white space will
 *  be removed if the line consists only of the "prefix".
 *  Also, if the last character is a newline, then *two* prefixes will
 *  be inserted into the result text.
 *
 *  For example, if the first string is "# " and the second contains:
 *  @example
 *  "two\nlines\n"
 *  @end example
 *  @noindent
 *  The result string will contain:
 *  @example
 *  # two
 *  # lines
 *  #
 *  @end example
 *
 *  The last line will be incomplete:  no newline and no space after the
 *  hash character, either.
=*/
SCM
ag_scm_prefix(SCM prefx, SCM txt)
{
    char *   prefix   = ag_scm2zchars(prefx, "pfx");
    char *   text     = ag_scm2zchars(txt,   "txt");
    char *   scan     = text;
    size_t   pfx_size = strlen(prefix);
    char *   r_str;   /* result string */

    {
        size_t out_size = pfx_size + 1; // NUL or NL byte adjustment
        for (;;) {
            switch (*(scan++)) {
            case NUL:
                out_size += scan - text;
                goto exit_count;
            case NL:
                out_size += pfx_size;
            }
        } exit_count:;

        r_str = scan = scribble_get((ssize_t)out_size);
    }

    memcpy(scan, prefix, pfx_size);
    scan += pfx_size;
    pfx_size++;

    for (;;) {
        char ch = *(text++);
        switch (ch) {
        case NUL:
            /*
             * Trim trailing white space on the final line.
             */
            scan = SPN_HORIZ_WHITE_BACK(r_str, scan);
            return AG_SCM_STR2SCM(r_str, scan - r_str);

        case NL:
            /*
             * Trim trailing white space on previous line first.
             */
            scan  = SPN_HORIZ_WHITE_BACK(r_str, scan);
            *scan = NL;
            memcpy(scan+1, prefix, pfx_size - 1);
            scan += pfx_size;  // prefix length plus 1 for new line
            break;

        default:
            *(scan++) = ch;
            break;
        }
    }
}
Exemplo n.º 5
0
/*
 *  If we got it, emit it.
 */
static SCM
get_text(char const* pzText, char const* pzStart, char const* pzEnd, SCM def)
{
    char const* pzS = strstr(pzText, pzStart);
    char const* pzE;

    if (pzS == NULL)
        return mk_empty_text(pzStart, pzEnd, def);

    pzE = strstr(pzS, pzEnd);
    if (pzE == NULL)
        return mk_empty_text(pzStart, pzEnd, def);

    pzE += strlen(pzEnd);

    return AG_SCM_STR2SCM(pzS, (size_t)(pzE - pzS));
}
Exemplo n.º 6
0
/*=gfunc string_substitute
 *
 * what:  multiple global replacements
 * general_use:
 *
 *  exparg:  source, string to transform
 *  exparg:  match,  substring or substring list to be replaced
 *  exparg:  repl,   replacement strings or substrings
 *
 * doc: @code{match} and  @code{repl} may be either a single string or
 *      a list of strings.  Either way, they must have the same structure
 *      and number of elements.  For example, to replace all amphersands,
 *      less than and greater than characters, do something like this:
 *
 * @example
 *      (string-substitute source
 *          (list "&"     "<"    ">")
 *          (list "&amp;" "&lt;" "&gt;"))
 * @end example
=*/
SCM
ag_scm_string_substitute(SCM str, SCM Match, SCM Repl)
{
    char const *  text;
    ssize_t len;
    SCM     res;

    if (! AG_SCM_STRING_P(str))
        return SCM_UNDEFINED;

    text = scm_i_string_chars(str);
    len   = (ssize_t)AG_SCM_STRLEN(str);

    if (AG_SCM_STRING_P(Match))
        do_substitution(text, len, Match, Repl, (char **)&text, &len);
    else
        do_multi_subs((char **)&text, &len, Match, Repl);

    res = AG_SCM_STR2SCM(text, (size_t)len);
    return res;
}
Exemplo n.º 7
0
/*=gfunc string_substitute
 *
 * what:  multiple global replacements
 * general_use:
 *
 *  exparg:  source, string to transform
 *  exparg:  match,  substring or substring list to be replaced
 *  exparg:  repl,   replacement strings or substrings
 *
 * doc: @code{match} and  @code{repl} may be either a single string or
 *      a list of strings.  Either way, they must have the same structure
 *      and number of elements.  For example, to replace all amphersands,
 *      less than and greater than characters, do something like this:
 *
 * @example
 *      (string-substitute source
 *          (list "&"     "<"    ">")
 *          (list "&amp;" "&lt;" "&gt;"))
 * @end example
=*/
SCM
ag_scm_string_substitute(SCM Str, SCM Match, SCM Repl)
{
    char const *  pzStr;
    ssize_t len;
    SCM     res;

    if (! AG_SCM_STRING_P(Str))
        return SCM_UNDEFINED;

    pzStr = AG_SCM_CHARS(Str);
    len   = AG_SCM_STRLEN(Str);

    if (AG_SCM_STRING_P(Match))
        do_substitution(pzStr, len, Match, Repl, (char**)&pzStr, &len);
    else
        do_multi_subs((char**)&pzStr, &len, Match, Repl);

    res = AG_SCM_STR2SCM(pzStr, len);
    return res;
}
Exemplo n.º 8
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));
}
Exemplo n.º 9
0
LOCAL SCM
run_printf(char const * pzFmt, int len, SCM alist)
{
    SCM     res;
    void*   args[8];
    void**  arglist;
    void**  argp;

    if (len < 8)
        arglist = argp = args;
    else
        arglist =
        argp    = (void**)malloc((len+1) * sizeof(void*));

    while (len-- > 0) {
        SCM  car = SCM_CAR(alist);
        alist = SCM_CDR(alist);
        switch (ag_scm_type_e(car)) {
        default:
        case GH_TYPE_UNDEFINED:
            *(argp++) = (char*)"???";
            break;

        case GH_TYPE_BOOLEAN:
            *(argp++) = (void*)((car == SCM_BOOL_F) ? "#f" : "#t");
            break;

        case GH_TYPE_CHAR:
            *(char*)(argp++) = AG_SCM_CHAR(car);
            break;

        case GH_TYPE_PAIR:
            *(argp++) = (char*)"..";
            break;

        case GH_TYPE_NUMBER:
            *(unsigned long*)(argp++) = AG_SCM_TO_ULONG(car);
            break;

        case GH_TYPE_SYMBOL:
        case GH_TYPE_STRING:
            *(argp++) = ag_scm2zchars(car, "printf str");
            break;

        case GH_TYPE_PROCEDURE:
            *(argp++) = (char*)"(*)()";
            break;

        case GH_TYPE_VECTOR:
        case GH_TYPE_LIST:
            *(argp++) = (char*)"...";
            break;
        }
    }

    /*
     *  Do the formatting and allocate a new SCM to hold the result.
     *  Free up any allocations made by ``gh_scm2newstr''
     */
    {
        char*   pzBuf;
        size_t  bfSize = safePrintf(&pzBuf, pzFmt, arglist);
        res = AG_SCM_STR2SCM(pzBuf, bfSize);
        free(pzBuf);
    }

    if (arglist != args)
        AGFREE((void*)arglist);

    return res;
}
Exemplo n.º 10
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 = (int)scm_ilength(list);
    if (l_len == 0)
        return AG_SCM_STR02SCM(zNil);

    pzSep   = scm_i_string_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 = scribble_get((ssize_t)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(VOIDP(pzScan), scm_i_string_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(VOIDP(pzScan), VOIDP(pzSep), sep_len);
        pzScan += sep_len;
    }

    return AG_SCM_STR2SCM(pzRes, str_len);
}