summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/lib/getopt.c
blob: 93097122fd24b62ddb206164b2d583b0f410bf5f (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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "getopt.h"
#include <string.h>

/*
 * by Olaf Dreesen
 */

int opterr;

int optind=1;
char *optarg;

static int opt_unknown=1,opt_unknown_len;

static int getopt_check(int c,char*o,int ol)
{
  int i;
  if (c==':') return 2;
  for (i=0;i<ol;i++)
  {
    if (o[i]==c)
    {
      if (o[i+1]==':') return 1;
      return 0;
    }
  }
  return 2;
}

static void getopt_sort(char*v[],int oi)
{
  int i;
  char *tmp, *tmp2=0;

  if (opt_unknown_len)
  {
    tmp=v[optind-(1+oi)];
    if (oi) tmp2=v[optind-1];

    for (i=opt_unknown+opt_unknown_len;i>opt_unknown;i--) v[i+oi]=v[i-1];

    v[opt_unknown++]=tmp;
    if (oi) v[opt_unknown++]=tmp2;
  }
}

static char* nextchar;
int getopt(int c,char*v[],char*o)
{
  int ol=strlen(o);
  int ret=0;
  int oi=0;

  optarg=0;

  while (nextchar || (optind<c))
  {
    if (nextchar)
    {
      if ((ret=(*(++nextchar))))
      {
	switch (getopt_check(ret,o,ol))
	{
	case 1:
	  if (*(++nextchar))
	    optarg=nextchar;
	  else
	  {
	    if (optind<c)
	    {
	      oi=1;
	      optarg=v[optind++];
	    }
	    else
	      ret='?';
	  }
	  nextchar=0;
	case 0:
	  if (!nextchar)
	    getopt_sort(v,oi);
	  else
	    if (!(*(nextchar+1)))
	      getopt_sort(v,oi);
	  return ret;
	  break;
	default:
	  return '?';
	  break;
	}
      }
      else
	nextchar=0;
    }
    else
    {
      if ((v[optind][0]=='-')&&((v[optind][1]!=0)))
      {
	if ((v[optind][1]=='-')&&(v[optind][2]==0))
	{
	  getopt_sort(v,oi);
	  optind=opt_unknown;
	  return -1;
	}
	else
	{
	  nextchar=v[optind];
	}
      }
      else
      {
	++opt_unknown_len;
      }
      ++optind;
    }
  }
  optind=opt_unknown;
  return -1;
}