source: libcaca/trunk/src/mygetopt.c @ 4333

Last change on this file since 4333 was 4333, checked in by Sam Hocevar, 10 years ago

Large source code cleanup, getting rid of spaces, tabs, and svn keywords.

File size: 2.8 KB
Line 
1/*
2 *  zzuf - general purpose fuzzer
3 *  Copyright (c) 2002, 2007 Sam Hocevar <sam@hocevar.net>
4 *                All Rights Reserved
5 *
6 *  This program is free software. It comes without any warranty, to
7 *  the extent permitted by applicable law. You can redistribute it
8 *  and/or modify it under the terms of the Do What The Fuck You Want
9 *  To Public License, Version 2, as published by Sam Hocevar. See
10 *  http://sam.zoy.org/wtfpl/COPYING for more details.
11 */
12
13/*
14 *  mygetopt.c: getopt_long reimplementation
15 */
16
17#include "config.h"
18
19#include <stdio.h>
20#include <string.h>
21
22#include "caca_types.h"
23
24#include "mygetopt.h"
25
26int   myoptind = 1;
27char *myoptarg = NULL;
28
29/* XXX: this getopt_long implementation should not be trusted for other
30 * applications without any serious peer reviewing. It “just works” with
31 * zzuf but may fail miserably in other programs. */
32int mygetopt(int argc, char * const _argv[], const char *optstring,
33             const struct myoption *longopts, int *longindex)
34{
35    char **argv = (char **)(uintptr_t)_argv;
36    char *flag;
37    int i;
38
39    if(myoptind >= argc)
40        return -1;
41
42    flag = argv[myoptind];
43
44    if(flag[0] == '-' && flag[1] != '-')
45    {
46        char *tmp;
47        int ret = flag[1];
48
49        if(ret == '\0')
50            return -1;
51
52        tmp = strchr(optstring, ret);
53        if(!tmp || ret == ':')
54            return '?';
55
56        myoptind++;
57        if(tmp[1] == ':')
58        {
59            if(flag[2] != '\0')
60                myoptarg = flag + 2;
61            else
62                myoptarg = argv[myoptind++];
63            return ret;
64        }
65
66        if(flag[2] != '\0')
67        {
68            flag[1] = '-';
69            myoptind--;
70            argv[myoptind]++;
71        }
72
73        return ret;
74    }
75
76    if(flag[0] == '-' && flag[1] == '-')
77    {
78        if(flag[2] == '\0')
79            return -1;
80
81        for(i = 0; longopts[i].name; i++)
82        {
83            size_t l = strlen(longopts[i].name);
84
85            if(strncmp(flag + 2, longopts[i].name, l))
86                continue;
87
88            switch(flag[2 + l])
89            {
90            case '=':
91                if(!longopts[i].has_arg)
92                    goto bad_opt;
93                if(longindex)
94                    *longindex = i;
95                myoptind++;
96                myoptarg = flag + 2 + l + 1;
97                return longopts[i].val;
98            case '\0':
99                if(longindex)
100                    *longindex = i;
101                myoptind++;
102                if(longopts[i].has_arg)
103                    myoptarg = argv[myoptind++];
104                return longopts[i].val;
105            default:
106                break;
107            }
108        }
109    bad_opt:
110        fprintf(stderr, "%s: unrecognized option `%s'\n", argv[0], flag);
111        return '?';
112    }
113
114    return -1;
115}
116
Note: See TracBrowser for help on using the repository browser.