w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

dvihp.c
Go to the documentation of this file.
1 /* dvihp.c: emulate the dvihp shell script
2 
3  Converted to C by Eli Zaretskii <eliz@is.elta.co.il>
4  Adapted to Win32 by Fabrice POPINEAU
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20 
21 #include <kpathsea/config.h>
22 #include <fcntl.h>
23 #ifdef _WIN32
24 #include <io.h>
25 #endif
26 
27 #include <kpathsea/kpathsea.h>
28 #include "mktex.h"
29 #include "stackenv.h"
30 
31 static const char rcs_id[] =
32  "$Id: dvihp.c,v 1.7 2002/10/06 14:02:09 olaf Exp $";
33 static char rcs_revision[] = "$Revision: 1.7 $";
34 
35 static void usage (void)
36 {
37  printf ("Usage: %s [OPTIONS] [DVIFILE[.dvi]].\n\
38  Translate the given DVIFILE to Hewlett-Packard PCL by calling dvicopy\n\
39  and then $DVILJ (dvilj4 by default).\n\
40  In the absence of other options, pipe the PCL to $SPOOL (lpr by default).\n\
41 \n\
42  Options are recognized from dvips where possible:\n\
43 -A print odd pages\n\
44 -B print even pages\n\
45 -d # set debug bits to # (see documentation)\n\
46 -D # set resolution to #\n\
47 -f run as filter\n\
48 -l # don't print pages after #\n\
49 -m manual feed\n\
50 -n # print # pages\n\
51 -O #,# set/change paper offset to #,# mm\n\
52 -o s output to s instead of spooling\n\
53 -p # don't print pages before #\n\
54 -Ps pass directly to lpr\n\
55 -v verbose operation\n\
56 -x # set magnification to #\n\
57 \n\
58 Other options are passed to the dvilj program.\n\
59 \n\
60 Email bug reports to tex-k@mail.tug.org.\n", kpse_invocation_name);
61  fflush (stdout);
62 }
63 
64 /* Emulate `rm -f prefix*' */
65 
66 
67 static void rmfiles (char *prefix)
68 {
69 #ifdef _WIN32
70  /* Win32 doesn't have POSIX dirent functions. */
71  WIN32_FIND_DATA ffd;
72  HANDLE hnd;
73  int go_on;
74  string temp = concat (prefix, "*");
75  string directory = xdirname (prefix);
76 
77  pushd (directory);
78  hnd = FindFirstFile(temp, &ffd);
79  go_on = (hnd != INVALID_HANDLE_VALUE);
80  while (go_on) {
81  /* FIXME: can this remove read-only files also, like rm -f does? */
82  DeleteFile(ffd.cFileName);
83  go_on = (FindNextFile(hnd, &ffd) == TRUE);
84  }
85  FindClose(hnd);
86  free(temp);
87  popd ();
88 #else /* not _WIN32 */
89  DIR *dp;
90  struct dirent *de;
91  int temp_len = strlen (prefix);
92  string directory = "./";
94 
95  /* Copy the directory part of PREFIX with the trailing slash, if any. */
96  if (base != prefix)
97  {
98  directory = (string) xmalloc (base - prefix + 1);
99  directory[0] = '\0';
100  strncat (directory, prefix, base - prefix);
101  }
102 
103  /* Find matching files and delete them. */
104  if ((dp = opendir (directory)) != 0) {
105  while ((de = readdir (dp)) != 0)
106  {
107  string found = concat (directory, de->d_name);
108 
109  if (FILESTRNCASEEQ (found, prefix, temp_len))
110  /* On POSIX-compliant systems, including DJGPP, this will also
111  remove read-only files and empty directories, like rm -f does. */
112  if (remove (found))
113  perror (found);
114  free (found);
115  }
116  }
117 #endif /* not _WIN32 */
118 }
119 
121 {
122  /* FIXME : what cleanup should be done ? */
123 }
124 
125 char *progname;
126 
127 int
128 main (int argc, char *argv[])
129 {
130  string opt = (string) xmalloc (1);
131  const_string output = "", infile = "";
132  const_string output_opt = " -e";
133  const_string dvilj;
134  const_string spool;
136  const_string spool_opt = "";
137  char template[PATH_MAX];
138  const_string vfless_dvi;
139  int verbose = 0;
140  string cmdline;
141  const_string maybe_spool_cmd = "";
142  const_string space = " ";
143 
145 
146  kpse_set_program_name (argv[0], "dvihp");
148 
149 #ifdef _WIN32
150  setmode(fileno(stdin), _O_BINARY);
152  SetConsoleCtrlHandler((PHANDLER_ROUTINE)mt_exit, TRUE);
153 #else
154 # ifdef SIGINT
155  signal (SIGINT, sigint_handler);
156 # endif
157 # ifdef SIGQUIT
158  signal (SIGQUIT, sigint_handler);
159 # endif
160 # ifdef SIGHUP
161  signal (SIGHUP, sigint_handler);
162 # endif
163 # ifdef SIGTERM
164  signal (SIGTERM, sigint_handler);
165 # endif
166 #endif
167 
168  dvilj = kpse_var_value ("DVILJ");
169  spool = kpse_var_value ("SPOOL");
170  tmpdir = kpse_var_value ("TMPDIR");
171  opt[0] = '\0';
172 
173  if(!tmpdir)
174  tmpdir = kpse_var_value ("TMP");
175  if(!tmpdir)
176  tmpdir = kpse_var_value ("TEMP");
177 
178  /* Set default values for variables:
179 
180  ${DVILJ=dvilj4} the dvilj variant to run
181  ${SPOOL=lpr} used to print an LJ file
182  ${TMPDIR=/tmp} for the dvicopy output */
183  if (!dvilj || !*dvilj)
184  dvilj = "dvilj4";
185  if (!spool || !*spool)
186  {
187 #ifdef __DJGPP__
188  /* Feature: if they don't have LPR installed, make the
189  default be to print to the local printer device. */
190  char lpr_path[PATH_MAX];
191  extern char *__dosexec_find_on_path (const char *, char **, char *);
192  extern char **environ;
193 
194  if (!__dosexec_find_on_path ("lpr", (char **)0, lpr_path)
195  && !__dosexec_find_on_path ("lpr", environ, lpr_path))
196  spool = "> PRN";
197  else
198 #endif
199  spool = "| lpr";
200  }
201 
202  if (!tmpdir || !*tmpdir)
203  {
204  tmpdir = "c:/tmp";
205  if (access (tmpdir, R_OK|W_OK) != 0)
206  {
207  _mkdir (tmpdir);
208  }
209  }
210 
211  if (argc <= 1)
212  {
213  fprintf (stderr, "%s: Missing argument(s).\nTry `%s --help' for more information.\n",
215  return 0;
216  }
217 
218  while (--argc)
219  {
220  char *arg = *++argv;
221 
222  if (STREQ (arg, "-help") || STREQ (arg, "--help"))
223  {
224  usage ();
225  return 0;
226  }
227  else if (STREQ (arg, "-version") || STREQ (arg, "--version"))
228  {
229  printf ("%s: (Dviljk 2.6) %s\nThere is NO warranty. This program is public domain.\n",
231  return 0;
232  }
233  else if (arg[0] == '-')
234  {
235  string newopt = NULL;
236 
237  switch (arg[1])
238  {
239  case 'A': /* -A => -D1 (odd pages) */
240  newopt = concat (opt, " -D1");
241  break;
242  case 'B': /* -B -> -D2 (even pages) */
243  newopt = concat (opt, " -D2");
244  break;
245  case 'd': /* -d => --D (debug) */
246  if (arg[2] == '\0')
247  {
248  argc--;
249  newopt = concat3 (opt, " --D", *++argv);
250  }
251  else
252  newopt = concat3 (opt, " --D", arg + 2);
253  break;
254  case 'D': /* -D => -R (resolution) */
255  argc--;
256  newopt = concat3 (opt, " -R", *++argv);
257  break;
258  case 'f': /* -f (run as filter) */
259  infile = "";
260  output = "-";
261  break;
262  case 'l': /* -l => -t (ending page) */
263  if (arg[2] == '\0')
264  {
265  argc--;
266  newopt = concat3 (opt, " -t", *++argv);
267  }
268  else
269  newopt = concat3 (opt, " -t", arg + 2);
270  break;
271  case 'm': /* -m => -A (manual feed) */
272  newopt = concat (opt, " -A");
273  break;
274  case 'n': /* -n => -p (page count) */
275  if (arg[2] == '\0')
276  {
277  argc--;
278  newopt = concat3 (opt, " -t", *++argv);
279  }
280  else
281  newopt = concat3 (opt, " -t", arg + 2);
282  break;
283  case 'o': /* -o (output file) */
284  {
285  string inbase = xstrdup (xbasename (infile));
286  if (argc == 1 && *inbase)
287  {
288  /* No remaining args, output to foo.lj. */
289  int inbaselen = strlen (inbase);
290 
291  if (FILESTRCASEEQ (inbase + inbaselen - 4, ".dvi"))
292  output = strcpy (inbase + inbaselen - 4, ".lj");
293  else
294  {
295 #if defined (MSDOS) && defined _PC_NAME_MAX
296  if (pathconf (infile, _PC_NAME_MAX) <= 12)
297  {
298  /* Plain MS-DOS (not Windows 95), can't have
299  more than a single dot in a filename. */
300  char *dot = strchr (inbase, '.');
301 
302  if (dot)
303  *dot = '\0';
304  }
305 #endif
306  output = concat (inbase, ".lj");
307  free (inbase);
308  }
309  }
310  else if (arg[2] == '\0')
311  {
312  argc--;
313  output = *++argv;
314  }
315  else
316  output = arg + 2;
317  break;
318  }
319  case 'O': /* -O => -x, -y (page offsets) */
320  {
321  int x_len;
322  char *params = arg + 2;
323  char *x;
324 
325  if (arg[2] == '\0')
326  {
327  argc--;
328  params = *++argv;
329  }
330 
331  x_len = strcspn (params, ",");
332  x = (char *)xmalloc (x_len + 1);
333  x[0] = '\0';
334  strncat (x, params, x_len);
335  if (params[x_len] == ',')
336  x_len++; /* get past the comma, if any */
337  newopt = concatn (opt, " -x", x, " y", params + x_len, NULL);
338  break;
339  }
340  case 'p': /* -p => -f (starting page) */
341  if (arg[2] == '\0')
342  {
343  argc--;
344  newopt = concat3 (opt, " -f", *++argv);
345  }
346  else
347  newopt = concat3 (opt, " -f", arg + 2);
348  break;
349  case 'P': /* -Pprinter */
350  output = "";
351  if (spool[0] == '>') /* direct printing: replace device */
352  spool = concat ("> ", arg[2] ? arg + 2 : *++argv);
353  else
354  spool_opt = concat ("-P", arg[2] ? arg + 2 : *++argv);
355  if (arg[2] == '\0')
356  argc--;
357  break;
358  case 'v': /* verbose */
359  verbose = 1;
360  newopt = concat (opt, " -v");
361  break;
362  case 'x': /* -x => -m (magnification) */
363  if (arg[2] == '\0')
364  {
365  argc--;
366  newopt = concat3 (opt, " -m", *++argv);
367  }
368  else
369  newopt = concat3 (opt, " -m", arg + 2);
370  break;
371  case '-': /* -- => end of options */
372  argc--;
373  infile = *++argv;
374  break;
375  default: /* pass other options through */
376  newopt = concat3 (opt, space, arg);
377  break;
378  }
379 
380  if (newopt)
381  {
382  free (opt);
383  opt = newopt;
384  }
385  }
386  else
387  infile = arg;
388  }
389 
390  /* Generate temporary filenames. Assumes PID is 5 digits. */
391  sprintf (template, "%s/dvi%5.5d.", tmpdir, getpid ());
392  vfless_dvi = concat (template, "-vf");
393 
394  /* Expand VF references.
395  If INFILE is null, this will read standard input.
396  dvilj can't read from a pipe, so always write to a file. */
397  if (verbose)
398  fprintf (stderr, "Running dvicopy %s >%s\n", infile, vfless_dvi);
399 
400  /* FIXME: special characters in filenames aren't protected from the shell. */
401  cmdline = concatn ("dvicopy ", infile, " >", vfless_dvi, NULL);
402  if (system (cmdline))
403  {
404  fprintf (stderr, "%s: dvicopy %s failed.\n", progname, infile);
405  return 1;
406  }
407  free (cmdline);
408 
409  if (verbose)
410  {
411  struct stat st_buf;
412 
413  if (stat (vfless_dvi, &st_buf))
414  perror (vfless_dvi);
415  else /* assume they only want to see the size and timestamp */
416  fprintf (stderr, " %ld %s %s\n",
417  (long)st_buf.st_size, ctime (&st_buf.st_mtime), vfless_dvi);
418  }
419  if (!*output)
420  {
421  output = "-"; /* output to stdout */
422  maybe_spool_cmd = concat (spool, spool_opt);
423  }
424 
425  /* Translate DVI to LJ. */
426  cmdline = concatn (dvilj, space, opt, output_opt, output,
427  space, vfless_dvi, space, maybe_spool_cmd, NULL);
428  if (verbose)
429  fprintf (stderr, "Running %s\n", cmdline);
430  if (system (cmdline))
431  {
432  fprintf (stderr, "%s: %s failed.\n", progname, dvilj);
433  return 2;
434  }
435 
436  /* rm -f $TMPDIR/dvi$$.* */
437  rmfiles (template);
438 
439  return 0;
440 }
void __cdecl perror(char const *_ErrMsg)
static const char * xbasename(const char *name)
Definition: afm2pl.c:410
static char * concat(const char *s1, const char *s2)
Definition: afm2pl.c:377
size_t __cdecl strcspn(char const *_Str, char const *_Control)
static BOOL sigint_handler(DWORD dwCtrlType)
Definition: cjklatex.c:98
@ TRUE
Definition: dd.h:102
#define free(a)
Definition: decNumber.cpp:310
int params
Definition: definitions.c:42
#define R_OK
Definition: defs.h:31
#define STREQ(s, t)
Definition: defs.h:149
#define fflush
Definition: xxstdio.h:24
int printf()
char * strcpy()
char * temp
Definition: dvidvi.c:137
char tmpdir[]
int main(int argc, char *argv[])
Definition: dvihp.c:128
static const char rcs_id[]
Definition: dvihp.c:31
static void rmfiles(char *prefix)
Definition: dvihp.c:67
static void output_and_cleanup(int code)
Definition: dvihp.c:120
char * progname
Definition: dvihp.c:125
static char rcs_revision[]
Definition: dvihp.c:33
static void usage(void)
Definition: dvihp.c:35
#define FILESTRCASEEQ
Definition: dvips.h:372
#define dot
Definition: globals.h:56
int base
Definition: gsftopk.c:1502
#define strchr
Definition: gsftopk.c:59
static FILE * infile
Definition: rdjpgcom.c:61
#define PATH_MAX
Definition: ftmac.c:91
#define NULL
Definition: ftobjs.h:61
#define xstrdup(s)
Definition: writet1.c:34
#define xmalloc(size)
Definition: writet1.c:33
char * concat3(const char *s1, const char *s2, const char *s3)
Definition: utils.c:178
#define W_OK
Definition: c-unistd.h:47
string concatn(const_string str1,...)
Definition: concatn.c:28
struct dirent * readdir(DIR *dirp)
Definition: dirent.c:138
DIR * opendir(char *fname)
Definition: dirent.c:60
KPSEDLL string xdirname(const_string name)
Definition: xdirname.c:29
#define FILESTRNCASEEQ
Definition: lib.h:114
char ** environ
const char * const_string
Definition: simpletypes.h:59
#define kpse_program_name
Definition: types.h:322
#define kpse_invocation_name
Definition: types.h:333
#define access
Definition: win32lib.h:59
#define fileno
Definition: win32lib.h:72
#define system(p)
Definition: win32lib.h:269
#define getpid
Definition: win32lib.h:76
#define fprintf
Definition: mendex.h:64
#define string
Definition: ctangleboot.c:111
int setmode()
#define _PC_NAME_MAX
Definition: unistd.h:87
long pathconf()
int remove()
#define sprintf
Definition: snprintf.c:44
#define _O_BINARY
Definition: lfs.c:127
#define __cdecl
Definition: mktexlib.h:16
float x
Definition: cordic.py:15
#define cmdline(i)
Definition: omfonts.c:51
HANDLE hnd
Definition: pst2eps.c:6
char * ctime()
RETTYPE mp_ptr mp_size_t mp_srcptr dp
Definition: sec_div.c:70
void popd()
Definition: stackenv.c:126
void pushd(char *p)
Definition: stackenv.c:102
pfnOutputAndCleanup output_and_cleanup_function
Definition: stackenv.c:38
void mt_exit(int)
Definition: stackenv.c:287
Definition: dirent.h:44
Definition: inftrees.h:24
Definition: dir.c:365
Definition: dirent.h:34
char d_name[260]
Definition: dirent.h:37
Definition: output.h:18
void signal(SIGFPE, sig_err)
*job_name strlen((char *) job_name) - 4)
found
Definition: tex4ht.c:5000
#define verbose
Definition: jpeg.c:35
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269