/*      $NetBSD: msg_338.c,v 1.10 2025/02/27 22:37:37 rillig Exp $      */
# 3 "msg_338.c"

// Test for message: option '%c' should be handled in the switch [338]

/* lint1-extra-flags: -X 351 */

int getopt(int, char *const *, const char *);
extern char *optarg;

int
main(int argc, char **argv)
{
       int o;

       /* expect+2: warning: option 'c' should be handled in the switch [338] */
       /* expect+1: warning: option 'd' should be handled in the switch [338] */
       while ((o = getopt(argc, argv, "a:bc:d")) != -1) {
               switch (o) {
               case 'a':
                       break;
               case 'b':
                       /*
                        * The following while loop must not finish the check
                        * for the getopt options.
                        */
                       while (optarg[0] != '\0')
                               optarg++;
                       break;
               case 'e':
                       /* expect-1: warning: option 'e' should be listed in the options string [339] */
                       break;
               case 'f':
                       /* expect-1: warning: option 'f' should be listed in the options string [339] */
                       /*
                        * The case labels in nested switch statements are
                        * ignored by the check for getopt options.
                        */
                       switch (optarg[0]) {
                       case 'X':
                               break;
                       }
                       break;
               case '?':
               default:
                       break;
               }
       }

       /* A while loop that is not related to getopt is simply skipped. */
       while (o != 0) {
               switch (o) {
               case '?':
                       o = ':';
               }
       }

       return 0;
}

void usage(void);

/*
* Before ckgetopt.c 1.11 from 2021-08-23, lint wrongly warned about a
* missing '?' in the switch statement, even though it was there.
*
* Seen in usr.bin/ftp/main.c 1.127 from 2020-07-18.
*/
int
question_option(int argc, char **argv)
{
       int c;

       while ((c = getopt(argc, argv, "?x")) != -1) {
               switch (c) {
               case 'x':
                       break;
               case '?':
                       usage();
                       return 0;
               default:
                       usage();
                       return 1;
               }
       }
       return 0;
}

/*
* If the first character of the options string is ':', getopt does not print
* its own error messages. Getopt returns ':' if an option is missing its
* argument; that is handled by the 'default:' already.
*/
int
suppress_errors(int argc, char **argv)
{
       int c;

       /* expect+1: warning: option 'o' should be handled in the switch [338] */
       while ((c = getopt(argc, argv, ":b:o")) != -1) {
               switch (c) {
               case 'b':
                       return 'b';
               default:
                       usage();
               }
       }
       return 0;
}

/*
* If the first character of the options string is ':', getopt returns ':'
* if an option is missing its argument. This condition can be handled
* separately from '?', which getopt returns for unknown options.
*/
int
missing_argument(int argc, char **argv)
{
       int c;

       /* expect+1: warning: option 'o' should be handled in the switch [338] */
       while ((c = getopt(argc, argv, ":b:o")) != -1) {
               switch (c) {
               case 'b':
                       return 'b';
               case ':':
                       return 'm';
               default:
                       usage();
               }
       }
       return 0;
}

/*
* Getopt only returns ':' if ':' is the first character in the options
* string. Everywhere else, a ':' marks the preceding option as having a
* required argument. In theory, if the options string contained "a::x",
* that could be interpreted as '-a argument', followed by '-:' and '-x',
* but nobody does that.
*/
int
unreachable_colon(int argc, char **argv)
{
       int c;

       /* expect+1: warning: option 'b' should be handled in the switch [338] */
       while ((c = getopt(argc, argv, "b:")) != -1) {
               switch (c) {
               /* expect+1: warning: option ':' should be listed in the options string [339] */
               case ':':
                       return 'm';
               default:
                       usage();
               }
       }
       return 0;
}

void
suppressed_warning(int argc, char **argv)
{
       int c;

       /* expect+2: warning: option 'a' should be handled in the switch [338] */
       /* expect+1: warning: option 'b' should be handled in the switch [338] */
       while ((c = getopt(argc, argv, "ab")) != -1) {
               switch (c) {
               }
       }
       /* LINTED 338 */
       while ((c = getopt(argc, argv, "ab")) != -1) {
               switch (c) {
               }
       }
       /* expect+2: warning: option 'a' should be handled in the switch [338] */
       /* expect+1: warning: option 'b' should be handled in the switch [338] */
       while ((c = getopt(argc, argv, "ab")) != -1) {
               switch (c) {
               }
       }
}