1 /*
2 Copyright (C) 2011-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: dk3opt.ctr
12 */
13 
14 /**	@file dk3opt.c The dk3opt module.
15 */
16 
17 
18 #include <libdk3c/dk3all.h>
19 
20 
21 
22 
23 
24 
25 
26 /**	Find index of character in options set.
27 	@param	os	Options set.
28 	@param	c	Character to search for.
29 	@param	pind	Pointer to destination variable.
30 	@return	1 on success, 0 on error.
31 */
32 static
33 int
dk3opt_find_index_short(dk3_option_set_t const * os,dkChar c,size_t * pind)34 dk3opt_find_index_short(
35   dk3_option_set_t const	*os,
36   dkChar			 c,
37   size_t			*pind
38 )
39 {
40   int		back = 0;
41   size_t	i;
42 
43   if((os) && (pind)) {
44     if((os->options) && (os->szoptions)) {
45       for(i = 0; ((i < os->szoptions) && (back == 0)); i++) {
46         if(((os->options)[i]).so == c) {
47 	  *pind = i; back = 1;
48 	}
49       }
50     }
51   }
52   return back;
53 }
54 
55 
56 
57 /**	Find index of long option in options set.
58 	@param	os	Options set.
59 	@param	t	Long option name to search for.
60 	@param	pind	Pointer to destination variable.
61 	@return	1 on success, 0 on error.
62 */
63 static
64 int
dk3opt_find_index_long(dk3_option_set_t const * os,dkChar const * t,size_t * pind)65 dk3opt_find_index_long(
66   dk3_option_set_t const	*os,
67   dkChar const			*t,
68   size_t			*pind
69 )
70 {
71   int		back = 0;
72   size_t	i;
73 
74   if((os) && (t) && (pind)) {
75     if((os->options) && (os->szoptions)) {
76       for(i = 0; ((i < os->szoptions) && (back == 0)); i++) {
77         if(((os->options)[i]).lo) {
78 	  if(dk3str_cmp(((os->options)[i]).lo, t) == 0) {
79 	    *pind = i; back = 1;
80 	  }
81 	}
82       }
83     }
84   }
85   return back;
86 }
87 
88 
89 
90 /**	Apply the command line options to the options set.
91 	@param	os	Options set.
92 	@param	argc	Number of command line arguments.
93 	@param	argv	Command line arguments array.
94 */
95 static
96 void
dk3opt_apply_options(dk3_option_set_t * os,int argc,dkChar const * const * argv)97 dk3opt_apply_options(
98   dk3_option_set_t	*os,
99   int			 argc,
100   dkChar const * const	*argv
101 )
102 {
103   dkChar const * const	*lfdptr;
104   dkChar const		*ptr;
105   dkChar const		*optr;
106   dkChar const		*cptr;
107   int			 i;
108   size_t		 j;
109   int			 done;
110   dkChar		 bu[2 * DK3_MAX_PATH];
111   dkChar		*p1;
112 
113   lfdptr = argv; i = 0;
114   while(i < argc) {
115     optr = ptr = *lfdptr;
116     if(*ptr == dkT('-')) {
117       ptr++;
118       if(*ptr == dkT('-')) {
119         ptr++;
120 	if(dk3str_len(ptr) < DK3_SIZEOF(bu,dkChar)) {
121 	  dk3str_cpy_not_overlapped(bu, ptr);
122 	  p1 = dk3str_chr(bu, dkT('='));
123 	  if(p1) {
124 	    *p1 = dkT('\0');
125 	  }
126 	  done = 0;
127 	  if(os->focl) {
128 	    if(dk3str_cmp(os->focl, bu) == 0) {
129 	      done = 1;
130 	      cptr = dk3str_chr(ptr, dkT('='));
131 	      if(cptr) {
132 	        cptr++;
133 		if(!(*cptr)) {
134 		  cptr = NULL;
135 		}
136 	      }
137 	      if(!(cptr)) {
138 	        lfdptr++; i++; if(i < argc) { cptr = *lfdptr; }
139 	      }
140 	      if(cptr) {
141 	        (os->fo)[os->fou] = cptr;
142 		os->fou += 1;
143 	      } else {
144 	        /* ERROR: Option needs argument! */
145 		os->ec = 1;
146 		if(os->app) {
147 		  dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
148 		}
149 	      }
150 	    }
151 	  }
152 	  if(!done) {
153 	    if(dk3opt_find_index_long(os, bu, &j)) {
154 	      (os->found)[j] += 1;
155 	      if((os->found)[j] == 0) { /* Overflow */
156 	        (os->found)[j] = 0x7FFF;
157 	      }
158 	      if(((os->options)[j]).na) {
159 	        cptr = dk3str_chr(ptr, dkT('='));
160 		if(cptr) { cptr++; if(!(*cptr)) { cptr = NULL; } }
161 		if(!(cptr)) {
162 		  lfdptr++; i++; if(i < argc) { cptr = *lfdptr; }
163 		}
164 		if(cptr) {
165 		  if((os->optargs)[j]) {
166 		    /* Warning: Redefinition */
167 		    /* os->ec = 1; */
168 		    if(os->app) {
169 		      dk3app_log_i5(
170 		        os->app, DK3_LL_WARNING, 206, 207, 208,
171 			(os->optargs)[j], cptr
172 		      );
173 		    }
174 		  }
175 		  (os->optargs)[j] = cptr;
176 		} else {
177 		  /* ERROR: Option needs argument! */
178 		  os->ec = 1;
179 		  if(os->app) {
180 		    dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
181 		  }
182 		}
183 	      }
184 	    } else {
185 	      /* ERROR: Illegal option! */
186 	      os->ec = 1;
187 	      if(os->app) {
188 	        dk3app_log_i3(os->app, DK3_LL_ERROR, 139, 140, optr);
189 	      }
190 	    }
191 	  }
192 	} else {
193 	  /* ERROR: Option too long! */
194 	  os->ec = 1;
195 	  if(os->app) {
196 	    dk3app_log_i3(os->app, DK3_LL_ERROR, 135, 136, optr);
197 	  }
198 	}
199       } else {
200 	if(*ptr == os->foc) {
201 	  ptr++;
202 	  if(!(*ptr)) {
203 	    ptr = NULL;
204 	    lfdptr++; i++;
205 	    if(i < argc) { ptr = *lfdptr; }
206 	  }
207 	  if(ptr) {
208 	    (os->fo)[os->fou] = ptr;
209 	    os->fou += 1;
210 	  } else {
211 	    /* ERROR: Option needs an argument! */
212 	    os->ec = 1;
213 	    if(os->app) {
214 	      dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
215 	    }
216 	  }
217 	} else {
218 	  if(dk3opt_find_index_short(os, *ptr, &j)) {
219 	    (os->found)[j] += 1;
220 	    if((os->found)[j] == 0) { /* Overflow */
221 	      (os->found)[j] = 0x7FFF;
222 	    }
223 	    if(((os->options)[j]).na) {
224 	      ptr++;
225 	      if(!(*ptr)) {
226 	        ptr = NULL;
227 		lfdptr++; i++;
228 		if(i < argc) { ptr = *lfdptr; }
229 	      }
230 	      if(ptr) {
231 	        if((os->optargs)[j]) {
232 		  /* Warning: Redefinition of option. */
233 		  /* os->ec = 1; */
234 		  if(os->app) {
235 		    dk3app_log_i5(
236 		      os->app, DK3_LL_WARNING, 206, 207, 208,
237 		      (os->optargs)[j], ptr
238 		    );
239 		  }
240 		}
241 	        (os->optargs)[j] = ptr;
242 	      } else {
243 	        /* ERROR: Option needs an argument! */
244 		os->ec = 1;
245 		if(os->app) {
246 		  dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
247 		}
248 	      }
249 	    } else {
250 	      ptr++;
251 	      if(*ptr) {
252 	        if((os->optargs)[j]) {
253 		  if(os->app) {
254 		    dk3app_log_i5(
255 		      os->app, DK3_LL_WARNING, 206, 207, 208,
256 		      (os->optargs)[j], ptr
257 		    );
258 		  }
259 		}
260 		(os->optargs)[j] = ptr;
261 	      }
262 	    }
263 	  } else {
264 	    /* ERROR: Illegal option! */
265 	    os->ec = 1;
266 	    if(os->app) {
267 	      dk3app_log_i3(os->app, DK3_LL_ERROR, 139, 140, optr);
268 	    }
269 	  }
270 	}
271       }
272     } else {
273       (os->args)[os->argsused] = ptr;
274       os->argsused += 1;
275     }
276     lfdptr++; i++;
277   }
278 }
279 
280 
281 
282 dk3_option_set_t *
dk3opt_open_app(dk3_option_t const * options,size_t szoptions,dkChar foc,dkChar const * focl,int argc,dkChar const * const * argv,dk3_app_t * app)283 dk3opt_open_app(
284   dk3_option_t const	*options,
285   size_t		 szoptions,
286   dkChar		 foc,
287   dkChar const		*focl,
288   int			 argc,
289   dkChar const * const	*argv,
290   dk3_app_t		*app
291 )
292 {
293   dk3_option_set_t	*back = NULL;
294   int			 ok   = 0;
295   int			 i    = 0;
296   size_t		 j    = 0;
297 
298   if((options) && (szoptions)) {
299     back = dk3_new_app(dk3_option_set_t,1,app);
300     if(back) {
301       back->app = app;
302       back->options = options;
303       back->szoptions = szoptions;
304       back->found = NULL;
305       back->optargs = NULL;
306       back->args = NULL;
307       back->fo = NULL;
308       back->foc = foc;
309       back->focl = focl;
310       back->argsav = 0;
311       back->argsused = 0;
312       back->foav = 0;
313       back->fou = 0;
314       back->ec = 0;
315       back->found = dk3_new_app(int,szoptions,app);
316       if(back->found) {
317         for(j = 0; j < szoptions; j++) {
318 	  (back->found)[j] = 0;
319 	}
320 	back->optargs = dk3_new_app(DK3_PCDKCHAR,szoptions,app);
321 	if(back->optargs) {
322 	  for(j = 0; j < szoptions; j++) {
323 	    (back->optargs)[j] = NULL;
324 	  }
325 	  if(argc) {
326 	    back->args = dk3_new_app(DK3_PCDKCHAR,argc,app);
327 	    if(back->args) {
328 	      back->argsav = argc;
329 	      for(i = 0; i < argc; i++) { (back->args)[i] = NULL; }
330 	      back->fo = dk3_new_app(DK3_PCDKCHAR,argc,app);
331 	      if(back->fo) {
332 	        back->foav = argc;
333 	        for(i = 0; i < argc; i++) { (back->fo)[i] = NULL; }
334 	        ok = 1;
335 	        dk3opt_apply_options(back, argc, argv);
336 	      }
337 	    }
338 	  } else {
339 	    ok = 1;
340 	  }
341 	} else {
342 	}
343       } else {
344       }
345       if(!ok) {
346         dk3opt_close(back); back = NULL;
347       }
348       if(back) {
349         if(back->ec) {
350           if(app) {
351 	    dk3app_log_i1(app, DK3_LL_ERROR, 252);
352 	  }
353 	}
354       }
355     }
356   }
357   return back;
358 }
359 
360 
361 
362 dk3_option_set_t *
dk3opt_open_from_app(dk3_option_t const * options,size_t szoptions,dkChar foc,dkChar const * focl,dk3_app_t * app)363 dk3opt_open_from_app(
364   dk3_option_t const	*options,
365   size_t		 szoptions,
366   dkChar		 foc,
367   dkChar const		*focl,
368   dk3_app_t		*app
369 )
370 {
371   dk3_option_set_t	*back = NULL;
372   dkChar const * const	*argv;
373   int			 argc;
374 
375   if((options) && (szoptions) && (app)) {
376     argc = dk3app_get_argc(app);
377     argv = dk3app_get_argv(app);
378     argv++; argc--;
379     back = dk3opt_open_app(options, szoptions, foc, focl, argc, argv, app);
380   }
381   return back;
382 }
383 
384 
385 
386 int
dk3opt_is_set(dk3_option_set_t const * optset,dkChar shortopt)387 dk3opt_is_set(
388   dk3_option_set_t const	*optset,
389   dkChar			 shortopt
390 )
391 {
392   int		back = 0;
393   size_t	i;
394 
395   if(optset) {
396     if(dk3opt_find_index_short(optset, shortopt, &i)) {
397       if(optset->found) {
398         back = (optset->found)[i];
399       }
400     }
401   }
402   return back;
403 }
404 
405 
406 
407 int
dk3opt_is_set_long(dk3_option_set_t const * optset,dkChar const * longopt)408 dk3opt_is_set_long(
409   dk3_option_set_t const	*optset,
410   dkChar const			*longopt
411 )
412 {
413   int		back = 0;
414   size_t	i;
415 
416   if((optset) && (longopt)) {
417     if(dk3opt_find_index_long(optset, longopt, &i)) {
418       if(optset->found) {
419         back = (optset->found)[i];
420       }
421     }
422   }
423   return back;
424 }
425 
426 
427 
428 dkChar const *
dk3opt_get_short_arg(dk3_option_set_t const * optset,dkChar shortopt)429 dk3opt_get_short_arg(
430   dk3_option_set_t const	*optset,
431   dkChar			 shortopt
432 )
433 {
434   dkChar const	*back = NULL;
435   size_t	 i;
436 
437   if(optset) {
438     if(dk3opt_find_index_short(optset, shortopt, &i)) {
439       if(optset->options) {
440         if(((optset->options)[i]).na) {
441 	  if(optset->optargs) {
442 	    back = (optset->optargs)[i];
443 	  }
444 	}
445       }
446     }
447   }
448   return back;
449 }
450 
451 
452 
453 dkChar const *
dk3opt_get_long_arg(dk3_option_set_t const * optset,dkChar const * longopt)454 dk3opt_get_long_arg(
455   dk3_option_set_t const	*optset,
456   dkChar const			*longopt
457 )
458 {
459   dkChar const	*back = NULL;
460   size_t	 i;
461 
462   if((optset) && (longopt)) {
463     if(dk3opt_find_index_long(optset, longopt, &i)) {
464       if(optset->options) {
465         if(((optset->options)[i]).na) {
466 	  if(optset->optargs) {
467 	    back = (optset->optargs)[i];
468 	  }
469 	}
470       }
471     }
472   }
473   return back;
474 }
475 
476 
477 
478 int
dk3opt_get_num_args(dk3_option_set_t const * optset)479 dk3opt_get_num_args(
480   dk3_option_set_t const	*optset
481 )
482 {
483   int back = 0;
484 
485   if(optset) {
486     back = optset->argsused;
487   }
488   return back;
489 }
490 
491 
492 
493 dkChar const *
dk3opt_get_arg(dk3_option_set_t const * optset,int num)494 dk3opt_get_arg(
495   dk3_option_set_t const	*optset,
496   int				 num
497 )
498 {
499   dkChar const *back	= NULL;
500 
501   if((optset) && (num >= 0)) {
502     if(num < optset->argsused) {
503       if(optset->args) {
504         back = (optset->args)[num];
505       }
506     }
507   }
508   return back;
509 }
510 
511 
512 
513 int
dk3opt_get_num_fo(dk3_option_set_t const * os)514 dk3opt_get_num_fo(
515   dk3_option_set_t const	*os
516 )
517 {
518   int back = 0;
519 
520   if(os) {
521     back = os->fou;
522   }
523   return  back;
524 }
525 
526 
527 
528 dkChar const *
dk3opt_get_fo(dk3_option_set_t const * os,int num)529 dk3opt_get_fo(
530   dk3_option_set_t const *os,
531   int			  num
532 )
533 {
534   dkChar const *back = NULL;
535 
536   if((os) && (num >= 0)) {
537     if(num < os->fou) {
538       if(os->fo) {
539         back = (os->fo)[num];
540       }
541     }
542   }
543   return back;
544 }
545 
546 
547 
548 void
dk3opt_close(dk3_option_set_t * os)549 dk3opt_close(
550   dk3_option_set_t *os
551 )
552 {
553   int		i;
554   size_t	j;
555 
556   if(os) {
557     if(os->optargs) {
558       for(j = 0; j < os->szoptions; j++) { (os->optargs)[j] = NULL; }
559 
560       dk3_delete(os->optargs);
561 
562     } os->optargs = NULL;
563     if(os->found) {
564       for(j = 0; j < os->szoptions; j++) { (os->found)[j] = 0;}
565 
566       dk3_delete(os->found);
567 
568     } os->found = NULL;
569     if(os->args) {
570       for(i = 0; i < os->argsav; i++) { (os->args)[i] = NULL; }
571 
572       dk3_delete(os->args);
573 
574     } os->args = NULL;
575     if(os->fo) {
576       for(i = 0; i < os->foav; i++) { (os->fo)[i] = NULL; }
577 
578       dk3_delete(os->fo);
579 
580     } os->fo = NULL;
581     os->options = NULL;
582     os->szoptions = 0;
583     os->argsav = os->argsused = 0;
584     os->foav = os->fou = 0;
585     os->ec = 0;
586     os->focl = NULL;
587     os->foc = dkT('\0');
588 
589     dk3_delete(os);
590 
591   }
592 }
593 
594 
595 
596 int
dk3opt_get_error_code(dk3_option_set_t const * os)597 dk3opt_get_error_code(dk3_option_set_t const *os)
598 {
599   int back = 0;
600   if(os) {
601     back = os->ec;
602   }
603   return back;
604 }
605 
606 
607 void
dk3opt_reset_error_code(dk3_option_set_t * os)608 dk3opt_reset_error_code(dk3_option_set_t *os)
609 {
610   if(os) {
611     os->ec = 0;
612   }
613 }
614 
615 
616 
617 /* vim: set ai sw=2 : */
618 
619