1 /*
2 Copyright (C) 2012-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5 
6 /*
7 	WARNING: This file was generated by the dkct program (see
8 	http://dktools.sourceforge.net/ for details).
9 	Changes you make here will be lost if dkct is run again!
10 	You should modify the original source and run dkct on it.
11 	Original source: f2lopt.ctr
12 */
13 
14 /**	@file f2lopt.c The f2lopt module.
15 */
16 
17 
18 #include <fig2lat/fig2lat.h>
19 
20 
21 
22 
23 
24 
25 
26 /**	Options for the fig2lat program.
27 */
28 static dk3_option_t const f2lopt_options[] = {
29   { dkT('h'), dkT("help"), 0 },
30   { dkT('v'), dkT("version"), 0 },
31   { dkT('L'), dkT("license-terms"), 0 },
32   { dkT('l'), dkT("language"), 1 },
33   { dkT('m'), dkT("make"), 0 }
34 };
35 
36 /**	Number of options in f2lopt_options.
37 */
38 static size_t const f2lopt_sz_options =
39 sizeof(f2lopt_options)/sizeof(dk3_option_t);
40 
41 
42 
43 /**	Key names for key/value pairs.
44 */
45 static dkChar const * f2lopt_key_names[] = {
46 /* 0 */
47 dkT("tf"),
48 
49 /* 1 */
50 dkT("ts"),
51 
52 /* 2 */
53 dkT("cosp"),
54 
55 /* 3 */
56 dkT("coah"),
57 
58 /* 4 */
59 dkT("xsss"),
60 
61 /* 5 */
62 dkT("qbs"),
63 
64 /* 6 */
65 dkT("lw"),
66 
67 /* 7 */
68 dkT("debug"),
69 
70 /* 8 */
71 dkT("showpage"),
72 
73 /* 9 */
74 dkT("level"),
75 
76 /* 10 */
77 dkT("dsc"),
78 
79 /* 11 */
80 dkT("xfig"),
81 
82 /* 12 */
83 dkT("jfig"),
84 
85 /* 13 */
86 dkT("winfig"),
87 
88 /* 14 */
89 dkT("ahas"),
90 
91 /* 15 */
92 dkT("ahss"),
93 
94 /* 16 */
95 dkT("ahms"),
96 
97 /* 17 */
98 dkT("ahip"),
99 
100 /* 18 */
101 dkT("smash"),
102 
103 /* 19 */
104 dkT("mbox"),
105 
106 /* 20 */
107 dkT("reset@font"),
108 
109 /* 21 */
110 dkT("codi"),
111 
112 /* 22 */
113 dkT("dcts"),
114 
115 /* 23 */
116 dkT("css"),
117 
118 /* 24 */
119 dkT("fragment"),
120 
121 /* 25 */
122 dkT("fontbase"),
123 
124 /* 26 */
125 dkT("group"),
126 
127 /* 27 */
128 dkT("miterlimit"),
129 
130 /* 28 */
131 dkT("cols"),
132 
133 /* 29 */
134 dkT("replacementfonts"),
135 
136 /* 30 */
137 dkT("bbts"),
138 
139 /* 31 */
140 dkT("ste"),
141 
142 /* 32 */
143 dkT("cofop"),
144 
145 /* 33 */
146 dkT("xsah"),
147 
148 /* 34 */
149 dkT("ahbs"),
150 
151 NULL
152 
153 };
154 
155 
156 
157 /**	Values for font base choices.
158 */
159 static dkChar const * const f2lopt_svg_font_bases[] = {
160 /* 0 */
161 dkT("none"),
162 
163 /* 1 */
164 dkT("local"),
165 
166 /* 2 */
167 dkT("web"),
168 
169 NULL
170 
171 };
172 
173 
174 /**	Fixed keywords used by the module, not localized.
175 */
176 static dkChar const * const f2lopt_kw[] = {
177 /* 0 */
178 dkT("none"),
179 
180 /* 1 */
181 dkT("lighten"),
182 
183 /* 2 */
184 dkT("auto$matic"),
185 
186 NULL
187 
188 };
189 
190 
191 
192 /**	Units for line width specification.
193 */
194 static dkChar const * const	f2lopt_units[] = {
195 /* 0 */
196 dkT("bp"),
197 
198 /* 1 */
199 dkT("pt"),
200 
201 /* 2 */
202 dkT("in"),
203 
204 /* 3 */
205 dkT("mm"),
206 
207 /* 4 */
208 dkT("cm"),
209 
210 NULL
211 
212 };
213 
214 
215 /**	Language (output driver) names.
216 	The order of names must correspond the the numbers defined
217 	in fig2lat.ctr, see @ref fig2latdrivers.
218 */
219 static dkChar const * const	f2lopt_language_names[] = {
220 /* 0 */
221 dkT("pgf"),
222 
223 /* 1 */
224 dkT("tex"),
225 
226 /* 2 */
227 dkT("tex.pdf"),
228 
229 /* 3 */
230 dkT("eps.tex"),
231 
232 /* 4 */
233 dkT("pdf.tex"),
234 
235 /* 5 */
236 dkT("eps"),
237 
238 /* 6 */
239 dkT("svg"),
240 
241 NULL
242 
243 };
244 
245 
246 
247 /**	Keywords for font name decision.
248 */
249 static dkChar const * f2lopt_text_font_names[] = {
250 /* 0 */
251 dkT("similar"),
252 
253 /* 1 */
254 dkT("fig"),
255 
256 NULL
257 
258 };
259 
260 
261 
262 /**	Set default options depending on the driver just configured.
263 	@param	job	Job structure.
264 */
265 static
266 void
f2lopt_set_default_options_for_language(f2l_job_t * job)267 f2lopt_set_default_options_for_language(f2l_job_t *job)
268 {
269 
270   job->ntf =    0;
271   job->nts = -1.0;
272   job->showpage = 0;
273   job->dsc = 0;
274   job->smash = 1;
275   job->mbox = 0;
276   job->resfont = 0;
277   switch(job->dr) {
278     case FIG2LAT_DRIVER_EPS_STANDALONE: {
279       job->ntf =    1;
280       job->showpage = 1;
281       job->dsc = 1;
282       job->smash = 0;
283       job->mbox = 0;
284       job->resfont = 0;
285     } break;
286     case FIG2LAT_DRIVER_SVG_STANDALONE:
287     {
288       job->smash = 0; job->mbox = 0; job->resfont = 0;
289       job->ntf =   1;
290     } break;
291     case FIG2LAT_DRIVER_TEX_FULL_PGF:
292     case FIG2LAT_DRIVER_TEX_FULL_PDF:
293     {
294       job->ntf =    1;
295     } break;
296   }
297 
298 }
299 
300 
301 
302 /**	Set language.
303 	@param	job	Job structure to configure.
304 	@param	lstr	Language name without trailing options.
305 	@return	1 on success, 0 on error.
306 */
307 static
308 int
f2lopt_apply_language(f2l_job_t * job,dkChar const * lstr)309 f2lopt_apply_language(f2l_job_t *job, dkChar const *lstr)
310 {
311   int			 back = 0;
312 
313   job->dr = dk3str_array_index(f2lopt_language_names, lstr, 0);
314   if(job->dr > -1) {
315     back = 1;
316     f2lopt_set_default_options_for_language(job);
317   } else {
318     /* ERROR: Unknown language ... */
319     dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 7, 8, lstr);
320     job->exval = FIG2LAT_EXIT_ERROR_SYNTAX;
321   }
322   return back;
323 }
324 
325 
326 
327 /**	Set text font.
328 	@param	job	Job structure.
329 	@param	vptr	Font specification (similar or fig).
330 	@return	1 on success, 0 on error.
331 */
332 static
333 int
f2lopt_set_text_font(f2l_job_t * job,dkChar const * vptr)334 f2lopt_set_text_font(f2l_job_t *job, dkChar const *vptr)
335 {
336   int	 i;		/* Decision for font handling. */
337   int	 back = 0;
338 
339   switch((i = dk3str_array_index(f2lopt_text_font_names, vptr, 0))) {
340     case 0: case 1: {
341       job->ntf = i;
342       back = 1;
343     } break;
344     default: {
345       /* ERROR: No such text font selection! */
346       dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 9, 10, vptr);
347     } break;
348   }
349 
350   return back;
351 }
352 
353 
354 
355 /**	Set text size.
356 	@param	job	Job structure.
357 	@param	vptr	Text size as string (none or scale factor).
358 	@return	1 on success, 0 on error.
359 */
360 static
361 int
f2lopt_set_text_size(f2l_job_t * job,dkChar const * vptr)362 f2lopt_set_text_size(f2l_job_t *job, dkChar const *vptr)
363 {
364   double	 d;		/* Font size factor. */
365   int		 back = 0;
366 
367   if(dk3str_cmp(vptr, f2lopt_kw[0]) == 0) {
368     job->nts = -1.0;
369     back = 1;
370   } else {
371 #if VERSION_BEFORE_20140716
372     if(dk3sf_sscanf3(vptr, dkT("%lf"), &d) == 1)
373 #else
374     if (0 != dk3ma_d_from_string(&d, vptr, NULL))
375 #endif
376     {
377       job->nts = d;
378       back = 1;
379     } else {
380       /* ERROR: Invalid font size specification! */
381       dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 11, 12, vptr);
382     }
383   }
384 
385   return back;
386 }
387 
388 
389 
390 /**	Read a size_t from text.
391 	@param	dptr	Pointer to destination variable.
392 	@param	vptr	Source text.
393 	@param	job	Job structure.
394 	@return	1 on success, 0 on error.
395 */
396 static
397 int
f2lopt_read_size_t(size_t * dptr,dkChar const * vptr,f2l_job_t * job)398 f2lopt_read_size_t(size_t *dptr, dkChar const *vptr, f2l_job_t *job)
399 {
400 #if VERSION_BEFORE_20140809
401   unsigned	u;		/* Conversion result. */
402   int	 	back = 0;
403   if(1 == dk3sf_sscanf3(vptr, dkT("%u"), &u)) {
404     *dptr = (size_t)u;
405     back = 1;
406     if((unsigned)(*dptr) != u) {
407       back = 0;
408       /* ERROR: Range overflow */
409       dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 13, 14, vptr);
410     }
411   } else {
412     /* ERRROR: Not a number! */
413     dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
414   }
415   return back;
416 #else
417   dk3_um_t	um	= DK3_UM_0;
418   int		back	= 0;
419   int		mec	= 0;
420 
421   if (dk3ma_um_from_string(&um, vptr, NULL)) {		/* OK: Number */
422     *dptr = dk3ma_um_to_sz(um, &mec);
423     if (0 == mec) {				/* OK: Converted */
424       back = 1;
425     } else {					/* Overflow */
426       dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 13, 14, vptr);
427     }
428   } else {					/* Not a number */
429     dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
430   }
431   return back;
432 #endif
433 }
434 
435 
436 
437 /**	Read double value from string to configuration variable.
438 	@param	job	Job structure.
439 	@param	dvar	Pointer to destination variable.
440 	@param	src	Source text.
441 	@param	min	Minimum value.
442 	@param	max	Maximum value.
443 	@param	tp	Type (1=check minimum, 2=positive number + check max).
444 	@param	optnr	Option index, used for error messages.
445 	@return	1 on success, 0 on error.
446 */
447 static
448 int
f2lopt_read_double(f2l_job_t * job,double * dvar,dkChar const * src,double min,double max,int tp,size_t optnr)449 f2lopt_read_double(
450   f2l_job_t		*job,
451   double		*dvar,
452   dkChar const		*src,
453   double		 min,
454   double		 max,
455   int			 tp,
456   size_t		 optnr
457 )
458 {
459   dkChar	buf[128];	/* Conversion buffer. */
460   double	dval	= 0.0;	/* Conversion result. */
461   int		back	= 0;
462   if(src) {
463 #if VERSION_BEFORE_20140716
464     if(dk3sf_sscanf3(src, dkT("%lg"), &dval) == 1)
465 #else
466     if (0 != dk3ma_d_from_string(&dval, src, NULL))
467 #endif
468     {
469       switch(tp) {
470         case 1: {
471 	  if(dval >= min) {
472 	    *dvar = dval;
473 	    back = 1;
474 	  } else {
475 	    /* ERROR: Minimum for option ... is ...! */
476 #if VERSION_BEFORE_20140716
477 	    dk3sf_sprintf3(buf, dkT("%g"), min);
478 	    dk3app_log_5(
479 	      job->app, DK3_LL_ERROR, job->msg, 15, 16, 17, src, buf
480 	    );
481 #else
482 	    if (0 != dk3ma_d_to_string(buf, DK3_SIZEOF(buf,dkChar), min)) {
483 	      dk3app_log_5(
484 	        job->app, DK3_LL_ERROR, job->msg, 15, 16, 17, src, buf
485 	      );
486 	    }
487 #endif
488 	  }
489 	} break;
490 	case 2: {
491 	  if(dval > 0) {
492 	    if(dval < max) {
493 	      *dvar = dval;
494 	      back = 1;
495 	    } else {
496 	      /* ERROR: Maximum for option ... is ...! */
497 #if VERSION_BEFORE_20140716
498 	      dk3sf_sprintf3(buf, dkT("%g"), max);
499 	      dk3app_log_5(job->app,DK3_LL_ERROR,job->msg,15,18,17,src,buf);
500 #else
501 	      if (0 != dk3ma_d_to_string(buf, DK3_SIZEOF(buf,dkChar), max)) {
502 	        dk3app_log_5(job->app,DK3_LL_ERROR,job->msg,15,18,17,src,buf);
503 	      }
504 #endif
505 	    }
506 	  } else {
507 	    /* ERROR: Option ... requires positive value! */
508 	    dk3app_log_3(
509 	      job->app, DK3_LL_ERROR, job->msg, 19, 20,
510 	      f2lopt_key_names[optnr]
511 	    );
512 	  }
513 	} break;
514       }
515     } else {
516       /* ERROR: Option argument is not numeric! */
517       dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, src);
518     }
519   } else {
520     /* ERROR: Option requires an argument. */
521     dk3app_log_3(
522       job->app, DK3_LL_ERROR, job->msg, 21, 22,
523       f2lopt_key_names[optnr]
524     );
525   }
526   return back;
527 }
528 
529 
530 /**	Process one option.
531 	@param	job	Job structure to configure.
532 	@param	str	Key=value text.
533 	@return	1 on success, 0 on error.
534 */
535 static
536 int
f2lopt_apply_option(f2l_job_t * job,dkChar const * str)537 f2lopt_apply_option(f2l_job_t *job, dkChar const *str)
538 {
539   dkChar		 bu[1024];	/* Private copy of str. */
540   dkChar		*kptr;		/* Key pointer. */
541   dkChar		*vptr;		/* Value pointer. */
542   int			 back = 0;
543 
544   if(dk3str_len(str) < DK3_SIZEOF(bu,dkChar)) {
545     dk3str_cpy_not_overlapped(bu, str);
546     kptr = dk3str_start(bu, NULL);
547     if(kptr) {
548       vptr = dk3str_chr(kptr, dkT('='));
549       if(vptr) {
550         *(vptr++) = dkT('\0');
551 	vptr = dk3str_start(vptr, NULL);
552       }
553       switch(dk3str_array_index(f2lopt_key_names, kptr, 0)) {
554         case 0: {
555 	  if(vptr) {
556 	    back = f2lopt_set_text_font(job, vptr);
557 	  } else {
558 	    /* ERRROR: Key needs an argument! */
559 	    dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 21, 22, kptr);
560 	  }
561 	} break;
562 	case 1: {
563 	  if(vptr) {
564 	    back = f2lopt_set_text_size(job, vptr);
565 	  } else {
566 	    job->nts = -1.0;
567 	    back = 1;
568 	  }
569 	} break;
570 	case 2: {
571 	  if(vptr) {
572 	    if(dk3str_is_bool(vptr)) {
573 	      job->cosp = (dk3str_is_on(vptr) ? 1 : 0);
574 	      back = 1;
575 	    } else {
576 	      /* ERROR: Not a boolean */
577 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
578 	    }
579 	  } else {
580 	    job->cosp = 1; back = 1;
581 	  }
582 	} break;
583 	case 3: {
584 	  if(vptr) {
585 	    if(dk3str_is_bool(vptr)) {
586 	      job->coah = (dk3str_is_on(vptr) ? 1 : 0);
587 	      back = 1;
588 	    } else {
589 	      /* ERROR: Not a boolean */
590 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
591 	    }
592 	  } else {
593 	    job->coah = 1; back = 1;
594 	  }
595 	} break;
596 	case 4: {
597 	  if(vptr) {
598 	    back = f2lopt_read_size_t(&(job->xssbs), vptr, job);
599 	  } else {
600 	    /* ERROR: Argument required! */
601             dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
602 	  }
603 	} break;
604 	case 5: {
605 	  if(vptr) {
606 	    back = f2lopt_read_size_t(&(job->qbs), vptr, job);
607 	  } else {
608 	    /* ERROR: Argument required! */
609 	    dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
610 	  }
611 	} break;
612 	case 6: {
613 #if VERSION_BEFORE_20140330
614 	  if(vptr) {
615 	    if(dk3str_is_bool(vptr)) {
616 	      job->lighten = ((dk3str_is_on(vptr)) ? 1 : 0);
617 	      back = 1;
618 	    } else {
619 	      /* ERROR: Not a boolean value! */
620 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
621 	    }
622 	  } else {
623 	    back = 1;
624 	    job->lighten = 1;
625 	  }
626 #else
627 	  job->lwbp = 0.9;
628 	  job->lwauto = 0;
629 	  if (vptr) {
630 	    double	x;
631 	    size_t	vplen;
632 	    vplen = dk3str_len(vptr);
633 	    if (0 == dk3str_cmp(f2lopt_kw[1], vptr)) {
634 	      job->lwbp = 0.45;
635 	      job->lwauto = 0;
636 	      back = 1;
637 	    } else {
638 	      if (dk3str_is_abbr(vptr,f2lopt_kw[2],dkT('$'), 0)) {
639 	        job->lwauto = 1;
640 		back = 1;
641 	      } else {
642 	        if (2 < vplen) {
643 		  switch (dk3str_array_index(f2lopt_units, &(vptr[vplen-2]), 0))
644 		  {
645 		    case 0: {	/* bp */
646 		      vptr[vplen - 2] = dkT('\0');
647 #if VERSION_BEFORE_20140716
648 		      if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
649 #else
650 		      if (0 != dk3ma_d_from_string(&x, vptr, NULL))
651 #endif
652 		      {
653 		        job->lwbp = x;
654 			back = 1;
655 		      } else {
656 		        /* ERROR: Failed to process */
657 			dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
658 		      }
659 		    } break;
660 		    case 1: {	/* pt */
661 		      vptr[vplen - 2] = dkT('\0');
662 #if VERSION_BEFORE_20140716
663 		      if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
664 #else
665 		      if (0 != dk3ma_d_from_string(&x, vptr, NULL))
666 #endif
667 		      {
668 		        job->lwbp = x * 72.0 / 72.27;
669 			back = 1;
670 		      } else {
671 		        /* ERROR: Failed to process */
672 			dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
673 		      }
674 		    } break;
675 		    case 2: {	/* in */
676 		      vptr[vplen - 2] = dkT('\0');
677 #if VERSION_BEFORE_20140716
678 		      if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
679 #else
680 		      if (0 != dk3ma_d_from_string(&x, vptr, NULL))
681 #endif
682 		      {
683 		        job->lwbp = x * 72.0;
684 			back = 1;
685 		      } else {
686 		        /* ERROR: Failed to process */
687 			dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
688 		      }
689 		    } break;
690 		    case 3: {	/* mm */
691 		      vptr[vplen - 2] = dkT('\0');
692 #if VERSION_BEFORE_20140716
693 		      if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
694 #else
695 		      if (0 != dk3ma_d_from_string(&x, vptr, NULL))
696 #endif
697 		      {
698 		        job->lwbp = x * 72.0 / 25.4;
699 			back = 1;
700 		      } else {
701 		        /* ERROR: Failed to process */
702 			dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
703 		      }
704 		    } break;
705 		    case 4: {	/* cm */
706 		      vptr[vplen - 2] = dkT('\0');
707 #if VERSION_BEFORE_20140716
708 		      if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
709 #else
710 		      if (0 != dk3ma_d_from_string(&x, vptr, NULL))
711 #endif
712 		      {
713 		        job->lwbp = x * 72.0 / 2.54;
714 			back = 1;
715 		      } else {
716 		        /* ERROR: Failed to process */
717 			dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
718 		      }
719 		    } break;
720 		    default: {
721 #if VERSION_BEFORE_20140716
722 		      if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
723 #else
724 		      if (0 != dk3ma_d_from_string(&x, vptr, NULL))
725 #endif
726 		      {
727 		        job->lwbp = x;
728 			back = 1;
729 		      } else {
730 		        /* ERROR: Failed to process */
731 			dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
732 		      }
733 		    } break;
734 		  }
735 		} else {
736 #if VERSION_BEFORE_20140716
737 		  if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
738 #else
739 		  if (0 != dk3ma_d_from_string(&x, vptr, NULL))
740 #endif
741 		  {
742 		    job->lwbp = x;
743 		    back = 1;
744 		  } else {
745 		    /* ERROR: Failed to process */
746 		    dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
747 		  }
748 		}
749 	      }
750 	    }
751 	  } else {
752 	    job->lwbp = 0.9;
753 	    job->lwauto = 1;
754 	    back = 1;
755 	    if (job->lwbp < 0.001) {
756 	      job->lwbp = 0.001;
757 	    }
758 	  }
759 #endif
760 	} break;
761 	case 7: {
762 	  if(vptr) {
763 	    if(dk3str_is_bool(vptr)) {
764 	      back = 1;
765 	      job->debug = ((dk3str_is_on(vptr)) ? 1 : 0);
766 	    } else {
767 	      /* ERROR: Not a boolean value! */
768 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
769 	    }
770 	  } else {
771 	    back = 1;
772 	    job->debug = 1;
773 	  }
774 	} break;
775 	case 8: {
776 	  if(vptr) {
777 	    if(dk3str_is_bool(vptr)) {
778 	      job->showpage = ((dk3str_is_on(vptr)) ? 1 : 0);
779 	      back = 1;
780 	    } else {
781 	      /* ERROR: Not a boolean value! */
782 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
783 	    }
784 	  } else {
785 	    job->showpage = 1;
786 	    back = 1;
787 	  }
788 	} break;
789 	case 9: {
790 	  if(vptr) {
791 	    int i;
792 #if VERSION_BEFORE_20140716
793 	    if(dk3sf_sscanf3(vptr, dkT("%d"), &i) == 1)
794 #else
795 	    if (0 != dk3ma_i_from_string(&i, vptr, NULL))
796 #endif
797 	    {
798 	      if((i >= 2) && (i <= 3)) {
799 	        job->pslevel = i;
800 	      } else {
801 	        /* ERROR: Must be 2 or 3! */
802 		dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 33);
803 	      }
804 	    } else {
805 	      /* ERROR: Argument not a number! */
806 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
807 	    }
808 	  } else {
809 	    /* ERROR: Argument required! */
810 	    dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
811 	  }
812 	} break;
813 	case 10: {
814 	  if(vptr) {
815 	    if(dk3str_is_bool(vptr)) {
816 	      job->dsc = ((dk3str_is_on(vptr)) ? 1 : 0);
817 	      back = 1;
818 	    } else {
819 	      /* ERROR: Not a boolean argument. */
820 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
821 	    }
822 	  } else {
823 	    job->dsc = 1;
824 	    back = 1;
825 	  }
826 	} break;
827 	case 11: {
828 	  if(DK3_FIG_SRCTYPE_UNKNOWN == job->srctype) {
829 	    job->srctype = DK3_FIG_SRCTYPE_XFIG;
830 	    back = 1;
831 	  } else {
832 	    /* ERROR: Source type already set! */
833 	    dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
834 	  }
835 	} break;
836 	case 12: {
837 	  if(DK3_FIG_SRCTYPE_UNKNOWN == job->srctype) {
838 	    job->srctype = DK3_FIG_SRCTYPE_JFIG;
839 	    back = 1;
840 	  } else {
841 	    /* ERROR: Source type already set! */
842 	    dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
843 	  }
844 	} break;
845 	case 13: {
846 	  if(DK3_FIG_SRCTYPE_UNKNOWN == job->srctype) {
847 	    job->srctype = DK3_FIG_SRCTYPE_WINFIG;
848 	    back = 1;
849 	  } else {
850 	    /* ERROR: Source type already set! */
851 	    dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
852 	  }
853 	} break;
854 	case 14: {	/* Arrowhead arc segments */
855 	  back = f2lopt_read_double(job,&(job->arcspp),vptr,2.0,-1.0,1,14);
856 	} break;
857 	case 15: {	/* Arrowhead spline segments */
858 	  back = f2lopt_read_double(job,&(job->splspp),vptr,2.0,-1.0,1,15);
859 	} break;
860 	case 16: {	/* Arrowhead min segments. */
861 	  unsigned u = 2;
862 	  if(vptr) {
863 #if VERSION_BEFORE_20140716
864 	    if(dk3sf_sscanf3(vptr, dkT("%u"), &u) == 1)
865 #else
866 	    if (0 != dk3ma_ui_from_string(&u, vptr, NULL))
867 #endif
868 	    {
869 	      if(2 <= u) {
870 	        job->minspp = (size_t)u;
871 		back = 1;
872 	      } else {
873 	        /* Warning: Must be at least 2! */
874 		job->minspp = 2;
875 		dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 34);
876 		back = 1;
877 	      }
878 	    } else {
879 	      /* ERROR: Argument is not numeric */
880 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
881 	    }
882 	  } else {
883 	    /* ERROR: Option requires an argument! */
884 	    dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
885 	  }
886 	} break;
887 	case 17: {	/* Arrowhead interpolation precision. */
888 	  back = f2lopt_read_double(job,&(job->xsprec),vptr,0.0,0.1,2,17);
889 	} break;
890 	case 18: {	/* smash */
891 	  if(vptr) {
892 	    if(dk3str_is_bool(vptr)) {
893 	      job->smash = ((dk3str_is_on(vptr)) ? 1 : 0);
894 	      back = 1;
895 	    } else {
896 	      /* ERROR: Option requires boolean argument */
897 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
898 	    }
899 	  } else {
900 	    job->smash = 1;
901 	    back = 1;
902 	  }
903 	} break;
904 	case 19: {	/* mbox */
905 	  if(vptr) {
906 	    if(dk3str_is_bool(vptr)) {
907 	      job->mbox = ((dk3str_is_on(vptr)) ? 1 : 0);
908 	      back = 1;
909 	    } else {
910 	      /* ERROR: Option requires boolean argument! */
911 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
912 	    }
913 	  } else {
914 	    job->mbox = 1;
915 	    back = 1;
916 	  }
917 	} break;
918 	case 20: {
919 	  if(vptr) {
920 	    if(dk3str_is_bool(vptr)) {
921 	      job->resfont = ((dk3str_is_on(vptr)) ? 1 : 0);
922 	      back = 1;
923 	    } else {
924 	      /* ERROR: Option requires boolean argument! */
925 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
926 	    }
927 	  } else {
928 	    job->resfont = 1;
929 	    back = 1;
930 	  }
931 	} break;
932 	case 21: {
933 	  if(vptr) {
934 	    unsigned u;
935 #if VERSION_BEFORE_20140716
936 	    if(dk3sf_sscanf3(vptr, dkT("%u"), &u) == 1)
937 #else
938 	    if (0 != dk3ma_ui_from_string(&u, vptr, NULL))
939 #endif
940 	    {
941 	      job->codi = (size_t)u;
942 	      back = 1;
943 	    } else {
944 	      /* ERROR: Option requires an unsigned numeric argument! */
945 	      dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 24, 25, kptr);
946 	    }
947 	  } else {
948 	    job->codi = 0;
949 	    back = 1;
950 	  }
951 	} break;
952 	case 22: {
953 	  if(vptr) {
954 	    double d;
955 #if VERSION_BEFORE_20140716
956 	    if(dk3sf_sscanf3(vptr, dkT("%lg"), &d) == 1)
957 #else
958 	    if (0 != dk3ma_d_from_string(&d, vptr, NULL))
959 #endif
960 	    {
961 	      if(d > 0.0) {
962 	        job->tts = d; back = 1;
963 	      } else {
964 	        /* ERROR: Cannot handle negative font size! */
965 		dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 26);
966 	      }
967 	    } else {
968 	      /* ERROR: Option requires a floating point number arg! */
969 	      dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 12, 22, kptr);
970 	    }
971 	  } else {
972 	    job->tts = 12.0; back = 1;
973 	  }
974 	} break;
975 	case 23: {
976 	  if(vptr) {
977 	    if(dk3str_is_bool(vptr)) {
978 	      job->css = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
979 	    } else {
980 	      /* ERROR: Option requires boolean argument! */
981 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
982 	    }
983 	  } else {
984 	    job->css = 1; back = 1;
985 	  }
986 	} break;
987 	case 24: {
988 	  if(vptr) {
989 	    if(dk3str_is_bool(vptr)) {
990 	      job->fragment = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
991 	    } else {
992 	      /* ERROR: Option requires boolean argument! */
993 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
994 	    }
995 	  } else {
996 	    job->fragment = 1; back = 1;
997 	  }
998 	} break;
999 	case 25: {
1000 	  if(vptr) {
1001 	    job->svgfontbase = dk3str_array_index(f2lopt_svg_font_bases, vptr, 0);
1002 	    if(0 <= job->svgfontbase) {
1003 	      back = 1;
1004 	    } else {
1005 	      /* ##### ERROR: Illegal font base name! */
1006 	    }
1007 	  } else {
1008 	    job->svgfontbase = 0; back = 1;
1009 	  }
1010 	} break;
1011 	case 26: {
1012 	  if(vptr) {
1013 	    if(dk3str_is_bool(vptr)) {
1014 	      job->group = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
1015 	    } else {
1016 	      /* ERROR: Option requires boolean argument! */
1017 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
1018 	    }
1019 	  } else {
1020 	    job->group = 1; back = 1;
1021 	  }
1022 	} break;
1023 	case 27: {
1024 	  if(vptr) {
1025 	    if(dk3str_is_bool(vptr)) {
1026 	      job->miterlim = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
1027 	    } else {
1028 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
1029 	    }
1030 	  } else {
1031 	    job->miterlim = 1; back = 1;
1032 	  }
1033 	} break;
1034 	case 28: {
1035 	  if(vptr) {
1036 	    if(dk3str_is_bool(vptr)) {
1037 	      job->cols = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
1038 	    } else {
1039 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
1040 	    }
1041 	  } else {
1042 	    job->cols = 1; back = 1;
1043 	  }
1044 	} break;
1045 	case 29: {
1046 	  if(vptr) {
1047 	    if(dk3str_is_bool(vptr)) {
1048 	      job->otherfonts = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
1049 	    } else {
1050 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
1051 	    }
1052 	  } else {
1053 	    job->otherfonts = 1; back = 1;
1054 	  }
1055 	} break;
1056 	case 30: {
1057 	  if(vptr) {
1058 	    if(dk3str_is_bool(vptr)) {
1059 	      job->bbts = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
1060 	    } else {
1061 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
1062 	    }
1063 	  } else {
1064 	    job->bbts = 1; back = 1;
1065 	  }
1066 	} break;
1067 	case 31: {
1068 	  int enc;
1069 	  if(vptr) {
1070 	    enc = dk3enc_get_text_encoding_app(vptr, job->app);
1071 	  } else {
1072 	    if(DK3_ENCODING_UTF8 == dk3app_get_encoding(job->app)) {
1073 	      enc = DK3_ENCODING_PLAIN;
1074 	    } else {
1075 	      enc = DK3_ENCODING_UTF8;
1076 	    }
1077 	  }
1078 	  back = 1;
1079 	  switch(enc) {
1080 	    case DK3_ENCODING_UTF8: {
1081 	      job->stu8 = 1;
1082 	    } break;
1083 	    case DK3_ENCODING_PLAIN: {
1084 	      job->stu8 = 0;
1085 	    } break;
1086 	    default: {
1087 	      job->stu8 = 0;
1088 	      /* ##### WARNING Only ascii and utf-8 allowed. */
1089 	    } break;
1090 	  }
1091 	} break;
1092 	case 32: {
1093 	  if(vptr) {
1094 	    if(dk3str_is_bool(vptr)) {
1095 	      job->cofop = ((dk3str_is_on(vptr)) ? 1 : 0);
1096 	      back = 1;
1097 	    } else {
1098 	      /* ERROR: Not a boolean! */
1099 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
1100 	    }
1101 	  } else {
1102 	    job->cofop = 1;
1103 	    back = 1;
1104 	  }
1105 	} break;
1106 	case 33: {
1107 	  if (vptr) {
1108 	    if(dk3str_is_bool(vptr)) {
1109 	      job->xsah = ((dk3str_is_on(vptr)) ? 1 : 0);
1110 	      back = 1;
1111 	    } else {
1112 	      /* ERROR: Not a boolean! */
1113 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
1114 	    }
1115 	  } else {
1116 	    job->xsah = 1;
1117 	    back = 1;
1118 	  }
1119 	} break;
1120 	case 34: {
1121 	  if (vptr) {
1122 	    if (dk3str_is_bool(vptr)) {
1123 	      job->ahbs = ((dk3str_is_on(vptr)) ? 1 : 0);
1124 	      back = 1;
1125 	    } else {
1126 	      /* ERROR: Not a boolean! */
1127 	      dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
1128 	    }
1129 	  } else {
1130 	    job->ahbs = 1;
1131 	    back = 1;
1132 	  }
1133 	} break;
1134 	default: {
1135 	  /* ERROR: Unknown key name! */
1136 	  dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 27, 28, kptr);
1137 	} break;
1138       }
1139     } else {
1140       back = 1;
1141     }
1142     if(!(back)) {
1143       job->exval = FIG2LAT_EXIT_ERROR_SYNTAX;
1144     }
1145   } else {
1146     /* ERROR: Option ... too long! */
1147     dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 29, 30, str);
1148     job->exval = FIG2LAT_EXIT_ERROR_SYNTAX;
1149   }
1150   return back;
1151 }
1152 
1153 
1154 
1155 /**	Set language, apply options if any.
1156 	@param	job	Job structure to set up.
1157 	@param	optarg	Language, optionally with further options.
1158 	@return	1 on success, 0 on error.
1159 */
1160 static
1161 int
f2lopt_set_language(f2l_job_t * job,dkChar const * optarg)1162 f2lopt_set_language(f2l_job_t *job, dkChar const *optarg)
1163 {
1164   dkChar		 bu[1024];	/* Private copy of optarg. */
1165   dkChar		*pc;		/* Current string. */
1166   dkChar		*pn;		/* Next string. */
1167   int			 back = 0;
1168 
1169   if(dk3str_len(optarg) < DK3_SIZEOF(bu,dkChar)) {
1170     dk3str_cpy_not_overlapped(bu, optarg);
1171     pc = dk3str_chr(bu, dkT(','));
1172     if(pc) {
1173       *(pc++) = dkT('\0');
1174       pc = dk3str_start(pc, NULL);
1175     }
1176     if(f2lopt_apply_language(job, bu)) {
1177       back = 1;
1178       while(pc) {
1179         pn = dk3str_chr(pc, dkT(','));
1180 	if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
1181 	if(!f2lopt_apply_option(job, pc)) {
1182 	  back = 0;
1183 	  pn = NULL;
1184 	}
1185 	pc = pn;
1186       }
1187     }
1188   } else {
1189     /* ERROR: Option argument too long! */
1190     dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 31, 30, optarg);
1191   }
1192   return back;
1193 }
1194 
1195 
1196 
1197 int
f2lopt_process(f2l_job_t * job)1198 f2lopt_process(f2l_job_t *job)
1199 {
1200   dkChar const		*optarg;	/* Option argument. */
1201   int			 back = 0;
1202   int			 i;		/* Current file name. */
1203 
1204   job->opt = dk3opt_open_from_app(
1205     f2lopt_options, f2lopt_sz_options,
1206     dkT('o'), dkT("option"),
1207     job->app
1208   );
1209   if(job->opt) {
1210     if(0 == dk3opt_get_error_code(job->opt)) {
1211       back = 1;
1212       if(dk3opt_is_set(job->opt, dkT('h'))) {
1213         job->cmd |= DK3_APP_CMD_HELP;
1214       }
1215       if(dk3opt_is_set(job->opt, dkT('v'))) {
1216         job->cmd |= DK3_APP_CMD_VERSION;
1217       }
1218       if(dk3opt_is_set(job->opt, dkT('L'))) {
1219         job->cmd |= DK3_APP_CMD_LICENSE;
1220       }
1221       if(0 == job->cmd) {
1222         if(dk3opt_is_set(job->opt, dkT('m'))) {
1223 	  job->mm = 1;
1224 	}
1225         if(dk3opt_is_set(job->opt, dkT('l'))) {
1226 	  optarg = dk3opt_get_short_arg(job->opt, dkT('l'));
1227 	  if(optarg) {
1228 	    if(f2lopt_set_language(job, optarg)) {
1229 	      for(i = 0; i < dk3opt_get_num_fo(job->opt); i++) {
1230 	        optarg = dk3opt_get_fo(job->opt, i);
1231 		if(optarg) {
1232 		  if(!f2lopt_apply_option(job, optarg)) {
1233 		    back = 0;
1234 		  }
1235 		}
1236 	      }
1237 	    } else {
1238 	      back = 0;
1239 	    }
1240 	  } else {
1241 	    back = 0;
1242 	    /* ERROR: Option requires an argument! */
1243 	    dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 32);
1244 	  }
1245 	} else {
1246 	}
1247       }
1248       /*	Automatically calculate line width in points
1249       		from TeX text size.
1250       */
1251       if (job->lwauto) {
1252         job->lwbp = 0.4 * 72.0 * job->tts / (10 * 72.27);
1253 
1254       }
1255     } else {
1256     }
1257   } else {
1258     job->exval = FIG2LAT_EXIT_ERROR_SYSTEM;
1259   }
1260   return back;
1261 }
1262 
1263 
1264