Linux Audio

Check our new training course

Loading...
   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
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef SHELL_H__
#define SHELL_H__

#include <zephyr/kernel.h>
#include <zephyr/shell/shell_types.h>
#include <zephyr/shell/shell_history.h>
#include <zephyr/shell/shell_fprintf.h>
#include <zephyr/shell/shell_log_backend.h>
#include <zephyr/shell/shell_string_conv.h>
#include <zephyr/logging/log_instance.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>

#if defined CONFIG_SHELL_GETOPT
#include <getopt.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifndef CONFIG_SHELL_CMD_BUFF_SIZE
#define CONFIG_SHELL_CMD_BUFF_SIZE 0
#endif

#ifndef CONFIG_SHELL_PRINTF_BUFF_SIZE
#define CONFIG_SHELL_PRINTF_BUFF_SIZE 0
#endif

#ifndef CONFIG_SHELL_HISTORY_BUFFER
#define CONFIG_SHELL_HISTORY_BUFFER 0
#endif

#define Z_SHELL_CMD_ROOT_LVL		(0u)

#define SHELL_HEXDUMP_BYTES_IN_LINE	16

/**
 * @brief Flag indicates that optional arguments will be treated as one,
 *	  unformatted argument.
 *
 * By default, shell is parsing all arguments, treats all spaces as argument
 * separators unless they are within quotation marks which are removed in that
 * case. If command rely on unformatted argument then this flag shall be used
 * in place of number of optional arguments in command definition to indicate
 * that only mandatory arguments shall be parsed and remaining command string is
 * passed as a raw string.
 */
#define SHELL_OPT_ARG_RAW	(0xFE)

/**
 * @brief Flag indicating that number of optional arguments is not limited.
 */
#define SHELL_OPT_ARG_CHECK_SKIP (0xFF)

/**
 * @brief Flag indicating maximum number of optional arguments that can be
 *	  validated.
 */
#define SHELL_OPT_ARG_MAX		(0xFD)

/**
 * @brief Shell API
 * @defgroup shell_api Shell API
 * @ingroup shell
 * @{
 */

struct shell_static_entry;

/**
 * @brief Shell dynamic command descriptor.
 *
 * @details Function shall fill the received shell_static_entry structure
 * with requested (idx) dynamic subcommand data. If there is more than
 * one dynamic subcommand available, the function shall ensure that the
 * returned commands: entry->syntax are sorted in alphabetical order.
 * If idx exceeds the available dynamic subcommands, the function must
 * write to entry->syntax NULL value. This will indicate to the shell
 * module that there are no more dynamic commands to read.
 */
typedef void (*shell_dynamic_get)(size_t idx,
				  struct shell_static_entry *entry);

/**
 * @brief Shell command descriptor.
 */
union shell_cmd_entry {
	/*!< Pointer to function returning dynamic commands.*/
	shell_dynamic_get dynamic_get;

	/*!< Pointer to array of static commands. */
	const struct shell_static_entry *entry;
};

struct shell;

struct shell_static_args {
	uint8_t mandatory; /*!< Number of mandatory arguments. */
	uint8_t optional;  /*!< Number of optional arguments. */
};

/**
 * @brief Get by index a device that matches .
 *
 * This can be used, for example, to identify I2C_1 as the second I2C
 * device.
 *
 * Devices that failed to initialize or do not have a non-empty name
 * are excluded from the candidates for a match.
 *
 * @param idx the device number starting from zero.
 *
 * @param prefix optional name prefix used to restrict candidate
 * devices.  Indexing is done relative to devices with names that
 * start with this text.  Pass null if no prefix match is required.
 */
const struct device *shell_device_lookup(size_t idx,
				   const char *prefix);

/**
 * @brief Shell command handler prototype.
 *
 * @param shell Shell instance.
 * @param argc  Arguments count.
 * @param argv  Arguments.
 *
 * @retval 0 Successful command execution.
 * @retval 1 Help printed and command not executed.
 * @retval -EINVAL Argument validation failed.
 * @retval -ENOEXEC Command not executed.
 */
typedef int (*shell_cmd_handler)(const struct shell *shell,
				 size_t argc, char **argv);

/**
 * @brief Shell dictionary command handler prototype.
 *
 * @param shell Shell instance.
 * @param argc  Arguments count.
 * @param argv  Arguments.
 * @param data  Pointer to the user data.
 *
 * @retval 0 Successful command execution.
 * @retval 1 Help printed and command not executed.
 * @retval -EINVAL Argument validation failed.
 * @retval -ENOEXEC Command not executed.
 */
typedef int (*shell_dict_cmd_handler)(const struct shell *shell, size_t argc,
				      char **argv, void *data);

/* When entries are added to the memory section a padding is applied for
 * native_posix_64 and x86_64 targets. Adding padding to allow handle data
 * in the memory section as array.
 */
#if (defined(CONFIG_ARCH_POSIX) && defined(CONFIG_64BIT)) || defined(CONFIG_X86_64)
#define Z_SHELL_STATIC_ENTRY_PADDING 24
#else
#define Z_SHELL_STATIC_ENTRY_PADDING 0
#endif

/*
 * @brief Shell static command descriptor.
 */
struct shell_static_entry {
	const char *syntax;			/*!< Command syntax strings. */
	const char *help;			/*!< Command help string. */
	const union shell_cmd_entry *subcmd;	/*!< Pointer to subcommand. */
	shell_cmd_handler handler;		/*!< Command handler. */
	struct shell_static_args args;		/*!< Command arguments. */
	uint8_t padding[Z_SHELL_STATIC_ENTRY_PADDING];
};

/**
 * @brief Macro for defining and adding a root command (level 0) with required
 * number of arguments.
 *
 * @note Each root command shall have unique syntax. If a command will be called
 * with wrong number of arguments shell will print an error message and command
 * handler will not be called.
 *
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
 * @param[in] mandatory	Number of mandatory arguments including command name.
 * @param[in] optional	Number of optional arguments.
 */
#define SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler,		   \
			       mandatory, optional)			   \
	static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
	SHELL_CMD_ARG(syntax, subcmd, help, handler, mandatory, optional); \
	static const union shell_cmd_entry UTIL_CAT(shell_cmd_, syntax)    \
	__attribute__ ((section("."					   \
			STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax)))))	   \
	__attribute__((used)) = {					   \
		.entry = &UTIL_CAT(_shell_, syntax)			   \
	}

/**
 * @brief Macro for defining and adding a conditional root command (level 0)
 * with required number of arguments.
 *
 * @see SHELL_CMD_ARG_REGISTER for details.
 *
 * Macro can be used to create a command which can be conditionally present.
 * It is and alternative to \#ifdefs around command registration and command
 * handler. If command is disabled handler and subcommands are removed from
 * the application.
 *
 * @param[in] flag	Compile time flag. Command is present only if flag
 *			exists and equals 1.
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
 * @param[in] mandatory	Number of mandatory arguments including command name.
 * @param[in] optional	Number of optional arguments.
 */
#define SHELL_COND_CMD_ARG_REGISTER(flag, syntax, subcmd, help, handler, \
					mandatory, optional) \
	COND_CODE_1(\
		flag, \
		(\
		SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, \
					mandatory, optional) \
		), \
		(\
		static shell_cmd_handler dummy_##syntax##_handler __unused = \
								handler;\
		static const union shell_cmd_entry *dummy_subcmd_##syntax \
			__unused = subcmd\
		) \
	)
/**
 * @brief Macro for defining and adding a root command (level 0) with
 * arguments.
 *
 * @note All root commands must have different name.
 *
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
 */
#define SHELL_CMD_REGISTER(syntax, subcmd, help, handler) \
	SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, 0, 0)

/**
 * @brief Macro for defining and adding a conditional root command (level 0)
 * with arguments.
 *
 * @see SHELL_COND_CMD_ARG_REGISTER.
 *
 * @param[in] flag	Compile time flag. Command is present only if flag
 *			exists and equals 1.
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
 */
#define SHELL_COND_CMD_REGISTER(flag, syntax, subcmd, help, handler) \
	SHELL_COND_CMD_ARG_REGISTER(flag, syntax, subcmd, help, handler, 0, 0)

/**
 * @brief Macro for creating a subcommand set. It must be used outside of any
 * function body.
 *
 * Example usage:
 * SHELL_STATIC_SUBCMD_SET_CREATE(
 *	foo,
 *	SHELL_CMD(abc, ...),
 *	SHELL_CMD(def, ...),
 *	SHELL_SUBCMD_SET_END
 * )
 *
 * @param[in] name	Name of the subcommand set.
 * @param[in] ...	List of commands created with @ref SHELL_CMD_ARG or
 *			or @ref SHELL_CMD
 */
#define SHELL_STATIC_SUBCMD_SET_CREATE(name, ...)			\
	static const struct shell_static_entry shell_##name[] = {	\
		__VA_ARGS__						\
	};								\
	static const union shell_cmd_entry name = {			\
		.entry = shell_##name					\
	}

#define Z_SHELL_UNDERSCORE(x) _##x
#define Z_SHELL_SUBCMD_NAME(...) \
	UTIL_CAT(shell_subcmd, MACRO_MAP_CAT(Z_SHELL_UNDERSCORE, __VA_ARGS__))

/** @brief Create set of subcommands.
 *
 * Commands to this set are added using @ref SHELL_SUBCMD_ADD and @ref SHELL_SUBCMD_COND_ADD.
 * Commands can be added from multiple files.
 *
 * @param[in] _name		Name of the set. @p _name is used to refer the set in the parent
 * command.
 *
 * @param[in] _parent	Set of comma separated parent commands in parenthesis, e.g.
 * (foo_cmd) if subcommands are for the root command "foo_cmd".
 */
#define SHELL_SUBCMD_SET_CREATE(_name, _parent)					\
	static const struct shell_static_entry _name				\
	__attribute__ ((section("."						\
			STRINGIFY(Z_SHELL_SUBCMD_NAME(NUM_VA_ARGS_LESS_1 _parent, \
					__DEBRACKET _parent)))))		\
	__attribute__((used))

/** @brief Conditionally add command to the set of subcommands.
 *
 * Add command to the set created with @ref SHELL_SUBCMD_SET_CREATE.
 *
 * @note The name of the section is formed as concatenation of number of parent
 * commands, names of all parent commands and own syntax. Number of parent commands
 * is added to ensure that section prefix is unique. Without it subcommands of
 * (foo) and (foo, cmd1) would mix.
 *
 * @param[in] _flag	 Compile time flag. Command is present only if flag
 *			 exists and equals 1.
 * @param[in] _parent	 Parent command sequence. Comma separated in parenthesis.
 * @param[in] _syntax	 Command syntax (for example: history).
 * @param[in] _subcmd	 Pointer to a subcommands array.
 * @param[in] _help	 Pointer to a command help string.
 * @param[in] _handler	 Pointer to a function handler.
 * @param[in] _mand	 Number of mandatory arguments including command name.
 * @param[in] _opt	 Number of optional arguments.
 */
#define SHELL_SUBCMD_COND_ADD(_flag, _parent, _syntax, _subcmd, _help, _handler, \
			   _mand, _opt) \
	COND_CODE_1(_flag, \
		(static const struct shell_static_entry \
		   Z_SHELL_SUBCMD_NAME(__DEBRACKET _parent, _syntax)\
		   __attribute__ ((section("."						\
			STRINGIFY(Z_SHELL_SUBCMD_NAME(NUM_VA_ARGS_LESS_1 _parent, \
				  __DEBRACKET _parent, _syntax)))))	\
		   __attribute__((used)) = \
			SHELL_EXPR_CMD_ARG(1, _syntax, _subcmd, _help, \
					   _handler, _mand, _opt)\
		), \
		(static shell_cmd_handler dummy_##syntax##_handler __unused = _handler;\
		 static const union shell_cmd_entry dummy_subcmd_##syntax __unused = { \
			.entry = (const struct shell_static_entry *)_subcmd\
		 } \
		) \
	)

/** @brief Add command to the set of subcommands.
 *
 * Add command to the set created with @ref SHELL_SUBCMD_SET_CREATE.
 *
 * @param[in] _parent	 Parent command sequence. Comma separated in parenthesis.
 * @param[in] _syntax	 Command syntax (for example: history).
 * @param[in] _subcmd	 Pointer to a subcommands array.
 * @param[in] _help	 Pointer to a command help string.
 * @param[in] _handler	 Pointer to a function handler.
 * @param[in] _mand	 Number of mandatory arguments including command name.
 * @param[in] _opt	 Number of optional arguments.
 */
#define SHELL_SUBCMD_ADD(_parent, _syntax, _subcmd, _help, _handler, _mand, _opt) \
	SHELL_SUBCMD_COND_ADD(1, _parent, _syntax, _subcmd, _help, _handler, _mand, _opt)

/**
 * @brief Define ending subcommands set.
 *
 */
#define SHELL_SUBCMD_SET_END {NULL}

/**
 * @brief Macro for creating a dynamic entry.
 *
 * @param[in] name	Name of the dynamic entry.
 * @param[in] get	Pointer to the function returning dynamic commands array
 */
#define SHELL_DYNAMIC_CMD_CREATE(name, get)					\
	static const union shell_cmd_entry name					\
	__attribute__ ((section("."						\
			STRINGIFY(UTIL_CAT(shell_dynamic_subcmd_, syntax)))))	\
	__attribute__((used)) = {						\
		.dynamic_get = get						\
	}

/**
 * @brief Initializes a shell command with arguments.
 *
 * @note If a command will be called with wrong number of arguments shell will
 * print an error message and command handler will not be called.
 *
 * @param[in] syntax	 Command syntax (for example: history).
 * @param[in] subcmd	 Pointer to a subcommands array.
 * @param[in] help	 Pointer to a command help string.
 * @param[in] handler	 Pointer to a function handler.
 * @param[in] mand	 Number of mandatory arguments including command name.
 * @param[in] opt	 Number of optional arguments.
 */
#define SHELL_CMD_ARG(syntax, subcmd, help, handler, mand, opt) \
	SHELL_EXPR_CMD_ARG(1, syntax, subcmd, help, handler, mand, opt)

/**
 * @brief Initializes a conditional shell command with arguments.
 *
 * @see SHELL_CMD_ARG. Based on the flag, creates a valid entry or an empty
 * command which is ignored by the shell. It is an alternative to \#ifdefs
 * around command registration and command handler. However, empty structure is
 * present in the flash even if command is disabled (subcommands and handler are
 * removed). Macro internally handles case if flag is not defined so flag must
 * be provided without any wrapper, e.g.: SHELL_COND_CMD_ARG(CONFIG_FOO, ...)
 *
 * @param[in] flag	 Compile time flag. Command is present only if flag
 *			 exists and equals 1.
 * @param[in] syntax	 Command syntax (for example: history).
 * @param[in] subcmd	 Pointer to a subcommands array.
 * @param[in] help	 Pointer to a command help string.
 * @param[in] handler	 Pointer to a function handler.
 * @param[in] mand	 Number of mandatory arguments including command name.
 * @param[in] opt	 Number of optional arguments.
 */
#define SHELL_COND_CMD_ARG(flag, syntax, subcmd, help, handler, mand, opt) \
	SHELL_EXPR_CMD_ARG(IS_ENABLED(flag), syntax, subcmd, help, \
			  handler, mand, opt)

/**
 * @brief Initializes a conditional shell command with arguments if expression
 *	  gives non-zero result at compile time.
 *
 * @see SHELL_CMD_ARG. Based on the expression, creates a valid entry or an
 * empty command which is ignored by the shell. It should be used instead of
 * @ref SHELL_COND_CMD_ARG if condition is not a single configuration flag,
 * e.g.:
 * SHELL_EXPR_CMD_ARG(IS_ENABLED(CONFIG_FOO) &&
 *		      IS_ENABLED(CONFIG_FOO_SETTING_1), ...)
 *
 * @param[in] _expr	 Expression.
 * @param[in] _syntax	 Command syntax (for example: history).
 * @param[in] _subcmd	 Pointer to a subcommands array.
 * @param[in] _help	 Pointer to a command help string.
 * @param[in] _handler	 Pointer to a function handler.
 * @param[in] _mand	 Number of mandatory arguments including command name.
 * @param[in] _opt	 Number of optional arguments.
 */
#define SHELL_EXPR_CMD_ARG(_expr, _syntax, _subcmd, _help, _handler, \
			   _mand, _opt) \
	{ \
		.syntax = (_expr) ? (const char *)STRINGIFY(_syntax) : "", \
		.help  = (_expr) ? (const char *)_help : NULL, \
		.subcmd = (const union shell_cmd_entry *)((_expr) ? \
				_subcmd : NULL), \
		.handler = (shell_cmd_handler)((_expr) ? _handler : NULL), \
		.args = { .mandatory = _mand, .optional = _opt} \
	}

/**
 * @brief Initializes a shell command.
 *
 * @param[in] _syntax	Command syntax (for example: history).
 * @param[in] _subcmd	Pointer to a subcommands array.
 * @param[in] _help	Pointer to a command help string.
 * @param[in] _handler	Pointer to a function handler.
 */
#define SHELL_CMD(_syntax, _subcmd, _help, _handler) \
	SHELL_CMD_ARG(_syntax, _subcmd, _help, _handler, 0, 0)

/**
 * @brief Initializes a conditional shell command.
 *
 * @see SHELL_COND_CMD_ARG.
 *
 * @param[in] _flag	Compile time flag. Command is present only if flag
 *			exists and equals 1.
 * @param[in] _syntax	Command syntax (for example: history).
 * @param[in] _subcmd	Pointer to a subcommands array.
 * @param[in] _help	Pointer to a command help string.
 * @param[in] _handler	Pointer to a function handler.
 */
#define SHELL_COND_CMD(_flag, _syntax, _subcmd, _help, _handler) \
	SHELL_COND_CMD_ARG(_flag, _syntax, _subcmd, _help, _handler, 0, 0)

/**
 * @brief Initializes shell command if expression gives non-zero result at
 *	  compile time.
 *
 * @see SHELL_EXPR_CMD_ARG.
 *
 * @param[in] _expr	Compile time expression. Command is present only if
 *			expression is non-zero.
 * @param[in] _syntax	Command syntax (for example: history).
 * @param[in] _subcmd	Pointer to a subcommands array.
 * @param[in] _help	Pointer to a command help string.
 * @param[in] _handler	Pointer to a function handler.
 */
#define SHELL_EXPR_CMD(_expr, _syntax, _subcmd, _help, _handler) \
	SHELL_EXPR_CMD_ARG(_expr, _syntax, _subcmd, _help, _handler, 0, 0)

/* Internal macro used for creating handlers for dictionary commands. */
#define Z_SHELL_CMD_DICT_HANDLER_CREATE(_data, _handler)		\
static int UTIL_CAT(UTIL_CAT(cmd_dict_, UTIL_CAT(_handler, _)),		\
			GET_ARG_N(1, __DEBRACKET _data))(		\
		const struct shell *shell, size_t argc, char **argv)	\
{									\
	return _handler(shell, argc, argv,				\
			(void *)GET_ARG_N(2, __DEBRACKET _data));	\
}

/* Internal macro used for creating dictionary commands. */
#define SHELL_CMD_DICT_CREATE(_data, _handler)				\
	SHELL_CMD_ARG(GET_ARG_N(1, __DEBRACKET _data), NULL, NULL,	\
		UTIL_CAT(UTIL_CAT(cmd_dict_, UTIL_CAT(_handler, _)),	\
			GET_ARG_N(1, __DEBRACKET _data)), 1, 0)

/**
 * @brief Initializes shell dictionary commands.
 *
 * This is a special kind of static commands. Dictionary commands can be used
 * every time you want to use a pair: (string <-> corresponding data) in
 * a command handler. The string is usually a verbal description of a given
 * data. The idea is to use the string as a command syntax that can be prompted
 * by the shell and corresponding data can be used to process the command.
 *
 * @param[in] _name	Name of the dictionary subcommand set
 * @param[in] _handler	Command handler common for all dictionary commands.
 *			@see shell_dict_cmd_handler
 * @param[in] ...	Dictionary pairs: (command_syntax, value). Value will be
 *			passed to the _handler as user data.
 *
 * Example usage:
 *	static int my_handler(const struct shell *shell,
 *			      size_t argc, char **argv, void *data)
 *	{
 *		int val = (int)data;
 *
 *		shell_print(shell, "(syntax, value) : (%s, %d)", argv[0], val);
 *		return 0;
 *	}
 *
 *	SHELL_SUBCMD_DICT_SET_CREATE(sub_dict_cmds, my_handler,
 *		(value_0, 0), (value_1, 1), (value_2, 2), (value_3, 3)
 *	);
 *	SHELL_CMD_REGISTER(dictionary, &sub_dict_cmds, NULL, NULL);
 */
#define SHELL_SUBCMD_DICT_SET_CREATE(_name, _handler, ...)		\
	FOR_EACH_FIXED_ARG(Z_SHELL_CMD_DICT_HANDLER_CREATE, (),		\
			   _handler, __VA_ARGS__)			\
	SHELL_STATIC_SUBCMD_SET_CREATE(_name,				\
		FOR_EACH_FIXED_ARG(SHELL_CMD_DICT_CREATE, (,), _handler, __VA_ARGS__),	\
		SHELL_SUBCMD_SET_END					\
	)

/**
 * @internal @brief Internal shell state in response to data received from the
 * terminal.
 */
enum shell_receive_state {
	SHELL_RECEIVE_DEFAULT,
	SHELL_RECEIVE_ESC,
	SHELL_RECEIVE_ESC_SEQ,
	SHELL_RECEIVE_TILDE_EXP
};

/**
 * @internal @brief Internal shell state.
 */
enum shell_state {
	SHELL_STATE_UNINITIALIZED,
	SHELL_STATE_INITIALIZED,
	SHELL_STATE_ACTIVE,
	SHELL_STATE_PANIC_MODE_ACTIVE,  /*!< Panic activated.*/
	SHELL_STATE_PANIC_MODE_INACTIVE /*!< Panic requested, not supported.*/
};

/** @brief Shell transport event. */
enum shell_transport_evt {
	SHELL_TRANSPORT_EVT_RX_RDY,
	SHELL_TRANSPORT_EVT_TX_RDY
};

typedef void (*shell_transport_handler_t)(enum shell_transport_evt evt,
					  void *context);


typedef void (*shell_uninit_cb_t)(const struct shell *shell, int res);

/** @brief Bypass callback.
 *
 * @param shell Shell instance.
 * @param data  Raw data from transport.
 * @param len   Data length.
 */
typedef void (*shell_bypass_cb_t)(const struct shell *shell,
				  uint8_t *data,
				  size_t len);

struct shell_transport;

/**
 * @brief Unified shell transport interface.
 */
struct shell_transport_api {
	/**
	 * @brief Function for initializing the shell transport interface.
	 *
	 * @param[in] transport   Pointer to the transfer instance.
	 * @param[in] config      Pointer to instance configuration.
	 * @param[in] evt_handler Event handler.
	 * @param[in] context     Pointer to the context passed to event
	 *			  handler.
	 *
	 * @return Standard error code.
	 */
	int (*init)(const struct shell_transport *transport,
		    const void *config,
		    shell_transport_handler_t evt_handler,
		    void *context);

	/**
	 * @brief Function for uninitializing the shell transport interface.
	 *
	 * @param[in] transport  Pointer to the transfer instance.
	 *
	 * @return Standard error code.
	 */
	int (*uninit)(const struct shell_transport *transport);

	/**
	 * @brief Function for enabling transport in given TX mode.
	 *
	 * Function can be used to reconfigure TX to work in blocking mode.
	 *
	 * @param transport   Pointer to the transfer instance.
	 * @param blocking_tx If true, the transport TX is enabled in blocking
	 *		      mode.
	 *
	 * @return NRF_SUCCESS on successful enabling, error otherwise (also if
	 * not supported).
	 */
	int (*enable)(const struct shell_transport *transport,
		      bool blocking_tx);

	/**
	 * @brief Function for writing data to the transport interface.
	 *
	 * @param[in]  transport  Pointer to the transfer instance.
	 * @param[in]  data       Pointer to the source buffer.
	 * @param[in]  length     Source buffer length.
	 * @param[out] cnt        Pointer to the sent bytes counter.
	 *
	 * @return Standard error code.
	 */
	int (*write)(const struct shell_transport *transport,
		     const void *data, size_t length, size_t *cnt);

	/**
	 * @brief Function for reading data from the transport interface.
	 *
	 * @param[in]  p_transport  Pointer to the transfer instance.
	 * @param[in]  p_data       Pointer to the destination buffer.
	 * @param[in]  length       Destination buffer length.
	 * @param[out] cnt          Pointer to the received bytes counter.
	 *
	 * @return Standard error code.
	 */
	int (*read)(const struct shell_transport *transport,
		    void *data, size_t length, size_t *cnt);

	/**
	 * @brief Function called in shell thread loop.
	 *
	 * Can be used for backend operations that require longer execution time
	 *
	 * @param[in] transport Pointer to the transfer instance.
	 */
	void (*update)(const struct shell_transport *transport);

};

struct shell_transport {
	const struct shell_transport_api *api;
	void *ctx;
};

/**
 * @brief Shell statistics structure.
 */
struct shell_stats {
	atomic_t log_lost_cnt; /*!< Lost log counter.*/
};

#ifdef CONFIG_SHELL_STATS
#define Z_SHELL_STATS_DEFINE(_name) static struct shell_stats _name##_stats
#define Z_SHELL_STATS_PTR(_name) (&(_name##_stats))
#else
#define Z_SHELL_STATS_DEFINE(_name)
#define Z_SHELL_STATS_PTR(_name) NULL
#endif /* CONFIG_SHELL_STATS */

/**
 * @internal @brief Flags for shell backend configuration.
 */
struct shell_backend_config_flags {
	uint32_t insert_mode :1; /*!< Controls insert mode for text introduction */
	uint32_t echo        :1; /*!< Controls shell echo */
	uint32_t obscure     :1; /*!< If echo on, print asterisk instead */
	uint32_t mode_delete :1; /*!< Operation mode of backspace key */
	uint32_t use_colors  :1; /*!< Controls colored syntax */
	uint32_t use_vt100   :1; /*!< Controls VT100 commands usage in shell */
};

BUILD_ASSERT((sizeof(struct shell_backend_config_flags) == sizeof(uint32_t)),
	     "Structure must fit in 4 bytes");

/**
 * @internal @brief Default backend configuration.
 */
#define SHELL_DEFAULT_BACKEND_CONFIG_FLAGS				\
{									\
	.insert_mode	= 0,						\
	.echo		= 1,						\
	.obscure	= IS_ENABLED(CONFIG_SHELL_START_OBSCURED),	\
	.mode_delete	= 1,						\
	.use_colors	= 1,						\
	.use_vt100	= 1,						\
};

struct shell_backend_ctx_flags {
	uint32_t processing   :1; /*!< Shell is executing process function */
	uint32_t tx_rdy       :1;
	uint32_t history_exit :1; /*!< Request to exit history mode */
	uint32_t last_nl      :8; /*!< Last received new line character */
	uint32_t cmd_ctx      :1; /*!< Shell is executing command */
	uint32_t print_noinit :1; /*!< Print request from not initialized shell */
	uint32_t sync_mode    :1; /*!< Shell in synchronous mode */
};

BUILD_ASSERT((sizeof(struct shell_backend_ctx_flags) == sizeof(uint32_t)),
	     "Structure must fit in 4 bytes");

/**
 * @internal @brief Union for internal shell usage.
 */
union shell_backend_cfg {
	atomic_t value;
	struct shell_backend_config_flags flags;
};

/**
 * @internal @brief Union for internal shell usage.
 */
union shell_backend_ctx {
	uint32_t value;
	struct shell_backend_ctx_flags flags;
};

enum shell_signal {
	SHELL_SIGNAL_RXRDY,
	SHELL_SIGNAL_LOG_MSG,
	SHELL_SIGNAL_KILL,
	SHELL_SIGNAL_TXDONE, /* TXDONE must be last one before SHELL_SIGNALS */
	SHELL_SIGNALS
};

/**
 * @brief Shell instance context.
 */
struct shell_ctx {
	const char *prompt; /*!< shell current prompt. */

	enum shell_state state; /*!< Internal module state.*/
	enum shell_receive_state receive_state;/*!< Escape sequence indicator.*/

	/*!< Currently executed command.*/
	struct shell_static_entry active_cmd;

	/* New root command. If NULL shell uses default root commands. */
	const struct shell_static_entry *selected_cmd;

	/*!< VT100 color and cursor position, terminal width.*/
	struct shell_vt100_ctx vt100_ctx;

	/*!< Callback called from shell thread context when unitialization is
	 * completed just before aborting shell thread.
	 */
	shell_uninit_cb_t uninit_cb;

	/*!< When bypass is set, all incoming data is passed to the callback. */
	shell_bypass_cb_t bypass;

#if defined CONFIG_SHELL_GETOPT
	/*!< getopt context for a shell backend. */
	struct getopt_state getopt;
#endif

	uint16_t cmd_buff_len; /*!< Command length.*/
	uint16_t cmd_buff_pos; /*!< Command buffer cursor position.*/

	uint16_t cmd_tmp_buff_len; /*!< Command length in tmp buffer.*/

	/*!< Command input buffer.*/
	char cmd_buff[CONFIG_SHELL_CMD_BUFF_SIZE];

	/*!< Command temporary buffer.*/
	char temp_buff[CONFIG_SHELL_CMD_BUFF_SIZE];

	/*!< Printf buffer size.*/
	char printf_buff[CONFIG_SHELL_PRINTF_BUFF_SIZE];

	volatile union shell_backend_cfg cfg;
	volatile union shell_backend_ctx ctx;

	struct k_poll_signal signals[SHELL_SIGNALS];

	/*!< Events that should be used only internally by shell thread.
	 * Event for SHELL_SIGNAL_TXDONE is initialized but unused.
	 */
	struct k_poll_event events[SHELL_SIGNALS];

	struct k_mutex wr_mtx;
	k_tid_t tid;
};

extern const struct log_backend_api log_backend_shell_api;

/**
 * @brief Flags for setting shell output newline sequence.
 */
enum shell_flag {
	SHELL_FLAG_CRLF_DEFAULT	= (1<<0),	/* Do not map CR or LF */
	SHELL_FLAG_OLF_CRLF	= (1<<1)	/* Map LF to CRLF on output */
};

/**
 * @brief Shell instance internals.
 */
struct shell {
	const char *default_prompt; /*!< shell default prompt. */

	const struct shell_transport *iface; /*!< Transport interface.*/
	struct shell_ctx *ctx; /*!< Internal context.*/

	struct shell_history *history;

	const enum shell_flag shell_flag;

	const struct shell_fprintf *fprintf_ctx;

	struct shell_stats *stats;

	const struct shell_log_backend *log_backend;

	LOG_INSTANCE_PTR_DECLARE(log);

	const char *thread_name;
	struct k_thread *thread;
	k_thread_stack_t *stack;
};

extern void z_shell_print_stream(const void *user_ctx, const char *data,
				 size_t data_len);
/**
 * @brief Macro for defining a shell instance.
 *
 * @param[in] _name		Instance name.
 * @param[in] _prompt		Shell default prompt string.
 * @param[in] _transport_iface	Pointer to the transport interface.
 * @param[in] _log_queue_size	Logger processing queue size.
 * @param[in] _log_timeout	Logger thread timeout in milliseconds on full
 *				log queue. If queue is full logger thread is
 *				blocked for given amount of time before log
 *				message is dropped.
 * @param[in] _shell_flag	Shell output newline sequence.
 */
#define SHELL_DEFINE(_name, _prompt, _transport_iface,			      \
		     _log_queue_size, _log_timeout, _shell_flag)	      \
	static const struct shell _name;				      \
	static struct shell_ctx UTIL_CAT(_name, _ctx);			      \
	static uint8_t _name##_out_buffer[CONFIG_SHELL_PRINTF_BUFF_SIZE];     \
	Z_SHELL_LOG_BACKEND_DEFINE(_name, _name##_out_buffer,		      \
				 CONFIG_SHELL_PRINTF_BUFF_SIZE,		      \
				 _log_queue_size, _log_timeout);	      \
	Z_SHELL_HISTORY_DEFINE(_name##_history, CONFIG_SHELL_HISTORY_BUFFER); \
	Z_SHELL_FPRINTF_DEFINE(_name##_fprintf, &_name, _name##_out_buffer,   \
			     CONFIG_SHELL_PRINTF_BUFF_SIZE,		      \
			     true, z_shell_print_stream);		      \
	LOG_INSTANCE_REGISTER(shell, _name, CONFIG_SHELL_LOG_LEVEL);	      \
	Z_SHELL_STATS_DEFINE(_name);					      \
	static K_KERNEL_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE); \
	static struct k_thread _name##_thread;				      \
	static const STRUCT_SECTION_ITERABLE(shell, _name) = {		      \
		.default_prompt = _prompt,				      \
		.iface = _transport_iface,				      \
		.ctx = &UTIL_CAT(_name, _ctx),				      \
		.history = IS_ENABLED(CONFIG_SHELL_HISTORY) ?		      \
				&_name##_history : NULL,		      \
		.shell_flag = _shell_flag,				      \
		.fprintf_ctx = &_name##_fprintf,			      \
		.stats = Z_SHELL_STATS_PTR(_name),			      \
		.log_backend = Z_SHELL_LOG_BACKEND_PTR(_name),		      \
		LOG_INSTANCE_PTR_INIT(log, shell, _name)		      \
		.thread_name = STRINGIFY(_name),			      \
		.thread = &_name##_thread,				      \
		.stack = _name##_stack					      \
	}

/**
 * @brief Function for initializing a transport layer and internal shell state.
 *
 * @param[in] shell		Pointer to shell instance.
 * @param[in] transport_config	Transport configuration during initialization.
 * @param[in] cfg_flags		Initial backend configuration flags.
 *				Shell will copy this data.
 * @param[in] log_backend	If true, the console will be used as logger
 *				backend.
 * @param[in] init_log_level	Default severity level for the logger.
 *
 * @return Standard error code.
 */
int shell_init(const struct shell *shell, const void *transport_config,
	       struct shell_backend_config_flags cfg_flags,
	       bool log_backend, uint32_t init_log_level);

/**
 * @brief Uninitializes the transport layer and the internal shell state.
 *
 * @param shell Pointer to shell instance.
 * @param cb Callback called when uninitialization is completed.
 */
void shell_uninit(const struct shell *shell, shell_uninit_cb_t cb);

/**
 * @brief Function for starting shell processing.
 *
 * @param shell Pointer to the shell instance.
 *
 * @return Standard error code.
 */
int shell_start(const struct shell *shell);

/**
 * @brief Function for stopping shell processing.
 *
 * @param shell Pointer to shell instance.
 *
 * @return Standard error code.
 */
int shell_stop(const struct shell *shell);

/**
 * @brief Terminal default text color for shell_fprintf function.
 */
#define SHELL_NORMAL	SHELL_VT100_COLOR_DEFAULT

/**
 * @brief Green text color for shell_fprintf function.
 */
#define SHELL_INFO	SHELL_VT100_COLOR_GREEN

/**
 * @brief Cyan text color for shell_fprintf function.
 */
#define SHELL_OPTION	SHELL_VT100_COLOR_CYAN

/**
 * @brief Yellow text color for shell_fprintf function.
 */
#define SHELL_WARNING	SHELL_VT100_COLOR_YELLOW

/**
 * @brief Red text color for shell_fprintf function.
 */
#define SHELL_ERROR	SHELL_VT100_COLOR_RED

/**
 * @brief printf-like function which sends formatted data stream to the shell.
 *
 * This function can be used from the command handler or from threads, but not
 * from an interrupt context.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] color	Printed text color.
 * @param[in] fmt	Format string.
 * @param[in] ...	List of parameters to print.
 */
void __printf_like(3, 4) shell_fprintf(const struct shell *shell,
				       enum shell_vt100_color color,
				       const char *fmt, ...);

/**
 * @brief vprintf-like function which sends formatted data stream to the shell.
 *
 * This function can be used from the command handler or from threads, but not
 * from an interrupt context. It is similar to shell_fprintf() but takes a
 * va_list instead of variable arguments.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] color	Printed text color.
 * @param[in] fmt	Format string.
 * @param[in] args	List of parameters to print.
 */
void shell_vfprintf(const struct shell *shell, enum shell_vt100_color color,
		   const char *fmt, va_list args);

/**
 * @brief Print a line of data in hexadecimal format.
 *
 * Each line shows the offset, bytes and then ASCII representation.
 *
 * For example:
 *
 * 00008010: 20 25 00 20 2f 48 00 08  80 05 00 20 af 46 00
 *	| %. /H.. ... .F. |
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] offset	Offset to show for this line.
 * @param[in] data	Pointer to data.
 * @param[in] len	Length of data.
 */
void shell_hexdump_line(const struct shell *shell, unsigned int offset,
			const uint8_t *data, size_t len);

/**
 * @brief Print data in hexadecimal format.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] data	Pointer to data.
 * @param[in] len	Length of data.
 */
void shell_hexdump(const struct shell *shell, const uint8_t *data, size_t len);

/**
 * @brief Print info message to the shell.
 *
 * See @ref shell_fprintf.
 *
 * @param[in] _sh Pointer to the shell instance.
 * @param[in] _ft Format string.
 * @param[in] ... List of parameters to print.
 */
#define shell_info(_sh, _ft, ...) \
	shell_fprintf(_sh, SHELL_INFO, _ft "\n", ##__VA_ARGS__)

/**
 * @brief Print normal message to the shell.
 *
 * See @ref shell_fprintf.
 *
 * @param[in] _sh Pointer to the shell instance.
 * @param[in] _ft Format string.
 * @param[in] ... List of parameters to print.
 */
#define shell_print(_sh, _ft, ...) \
	shell_fprintf(_sh, SHELL_NORMAL, _ft "\n", ##__VA_ARGS__)

/**
 * @brief Print warning message to the shell.
 *
 * See @ref shell_fprintf.
 *
 * @param[in] _sh Pointer to the shell instance.
 * @param[in] _ft Format string.
 * @param[in] ... List of parameters to print.
 */
#define shell_warn(_sh, _ft, ...) \
	shell_fprintf(_sh, SHELL_WARNING, _ft "\n", ##__VA_ARGS__)

/**
 * @brief Print error message to the shell.
 *
 * See @ref shell_fprintf.
 *
 * @param[in] _sh Pointer to the shell instance.
 * @param[in] _ft Format string.
 * @param[in] ... List of parameters to print.
 */
#define shell_error(_sh, _ft, ...) \
	shell_fprintf(_sh, SHELL_ERROR, _ft "\n", ##__VA_ARGS__)

/**
 * @brief Process function, which should be executed when data is ready in the
 *	  transport interface. To be used if shell thread is disabled.
 *
 * @param[in] shell Pointer to the shell instance.
 */
void shell_process(const struct shell *shell);

/**
 * @brief Change displayed shell prompt.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] prompt	New shell prompt.
 *
 * @return 0		Success.
 * @return -EINVAL	Pointer to new prompt is not correct.
 */
int shell_prompt_change(const struct shell *shell, const char *prompt);

/**
 * @brief Prints the current command help.
 *
 * Function will print a help string with: the currently entered command
 * and subcommands (if they exist).
 *
 * @param[in] shell      Pointer to the shell instance.
 */
void shell_help(const struct shell *shell);

/* @brief Command's help has been printed */
#define SHELL_CMD_HELP_PRINTED	(1)

/** @brief Execute command.
 *
 * Pass command line to shell to execute.
 *
 * Note: This by no means makes any of the commands a stable interface, so
 *	 this function should only be used for debugging/diagnostic.
 *
 *	 This function must not be called from shell command context!

 *
 * @param[in] shell	Pointer to the shell instance.
 *			It can be NULL when the
 *			@kconfig{CONFIG_SHELL_BACKEND_DUMMY} option is enabled.
 * @param[in] cmd	Command to be executed.
 *
 * @return		Result of the execution
 */
int shell_execute_cmd(const struct shell *shell, const char *cmd);

/** @brief Set root command for all shell instances.
 *
 * It allows setting from the code the root command. It is an equivalent of
 * calling select command with one of the root commands as the argument
 * (e.g "select log") except it sets command for all shell instances.
 *
 * @param cmd String with one of the root commands or null pointer to reset.
 *
 * @retval 0 if root command is set.
 * @retval -EINVAL if invalid root command is provided.
 */
int shell_set_root_cmd(const char *cmd);

/** @brief Set bypass callback.
 *
 * Bypass callback is called whenever data is received. Shell is bypassed and
 * data is passed directly to the callback. Use null to disable bypass functionality.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] bypass	Bypass callback or null to disable.
 */
void shell_set_bypass(const struct shell *shell, shell_bypass_cb_t bypass);

/** @brief Get shell readiness to execute commands.
 *
 * @param[in] sh	Pointer to the shell instance.
 *
 * @retval true		Shell backend is ready to execute commands.
 * @retval false	Shell backend is not initialized or not started.
 */
bool shell_ready(const struct shell *sh);

/**
 * @brief Allow application to control text insert mode.
 * Value is modified atomically and the previous value is returned.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] val	Insert mode.
 *
 * @retval 0 or 1: previous value
 * @retval -EINVAL if shell is NULL.
 */
int shell_insert_mode_set(const struct shell *shell, bool val);

/**
 * @brief Allow application to control whether terminal output uses colored
 * syntax.
 * Value is modified atomically and the previous value is returned.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] val	Color mode.
 *
 * @retval 0 or 1: previous value
 * @retval -EINVAL if shell is NULL.
 */
int shell_use_colors_set(const struct shell *shell, bool val);

/**
 * @brief Allow application to control whether user input is echoed back.
 * Value is modified atomically and the previous value is returned.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] val	Echo mode.
 *
 * @retval 0 or 1: previous value
 * @retval -EINVAL if shell is NULL.
 */
int shell_echo_set(const struct shell *shell, bool val);

/**
 * @brief Allow application to control whether user input is obscured with
 * asterisks -- useful for implementing passwords.
 * Value is modified atomically and the previous value is returned.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] obscure	Obscure mode.
 *
 * @retval 0 or 1: previous value.
 * @retval -EINVAL if shell is NULL.
 */
int shell_obscure_set(const struct shell *shell, bool obscure);

/**
 * @brief Allow application to control whether the delete key backspaces or
 * deletes.
 * Value is modified atomically and the previous value is returned.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] val	Delete mode.
 *
 * @retval 0 or 1: previous value
 * @retval -EINVAL if shell is NULL.
 */
int shell_mode_delete_set(const struct shell *shell, bool val);

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* SHELL_H__ */