% $Id: tex4ht-htcmd.tex 748 2020-06-29 22:18:30Z karl $
% tex tex4ht-htcmd
% or ht tex tex4ht-htcmd
%
% htcmd is apparently not used for anything, but this .tex file is
% preserved for history.
%
% htcmd OPTFLAG CMDLINE passed CMDLINE to system(), translating each
% forward slash into a single or double backslash for OPTFLAG set to
% -slash or -dslash respectively.
%
% Copyright 2009-2020 TeX Users Group
% Copyright 1996-2009 Eitan M. Gurari
% Released under LPPL 1.3c+.
% See tex4ht-cpright.tex for license text.
\input common
\input tex4ht.sty
\Preamble{xhtml,th4,sections+,xhtml}\EndPreamble
\input ProTex.sty
\AlProTex{c,<<<>>>,`,title,list,_^}
%\input tex4ht-cpright.tex (see below)
\Comment{
}{}
\def\CodeId#1#2{}
\def\UnderLine#1{\ifHtml
\HCode{}#1\HCode{}\else\underbar{#1}\fi}
\let\CModifyShowCode=\ModifyShowCode
\let\CModifyOutputCode=\ModifyOutputCode
\def\ModifyShowCode{\def\[##1({##1\UnderLine{(}}\def
\;{\UnderLine{;}}\CModifyShowCode}
\catcode`\^=7 \catcode`\@=6 \catcode`\#=12 \catcode`\^^M=13\relax%
\def\ModifyOutputCode{%
\def\;{ SEP }%
\def\[@@1(@@2)@@3;{@@1
#ifdef ANSI
#define SEP ,
(@@3)
#undef SEP
#else
#define SEP ;
(@@2)@@3;
#undef SEP
#endif
}%
\CModifyOutputCode}%
\catcode`\^^M=5 \catcode`\@=12 \catcode`\#=6 \catcode`\^=13
\let\'=\Verb
\def\`{\expandafter\expandafter\expandafter\qts\Verb}
\def\qts#1{`#1\aftergroup'}
\def\FTP{http://www.cse.ohio-state.edu/\string~gurari/tpf/}
\input tex4ht-cpright
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\<<<
/* htcmd.c (`version), generated from `jobname.tex
Copyright 2009-2020 TeX Users Group
Copyright `CopyYear.1996. Eitan M. Gurari
` */
`
`
`
`
`
`[
int ` main(argc, argv)
int argc`;
Q_CHAR **argv
;{ `
`
#ifdef PLATFORM
(IGNORED) printf("htcmd.c (`version %s)\n",PLATFORM);
#else
(IGNORED) printf("htcmd.c (`version)\n");
#endif
`
`
`
return 0;
}
>>>
\<<<
/* **********************************************
Compiler options *
(uncommented | command line) *
------------------------------------------------*
Clasic C (CC) default
#define ANSI ansi-c, c++
#define DOS_C
#define HAVE_STRING_H
#define HAVE_DIRENT_H
#define HAVE_SYS_NDIR_H
#define HAVE_SYS_DIR_H
#define HAVE_NDIR_H
#define HAVE_IO_H
#define HAVE_UNISTD_H
#define WIN32
#define KPATHSEA
#define SYSTEM_FUNCTION_OK
#define CDECL ..........
#define BCC32 bordland c++
*************************************************
Tex4ht variables *
(uncommented | command line) *
----------------------------------------------- */
`
/* ******************************************** */
`
`
`
`
#ifdef DOS_C
#define DOS
#endif
#ifdef DOS
#define DOS_WIN32
#ifndef HAVE_STRING_H
#define HAVE_STRING_H
#endif
#endif
#ifdef WIN32
#define DOS_WIN32
#endif
`
`
`
`
>>>
\<<<
#ifdef DOS
#define PROTOTYP
#endif
#ifdef ANSI
#define PROTOTYP
#endif
#ifdef KWIN32
#define PROTOTYP
#endif
>>>
\<<<
#ifdef KPATHSEA
#ifdef WIN32
#undef CDECL
#define CDECL __cdecl
#else
#define CDECL
#endif
#endif
>>>
\<<<
#ifdef KPATHSEA
#ifdef WIN32
#define KWIN32
#endif
#endif
>>>
\''open(file, ..._FLAGS)': All
text files should be opened with "r" or "w"; all binary files with "rb"
or "wb". This is the portable way and will work both under Unix and DOS;
as Unix doesn't distinguish between text and binary files, its compilers
will simply ignore the "b" part.
On the subject of the .lg file: you open the tex4ht.env file in binary
mode ("rb"), which results in strange line endings in the .lg file
(CR/CR/LF). Changing the mode to "r" fixes this.
\<<<
#if defined(DOS_WIN32) || defined(__MSDOS__)
#define READ_BIN_FLAGS "rb"
#define READ_TEXT_FLAGS "r"
#define WRITE_BIN_FLAGS "wb"
#define WRITE_TEXT_FLAGS "w"
#else
#define READ_BIN_FLAGS "r"
#define READ_TEXT_FLAGS "r"
#define WRITE_BIN_FLAGS "w"
#define WRITE_TEXT_FLAGS "w"
#endif
>>>
\<<<
#define Q_CHAR char
#define U_CHAR char
#define C_CHAR char
#define Q_NULL (Q_CHAR *) 0
#define U_NULL (U_CHAR *) 0
#define C_NULL (C_CHAR *) 0
>>>
\<<<
#define IGNORED void
>>>
\<<<
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
>>>
\<<<
#ifdef PROTOTYP
#define VOID void
#define ARG_I(x) x
#define ARG_II(x,y) x,y
#define ARG_III(x,y,z) x,y,z
#define ARG_IV(x,y,z,w) x,y,z,w
#define ARG_V(x,y,z,w,u) x,y,z,w,u
#else
#define VOID
#define ARG_I(x)
#define ARG_II(x,y)
#define ARG_III(x,y,z)
#define ARG_IV(x,y,z,w)
#define ARG_V(x,y,z,w,u)
#endif
>>>
\<<<
struct sys_call_rec{
Q_CHAR * filter;
struct sys_call_rec *next;
};
>>>
\<<<
static BOOL system_yes;
>>>
\<<<
struct script_struct{
Q_CHAR *command;
struct script_struct *next;
};
>>>
\<<<
#define NULL_SCRIPT (struct script_struct *) 0
>>>
\SubSection{Signals}
\<<<
#include
>>>
\<<<
static void
`
sig_err(ARG_I(int));
>>>
\<<<
`[
static void
`
sig_err(s) int s
;{
(void) signal(s,SIG_IGN); `%ignore the signal`%
switch( s ){
#ifdef SIGSEGV
case SIGSEGV: err_i(2);
#endif
case SIGFPE : err_i(3);
#if defined(SIGINT) && !defined(WIN32)
case SIGINT : err_i(4);
#endif
}
`
}
>>>
Forgetting \`'_pascal' and \`'_cdecl' modifiers: Each C function may
be either \`'_pascal' or \`'_cdecl'. This modifier defines how
parameters are passed to it. Default for Smalltalk definition is
\`'_cdecl'. Default for C functions depends on compiler settings, and
you can use other types uncompatible with Smalltalk. In Windows API
16-bit functions are \`'_pascal' and 32-bit \`'_cdecl'.
\<<<
#ifdef CDECL
CDECL
#endif
>>>
\<<<
#ifdef SIGSEGV
(void) signal(SIGSEGV,sig_err);
#endif
(void) signal(SIGFPE,sig_err);
#ifdef KWIN32
`
#else
#ifdef SIGINT
(void) signal(SIGINT,sig_err); `%Control-c, user interrupt`%
#endif
#endif
>>>
SIGFPE is handled by the C library, SIGSEGV too but not generated by
the system, so it does nothing but is harmless
SetConsoleCtrlHandler is need to catch Ctrl+C and Ctrl+Break under
Windows, SIGINT is not generated by the system.
\<<<
SetConsoleCtrlHandler((PHANDLER_ROUTINE)sigint_handler, TRUE);
>>>
SIGSEGV, SIGILL, SIGTERM not implemented in MS-DOS. They are supplied just for
compatibility. Looks like that SIGINT is defined for windows but not for dos.
\<<<
static int system_return;
>>>
\<<<
int i;
BOOL slash, dslash;
char *in_command, *command, *p, *q;
>>>
\<<<
in_command = (char *) malloc(1024);
command = (char *) malloc(1024);
in_command[0] = '\0';
`
if( argc == 1 ){ bad_arg; }
slash = eq_str(argv[1],"-slash") ;
dslash = eq_str(argv[1],"-dslash") ;
for(i=1+slash+dslash; i>>
\<<<
p = in_command;
q = command;
do{
if( (*p != '"' ) && (*p != '\'' ) && (*p != '``' ) ){
if(slash && (*p == '/')) {
*(q++) = '\\';
}
else if(dslash && (*p == '/')) {
*(q++) = '\\';
*(q++) = '\\';
}
else { *(q++) = *p; }
}
} while (*(p++) != '\0');
(IGNORED) call_sys(command);
>>>
\SubSection{PreProcessor Directives}
Symantec C++ for wid95:
\''sc htcmd.c -mn -o+time -WA -3 -a8 -c -D_CONSOLE=1 -ohtcmd.obj'
\<<<
#ifdef BCC32
#define WIN32
#define ANSI
#define HAVE_IO_H
#define HAVE_STRING_H
#define PLATFORM "ms-win32"
#endif
>>>
%
\<<<
#ifdef BCC
#define DOS_C
#define ANSI
#define HAVE_IO_H
#define PLATFORM "ms-dos"
#endif
>>>
\<<<
#include `% EOF, FILE `%
#include `% EXIT_FAILURE `%
>>>
Under ANSI C, all malloc stuff is declared in \`'' (which you
also include), hence this non-standard header is redundant.
\<<<
#ifdef HAVE_STRING_H
#include
#endif
>>>
\<<<
#ifdef DOS_WIN32
#define STRUCT_DIRENT
#endif
>>>
\<<<
#ifdef HAVE_DIRENT_H
`
#else
#ifndef STRUCT_DIRENT
#define STRUCT_DIRECT
#endif
`
#endif
>>>
\<<<
#include
>>>
\<<<
#ifdef HAVE_SYS_NDIR_H
#include
#endif
#ifdef HAVE_SYS_DIR_H
#include
#endif
#ifdef HAVE_NDIR_H
#include
#endif
>>>
REPLACE EXIT with somthing that DOS also accept.
\SubSection{KPATHSEA}
\<<<
`
#ifdef KPATHSEA
#ifndef HAVE_STRCHR
#define strchr index
#endif
#ifndef HAVE_STRRCHR
#define strrchr rindex
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if !defined(_AMIGA) && !defined(WIN32)
#include
#endif
#include
#include
#endif `%/* KPATHSEA */`%
`
>>>
\<<<
`
#ifdef KPATHSEA
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if !defined(_AMIGA) && !defined(WIN32)
#include
#endif
#include
#include
#endif `%/* KPATHSEA */`%
`
>>>
The \`'__cdecl' is defined in KPATHSEA: kpathsea/c-protos.h
is defined to nothing for compilers
other than MS.
\<<<
#ifdef __DJGPP__
#define DOS_WIN32
#define ANSI
#endif
>>>
\<<<
#ifdef __DJGPP__
if (s != SIGINT && s != SIGQUIT)
exit(EXIT_FAILURE);
#endif
>>>
\<<<
#ifndef __DJGPP__
`
#endif
>>>
The following is because \`'
defines F_OK in DJGPP'.
\<<<
#ifdef __DJGPP__
`
#endif
>>>
\<<<
#ifndef F_OK
#ifdef DOS_WIN32
#define F_OK 0 `% does file exist `%
#endif
#ifndef DOS_WIN32
#define HAVE_UNISTD_H
#endif
#endif
#ifdef HAVE_IO_H
#include
#endif
#ifdef HAVE_UNISTD_H
#include
#endif
>>>
\<<<
#ifndef F_OK
#ifdef DOS_WIN32
#define F_OK 0 `% does file exist `%
#endif
#ifndef KPATHSEA
#ifndef DOS_WIN32
#define HAVE_UNISTD_H
#endif
#endif
#endif
#ifdef HAVE_IO_H
#include
#endif
#ifndef KPATHSEA
#ifdef HAVE_UNISTD_H
#include
#endif
#endif
>>>
\<<<
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef BOOL
#define BOOL int
#endif
>>>
\<<<
#define bad_arg err_arg(0)
#define bad_mem err_i(1)
>>>
\<<<
static void err_i( ARG_I(int) );
>>>
\<<<
`[
static void err_i(n) int n
;{ (IGNORED) fprintf(stderr,"--- error --- ");
(IGNORED) fprintf(stderr, "%s", warn_err_mssg[n]);
exit(EXIT_FAILURE);
}
>>>
\<<<
static void err_arg( ARG_I(int) );
>>>
\<<<
`[
static void err_arg(n) int n
;{ (IGNORED) fprintf(stderr,"--- error --- ");
(IGNORED) fprintf(stderr, "%s", warn_err_mssg[n]);
exit(EXIT_FAILURE);
}
>>>
\<<<
static C_CHAR *warn_err_mssg[]={ ` "" };
>>>
\<<<
"\n---------------------------------------------------------------\n\
htcmd optional-flag command-line\n\n\
optional-flag:\n\
-slash translate '/' into '\\'\n\
-dslash translate '/' into '\\\\'\n\n\
Example: \n\
htcmd t4ht name -d/WWW/temp/ -etex4ht-32.env -m644\n\
---------------------------------------------------------------\n"
>>>
\<<<
#ifdef SYSTEM_FUNCTION_OK
0
#else
system( yes ) != 0
#endif
>>>
\<<<
static void call_sys(ARG_I(Q_CHAR *));
>>>
\<<<
`[
static void call_sys(command) Q_CHAR * command
;{
if( *command ){
(IGNORED) printf("htcmd calls: %s\n", command);
system_return = system_yes? (int) system(command) : -1;
(IGNORED) printf("%shtcmd returns: %d\n",
system_return? "--- Warning --- " : "", system_return );
}
}
>>>
strcat should be in string.h, but c++ doesn't find it there.
We use it just for concatenating an extension of
file name. Should have the interface
\`'char *strcat( ARG_II(C_CHAR *, const Q_CHAR *) );'.
\<<<
static void strct( ARG_II(C_CHAR *, C_CHAR *) );
>>>
\<<<
`[
static void strct( str1, str2 )
Q_CHAR * str1`;
Q_CHAR * str2
;{ Q_CHAR * ch;
ch = str1 + (int) strlen(str1);
(IGNORED) strcpy( ch, str2 );
}
>>>
\<<<
{ C_CHAR *yes = NULL;
system_yes = (`);
}
>>>
\<<<
#define eq_str(x,y) (!strcmp(x,y))
>>>
%----------------------------------------------------
\OutputCodE\
\bye