示例#1
0
/*=gfunc find_file
 *
 * what:   locate a file in the search path
 * exparg: file-name,  name of file with text
 * exparg: @suffix  @  file suffix to try, too   @ opt @
 *
 * doc:
 *
 * AutoGen has a search path that it uses to locate template and definition
 * files.  This function will search the same list for @file{file-name}, both
 * with and without the @file{.suffix}, if provided.
=*/
SCM
ag_scm_find_file(SCM file, SCM suffix)
{
    SCM res = SCM_UNDEFINED;

    if (! AG_SCM_STRING_P(file))
        scm_wrong_type_arg(FIND_FILE_NAME, 1, file);

    {
        char z[ AG_PATH_MAX+1 ];
        char const * pz = ag_scm2zchars(file, "file-name");

        /*
         *  The suffix is optional.  If provided, it will be a string.
         */
        if (AG_SCM_STRING_P(suffix)) {
            char* apz[2];
            apz[0] = (char *)ag_scm2zchars(suffix, "file suffix");
            apz[1] = NULL;
            if (SUCCESSFUL(findFile(pz, z, (char const **)apz, NULL)))
                res = AG_SCM_STR02SCM(z);

        } else if (SUCCESSFUL(findFile(pz, z, NULL, NULL)))
            res = AG_SCM_STR02SCM(z);
    }

    return res;
}
示例#2
0
/*=gfunc extract
 *
 * what:   extract text from another file
 * general_use:
 * exparg: file-name,  name of file with text
 * exparg: marker-fmt, format for marker text
 * exparg: caveat,     warn about changing marker, opt
 * exparg: default,    default initial text,       opt
 *
 * doc:
 *
 * This function is used to help construct output files that may contain
 * text that is carried from one version of the output to the next.
 *
 * The first two arguments are required, the second are optional:
 *
 * @itemize @bullet
 * @item
 *      The @code{file-name} argument is used to name the file that
 *      contains the demarcated text.
 * @item
 *      The @code{marker-fmt} is a formatting string that is used to construct
 *      the starting and ending demarcation strings.  The sprintf function is
 *      given the @code{marker-fmt} with two arguments.  The first is either
 *      "START" or "END".  The second is either "DO NOT CHANGE THIS COMMENT"
 *      or the optional @code{caveat} argument.
 * @item
 *      @code{caveat} is presumed to be absent if it is the empty string
 *      (@code{""}).  If absent, ``DO NOT CHANGE THIS COMMENT'' is used
 *      as the second string argument to the @code{marker-fmt}.
 * @item
 *      When a @code{default} argument is supplied and no pre-existing text
 *      is found, then this text will be inserted between the START and END
 *      markers.
 * @end itemize
 *
 * @noindent
 * The resulting strings are presumed to be unique within
 * the subject file.  As a simplified example:
 *
 * @example
 * [+ (extract "fname" "// %s - SOMETHING - %s" ""
 *             "example default") +]
 * @end example
 * @noindent
 * will result in the following text being inserted into the output:
 *
 * @example
 * // START - SOMETHING - DO NOT CHANGE THIS COMMENT
 * example default
 * // END   - SOMETHING - DO NOT CHANGE THIS COMMENT
 * @end example
 *
 * @noindent
 * The ``@code{example default}'' string can then be carried forward to
 * the next generation of the output, @strong{@i{provided}} the output
 * is not named "@code{fname}" @i{and} the old output is renamed to
 * "@code{fname}" before AutoGen-eration begins.
 *
 * @table @strong
 * @item NB:
 * You can set aside previously generated source files inside the pseudo
 * macro with a Guile/scheme function, extract the text you want to keep
 * with this extract function.  Just remember you should delete it at the
 * end, too.  Here is an example from my Finite State Machine generator:
 *
 * @example
 * [+ AutoGen5 Template  -*- Mode: text -*-
 * h=%s-fsm.h   c=%s-fsm.c
 * (shellf
 * "test -f %1$s-fsm.h && mv -f %1$s-fsm.h .fsm.head
 *  test -f %1$s-fsm.c && mv -f %1$s-fsm.c .fsm.code" (base-name))
 * +]
 * @end example
 *
 * This code will move the two previously produced output files to files
 * named ".fsm.head" and ".fsm.code".  At the end of the 'c' output
 * processing, I delete them.
 *
 * @item also NB:
 * This function presumes that the output file ought to be editable so
 * that the code between the @code{START} and @code{END} marks can be edited
 * by the template user.  Consequently, when the @code{(extract ...)} function
 * is invoked, if the @code{writable} option has not been specified, then
 * it will be set at that point.  If this is not the desired behavior, the
 * @code{--not-writable} command line option will override this.
 * Also, you may use the guile function @code{(chmod "file" mode-value)}
 * to override whatever AutoGen is using for the result mode.
 * @end table
=*/
SCM
ag_scm_extract(SCM file, SCM marker, SCM caveat, SCM def)
{
    char const * pzStart;
    char const * pzEnd;
    char const * pzText;

    if (! AG_SCM_STRING_P(file) || ! AG_SCM_STRING_P(marker))
        return SCM_UNDEFINED;

    pzText = load_extract_file(ag_scm2zchars(file, "extr file"));

    {
        char const * pzMarker = ag_scm2zchars(marker, "marker");
        char const * pzCaveat = EXTRACT_CAVEAT;

        if (AG_SCM_STRING_P(caveat) && (AG_SCM_STRLEN(caveat) > 0))
            pzCaveat = ag_scm2zchars(caveat, "caveat");

        pzStart = aprf(pzMarker, EXTRACT_START, pzCaveat);
        pzEnd   = aprf(pzMarker, EXTRACT_END,   pzCaveat);
    }

    {
        SCM res;

        if (pzText == NULL)
             res = mk_empty_text(pzStart, pzEnd, def);
        else res = get_text(pzText, pzStart, pzEnd, def);

        AGFREE((void*)pzStart);
        AGFREE((void*)pzEnd);
        return res;
    }
}
示例#3
0
SCM
ag_scm_string_contains_p(SCM text, SCM substr)
{
    char* pzText   = ag_scm2zchars(text, "text to match");
    char* pzSubstr = ag_scm2zchars(substr, "match expr");

    return (strstr(pzText, pzSubstr) == NULL) ? SCM_BOOL_F : SCM_BOOL_T;
}
示例#4
0
SCM
ag_scm_string_ends_with_p(SCM text, SCM substr)
{
    char* pzText   = ag_scm2zchars(text, "text to match");
    char* pzSubstr = ag_scm2zchars(substr, "match expr");
    return (SUCCESSFUL(Select_Compare_End(pzText, pzSubstr)))
        ? SCM_BOOL_T : SCM_BOOL_F;
}
示例#5
0
SCM
ag_scm_string_equals_p(SCM text, SCM substr)
{
    char* pzText   = ag_scm2zchars(text, "text to match");
    char* pzSubstr = ag_scm2zchars(substr, "match expr");

    return (strcmp(pzText, pzSubstr) == 0) ? SCM_BOOL_T : SCM_BOOL_F;
}
示例#6
0
SCM
ag_scm_string_starts_eqv_p(SCM text, SCM substr)
{
    char* pzText   = ag_scm2zchars(text, "text to match");
    char* pzSubstr = ag_scm2zchars(substr, "match expr");
    return (SUCCESSFUL(Select_Equivalent_Start(pzText, pzSubstr)))
        ? SCM_BOOL_T : SCM_BOOL_F;
}
示例#7
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;
        }
    }
}
示例#8
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;
        }
    }
}
示例#9
0
/**
 * Convert version number strings into a binary representation and compare.
 */
SCM
ag_scm_version_compare(SCM op, SCM v1, SCM v2)
{
    static char const  zVer[] = "version str";

    ver_type_t val1 = str2int_ver(ag_scm2zchars(v1, zVer));
    ver_type_t val2 = str2int_ver(ag_scm2zchars(v2, zVer));
    v1 = SCM_FROM(val1);
    v2 = SCM_FROM(val2);
    return scm_apply(op, v1, scm_cons(v2, AG_SCM_LISTOFNULL()));
}
示例#10
0
/*=gfunc string_tr_x
 *
 * what:  convert characters
 * general_use:
 *
 *  exparg:  source, string to transform
 *  exparg:  match,  characters to be converted
 *  exparg:  translation, conversion list
 *
 * doc: This is the same as the @code{tr(1)} program, except the
 *      string to transform is the first argument.  The second and
 *      third arguments are used to construct mapping arrays for the
 *      transformation of the first argument.
 *
 *      It is too bad this little program has so many different
 *      and incompatible implementations!
=*/
SCM
ag_scm_string_tr_x(SCM str, SCM from_xform, SCM to_xform)
{
    unsigned char ch_map[ 1 << 8 /* bits-per-byte */ ];
    int    i    = sizeof(ch_map) - 1;
    char * from = ag_scm2zchars(from_xform, "str");
    char * to   = ag_scm2zchars(to_xform, "str");

    do  {
        ch_map[i] = (unsigned char)i;
    } while (--i > 0);

    for (; i <= (int)sizeof(ch_map) - 1; i++) {
        unsigned char fch = (unsigned char)*(from++);
        unsigned char tch = (unsigned char)*(to++);

        if (tch == NUL) {
            to--;
            tch = (unsigned char)to[-1];
        }

        switch (fch) {
        case NUL:
            goto map_done;

        case '-':
            if ((i > 0) && (tch == '-')) {
                unsigned char fs = (unsigned char)from[-2];
                unsigned char fe = (unsigned char)from[0];
                unsigned char ts = (unsigned char)to[-2];
                unsigned char te = (unsigned char)to[0];
                if (te != NUL) {
                    while (fs < fe) {
                        ch_map[ fs++ ] = ts;
                        if (ts < te) ts++;
                    }
                    break;
                }
            }

        default:
            ch_map[ fch ] = tch;
        }
    } map_done:;

    to = C(char *, scm_i_string_chars(str));
    i    = (int)AG_SCM_STRLEN(str);
    while (i-- > 0) {
        *to = (char)ch_map[ (int)*to ];
        to++;
    }
    return str;
}
示例#11
0
/*=gfunc string_tr_x
 *
 * what:  convert characters
 * general_use:
 *
 *  exparg:  source, string to transform
 *  exparg:  match,  characters to be converted
 *  exparg:  translation, conversion list
 *
 * doc: This is the same as the @code{tr(1)} program, except the
 *      string to transform is the first argument.  The second and
 *      third arguments are used to construct mapping arrays for the
 *      transformation of the first argument.
 *
 *      It is too bad this little program has so many different
 *      and incompatible implementations!
=*/
SCM
ag_scm_string_tr_x(SCM str, SCM from_xform, SCM to_xform)
{
    unsigned char ch_map[ 1 << 8 /* bits-per-byte */ ];
    int   i      = sizeof(ch_map) - 1;
    char* pzFrom = ag_scm2zchars(from_xform, "str");
    char* pzTo   = ag_scm2zchars(to_xform, "str");

    do  {
        ch_map[i] = i;
    } while (--i > 0);

    for (;i <= sizeof(ch_map) - 1;i++) {
        unsigned char fch = (unsigned char)*(pzFrom++);
        unsigned char tch = (unsigned char)*(pzTo++);

        if (tch == NUL) {
            pzTo--;
            tch = pzTo[-1];
        }

        switch (fch) {
        case NUL:
            goto mapDone;

        case '-':
            if ((i > 0) && (tch == '-')) {
                unsigned char fs = (unsigned char)pzFrom[-2];
                unsigned char fe = (unsigned char)pzFrom[0];
                unsigned char ts = (unsigned char)pzTo[-2];
                unsigned char te = (unsigned char)pzTo[0];
                if (te != NUL) {
                    while (fs < fe) {
                        ch_map[ fs++ ] = ts;
                        if (ts < te) ts++;
                    }
                    break;
                }
            }

        default:
            ch_map[ fch ] = tch;
        }
    } mapDone:;

    pzTo = (char*)(void*)AG_SCM_CHARS(str);
    i    = AG_SCM_STRLEN(str);
    while (i-- > 0) {
        *pzTo = ch_map[ (int)*pzTo ];
        pzTo++;
    }
    return str;
}
示例#12
0
SCM
ag_scm_string_has_match_p(SCM text, SCM substr)
{
    SCM      res;
    regex_t  re;

    compile_re(&re, ag_scm2zchars( substr, "match expr" ), REG_EXTENDED);

    if (regexec(&re, ag_scm2zchars(text, "text to match"), (size_t)0,
                 NULL, 0) == 0)
         res = SCM_BOOL_T;
    else res = SCM_BOOL_F;
    regfree(&re);

    return res;
}
示例#13
0
/*=gfunc stack
 *
 * what:  make list of AutoGen values
 *
 * exparg: ag-name, AutoGen value name
 *
 * doc:  Create a scheme list of all the strings that are associated
 *       with a name.  They must all be text values or we choke.
=*/
SCM
ag_scm_stack(SCM obj)
{
    SCM          res;
    SCM *        pos = &res;
    def_ent_t ** ppDE;
    def_ent_t *  pDE;
    SCM          str;

    res = SCM_EOL;

    ppDE = find_def_ent_list(ag_scm2zchars(obj, "AG Object"));
    if (ppDE == NULL)
        return SCM_EOL;

    for (;;) {
        pDE = *(ppDE++);

        if (pDE == NULL)
            break;

        if (pDE->de_type != VALTYP_TEXT)
            return SCM_UNDEFINED;

        str  = AG_SCM_STR02SCM(pDE->de_val.dvu_text);
        *pos = scm_cons(str, SCM_EOL);
        pos  = SCM_CDRLOC(*pos);
    }

    return res;
}
示例#14
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;
    }
}
示例#15
0
/*=gfunc count
 *
 * what:   definition count
 *
 * exparg: ag-name, name of AutoGen value
 *
 * doc:  Count the number of entries for a definition.
 *      The input argument must be a string containing the name
 *      of the AutoGen values to be counted.  If there is no
 *      value associated with the name, the result is an SCM
 *      immediate integer value of zero.
=*/
SCM
ag_scm_count(SCM obj)
{
    int ent_len = count_entries(ag_scm2zchars(obj, "ag object"));

    return AG_SCM_INT2SCM(ent_len);
}
示例#16
0
/*=gfunc len
 *
 * what:   get count of values
 *
 * exparg: ag-name, name of AutoGen value
 *
 * doc:  If the named object is a group definition, then "len" is
 *       the same as "count".  Otherwise, if it is one or more text
 *       definitions, then it is the sum of their string lengths.
 *       If it is a single text definition, then it is equivalent to
 *       @code{(string-length (get "ag-name"))}.
=*/
SCM
ag_scm_len(SCM obj)
{
    int len = entry_length(ag_scm2zchars(obj, "ag value"));

    return AG_SCM_INT2SCM(len);
}
示例#17
0
/*=gfunc stack
 *
 * what:  make list of AutoGen values
 *
 * exparg: ag-name, AutoGen value name
 *
 * doc:  Create a scheme list of all the strings that are associated
 *       with a name.  They must all be text values or we choke.
=*/
SCM
ag_scm_stack(SCM obj)
{
    SCM         res;
    SCM *       pos = &res;
    tDefEntry** ppDE;
    tDefEntry*  pDE;
    SCM         str;

    res = SCM_EOL;

    ppDE = findEntryList(ag_scm2zchars(obj, "AG Object"));
    if (ppDE == NULL)
        return SCM_EOL;

    for (;;) {
        pDE = *(ppDE++);

        if (pDE == NULL)
            break;

        if (pDE->valType != VALTYP_TEXT)
            return SCM_UNDEFINED;

        str  = AG_SCM_STR02SCM(pDE->val.pzText);
        *pos = scm_cons(str, SCM_EOL);
        pos  = SCM_CDRLOC(*pos);
    }

    return res;
}
示例#18
0
SCM
ag_scm_string_contains_eqv_p(SCM text, SCM substr)
{
    static char const zSrch[] = "search string";
    char* pzSubstr;
    SCM   res;

    AGDUPSTR(pzSubstr, ag_scm2zchars( substr, zSrch ), "substring");

    upString(pzSubstr);
    if (SUCCESSFUL(Select_Equivalent(ag_scm2zchars(text, "sample text"),
                                     pzSubstr)))
         res = SCM_BOOL_T;
    else res = SCM_BOOL_F;
    AGFREE((void*)pzSubstr);
    return res;
}
示例#19
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 = (int)AG_SCM_STRLEN(match);
    int    repl_len = (int)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 = scribble_get(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 = (size_t)(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);
    }
}
示例#20
0
SCM
ag_scm_string_has_eqv_match_p(SCM text, SCM substr)
{
    char* pzText   = ag_scm2zchars(text, "text to match");
    char* pzSubstr = ag_scm2zchars(substr, "match expr");
    SCM      res;
    regex_t  re;

    compile_re(&re, pzSubstr, REG_EXTENDED | REG_ICASE);

    if (regexec(&re, pzText, (size_t)0, NULL, 0) == 0)
         res = SCM_BOOL_T;
    else res = SCM_BOOL_F;
    regfree(&re);

    return res;
}
示例#21
0
/*=gfunc mk_gettextable
 *
 * what:   print a string in a gettext-able format
 * exparg: string, a multi-paragraph string
 *
 * doc: Returns SCM_UNDEFINED.  The input text string is printed
 *      to the current output as one puts() call per paragraph.
=*/
SCM
ag_scm_mk_gettextable(SCM txt)
{
    if (AG_SCM_STRING_P(txt)) {
        char const * pz = ag_scm2zchars(txt, "txt");
        optionPrintParagraphs(pz, false, cur_fpstack->stk_fp);
    }
    return SCM_UNDEFINED;
}
示例#22
0
SCM
ag_scm_string_eqv_p(SCM text, SCM substr)
{
    char* pzText;
    char* pzSubstr;

    /*
     *  We are overloading the "=" operator.  Our arguments may be
     *  numbers...
     */
    if (! AG_SCM_STRING_P(text) || ! AG_SCM_STRING_P(substr))
        return scm_num_eq_p(text, substr);

    pzText   = ag_scm2zchars(text, "text to match");
    pzSubstr = ag_scm2zchars(substr, "match expr");

    return (streqvcmp(pzText, pzSubstr) == 0) ? SCM_BOOL_T : SCM_BOOL_F;
}
示例#23
0
/*=gfunc fprintf
 *
 * what:  format to a file
 * general_use:
 *
 * exparg: port, Guile-scheme output port
 * exparg: format, formatting string
 * exparg: format-arg, list of arguments to formatting string, opt, list
 *
 * doc:  Format a string using arguments from the alist.
 *       Write to a specified port.  The result will NOT appear in your
 *       output.  Use this to print information messages to a template user.
=*/
SCM
ag_scm_fprintf(SCM port, SCM fmt, SCM alist)
{
    int   list_len = scm_ilength(alist);
    char* pzFmt    = ag_scm2zchars(fmt, zFormat);
    SCM   res      = run_printf(pzFmt, list_len, alist);

    return  scm_display(res, port);
}
示例#24
0
/*=gfunc printf
 *
 * what:  format to stdout
 * general_use:
 *
 * exparg: format, formatting string
 * exparg: format-arg, list of arguments to formatting string, opt, list
 *
 * doc:  Format a string using arguments from the alist.
 *       Write to the standard out port.  The result will NOT appear in your
 *       output.  Use this to print information messages to a template user.
 *       Use ``(sprintf ...)'' to add text to your document.
=*/
SCM
ag_scm_printf(SCM fmt, SCM alist)
{
    int   list_len = scm_ilength(alist);
    char* pzFmt    = ag_scm2zchars(fmt, zFormat);

    AG_SCM_DISPLAY(run_printf(pzFmt, list_len, alist));
    return SCM_UNDEFINED;
}
示例#25
0
/*=gfunc tpl_file_next_line
 *
 * what:   get the template file plus next line number
 *
 * exparg: msg-fmt, formatting for line message, optional
 *
 * doc:
 *  This is almost the same as @xref{SCM tpl-file-line}, except that
 *  the line referenced is the next line, per C compiler conventions, and
 *  consequently defaults to the format:  # <line-no+1> "<file-name>"
=*/
SCM
ag_scm_tpl_file_next_line(SCM fmt)
{
    char const * pzFmt = "# %2$d \"%1$s\"";

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

    return do_tpl_file_line(1, pzFmt);
}
示例#26
0
/*=gfunc c_string
 *
 * what:  emit string for ANSI C
 * general_use:
 *
 * exparg: string, string to reformat
 *
 * doc:
 *  Reform a string so that, when printed, the C compiler will be able to
 *  compile the data and construct a string that contains exactly what the
 *  current string contains.  Many non-printing characters are replaced with
 *  escape sequences.  Newlines are replaced with a backslash, an @code{n}, a
 *  closing quote, a newline, seven spaces and another re-opening quote.  The
 *  compiler will implicitly concatenate them.  The reader will see line
 *  breaks.
 *
 *  A K&R compiler will choke.  Use @code{kr-string} for that compiler.
 *
=*/
SCM
ag_scm_c_string(SCM str)
{
    char const * pz = ag_scm2zchars(str, "cstr");
    SCM res;
    pz  = optionQuoteString(pz, C_STRING_NEWLINE);
    res = AG_SCM_STR02SCM(pz);
    AGFREE(pz);
    return res;
}
示例#27
0
/*=gfunc tpl_file_line
 *
 * what:   get the template file+line number
 *
 * exparg: msg-fmt, formatting for line message, optional
 *
 * doc:
 *  Returns the file and line number of the current template macro 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
 *  (tpl-file-line 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},
 *  and it does not need to know the types of each argument in order to
 *  skip forward to the second argument.
=*/
SCM
ag_scm_tpl_file_line(SCM fmt)
{
    char const * pzFmt = "from %s line %d";

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

    return do_tpl_file_line(0, pzFmt);
}
示例#28
0
/*=gfunc sprintf
 *
 * what:  format a string
 * general_use:
 *
 * exparg: format, formatting string
 * exparg: format-arg, list of arguments to formatting string, opt, list
 *
 * doc:  Format a string using arguments from the alist.
=*/
SCM
ag_scm_sprintf(SCM fmt, SCM alist)
{
    int   list_len = scm_ilength(alist);
    char* pzFmt    = ag_scm2zchars(fmt, zFormat);

    if (list_len <= 0)
        return fmt;

    return run_printf(pzFmt, list_len, alist);
}
示例#29
0
/*=gfunc ag_function_p
 *
 * what:   test for function
 *
 * exparg: ag-name, name of AutoGen macro
 *
 * doc:  return SCM_BOOL_T if a specified name is a user-defined AutoGen
 *       macro, otherwise return SCM_BOOL_F.
=*/
SCM
ag_scm_ag_function_p(SCM obj)
{
    SCM     res;

    if (findTemplate(ag_scm2zchars(obj, "ag user macro")) == NULL)
         res = SCM_BOOL_F;
    else res = SCM_BOOL_T;

    return res;
}
示例#30
0
SCM
ag_scm_string_start_eqv_match_p(SCM text, SCM substr)
{
    char* pzText   = ag_scm2zchars(text, "text to match");
    char* pzSubstr = ag_scm2zchars(substr, "match expr");
    SCM        res;
    regex_t    re;
    regmatch_t m[2];

    compile_re(&re, pzSubstr, REG_EXTENDED | REG_ICASE);

    if (regexec(&re, pzText, (size_t)2, m, 0) != 0)
         res = SCM_BOOL_F;
    else if (m[0].rm_so != 0)
         res = SCM_BOOL_F;
    else res = SCM_BOOL_T;

    regfree(&re);

    return res;
}