/* $NetBSD: lsym_case_label.c,v 1.11 2023/06/15 09:19:07 rillig Exp $ */

/*
* Tests for the tokens lsym_case and lsym_default, which represent the
* keywords 'case' and 'default', which are both used in 'switch' statements.
*
* Since C11, the keyword 'default' is used in _Generic selections as well.
*
* See also:
*      opt_cli.c
*      psym_switch_expr.c
*      C11 6.5.1.1             "Generic selection"
*/

/*
* A case label can be used in a 'switch' statement.
*/
//indent input
void function(void){switch(expr){case 1:;case 2:break;default:switch(inner){case 4:break;}}}
//indent end

//indent run
void
function(void)
{
       switch (expr) {
       case 1: ;
       case 2:
               break;
       default:
               switch (inner) {
               case 4:
                       break;
               }
       }
}
//indent end


/*
* If there is a '{' after a case label, it gets indented using tabs instead
* of spaces. Indent does not necessarily insert a space in this situation,
* which looks strange.
*/
//indent input
void
function(void)
{
       switch (expr) {
       case 1: {
               break;
       }
       case 11: {
               break;
       }
       }
}
//indent end

//indent run
void
function(void)
{
       switch (expr) {
       /* $ The space between the ':' and the '{' is actually a tab. */
       case 1: {
                       break;
               }
       case 11: {
                       break;
               }
       }
}
//indent end


/*
* Since C11, the _Generic selection expression allows a switch on the data
* type of an expression.
*/
//indent input
const char *type_name = _Generic(
       ' ',
       int: "character constants have type 'int'",
       char: "character constants have type 'char'",
       default: "character constants have some other type"
);
//indent end

//indent run -di0
const char *type_name = _Generic(
// $ XXX: It's strange to align the arguments at the parenthesis even though
// $ XXX: the first argument is already on a separate line.
                                ' ',
// $ The indentation is so large that the strings would spill over the right
// $ margin.  To prevent that, the code is right-aligned.  Since the base
// $ indentation of this declaration is 0, the code might even start at the
// $ beginning of the line.
                                int: "character constants have type 'int'",
                              char: "character constants have type 'char'",
                        default: "character constants have some other type"
);
//indent end

//indent run-equals-input -di0 -nlp


/*
* Multi-line case expressions are rare but still should be processed in a
* sensible way.
*/
//indent input
{
       switch (expr) {
// $ FIXME: The line containing the 'case' must be indented like a 'case'.
               case 1
                   + 2
// $ FIXME: This continuation line must be indented by 4 columns.
       + 3:
               stmt;
       }
}
//indent end

//indent run-equals-input -ci4