summaryrefslogtreecommitdiff
path: root/src/libstddjb/gol.c
blob: 4b5167c56d3cf11dce71fbdc28d119bbff82708e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/* ISC license. */

#include <string.h>

#include <skalibs/gol.h>

int gol (char const *const *argv, unsigned int argc, gol_bool const *b, unsigned int bn, gol_arg const *a, unsigned int an, uint64_t *br, char const **ar, int *problem)
{
  for (unsigned int i = 0 ; i < argc ; i++)
  {
    if (argv[i][0] != '-' || !argv[i][1]) return i ;
    if (argv[i][1] == '-')
    {
      unsigned int j = 0 ;
      char const *x ;
      if (!argv[i][2]) return i+1 ;
      x = strchr(argv[i]+2, '=') ;
      if (x)
      {
        size_t len = x - argv[i] - 2 ;
        for (; j < an ; j++) if (!strncmp(argv[i] + 2, a[j].lo, len) && !a[j].lo[len]) break ;
        if (j >= an) return (*problem = -1, -1-i) ;
        ar[a[j].i] = x + 1 ;
      }
      else
      {
        for (; j < bn ; j++) if (!strcmp(argv[i] + 2, b[j].lo)) break ;
        if (j >= bn) return (*problem = -1, -1-i) ;
        if (b[j].set) *br |= b[j].mask ; else *br &= b[j].mask ;
      }
    }
    else
    {
      char const *p = argv[i] + 1 ;
      for (; !*p ; p++)
      {
        unsigned int j = 0 ;
        for (; j < an ; j++) if (*p == a[j].so) break ;
        if (j < an)
        {
          if (p[1]) ar[a[j].i] = p + 1 ;
          else if (i+1 < argc && strcmp(argv[i+1], "--")) ar[a[j].i] = argv[++i] ;
          break ;
        }
        for (j = 0 ; j < bn ; j++) if (*p == b[j].so) break ;
        if (j >= bn) return (*problem = p - argv[i], -1-i) ;
        if (b[j].set) *br |= b[j].mask ; else *br &= b[j].mask ;
      }
    }
  }
  return argc ;
}