1f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley/* skeleton.c - Example program to act as template for new commands.
2f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley *
3f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley * Copyright 2014 Rob Landley <rob@landley.net>
4f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley *
5f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/
6f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cmdbehav.html
7f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
8f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley// Accept many different kinds of command line argument (see top of lib/args.c)
9f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley// Demonstrate two commands in the same file (see www/documentation.html)
10f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
11f9070f36adfaf1b5c175768fb7169b9ff79da21dRob LandleyUSE_SKELETON(NEWTOY(skeleton, "(walrus)(blubber):;(also):e@d*c#b:a", TOYFLAG_USR|TOYFLAG_BIN))
12f9070f36adfaf1b5c175768fb7169b9ff79da21dRob LandleyUSE_SKELETON_ALIAS(NEWTOY(skeleton_alias, "b#dq", TOYFLAG_USR|TOYFLAG_BIN))
13f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
14f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landleyconfig SKELETON
15f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  bool "skeleton"
16f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  default n
17f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  help
18f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    usage: skeleton [-a] [-b STRING] [-c NUMBER] [-d LIST] [-e COUNT] [...]
19f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
20f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    Template for new commands. You don't need this.
21f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
22f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    When creating a new command, copy this file and delete the parts you
23f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    don't need. Be sure to replace all instances of "skeleton" (upper and lower
24f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    case) with your new command name.
25f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
26f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    For simple commands, "hello.c" is probably a better starting point.
27f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
28f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landleyconfig SKELETON_ALIAS
29f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  bool "skeleton_alias"
30f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  default n
31f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  help
32f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    usage: skeleton_alias [-dq] [-b NUMBER]
33f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
34f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    Example of a second command with different arguments in the same source
35f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    file as the first. This allows shared infrastructure not added to lib/.
36f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley*/
37f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
38f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley#define FOR_skeleton
39f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley#include "toys.h"
40f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
41f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley// The union lets lib/args.c store arguments for either command.
42f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley// It's customary to put a space between argument variables and other globals.
43f9070f36adfaf1b5c175768fb7169b9ff79da21dRob LandleyGLOBALS(
44f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  union {
45f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    struct {
46f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley      char *b_string;
47f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley      long c_number;
48f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley      struct arg_list *d_list;
49f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley      long e_count;
50f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley      char *also_string;
51f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley      char *blubber_string;
52f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    } s;
53f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    struct {
54f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley      long b_number;
55f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    } a;
56f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  };
57f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
58f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  int more_globals;
59f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley)
60f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
61f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley// Don't blindly build allyesconfig. The maximum _sane_ config is defconfig.
62f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley#warning skeleton.c is just an example, not something to deploy.
63f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
64f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley// Parse many different kinds of command line argument:
65f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landleyvoid skeleton_main(void)
66f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley{
67f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  char **optargs;
68f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
69f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  printf("Ran %s\n", toys.which->name);
70f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
71f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  // Command line options parsing is done for you by lib/args.c called
72f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  // from main.c using the optstring in the NEWTOY macros. Display results.
73f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  if (toys.optflags) printf("flags=%x\n", toys.optflags);
74f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  if (toys.optflags & FLAG_a) printf("Saw a\n");
75f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  if (toys.optflags & FLAG_b) printf("b=%s\n", TT.s.b_string);
76f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  if (toys.optflags & FLAG_c) printf("c=%ld\n", TT.s.c_number);
77f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  while (TT.s.d_list) {
78f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    printf("d=%s\n", TT.s.d_list->arg);
79f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    TT.s.d_list = TT.s.d_list->next;
80f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  }
81f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  if (TT.s.e_count) printf("e was seen %ld times\n", TT.s.e_count);
82f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  for (optargs = toys.optargs; *optargs; optargs++)
83f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley    printf("optarg=%s\n", *optargs);
84f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  if (toys.optflags & FLAG_walrus) printf("Saw --walrus\n");
85f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  if (TT.s.blubber_string) printf("--blubber=%s\n", TT.s.blubber_string);
86f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
87f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  printf("Other globals should start zeroed: %d\n", TT.more_globals);
88f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley}
89f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
90f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley// Switch gears from skeleton to skeleton_alias (swap FLAG macros).
91f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley#define CLEANUP_skeleton
92f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley#define FOR_skeleton_alias
93f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley#include "generated/flags.h"
94f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
95f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landleyvoid skeleton_alias_main(void)
96f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley{
97f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  printf("Ran %s\n", toys.which->name);
98f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  printf("flags=%x\n", toys.optflags);
99f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley
100f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  // Note, this FLAG_b is a different bit position than the other FLAG_b,
101f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  // and fills out a different variable of a different type.
102f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley  if (toys.optflags & FLAG_b) printf("b=%ld", TT.a.b_number);
103f9070f36adfaf1b5c175768fb7169b9ff79da21dRob Landley}
104