Beispiel #1
0
/*
 * hsc_parse_end
 *
 * check for all tags closed and required
 * tags occured
 */
BOOL hsc_parse_end(HSCPRC * hp)
{
    if (!hp->fatal)
    {
        /* remember current file position */
        INFILEPOS *infpos = new_infilepos(hp->inpf);
        DLNODE *nd = NULL;

        /* check for unclosed containers:
         * for every container tag still on stack launch a message,
         * exept for autoclose tags */
        nd = hp->container_stack->last;
        while (nd)
        {
            HSCTAG *endtag = (HSCTAG *) dln_data(nd);

            if (!(endtag->option & HT_AUTOCLOSE))
            {
                set_infilepos(hp->inpf, endtag->start_fpos);
                hsc_message(hp, MSG_MISS_CTAG,
                            "%c missing", endtag->name);
            }

            nd = dln_prev(nd);
        }

        /* restore file position */
        set_infilepos(hp->inpf, infpos);
        del_infilepos(infpos);

        /* check for required and recommended tags missing */
        nd = dll_first(hp->deftag);
        while (nd)
        {
            HSCTAG *tag = (HSCTAG *) dln_data(nd);

            if ((tag->option & HT_REQUIRED
                 && (tag->occured == FALSE)))
            {
                hsc_message(hp, MSG_MISS_REQTAG,
                            "required %T missing", tag);
            }
            else if ((tag->option & HT_RECOMMENDED
                      && (tag->occured == FALSE)))
            {
                hsc_message(hp, MSG_MISS_RCMDTAG,
                            "recommended %T missing", tag);
            }
            nd = dln_next(nd);
        }

        /* output last white spaces at eof */
        hsc_output_text(hp, "", "");
    }
    return (BOOL) (!hp->fatal);
}
Beispiel #2
0
/*
 * remove_end_tag
 *
 * remove tag from container stack, check for legal nesting,
 * show up message if necessary.
 *
 * params: hp....hsc process
 *         tag...tag to be removed
 */
VOID remove_end_tag(HSCPRC * hp, HSCTAG * tag)
{
    /* search for tag on stack of occured tags */
    DLNODE *nd = find_dlnode_bw(hp->container_stack->last, (APTR) tag->name, cmp_strtag);
    if (nd == NULL)
    {
        /* closing tag not found on stack */
        /* ->unmatched closing tag without previous opening tag */
        hsc_message(hp, MSG_UNMA_CTAG, "unmatched %C", tag);
    }
    else
    {
        /* closing tag found on stack */
        HSCTAG *end_tag = (HSCTAG *) dln_data(nd);
        STRPTR foundnm = (STRPTR) end_tag->name;
        STRPTR lastnm = (STRPTR) dln_data(dll_last(hp->container_stack));

        /* check if name of closing tag is -not- equal
         * to the name of the last tag last on stack
         * ->illegal tag nesting
         */
        if (upstrcmp(lastnm, foundnm)
            && !(tag->option | HT_MACRO)
            && !(is_hsc_tag(tag)))
        {
            hsc_message(hp, MSG_CTAG_NESTING,
                        "illegal end tag nesting (expected %c, found %C)",
                        lastnm, tag);
        }

        /* if closing tag has any attributes defined,
         * it must be a closing macto tag. so copy
         * the attributes of the closing tag to the
         * attributes of the macro tag. therefor,
         * the closing macro tag inherits the
         * attributes of his opening macro
         */
        if (end_tag->attr)
        {
            set_local_varlist(tag->attr, end_tag->attr, MCI_APPCTAG);
        }

        /* remove node for closing tag from container_stack */
        del_dlnode(hp->container_stack, nd);
    }
}
Beispiel #3
0
/* append ids defined within documents */
static VOID append_doc_iddefs(EXPSTR * prjstr, DLLIST * iddefs)
{
    DLNODE *nd = dll_first(iddefs);
    while (nd)
    {
        append_iddef(prjstr, (HSCIDD *) dln_data(nd));
        nd = dln_next(nd);
    }
}
Beispiel #4
0
/* append other documents referered */
static VOID append_doc_references(EXPSTR * prjstr, DLLIST * reflist)
{
    DLNODE *nd = dll_first(reflist);
    while (nd)
    {
        append_reference(prjstr, (HSCREF *) dln_data(nd));
        nd = dln_next(nd);
    }
}
Beispiel #5
0
/* append included files */
static VOID append_doc_includes(EXPSTR * prjstr, DLLIST * inclist)
{
    DLNODE *nd = dll_first(inclist);
    while (nd)
    {
        append_include(prjstr, (HSCINC *) dln_data(nd));
        nd = dln_next(nd);
    }
}
Beispiel #6
0
/*
 * find_end_tag
 *
 * return first end tag on the container stack;
 * if not found, return NULL
 */
HSCTAG *find_end_tag(HSCPRC * hp, STRPTR tagname)
{
    HSCTAG *tag = NULL;
    DLNODE *nd = find_dlnode_bw(hp->container_stack->last,
                                (APTR) tagname, cmp_strtag);

    if (nd)
    {
        tag = (HSCTAG *) dln_data(nd);
    }

    return tag;
}
Beispiel #7
0
/*
 * postprocess_attributes
 *
 * This function scans a tag's list of attributes for URI-attributes
 * referring to an external URI. If it succeeds, and the hsc-process
 * has it's hp->strip_ext flag enabled, the function exits.
 *
 * Otherwise, it scans the attributes for new IDs and references
 * and updates the document data if neccessary (but only for start tags)
 *
 * params:
 *   hp ........ hsc-process
 *   tag ....... tag whose attribute list should be examined
 *   open_tag .. for end tags, the document-data should not be
 *               updated again
 * result:
 *   TRUE, if tag should NOT be stripped
 */
BOOL postprocess_tagattr(HSCPRC * hp, HSCTAG * tag, BOOL open_tag) {
    BOOL dontstrip = TRUE;

    if (tag->attr) {

        /*
         * find out, if list should be refused
         */
        if (hp->strip_ext
            && tag->uri_stripext
            && get_vartext(tag->uri_stripext)
            && (uri_kind(get_vartext(tag->uri_stripext)) == URI_ext)
            )
        {
            D(fprintf(stderr, DHL "strip external\n"));
            dontstrip = FALSE;
        } else if (open_tag) {
            /*
             * search for new IDs and references
             */
            DLNODE *nd = dll_first(tag->attr);
            while (nd) {
                HSCATTR *attrib = (HSCATTR *) dln_data(nd);
                STRPTR value = get_vartext(attrib);

                if (value) {
                    if (attrib->vartype == VT_URI) {
                        /* new reference */
                        INFILEPOS *fpos = new_infilepos(hp->inpf);
                        CALLER *newcaller = fpos2caller(fpos);
                        HSCREF *newref =
                        app_reference(hp->project->document, value);

                        newref->caller = newcaller;

                        del_infilepos(fpos);
                        D(fprintf(stderr, DHL "new REFERENCE: `%s'\n", value));

                    } else if (attrib->vartype == VT_ID) {
                        /* new id defined */
                        D(fprintf(stderr, DHL "new ID: `%s'\n", value));
                        add_local_iddef(hp, value);
                    }
                }
                nd = dln_next(nd);
            }
        }
    }
    return (dontstrip);
}
Beispiel #8
0
/*
 * append_output
 *
 * append text to output string
 */
void append_output(STRPTR text)
{
    EXPSTR *outstr = (EXPSTR *) dln_data(dll_last(outlist));

    /* check if current output-string will be full */
    if ((estrlen(outstr) + strlen(text) + 1) > OUTPUT_STEPSIZE) {

        /* if so, append a new output-string to the list
         * and make use this one */
#if DEBUG_HSC_OUTPUT
        fprintf(stderr, DHSC "new string after %lu/%lu chars\n",
                estrlen(outstr), OUTPUT_STEPSIZE);
#endif
        outstr = init_estr(OUTPUT_STEPSIZE);
        app_dlnode(outlist, (APTR) outstr);

    }

    app_estr(outstr, text);
}
Beispiel #9
0
/*
 * find_includefile
 *
 * scan all include-directories for file to be opened;
 * if the file can't be found, the filename in the current
 * directory will be returned (which should therefor result
 * in an error while processing hsc_include())
 *
 * NOTE: this function considers the file to be found if it could have
 *       been opened for input. afterwards, the file is immediatly
 *       closed. This isn't really a multitasking-conform behavior
 *       because the file will have to be reopend again by the
 *       hsc_include() function later and meanwhile could have been
 *       removed by another task.
 */
static BOOL find_includefile(HSCPRC *hp, EXPSTR * dest, STRPTR filename)
{
    BOOL found = FALSE;

    /* reset filename */
    set_estr(dest, filename);

    if (!fexists(filename))
    {
        DLNODE *nd = dll_first(hp->include_dirs);

        /* process all include-directories.. */
        while (nd && !found)
        {
            /* concat incdir+filename, check if it exists,
             * process next or abort loop */
            link_fname(dest, (STRPTR) dln_data(nd), filename);
            D(fprintf(stderr, DHL "  try `%s'\n", estr2str(dest)));
            if (fexists(estr2str(dest)))
            {
                found = TRUE;
            }
            else
                nd = dln_next(nd);
        }
    }
    else
    {
        /* found in current directory */
        found = TRUE;
    }

    if (found)
    {
        D(fprintf(stderr, DHL "  found at `%s'\n", estr2str(dest)));
    }

    return (found);
}
Beispiel #10
0
/*
 * hsc_parse_end
 *
 * check for all tags closed and required
 * tags occured
 */
BOOL hsc_parse_end(HSCPRC * hp)
{
    if (!hp->fatal)
    {
        INFILEPOS *infpos = new_infilepos(hp->inpf);

        /* check for unclosed containers */
        DLNODE *nd = hp->container_stack->first;
        while (nd)
        {
            HSCTAG *endtag = (HSCTAG *) dln_data(nd);

            set_infilepos(hp->inpf, endtag->start_fpos);
            hsc_message(hp, MSG_MISS_CTAG,
                        "%c missing", endtag->name);

            nd = dln_next(nd);
        }

        set_infilepos(hp->inpf, infpos);
        del_infilepos(infpos);

        /* check for required tags missing */
        nd = hp->deftag->first;
        while (nd)
        {
            HSCTAG *tag = (HSCTAG *) nd->data;

            if ((tag->option & HT_REQUIRED
                 && (tag->occured == FALSE)))
            {
                hsc_message(hp, MSG_MISS_REQTAG,
                            "required %T missing", tag);
            }
            nd = nd->next;
        }
    }
    return (BOOL) (!hp->fatal);
}
Beispiel #11
0
/*
 * find_end_container
 *
 * search container stack for the first macro which is a
 * container macro anjd return the cerresponding tag structure
 */
HSCTAG *find_end_container_macro(HSCPRC * hp)
{
    HSCTAG *tag = NULL;
    DLNODE *nd = dll_last(hp->container_stack);

    while (nd)
    {
        HSCTAG *nd_tag = (HSCTAG *) dln_data(nd);

        if (nd_tag->option & HT_CONTENT)
        {
            tag = nd_tag;
            nd = NULL;
        }
        else
        {
            nd = dln_prev(nd);
        }
    }

    return tag;
}
Beispiel #12
0
/*
 * hsc_parse_amp
 *
 * parse ampersand ("&")
 */
BOOL hsc_parse_amp(HSCPRC * hp)
{
    INFILE *inpf = hp->inpf;
    EXPSTR *amp_str = init_estr(0);

    if (!hp->fatal)
    {
        BOOL rplc = hp->smart_ent;      /* TRUE, if "&" should be replaced */

        hp_enable_output(hp, "entity");

        if (rplc)
        {
            /*
             * test if char before and
             * after ">" is white-space
             */
            int ch = infgetc(inpf);

            inungetc(ch, inpf);

            if (!(hsc_whtspc(ch) && estrlen(hp->whtspc)))
                rplc = FALSE;
        }
        if (rplc)
        {
            /* replace ampersand */
            message_rplc(hp, "&", "&");
            set_estr(amp_str, "&");
        }
        else
        {
            /*
             * get entity-id, test for unknown entity
             */
            char *nxtwd;
            DLNODE *nd;
            BOOL app_entity = TRUE;

            /* remember "&" */
            set_estr(amp_str, infgetcw(inpf));

            /* get entity id */
            nxtwd = infgetw(inpf);

            /* TODO: check for white-space */

            if (!strcmp(nxtwd, "#"))
            {
                /*
                 * process numeric entity
                 */

                /* append "#" */
                app_estr(amp_str, infgetcw(inpf));

                nxtwd = infgetw(inpf);
                errno = 0;
                strtoul(nxtwd, NULL, 0);
                if (errno || strlen(infgetcws(inpf)))
                {
                    hsc_message(hp, MSG_ILLG_NUM,       /* illegal numeric entity */
                              "illegal numeric value %n for entity", nxtwd);
                }
                /* append entity specifier */
                app_estr(amp_str, nxtwd);
            }
            else
            {
                /*
                 * process text entity
                 */
                HSCVAR *attr = NULL;

                /* search for entity in list */
                nd = find_dlnode(hp->defent->first, (APTR) nxtwd, cmp_strent);

                if (hp->jens && (nd == NULL))
                {
                    /* asume that entity is an attribute,
                     * try to find it and append it's value
                     */
                    attr = find_varname(hp->defattr, nxtwd);
                    if (attr)
                    {
                        set_estr(amp_str, get_vartext(attr));
                        app_entity = FALSE;
                    }
                }

                if ((nd == NULL) && (attr == NULL))
                {
                    hsc_message(hp, MSG_UNKN_ENTITY,
                                "unknown %e", nxtwd);
                }
                else
                {
                    /* check for icon-entity and warn about */
                    /* portability peoblem */
                    HSCENT *entity = dln_data(nd);

                    if (entity->numeric == ICON_ENTITY)
                        if (estrlen(hp->iconbase))
                        {
                            replace_icon(hp, nxtwd);
                            set_estr(amp_str, "");
                            app_entity = FALSE;
                        }
                        else
                        {
                            hsc_message(hp, MSG_ICON_ENTITY,
                                        "icon %e found", nxtwd);
                        }
                }

                if (app_entity)
                    /* append entity specifier */
                    app_estr(amp_str, nxtwd);
            }

            /* TODO: check for whitespace before ";" */

            /* check for closing ';' */
            parse_wd(hp, ";");

            /* append ";" */
            if (app_entity)
                app_estr(amp_str, infgetcw(inpf));
        }

        /* output whole entity */
        if (estrlen(amp_str))
            hsc_output_text(hp, "", estr2str(amp_str));

        del_estr(amp_str);

#if (defined MSDOS & (!defined HSC_BILL))
#define WASTE_SIZE (1024*1024)
        /* waste some time */
        {
            STRPTR mem1 = (STRPTR) umalloc(WASTE_SIZE);
            STRPTR mem2 = (STRPTR) umalloc(WASTE_SIZE);
            size_t i = WASTE_SIZE;

            while (i)
            {
                if (mem1[i] && mem2[i])
                {
                    mem1[i] = mem2[i];
                }
                else
                {
                    mem2[i] = mem1[i];
                }
                i--;
            }

            ufree(mem2);
            ufree(mem1);
        }
#endif
    }

    return (BOOL) (!hp->fatal);
}
Beispiel #13
0
/*
 * args_ok
 *
 * prepare args, check & parse user args, display error and
 * help message if neccessary
 *
 * result: TRUE, if all args ok
 */
BOOL args_ok(HSCPRC * hp, int argc, char *argv[])
{
    BOOL ok;                    /* return value */
    DLLIST *ignore_list = NULL; /* dummy */
    EXPSTR *destdir = init_estr(32);    /* destination dir */
    EXPSTR *rel_destdir = init_estr(32);        /* relative destination dir */
    EXPSTR *kack_name = init_estr(0);   /* temp. str for outfilename */
    struct arglist *hsc_args;   /* argument structure */

    arg_hp = hp;

    arg_mode_CB(DEFAULT_MODE_STR);

    /* create arg-table */
    hsc_args =
        prepare_args("HSC_ARGS",

    /* file args */
                     "FROM/M", &incfile,
                     "include- and input-file(s)",

                     "TO/K", &arg_outfname,
                     "output file (default: stdout)",

                     "PRJFILE/T/K", &prjfilename,
                     "project file (default: none)",

                     "PREFSFILE/T/K", &prefsfilename,
                     "syntax preferences (default: hsc.prefs)",

                     "MSGFILE=MF/T/K", &msgfilename,
                     "message file (default: stderr)",

                     "MSGFORMAT/T/K", &msg_format,
                     "how to display message",
    /* numeric */
                     "MAXERR/N/K", &max_error,
                     "max. number of errors (default: 20)",

                     "EXTENSION/T/K", &arg_extension,
                   "output-file-extension (default: " DEFAULT_EXTENSION ")",

                     "DEFINE=DEF/T/K/M", &define_list,
                     "define global attribute",

                     "IGNORE=IGN/N/K/M/$", arg_ignore_CB, &ignore_list,
                     "ignore message number",

                     "MODE/E/K/$", arg_mode_CB, MODE_ENUMSTR, &arg_mode,
                     "mode for syntax check (" MODE_ENUMSTR ")",

                     "QUOTESTYLE=QS/E/K", QMODE_ENUMSTR, &arg_quotemode,
                     "defines how quotes appear (" QMODE_ENUMSTR ")",
#if 0
                     "ENTITYSTYLE=ES/E/K", EMODE_ENUMSTR, &entmode,
                     "defines how special chars. appear (" EMODE_ENUMSTR ")",
    /* switches */
#endif
                     "COMPACT=CO/S", &arg_compact,
                     "strip useless LFs and white-spaces",

                     "GETSIZE/S", &arg_getsize,
                     "get width and height of images",

                     "MSGANSI/S", &msg_ansi,
                     "use ansi-sequences in messages",

                     "RPLCENT=RE/S", &arg_rplc_ent,
                     "replace special characters",

                     "RPLCQUOTE=RQ/S", &arg_rplc_quote,
                     "replace quotes in text by `"'",

                     "SMARTENT=SA/S", &arg_smart_ent,
                     "replace special entities (`&<>\"')",

                     "JENS/S", &arg_jens,
                     "don't try this at home",
                     "STRIPCOMMENT=SC/S", &arg_strip_cmt,
                     "strip SGML-comments",

                     "STRIPEXTERNAL=SX/S", &arg_strip_ext,
                     "strip tags with external URIs",

                     "STRIPTAGS=ST/K", &arg_striptags,
                     "tags to be stripped",

                     "ICONBASE/T/K", &arg_iconbase,
                     "base-uri for icon-entities",

                     "STATUS/E/K/$", arg_status_CB,
                     STATUS_ENUM_STR, &disp_status,
                     "status message (" STATUS_ENUM_STR ")",

                     "-DEBUG/S", &arg_debug, "enable debugging output",
    /* help */
                     "HELP=?/S", &arg_help, "display this text",
                     "LICENSE/S", &arg_license, "display license",

                     NULL);

    /* remove dummy list TODO: this sucks */
    del_dllist(ignore_list);

    ok = (hsc_args != NULL);

    /* set & test args */
    if (ok)
    {
        BOOL use_stdout = FALSE;        /* flag: use stdout as output-file */

        ok = set_args(argc, argv, hsc_args);

        /* display help, if requested vie HELP switch, or no
         * input to pipe or read is passed */
        ok &= (!arg_help &&
               (arg_pipe_in || (incfile && dll_first(incfile))));

        if (arg_license)
        {
            /* display license text */
            fprintf_prginfo(stderr);
            show_license();
            set_return_code(RC_WARN);
        }
        else if (!ok)
        {
            /* display help, if error in args or HELP-switch set */
            fprintf_prginfo(stderr);
            fprintf_arghelp(stderr, hsc_args);
            set_return_code(RC_WARN);
        }
        else
        {
            BOOL fnsux = FALSE; /* flag: TRUE = can't evaluate out-filename */

            /* set debugging switch */
            hsc_set_debug(hp, arg_debug);

            /* autoset depending options */
            if (hsc_get_debug(hp))
                disp_status = STATUS_VERBOSE;

            /* set default options */
            if (!arg_extension)
                arg_extension = DEFAULT_EXTENSION;

            /* disable ID-warning if no project-file */
            if (!prjfilename)
                hsc_set_msg_ignore(hp, MSG_NO_DOCENTRY, TRUE);

            /* compute name of input file */
            arg_inpfname = NULL;
            if (dll_first(incfile) && !arg_pipe_in)
            {
                /* use last FROM as input file */
                arg_inpfname = dln_data(dll_last(incfile));

                set_estr(inpfilename, arg_inpfname);

                /* get path part of inputfilename as relative
                 * destination directory */
                get_fpath(rel_destdir, arg_inpfname);

                /* TODO: set reldir when including first file */
                /* TODO: find out why the above TODO is there */

                /* remove input filename from incfile */
                del_dlnode(incfile, dll_last(incfile));

                D(fprintf(stderr, DHSC "input : use `%s'\n"
                          DHSC "reldir: use `%s'\n",
                          estr2str(inpfilename), estr2str(rel_destdir)));
            }

            /* display include files */
            D(
                 {
                 DLNODE * nd = dll_first(incfile);

                 while (nd)
                 {
                 fprintf(stderr, DHSC "includ: use `%s'\n", (
                                                      STRPTR) dln_data(nd));
                 nd = dln_next(nd);
                 }
                 }
            );

            /*
             * if no output-filename given,
             * outfilename stays NULL. this let open_output
             * open stdout as output-file
             */
            if (arg_outfname)
            {
                /* check, if last char of outputfilename is a
                 * directory separator; if so, use the filename
                 * as destination directory
                 */
                if (arg_outfname)
                {
                    UBYTE lastch = 0;

                    /* get last char of outfname to determine
                     * if it's a directory
                     */
                    if (strlen(arg_outfname))
                        lastch = arg_outfname[strlen(arg_outfname) - 1];

#ifdef AMIGA
                    /* for Amiga, execpt empty string for current dir */
                    if (!lastch)
                    {
                        lastch = (PATH_SEPARATOR[0]);
                        D(fprintf(stderr, DHSC "AMIGA: use current dir\n"));
                    }
#endif

                    if (strchr(PATH_SEPARATOR, lastch))
                    {
                        /* use outfilename as destdir */
                        set_estr(destdir, arg_outfname);
                        arg_outfname = NULL;
                        D(fprintf(stderr, DHSC "output: use `%s' as destdir\n",
                                  estr2str(destdir)));
                    }
                    else if (arg_inpfname)
                    {
                        /* output-filename already specified */
                        /* separate it to destdir + reldir + name */
                        EXPSTR *kack_destdir = init_estr(0);
                        EXPSTR *kack_reldir = init_estr(0);
                        STRPTR inp_reldir = estr2str(rel_destdir);
                        STRPTR out_reldir = NULL;
                        STRPTR ou2_reldir = NULL;

                        get_fname(kack_name, arg_outfname);
                        get_fpath(kack_destdir, arg_outfname);

                        /* check corresponding dirs for
                         * consistency: check if last strlen(rel_destdir)
                         * chars are equal */
                        out_reldir = estr2str(kack_destdir);
                        ou2_reldir = out_reldir;
                        out_reldir = out_reldir
                            + (strlen(out_reldir) - strlen(inp_reldir));

                        if (out_reldir[0])
                        {
                            /* search for next dir-sparator backwards */
                            /* (this ones only needed for a smart error message) */
                            while ((out_reldir != ou2_reldir)
                                 && (!strchr(PATH_SEPARATOR, out_reldir[0]))
                                )
                            {
                                out_reldir--;
                            }
                            out_reldir++;
                        }
                        D(fprintf(stderr, DHSC "corr_inp: `%s'\n"
                                  DHSC "corr_out: `%s'\n",
                                  inp_reldir, out_reldir)
                            );

                        /* check if correspondig relative in/out-dirs
                         * are equal */
                        if (!fnamecmp(inp_reldir, out_reldir))
                        {
                            /* they match.. */
                            STRPTR tmp_name = NULL;     /* copy of kack_nam */

                            /* cut corresponding chars */
                            get_left_estr(kack_destdir, kack_destdir,
                                          estrlen(kack_destdir)
                                          - strlen(out_reldir));

                            set_estr(kack_reldir, inp_reldir);

                            D(fprintf(stderr, DHSC "kack_dst: `%s'\n"
                                      DHSC "kack_rel: `%s'\n"
                                      DHSC "kack_nam: `%s'\n",
                                      estr2str(kack_destdir),
                                      estr2str(kack_reldir),
                                      estr2str(kack_name))
                                );

                            /* just copy these values where they are
                             * expected to be */
                            estrcpy(destdir, kack_destdir);
                            estrcpy(rel_destdir, kack_reldir);

                            /* create output filename */
                            tmp_name = strclone(estr2str(kack_name));
                            estrcpy(kack_name, kack_destdir);
                            estrcat(kack_name, kack_reldir);
                            app_estr(kack_name, tmp_name);
                            ufreestr(tmp_name);

                            arg_outfname = estr2str(kack_name);
                        }
                        else
                        {
                            /* unmatched corresponding dirs */
                            fprintf(stderr, "unmatched corresponding relative directories:\n"
                                    "  input  `%s'\n  output `%s'\n",
                                    inp_reldir, out_reldir);
                            ok = FALSE;
                        }

                        /* free temp. vars */
                        del_estr(kack_reldir);
                        del_estr(kack_destdir);
                    }
                }
                if (arg_outfname)
                {
                    /* set outputfilename with value passed iwithin args */
                    outfilename = init_estr(32);
                    set_estr(outfilename, arg_outfname);
                    D(fprintf(stderr, DHSC "output: set to `%s'\n",
                              estr2str(outfilename)));
                }
                else
                {
                    if (!arg_pipe_in)
                    {
                        /* no outfilename given */
                        /* ->outfilename = destdir + inpfilename + ".html" */

                        /* link destdir & input filename */
                        outfilename = init_estr(32);
                        link_fname(outfilename, estr2str(destdir),
                                   arg_inpfname);
                        if (strcmp(arg_extension, "."))
                            set_fext(outfilename, arg_extension);
                        D(fprintf(stderr,
                              DHSC "output: concat destdir+inpfile+`.%s'\n"
                                  DHSC "output: set to `%s'\n",
                                  arg_extension, estr2str(outfilename)));
                    }
                    else
                        fnsux = TRUE;
                }

                if (fnsux)
                {
                    /* no way to find out output filename */
                    status_error("unable to evaluate output filename\n");
                    arg_outfname = NULL;
                    ok = FALSE;
                }
            }
            else
            {
                D(fprintf(stderr, DHSC "output: use stdout\n"));
                use_stdout = TRUE;
            }

            if (!ok)
                set_return_code(RC_ERROR);

        }

        if (ok)
        {
            if (arg_iconbase)
                hsc_set_iconbase(hp, arg_iconbase);
            if (!use_stdout)
                hsc_set_filename_document(hp, estr2str(outfilename));
        }
        /* display argument error message */
        if (!ok)
        {
            /* NOTE: no strclone() is used on outfilename, if an
             * error already occured within set_args(). therefore,
             * you must not call ufreestr( outfilename ) */
            pargerr();
            arg_outfname = NULL;
            set_return_code(RC_ERROR);
        }
        else
        {
            EXPSTR *tmp_fname = init_estr(32);  /* filename only part */

            fileattr_str = init_estr(64);

            if (outfilename)
                get_fname(tmp_fname, estr2str(outfilename));
            set_dest_attribs(hp, estr2str(rel_destdir),
                             estr2str(tmp_fname));
            if (!arg_pipe_in)
            {
                if (outfilename)
                    get_fname(tmp_fname, estr2str(outfilename));
                else
                    clr_estr(tmp_fname);
                set_source_attribs(hp, estr2str(rel_destdir),
                                   estr2str(tmp_fname));
            }
            else
                set_source_attribs(hp, NULL, NULL);

            D(
                 {
                 HSCMSG_ID i;

                 fprintf(stderr, "\n"
                         DHSC "input : `%s'\n", estr2str(inpfilename));
                 fprintf(stderr, DHSC "output: `%s'\n", get_outfilename());
                 fprintf(stderr, DHSC "destdr: `%s'\n", estr2str(destdir));
                fprintf(stderr, DHSC "reldst: `%s'\n", estr2str(rel_destdir));
                 if (prjfilename)
                 fprintf(stderr, DHSC "projct: `%s'\n", prjfilename);
                 if (!use_stdout)
                fprintf(stderr, DHSC "procss: `%s'\n", estr2str(outfilename));
                 fprintf(stderr, DHSC "ignore:");
                 for (i = 0; i < MAX_MSGID; i++)
                 if (hsc_get_msg_ignore(hp, i))
                 fprintf(stderr, " %lu", i);
                 fprintf(stderr, "\n");
                 }
            );

            del_estr(tmp_fname);
        }
Beispiel #14
0
/*
 * user_defines_ok
 *
 * process all defines passed via user args
 *
 * result: always TRUE
 */
BOOL user_defines_ok(HSCPRC * hp)
{
    /* define destination attributes (HSC.DOCUMENT.URI etc.) */
    define_file_attribs(hp);

    if (define_list && dll_first(define_list))
    {
        DLNODE *nd = dll_first(define_list);
        EXPSTR *defbuf = init_estr(64);
#if 0
        BOOL old_ignore_quotemsg =
        hsc_get_msg_ignore(hp, MSG_ARG_NO_QUOTE);
#endif

        while (nd)
        {
            STRPTR defarg = (STRPTR) dln_data(nd);

            D(fprintf(stderr, DHSC "define using `%s'\n", defarg));

            set_estr(defbuf, "<$define ");

            /* append attribute name */
            do
            {
                app_estrch(defbuf, defarg[0]);
                defarg++;
            }
            while (defarg[0] && (defarg[0] != '=')
                   && (defarg[0] != '/') && (defarg[0] != ':'));

            /* if no type set, use "string" as default */
            if (defarg[0] != ':')
            {
                app_estr(defbuf, ":string");
            }

            /* append type (if set) and attribute-flags */
            while (defarg[0] && (defarg[0] != '='))
            {
                app_estrch(defbuf, defarg[0]);
                defarg++;
            }

            /* append value (if any) and quotes */
            if (defarg[0] == '=')
            {
                char quote_needed = 0;  /* flag: user did not use quotes */

                /* append "=" */
                app_estrch(defbuf, defarg[0]);
                defarg++;

                /* check which kind of quote should be appended */
                if ((defarg[0] != '\"') && (defarg[0] != '\''))
                {
                    BOOL single_quote = FALSE;
                    BOOL double_quote = FALSE;
                    STRPTR scanarg = defarg;

                    /* scan value for quotes */
                    while (scanarg[0])
                    {
                        if (scanarg[0] == '\"')
                            double_quote = TRUE;
                        else if (scanarg[0] == '\'')
                            single_quote = TRUE;
                        scanarg++;
                    }

                    /* choose quote to enclose value */
                    if (!double_quote)
                        quote_needed = '\"';
                    else if (!single_quote)
                        quote_needed = '\'';
                    else
                        panic("both quotes in value");
                }

                /* append quote (if not already done by user) */
                if (quote_needed)
                    app_estrch(defbuf, quote_needed);

                /* append value */
                while (defarg[0])
                {
                    app_estrch(defbuf, defarg[0]);
                    defarg++;
                }

                /* append quote (if not already done by user) */
                if (quote_needed)
                    app_estrch(defbuf, quote_needed);

            }

            /* append end ">" */
            app_estrch(defbuf, '>');

            D(fprintf(stderr, DHSC "define: `%s'\n", estr2str(defbuf)));

            hsc_include_string(hp, "DEFINE",
                             estr2str(defbuf), IH_PARSE_HSC | IH_NO_STATUS);
            nd = dln_next(nd);
        }

        del_estr(defbuf);
#if 0
        hsc_set_msg_ignore(hp, MSG_ARG_NO_QUOTE, old_ignore_quotemsg);
#endif
    }
    else
    {
        D(fprintf(stderr, DHSC "(no defines)\n"));
    }

    return ((BOOL) (return_code < RC_ERROR));
}
Beispiel #15
0
/*
 * close_output
 *
 * close output file, if it not stdout
 */
BOOL write_output(HSCPRC * hp)
{
#define MAX_ERRORLEN 500
    STRPTR outfilenm = NULL;
    BOOL written = FALSE;

    if (outfilename)
        outfilenm = estr2str(outfilename);

    if ((return_code == RC_OK)
        || (return_code == RC_WARN)
        || hp->debug) {
        FILE *outfile = NULL;   /* output file */
        char buf[MAX_ERRORLEN + 2];     /* buffer for error string */

        /*
         * try to open output file
         */
        if (outfilenm) {
            errno = 0;
            outfile = fopen(outfilenm, "w");
            if (!outfile) {
                strncpy(buf, "unable to open `", MAX_ERRORLEN);
                strncat(buf, estr2str(outfilename),
                        MAX_ERRORLEN - strlen(buf));
                strncat(buf, "' for output: ", MAX_ERRORLEN - strlen(buf));
                strncat(buf, strerror(errno), MAX_ERRORLEN - strlen(buf));
                status_error(buf);
            }
        } else {
            outfile = stdout;
            outfilenm = STDOUT_NAME;
        }

        /*
         * write output
         */
        if (outfile) {

            DLNODE *nd = dll_first(outlist);

            status_msg("writing output...");
            errno = 0;

            /* write whole list of output-strings */
            while (nd && !errno) {

                EXPSTR *outstring = (EXPSTR *) dln_data(nd);

                nd = dln_next(nd);
                fwrite(estr2str(outstring), sizeof(char),
                       estrlen(outstring), outfile);
            }

            /* handle write-error, display message */
            if (errno) {
                strncpy(buf, "error writing `", MAX_ERRORLEN);
                strncat(buf, outfilenm, MAX_ERRORLEN - strlen(buf));
                strncat(buf, "': ", MAX_ERRORLEN - strlen(buf));
                strncat(buf, strerror(errno), MAX_ERRORLEN - strlen(buf));
                status_error(buf);
            } else
                written = TRUE;

            status_clear();

            /* close output file */
            if (outfile != stdout)
            {
                fclose(outfile);

#ifdef RISCOS
                {
                  /* set the filetype to HTML (&FAF) */
                  char *riscos_filename=unixname_to_riscos(outfilenm);
                  _swix(OS_File,_IN(0)|_IN(1)|_IN(2),18,riscos_filename,0xFAF);
                  free(riscos_filename);
                }
#endif
            }
        }
    } else {

        status_msg("no output written");
        status_lf();

    }

    return (written);
}
Beispiel #16
0
/*
 * hsc_parse_tag
 *
 * parse tag (after "<")
 */
BOOL hsc_parse_tag(HSCPRC * hp)
{
    INFILE *inpf = hp->inpf;
    STRPTR nxtwd = NULL;
    DLNODE *nd = NULL;
    HSCTAG *tag = NULL;
    HSCTAG *now_tag_strip_whtspc = NULL;
    ULONG tci = 0;              /* tag_call_id returned by set_tag_args() */
    BOOL(*hnd) (HSCPRC * hp, HSCTAG * tag) = NULL;
    BOOL open_tag;
    DLLIST *taglist = hp->deftag;
    BOOL rplc_lt = FALSE;       /* TRUE, if replace spc. char "<" */
    BOOL hnd_result = TRUE;     /* result returned by handle */
    BOOL unknown_tag = FALSE;   /* TRUE, if tag has not been defined before */
    BOOL preceeding_whtspc = estrlen(hp->whtspc);

    /* init strings used inside tag-handles */
    set_estr(hp->tag_name_str, infgetcw(inpf));
    clr_estr(hp->tag_attr_str);
    clr_estr(hp->tag_close_str);

    if (hp->smart_ent && preceeding_whtspc)
    {
        /*
         * check for special char "<"
         */
        int ch = infgetc(inpf);

        /* check if next char is a white space */
        if (hsc_whtspc(ch))
        {
            rplc_lt = TRUE;

            /* write "&lt;" and white spaces */
            message_rplc(hp, "<", "&lt;");
            hsc_output_text(hp, "", "&lt;");
        }
        inungetc(ch, inpf);
    }

    if (!rplc_lt)
    {
        /* get tag id */
        nxtwd = infget_tagid(hp);

        if (!hp->fatal)
        {
            /* append tag-name to tag_name_str */
            if (!hp->compact)
            {
                app_estr(hp->tag_name_str, infgetcws(inpf));
            }
            app_estr(hp->tag_name_str, infgetcw(inpf));

            if (!hp->suppress_output)
            {
                /* output tag currently processing
                 * NOTE: the first tag of the source is skipped because
                 *   hp->supress_ouptut is disable later */
                D(fprintf(stderr, DHL "tag <"));
            }
        }
    }

    if (!hp->fatal && !rplc_lt)
    {
        BOOL write_tag = FALSE; /* flag: write tag text & attrs to output? */

        if (strcmp("/", nxtwd)) /* is it a closing tag? */
        {
            /*
             *
             * process start-tag
             *
             */
            open_tag = TRUE;
            if (!hp->suppress_output)
            {
                D(fprintf(stderr, "%s>\n", nxtwd));
            }
            /* search for tag in list */
            nd = find_dlnode(taglist->first, (APTR) nxtwd, cmp_strtag);
            if (nd == NULL)
            {
                hsc_message(hp, MSG_UNKN_TAG,   /* tag not found */
                            "unknown %t", nxtwd);
                tag = new_hsctag(nxtwd);
                tag->option |= HT_UNKNOWN;
                unknown_tag = TRUE;
            }
            else
            {
                tag = (HSCTAG *) nd->data;
            }

            /* set handle-function */
            hnd = tag->o_handle;

            /*
             * handle options
             */

            /* check for obsolete tag */
            if (tag->option & HT_OBSOLETE)
            {
                hsc_message(hp, MSG_TAG_OBSOLETE,
                            "%T is obsolete", tag);
            }

            /* check for jerk-tag */
            if (tag->option & HT_JERK)
            {
                hsc_message(hp, MSG_TAG_JERK,
                            "%T is only used by %j", tag);
            }

            /* only-once-tag occured twice? */
            if ((tag->option & HT_ONLYONCE) && (tag->occured))
            {
                hsc_message(hp, MSG_TAG_TOO_OFTEN,
                            "%T occured too often", tag);
            }

            /* set occured-flag */
            if (tag->option & (HT_ONLYONCE | HT_REQUIRED))
            {
                tag->occured = TRUE;
            }

            /* check for "must be inside"/"not allowed within"-tags */
            if (!check_mbinaw(hp, tag))
            {
                hnd = NULL;
            }

            /* clear (reset to default) attribute values of tag */
            clr_varlist(tag->attr);

            /* set attributes or check for ">" */
            if (!(tag->option & HT_SPECIAL))
            {
                tci = set_tag_args(hp, tag);
                if (tci == MCI_ERROR)
                {
                    skip_until_eot(hp, NULL);
                    hnd = NULL;
                }

                if (!hp->fatal)
                {
                    /* set ">" in string that contains closing text */
                    if (!hp->compact)
                    {
                        set_estr(hp->tag_close_str, infgetcws(inpf));
                    }
                    else
                    {
                        clr_estr(hp->tag_close_str);
                    }
                    app_estr(hp->tag_close_str, infgetcw(inpf));

                    /* check for succeeding white-space */
                    if ((tag->option & HT_WHTSPC) && !infeof(inpf))
                    {
                        int ch = infgetc(inpf);

                        if (hsc_whtspc(ch))
                        {
                            if (hp->strip_badws)
                            {
                                hp->strip_next2_whtspc = TRUE;
                            }
                            else if (!hp->strip_next2_whtspc)
                            {
#if 1
                                now_tag_strip_whtspc = tag;
#else /* TODO: remove this */
                                hsc_message(hp, MSG_SUCC_WHTSPC,
                                            "succeeding white-space for %T",
                                            tag);
#endif
                            }
                        }
                        inungetc(ch, inpf);
                    }
                }
            }

            /* for AUTOCLOSE-tags, remove eventually existing
             * end tags on stack */
            if (tag->option & HT_AUTOCLOSE)
            {
                DLNODE *nd = find_end_tag_node(hp, tag->name);

                if (nd)
                {
                    if (nd == dll_last(hp->container_stack))
                    {
                        D(fprintf(stderr, DHL "  autoclose </%s> before\n", tag->name));
                        remove_end_tag(hp, tag);
                    }
                    else
                    {
                        HSCTAG *end_tag = (HSCTAG *) dln_data(dll_last(hp->container_stack));

                        D(fprintf(stderr,
                                  DHL "  no autoclose because of <%s> \n",
                                  end_tag->name));
                    }
                }
                else
                {
                    D(fprintf(stderr, DHL "  no autoclose neccessary\n"));
                }
            }

            /* end-tag required? */
            if ((tag->option & HT_CLOSE)
                || (tag->option & HT_AUTOCLOSE))
            {
                /* yes: push current tag to container stack;
                 * (current values of attributes will be
                 * remembered */
                append_end_tag(hp, tag);
            }
        }
        else
        {
            /*
             *
             * process end-tag
             *
             */

            /* get tag id */
            nxtwd = infget_tagid(hp);   /* get tag id */
            open_tag = FALSE;

            /* append tag-name to tag_name_str */
            if (!hp->compact)
            {
                app_estr(hp->tag_name_str, infgetcws(inpf));
            }
            app_estr(hp->tag_name_str, infgetcw(inpf));

            if (!hp->suppress_output)
            {
                D(fprintf(stderr, "/%s>\n", nxtwd));
            }

            /* search for tag in taglist */
            /* (see if it exists at all) */
            nd = find_dlnode(taglist->first, (APTR) nxtwd, cmp_strtag);
            if (nd == NULL)
            {
                /* closing tag is absolutely unknown */
                hsc_message(hp, MSG_UNKN_TAG,   /* tag not found */
                            "unknown %c", nxtwd);
                skip_until_eot(hp, hp->tag_attr_str);
            }
            else
            {
                tag = (HSCTAG *) nd->data;      /* fitting tag in taglist */

                /* check for preceding white-spaces */
                if ((tag->option & HT_WHTSPC) && anyWhtspc(hp))
                {
                    if (hp->strip_badws)
                    {
                        hp->strip_next_whtspc = TRUE;
                    }
                    else if (!hp->strip_next_whtspc)
                    {
                        hsc_message(hp, MSG_PREC_WHTSPC,
                                    "preceding white space for %C", tag);
                    }
                }

                if (tag->option & (HT_CLOSE | HT_AUTOCLOSE))
                {
                    /* set closing handle */
                    hnd = tag->c_handle;

                    /* check for no args */
                    if (!parse_wd(hp, ">"))
                    {
                        hsc_message(hp, MSG_CL_TAG_ARG,
                                    "no attributes allowed for end-tags");
                    }
                    else
                    {
                        /* set ">" in string that contains closing text */
                        if (!hp->compact)
                        {
                            set_estr(hp->tag_close_str, infgetcws(inpf));
                        }
                        app_estr(hp->tag_close_str, infgetcw(inpf));
                    }

                    /* set values of attributes stored
                     * in end-tag,
                     * remove end-tag from stack
                     */
                    remove_end_tag(hp, tag);
                }
                else
                {
                    /* illegal closing tag */
                    hsc_message(hp, MSG_ILLG_CTAG,      /* tag not found */
                                "illegal %c", nxtwd);
                    parse_gt(hp);
                    tag = NULL;
                }
            }
        }

        /*
         * processed for opening AND closing tag
         */
        write_tag = (!(tag) || !(tag->option & HT_NOCOPY));

        if (tag)
        {
            /*
             * check if tag should be stripped
             */
            if (!postprocess_tagattr(hp, tag, open_tag))
            {
                /* stripped tag with external reference */
                if (open_tag)
                {
                    hsc_msg_stripped_tag(hp, tag, "external reference");
                }
                hnd = NULL;     /* don't call handle */
                write_tag = FALSE;      /* don't output tag */
            }
            else if (hp->strip_tags
                     && strenum(tag->name, hp->strip_tags, '|', STEN_NOCASE))
            {
                /* strip tag requested by user */
                if (!(tag->option & HT_SPECIAL))
                {
                    if (open_tag)
                    {
                        hsc_msg_stripped_tag(hp, tag, "as requested");
                    }
                    hnd = NULL; /* don't call handle */
                    write_tag = FALSE;  /* don't output tag */
                }
                else
                {
                    hsc_message(hp, MSG_TAG_CANT_STRIP,
                                "can not strip special tag %T", tag);
                }

                /*
                 * get values for size from reference
                 */
            }
            else if (tag->uri_size && get_vartext(tag->uri_size))
                get_attr_size(hp, tag);
        }

        /* call handle if available */
        if (hnd && !hp->fatal)
            hnd_result = (*hnd) (hp, tag);

        /* write whole tag out */
        if (write_tag && hnd_result)
        {
            VOID(*tag_callback) (HSCPRC * hp, HSCTAG * tag,
                 STRPTR tag_name, STRPTR tag_attr, STRPTR tag_close) = NULL;

            if (open_tag)
            {
                tag_callback = hp->CB_start_tag;
            }
            else
            {
                tag_callback = hp->CB_end_tag;
            }

#if 1                           /* TODO: remove conditionals, but leave below code intact */
            /* enable output if necessary */
            if (hp->suppress_output)
            {
                hp_enable_output(hp, "non-internal tag occured");
            }
#endif

            /* write (flush) white spaces */
            hsc_output_text(hp, "", "");

            if (tag_callback)
            {
                (*tag_callback) (hp, tag,
                                 estr2str(hp->tag_name_str),
                                 estr2str(hp->tag_attr_str),
                                 estr2str(hp->tag_close_str));
            }
        }

        /* skip LF if requested */
        if (tag && (tag->option & HT_SKIPLF))
        {
            skip_next_lf(hp);   /* TODO: really skip single lf */
        }

        /* if tag should check for succeeding white spaces,
         * tell this hscprc now */
        if (now_tag_strip_whtspc)
        {
            D(fprintf(stderr, "  requested to check for succ.whtspc\n"));
            hp->tag_next_whtspc = now_tag_strip_whtspc;
        }

        /* remove temporary created tag */
        if (unknown_tag)
        {
            del_hsctag(tag);
        }

#if (defined MSDOS)             /* HSC_TRIGGER */
#define UNLIKELY (10*1024)
        /* crash randomly */
        if ((rand() % UNLIKELY) == (UNLIKELY / 2))
        {
            enforcerHit();
        }
#endif
    }

    return (BOOL) (!hp->fatal);
}