%% options copyright owner = Dirk Krause copyright year = 2011-2014 license = bsd %% module #include "dk3all.h" #include "dkt.h" $!trace-include /** Job structure. */ typedef struct { dk3_app_t *app; /**< Application. */ dk3_option_set_t *opt; /**< Option set. */ dkChar const * const *msg; /**< Localized messages. */ dkChar const * const *kwnl; /**< Keywords, not localized. */ dkChar const *title; /**< Page title for full page. */ int exval; /**< Exit status code. */ int enc_s; /**< Encoding for stdin. */ int enc_f; /**< Encoding for files. */ int f_fp; /**< Flag: Produce full page. */ int f_em; /**< Flag: Echo mode. */ int f_nl; /**< Flag: Last was newline. */ int f_ln; /**< Flag: Add code for line numbers. */ int coli; /**< Code line number. */ int cols; /**< Code line numbering state. */ } DKT_HTML_J; /** Long options / configuration file keywords. */ static dkChar const * const dkt_html_long_opt[] = { dkT("stdin-encoding"), dkT("file-encoding"), dkT("reset"), NULL }; /** Data for the option set. */ static dk3_option_t const dkt_html_options[] = { { dkT('R'), dkT("reset"), 0 }, { dkT('t'), dkT("title"), 1 }, { dkT('f'), dkT("full"), 0 }, { dkT('i'), dkT("input-encoding"), 1 }, { dkT('p'), dkT("plain"), 0 }, { dkT('e'), dkT("echo"), 0 }, { dkT('l'), dkT("line-numbers"), 0 } }; /** Number of options in the dkt_html_options array. */ static size_t const dkt_html_szoptions = sizeof(dkt_html_options)/sizeof(dk3_option_t); /** Translation table for ASCII characters. */ static char const * const dkt_html_translation_table[] = { /* 0 00 */ NULL, /* 1 01 */ NULL, /* 2 02 */ NULL, /* 3 03 */ NULL, /* 4 04 */ NULL, /* 5 05 */ NULL, /* 6 06 */ NULL, /* 7 07 */ NULL, /* 8 08 */ NULL, /* 9 09 */ "\t", /* 10 0a */ NULL, /* 11 0b */ NULL, /* 12 0c */ NULL, /* 13 0d */ NULL, /* 14 0e */ NULL, /* 15 0f */ NULL, /* 16 10 */ NULL, /* 17 11 */ NULL, /* 18 12 */ NULL, /* 19 13 */ NULL, /* 20 14 */ NULL, /* 21 15 */ NULL, /* 22 16 */ NULL, /* 23 17 */ NULL, /* 24 18 */ NULL, /* 25 19 */ NULL, /* 26 1a */ NULL, /* 27 1b */ NULL, /* 28 1c */ NULL, /* 29 1d */ NULL, /* 30 1e */ NULL, /* 31 1f */ NULL, /* 32 20 */ " ", /* 33 21 */ "!", /* 34 22 */ """, /* 35 23 */ "#", /* 36 24 */ "$", /* 37 25 */ "%", /* 38 26 */ "&", /* 39 27 */ "'", /* 40 28 */ "(", /* 41 29 */ ")", /* 42 2a */ "*", /* 43 2b */ "+", /* 44 2c */ ",", /* 45 2d */ "-", /* 46 2e */ ".", /* 47 2f */ "/", /* 48 30 */ "0", /* 49 31 */ "1", /* 50 32 */ "2", /* 51 33 */ "3", /* 52 34 */ "4", /* 53 35 */ "5", /* 54 36 */ "6", /* 55 37 */ "7", /* 56 38 */ "8", /* 57 39 */ "9", /* 58 3a */ ":", /* 59 3b */ ";", /* 60 3c */ "<", /* 61 3d */ "=", /* 62 3e */ ">", /* 63 3f */ "?", /* 64 40 */ "@", /* 65 41 */ "A", /* 66 42 */ "B", /* 67 43 */ "C", /* 68 44 */ "D", /* 69 45 */ "E", /* 70 46 */ "F", /* 71 47 */ "G", /* 72 48 */ "H", /* 73 49 */ "I", /* 74 4a */ "J", /* 75 4b */ "K", /* 76 4c */ "L", /* 77 4d */ "M", /* 78 4e */ "N", /* 79 4f */ "O", /* 80 50 */ "P", /* 81 51 */ "Q", /* 82 52 */ "R", /* 83 53 */ "S", /* 84 54 */ "T", /* 85 55 */ "U", /* 86 56 */ "V", /* 87 57 */ "W", /* 88 58 */ "X", /* 89 59 */ "Y", /* 90 5a */ "Z", /* 91 5b */ "[", /* 92 5c */ "\\", /* 93 5d */ "]", /* 94 5e */ "^", /* 95 5f */ "_", /* 96 60 */ "`", /* 97 61 */ "a", /* 98 62 */ "b", /* 99 63 */ "c", /* 100 64 */ "d", /* 101 65 */ "e", /* 102 66 */ "f", /* 103 67 */ "g", /* 104 68 */ "h", /* 105 69 */ "i", /* 106 6a */ "j", /* 107 6b */ "k", /* 108 6c */ "l", /* 109 6d */ "m", /* 110 6e */ "n", /* 111 6f */ "o", /* 112 70 */ "p", /* 113 71 */ "q", /* 114 72 */ "r", /* 115 73 */ "s", /* 116 74 */ "t", /* 117 75 */ "u", /* 118 76 */ "v", /* 119 77 */ "w", /* 120 78 */ "x", /* 121 79 */ "y", /* 122 7a */ "z", /* 123 7b */ "{", /* 124 7c */ "|", /* 125 7d */ "}", /* 126 7e */ "~", /* 127 7f */ NULL, /* 128 80 */ NULL, /* 129 81 */ NULL, /* 130 82 */ NULL, /* 131 83 */ NULL, /* 132 84 */ NULL, /* 133 85 */ NULL, /* 134 86 */ NULL, /* 135 87 */ NULL, /* 136 88 */ NULL, /* 137 89 */ NULL, /* 138 8a */ NULL, /* 139 8b */ NULL, /* 140 8c */ NULL, /* 141 8d */ NULL, /* 142 8e */ NULL, /* 143 8f */ NULL, /* 144 90 */ NULL, /* 145 91 */ NULL, /* 146 92 */ NULL, /* 147 93 */ NULL, /* 148 94 */ NULL, /* 149 95 */ NULL, /* 150 96 */ NULL, /* 151 97 */ NULL, /* 152 98 */ NULL, /* 153 99 */ NULL, /* 154 9a */ NULL, /* 155 9b */ NULL, /* 156 9c */ NULL, /* 157 9d */ NULL, /* 158 9e */ NULL, /* 159 9f */ NULL, /* 160 a0 */ " ", /* 161 a1 */ "¡", /* 162 a2 */ "¢", /* 163 a3 */ "£", /* 164 a4 */ "¤", /* 165 a5 */ "¥", /* 166 a6 */ "¦", /* 167 a7 */ "§", /* 168 a8 */ "¨", /* 169 a9 */ "©", /* 170 aa */ "ª", /* 171 ab */ "«", /* 172 ac */ "¬", /* 173 ad */ "", /* 174 ae */ "®", /* 175 af */ "¯", /* 176 b0 */ "°", /* 177 b1 */ "±", /* 178 b2 */ "²", /* 179 b3 */ "³", /* 180 b4 */ "´", /* 181 b5 */ "µ", /* 182 b6 */ "¶", /* 183 b7 */ "·", /* 184 b8 */ "¸", /* 185 b9 */ "¹", /* 186 ba */ "º", /* 187 bb */ "»", /* 188 bc */ "¼", /* 189 bd */ "½", /* 190 be */ "¾", /* 191 bf */ "¿", /* 192 c0 */ "À", /* 193 c1 */ "Á", /* 194 c2 */ "Â", /* 195 c3 */ "Ã", /* 196 c4 */ "Ä", /* 197 c5 */ "Å", /* 198 c6 */ "Æ", /* 199 c7 */ "Ç", /* 200 c8 */ "È", /* 201 c9 */ "É", /* 202 ca */ "Ê", /* 203 cb */ "Ë", /* 204 cc */ "/Igrave;", /* 205 cd */ "Í", /* 206 ce */ "Î", /* 207 cf */ "Ï", /* 208 d0 */ "Ð", /* 209 d1 */ "Ñ", /* 210 d2 */ "Ò", /* 211 d3 */ "Ó", /* 212 d4 */ "Ô", /* 213 d5 */ "Õ", /* 214 d6 */ "Ö", /* 215 d7 */ "×", /* 216 d8 */ "Ø", /* 217 d9 */ "Ù", /* 218 da */ "Ú", /* 219 db */ "Û", /* 220 dc */ "Ü", /* 221 dd */ "Ý", /* 222 de */ "Þ", /* 223 df */ "ß", /* 224 e0 */ "à", /* 225 e1 */ "á", /* 226 e2 */ "â", /* 227 e3 */ "ã", /* 228 e4 */ "ä", /* 229 e5 */ "å", /* 230 e6 */ "æ", /* 231 e7 */ "ç", /* 232 e8 */ "è", /* 233 e9 */ "é", /* 234 ea */ "ê", /* 235 eb */ "ë", /* 236 ec */ "ì", /* 237 ed */ "í", /* 238 ee */ "î", /* 239 ef */ "ï", /* 240 f0 */ "ð", /* 241 f1 */ "ñ", /* 242 f2 */ "ò", /* 243 f3 */ "ó", /* 244 f4 */ "ô", /* 245 f5 */ "õ", /* 246 f6 */ "ö", /* 247 f7 */ "÷", /* 248 f8 */ "ø", /* 249 f9 */ "ù", /* 250 fa */ "ú", /* 251 fb */ "û", /* 252 fc */ "ü", /* 253 fd */ "ý", /* 254 fe */ "þ", /* 255 ff */ "ÿ" }; /** First part of a full HTML file. */ static char const * const dkt_html_part1[] = { "", "", "
", "", "", NULL }; /** Last part of a full HTML file. */ static char const * const dkt_html_part2[] = { "", "", "", NULL }; /** End of HTML header. */ static char const * const dkt_html_part3[] = { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", NULL }; /** Strings to construct the title tag. */ static char const * const dkt_html_title[] = { "
\n",
};
/** Keywords.
*/
static char const * const dkt_html_c8_kw[] = {
$!string-table
#
# 0 1 2 3 4
#
%03d
#
#
#
$!end
};
/** Reset the job structure.
@param j Job structure.
*/
static
void
dkt_html_job_reset(DKT_HTML_J *j)
{
$? "+ dkt_html_job_reset"
j->enc_f = dk3app_get_default_file_encoding(j->app); $? ". enc_f=%d", j->enc_f
j->enc_s = dk3app_get_default_stdin_encoding(j->app); $? ". enc_s=%d",j->enc_s
j->f_fp = 0;
j->f_em = 0;
j->title = NULL;
$? "- dkt_html_job_reset"
}
/** Initialize job structure.
@param j Job structure.
*/
static
void
dkt_html_job_init(DKT_HTML_J *j)
{
$? "+ dkt_html_job_init"
j->exval = DKT_RESULT_ERR_UNSPECIFIC;
j->opt = NULL;
dkt_html_job_reset(j);
j->enc_f = dk3app_get_input_file_encoding(j->app); $? ". enc_f=%d", j->enc_f
j->enc_s = dk3app_get_input_stdin_encoding(j->app); $? ". enc_s=%d", j->enc_s
j->f_nl = 0;
j->f_ln = 0;
j->coli = 1;
j->cols = 0;
$? "- dkt_html_job_init"
}
/** Clean up job structure.
@param j Job structure.
*/
static
void
dkt_html_job_cleanup(DKT_HTML_J *j)
{
$? "+ dkt_html_job_cleanup"
/* Release option set. */
if(j->opt) {
dk3opt_close(j->opt);
} j->opt = NULL;
j->title = NULL;
$? "- dkt_html_job_cleanup"
}
/** Process one key/value pair, either long option or config file line.
@param job Job structure.
@param key Key (option name).
@param val Value.
@param ori Original text.
@param verb Flag: Verbose.
@return 1 on success, 0 on error.
*/
static
int
dkt_html_long_opt_handler(
DKT_HTML_J *job,
dkChar const *key,
dkChar const *val,
dkChar const *ori,
int verb
)
{
int back = 0;
int i = 0; /* Index of long option keyword in array. */
$? "+ dkt_html_long_opt_handler"
if((job) && (key) && (ori)) {
i = dk3str_array_index(dkt_html_long_opt, key, 0);
switch(i) {
case 0: {
back = dkt_tool_set_encoding(
job->app, &(job->enc_s), val,
dk3app_get_input_stdin_encoding(job->app)
); $? ". enc_s=%d", job->enc_s
} break;
case 1: {
back = dkt_tool_set_encoding(
job->app, &(job->enc_f), val,
dk3app_get_input_file_encoding(job->app)
); $? ". enc_f=%d", job->enc_f
} break;
case 2: {
dkt_html_job_reset(job);
back = 1;
} break;
default: {
if(verb) {
/* ERROR: Unknown option */
dk3app_log_i3(job->app, DK3_LL_ERROR, 139, 140, key);
}
} break;
}
} $? "- dkt_html_long_opt_handler %d", back
return back;
}
/** Process one key/value pair.
@param jv Pointer to job structure casted to void *.
@param k Key.
@param v Value.
@return 1 to indicate success.
*/
static
int
dkt_html_conf_line(void *jv, dkChar const *k, dkChar const *v)
{
$? "+ dkt_html_conf_line k=\"%s\" v=\"%s\"", TR_STR(k), TR_STR(v)
(void)dkt_html_long_opt_handler((DKT_HTML_J *)jv, k, v, k, 0);
$? "- dkt_html_conf_line"
return 1;
}
/** Process command line arguments.
@param j Job structure.
@return 1 on success, 0 on error.
*/
static
int
dkt_html_process_arguments(DKT_HTML_J *j)
{
int back = 0;
int xargc = 0; /* Number of command line arguments. */
dkChar const * const *xargv = NULL; /* Command line arguments array. */
dkChar const *x = NULL; /* Option argument. */
int res = 0; /* Result of set encoding operation. */
$? "+ dkt_html_process_arguments"
xargc = dk3app_get_argc(j->app);
xargv = dk3app_get_argv(j->app);
xargv++; xargv++; xargc--; xargc--;
j->opt = dk3opt_open_app(
dkt_html_options,
dkt_html_szoptions,
dkT('\0'),
NULL,
xargc,
xargv,
j->app
);
if(j->opt) {
if(dk3opt_get_error_code(j->opt) == 0) {
back = 1;
if(dk3opt_is_set(j->opt, dkT('R'))) {
dkt_html_job_reset(j);
}
if(dk3opt_is_set(j->opt, dkT('f'))) {
j->f_fp = 1;
if(dk3opt_is_set(j->opt, dkT('t'))) {
j->title = dk3opt_get_short_arg(j->opt, dkT('t'));
}
}
if(dk3opt_is_set(j->opt, dkT('i'))) {
x = dk3opt_get_short_arg(j->opt, dkT('i'));
if(x) {
res = dkt_tool_set_encoding(
j->app, &(j->enc_s), x,
dk3app_get_input_stdin_encoding(j->app)
); $? ". enc_s=%d", j->enc_s
if(res) {
j->enc_f = j->enc_s;
} else {
back = 0; j->exval = DKT_RESULT_ERR_OPTION;
}
} else {
back = 0; j->exval = DKT_RESULT_ERR_OPTION;
}
} else {
if(dk3opt_is_set(j->opt, dkT('p'))) {
j->enc_f = j->enc_s = DK3_FILE_ENCODING_ASCII;
}
}
if(dk3opt_is_set(j->opt, dkT('e'))) {
j->f_em = 1;
}
if (dk3opt_is_set(j->opt, dkT('l'))) {
if (j->f_em) {
/* WARNING -l ignored for -e */
dk3app_log_1(j->app, DK3_LL_WARNING, j->msg, 75);
} else {
j->f_ln = 1;
}
}
} else {
j->exval = DKT_RESULT_ERR_OPTION;
}
} else {
j->exval = DKT_RESULT_ERR_MEMORY;
} $? "- dkt_html_process_arguments %d", back
return back;
}
/** Write one 32-bit character to output.
@param j Job structure.
@param c32 Character to write.
*/
static
void
dkt_html_out_c32(DKT_HTML_J *j, dk3_c32_t c32)
{
int done = 0; /* Flag: Character already handled. */
size_t sz = 0; /* Index into fixed decodings array. */
if((unsigned long)c32 < 0x00000100UL) {
sz = (size_t)c32;
sz &= 0x00FFU;
if(dkt_html_translation_table[sz]) {
fputs(dkt_html_translation_table[sz], stdout);
done = 1;
}
}
if(!done) {
#if DK3_SIZEOF_WCHAR_T == 4
if((unsigned long)c32 > 0x000000FFUL) {
if((unsigned long)c32 > 0x0000FFFFUL) {
if((unsigned long)c32 > 0x00FFFFFFUL) {
fprintf(stdout, "%08lx;", (unsigned long)c32);
} else {
fprintf(stdout, "%06lx;", (unsigned long)c32);
}
} else {
fprintf(stdout, "%04lx;", (unsigned long)c32);
}
} else {
fprintf(stdout, "%02lx;", (unsigned long)c32);
}
#else
if((unsigned long)c32 > 0x000000FFUL) {
if((unsigned long)c32 > 0x0000FFFFUL) {
if((unsigned long)c32 > 0x00FFFFFFUL) {
fprintf(stdout, "%08lx;", c32);
} else {
fprintf(stdout, "%06lx;", c32);
}
} else {
fprintf(stdout, "%04lx;", c32);
}
} else {
fprintf(stdout, "%02lx;", c32);
}
#endif
}
}
/** Open a code tag.
@param j Job structure.
@return 1 on success, 0 on error.
*/
static
int
dkt_html_open_code_tag(DKT_HTML_J *j)
{
int back = 1;
if (j->f_ln) {
if (0 == j->cols) {
if (EOF == fputs(dkt_html_c8_kw[0], stdout)) { back = 0; }
if (1000 > j->coli) {
if (0 > fprintf(stdout, dkt_html_c8_kw[3], j->coli)) { back = 0; }
} else {
if (EOF == fputs(dkt_html_c8_kw[4], stdout)) { back = 0; }
}
if (EOF == fputs(dkt_html_c8_kw[1], stdout)) { back = 0; }
j->cols = 1;
j->coli += 1;
if (1000 == j->coli) {
back = 0;
/* Too many code lines */
dk3app_log_1(j->app, DK3_LL_WARNING, j->msg, 76);
}
}
}
return back;
}
/** Close code tag.
@param j Job structure.
@return 1 on success, 0 on error.
*/
static
int
dkt_html_close_code_tag(DKT_HTML_J *j)
{
int back = 1;
if (j->f_ln) {
if (!(j->cols)) {
if (!dkt_html_open_code_tag(j)) { back = 0; }
if (EOF == fputc(' ', stdout)) { back = 0; }
}
if (j->cols) {
if (EOF == fputs(dkt_html_c8_kw[2], stdout)) { back = 0; }
j->cols = 0;
}
}
return back;
}
/** Handler function to process one 32-bit character.
@param vj Job structure, casted to void *.
@param c32 The character to write.
@return 1 to indicate success.
*/
static
int
dkt_html_char_handler(void *vj, dk3_c32_t c32)
{
DKT_HTML_J *j;
int back = 1;
j = (DKT_HTML_J *)vj;
if(c32 == 0x0000000DUL) {
j->f_nl = 0;
} else {
if(c32 == 0x0000000AUL) {
if (!dkt_html_close_code_tag((DKT_HTML_J *)vj)) { back = 0; }
fputc('\n', stdout);
j->f_nl = 1;
} else {
j->f_nl = 0;
if (!dkt_html_open_code_tag((DKT_HTML_J *)vj)) { back = 0; }
dkt_html_out_c32((DKT_HTML_J *)vj, c32);
}
}
return back;
}
/** Write a dkChar string to HTML, used to write page title.
@param j Job structure.
@param tx Text to write.
*/
static
void
dkt_html_print_text(DKT_HTML_J *j, dkChar const *tx)
{
dk3_c32_t c32 = 0UL; /* 32-bit character. */
#if DK3_CHAR_SIZE > 1
dk3_c16_t const *sp = NULL; /* Source pointer. */
size_t sl = 0; /* Remaining source length. */
size_t used = 0; /* Number of bytes used. */
$? "+ dkt_html_print_text \"%s\"", tx
sp = (dk3_c16_t const *)tx;
sl = dk3str_c16_len(sp);
while(sl > 0) {
used = 0;
if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
dkt_html_out_c32(j, c32);
if(used > 0) {
if(sl >= used) {
sl = sl - used;
sp = &(sp[used]);
} else {
sl = 0;
/* ERROR: Decoding! */
dk3app_log_i1(j->app, DK3_LL_ERROR, 119);
}
} else {
sl = 0;
/* ERROR: Decoding! */
dk3app_log_i1(j->app, DK3_LL_ERROR, 119);
}
} else {
sl = 0;
/* ERROR: Decoding! */
dk3app_log_i1(j->app, DK3_LL_ERROR, 119);
}
}
#else
unsigned char const *sp = NULL; /* Source pointer. */
unsigned char c = 0x00; /* Current character. */
size_t sl = 0; /* Remaining source length. */
size_t used = 0; /* Number of bytes used. */
$? "+ dkt_html_print_text \"%s\"", tx
if(dk3app_get_encoding(j->app) == DK3_ENCODING_UTF8) {
sp = (unsigned char const *)tx;
sl = dk3str_c8_len(tx);
while(sl > 0) {
used = 0;
if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
dkt_html_out_c32(j, c32);
if(used > 0) {
if(sl >= used) {
sl = sl - used;
sp = &(sp[used]);
} else {
sl = 0;
/* Decoding problem! */
dk3app_log_i1(j->app, DK3_LL_ERROR, 118);
}
} else {
sl = 0;
/* Decoding problem! */
dk3app_log_i1(j->app, DK3_LL_ERROR, 118);
}
} else {
sl = 0;
/* Decoding problem! */
dk3app_log_i1(j->app, DK3_LL_ERROR, 118);
}
}
} else {
sp = (unsigned char const *)tx;
while(*sp) {
c = *(sp++);
c32 = (dk3_c32_t)c;
c32 &= 0x000000FFUL;
dkt_html_out_c32(j, c32);
}
}
#endif
}
/** Write one text paragraph.
@param j Job structure.
@param t Text.
*/
static
void
dkt_html_write_paragraph(DKT_HTML_J *j, char const * const *t)
{
char const * const *ptr = NULL; /* Current source line. */
ptr = t;
while(*ptr) {
fputs(*(ptr++), stdout);
fputc('\n', stdout);
}
}
/** Print start of HTML page.
@param j Job structure.
*/
static
void
dkt_html_start_page(DKT_HTML_J *j)
{
dkt_html_write_paragraph(j, dkt_html_part1);
fputs(dkt_html_title[0], stdout);
if(j->title) {
dkt_html_print_text(j, j->title);
} else {
fputs(dkt_html_title[2], stdout);
}
fputs(dkt_html_title[1], stdout);
dkt_html_write_paragraph(j, dkt_html_part3);
}
/** Print HTML page end.
@param j Job structure.
*/
static
void
dkt_html_end_page(DKT_HTML_J *j)
{
dkt_html_write_paragraph(j, dkt_html_part2);
}
/** Process one file name (correction and expansion is already done).
@param j Job structure.
@param fn File name.
@param de Default encoding if no BOM found at start of file.
*/
static
void
dkt_html_process_one_file(DKT_HTML_J *j, dkChar const *fn, int de)
{
int back;
$? "+ dkt_html_process_one_file \"%s\"", TR_STR(fn)
j->f_nl = 0;
back = dk3stream_process_filename_chars_app(
(void *)j,
dkt_html_char_handler,
fn,
de,
j->app
);
if ((j->f_ln) && (j->cols)) {
if (!dkt_html_close_code_tag(j)) { back = 0; }
}
if(!(j->f_nl)) {
fputc('\n', stdout);
}
if(!back) {
j->exval = DKT_RESULT_ERR_FOPEN;
} $? "- dkt_html_process_one_file %d", back
}
/** Process the file names.
@param j Job structure.
@param nfn Number of file names.
*/
static
void
dkt_html_process_files(DKT_HTML_J *j, int nfn)
{
dkChar fnb[DK3_MAX_PATH]; /* File name buffer for correction. */
dkChar const *fn = NULL; /* Current file name as specified. */
dkChar const *en = NULL; /* Current expander result. */
int i = 0; /* Index of current file name. */
dk3_dir_t *fne = NULL; /* File name expander. */
$? "+ dkt_html_process_files"
for(i = 0; i < nfn; i++) {
fn = dk3opt_get_arg(j->opt, i);
if(fn) {
if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
dk3str_cpy_not_overlapped(fnb, fn);
dk3str_correct_filename(fnb);
if(dk3sf_must_expand(fnb)) {
fne = dk3dir_fne_open_app(fnb, j->app);
if(fne) {
if(dk3dir_get_number_of_files(fne)) {
while(dk3dir_get_next_file(fne)) {
en = dk3dir_get_fullname(fne);
if(en) {
dkt_html_process_one_file(j, en, j->enc_f);
}
}
} else {
j->exval = DKT_RESULT_ERR_FILENAME;
/* ERROR: No such file! */
dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, fn);
}
dk3dir_close(fne);
} else {
j->exval = DKT_RESULT_ERR_MEMORY;
}
} else {
dkt_html_process_one_file(j, fnb, j->enc_f);
}
} else {
j->exval = DKT_RESULT_ERR_FILENAME;
/* ERROR: File name too long! */
dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
}
}
} $? "- dkt_html_process_files"
}
/** Process arguments in echo mode.
@param j Job structure.
@param nfn Number of command line arguments.
*/
static
void
dkt_html_process_echo_arguments(DKT_HTML_J *j, int nfn)
{
int i;
dkChar const *arg = NULL; /* Current argument to process. */
for(i = 0; i < nfn; i++) {
arg = dk3opt_get_arg(j->opt, i);
if(arg) {
if(i > 0) { fputc(' ', stdout); }
dkt_html_print_text(j, arg);
}
}
fputc('\n', stdout);
}
/** Do processing.
@param j Job structure.
*/
static
void
dkt_html_run(DKT_HTML_J *j)
{
int nfn; /* Number of file names. */
$? "+ dkt_html_run"
nfn = dk3opt_get_num_args(j->opt);
/* Write HTML page start */
if(j->f_fp) {
dkt_html_start_page(j);
}
/* Process input */
if(nfn > 0) {
if(j->f_em) {
dkt_html_process_echo_arguments(j, nfn);
} else {
dkt_html_process_files(j, nfn);
}
} else {
j->f_nl = 0;
dk3app_process_stdin_chars(j->app,(void *)j,dkt_html_char_handler,j->enc_s);
if(!(j->f_nl)) { fputc('\n', stdout); }
}
/* Write HTML page end */
if(j->f_fp) {
dkt_html_end_page(j);
}
$? "- dkt_html_run"
}
int
dkt_html(
dk3_app_t *app,
dkChar const *sn,
dkChar const * const *msg,
dkChar const * const *kwnl
)
{
int back = DKT_RESULT_ERR_UNSPECIFIC;
DKT_HTML_J j;
$? "+ dkt_html"
j.app = app; j.msg = msg; j.kwnl = kwnl;
dkt_html_job_init(&j);
dkt_tool_read_conf(app, sn, (void *)(&j), dkt_html_conf_line);
$? ". file encoding = %d, stdin encoding = %d", j.enc_f, j.enc_s
if(dkt_html_process_arguments(&j)) {
j.exval = DKT_RESULT_OK;
dkt_html_run(&j);
}
back = j.exval;
dkt_html_job_cleanup(&j);
$? "- dkt_html %d", back
return back;
}
/* vim: set ai sw=2 : */