Max Mahn

aboutsummaryrefslogtreecommitdiff
path: root/args.awk
blob: 17d9431f6d3ed7f04bc6fc623a90f1d7715d331d (plain)
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

BEGIN {
  opt_count = 0;
  FIELDS["short"] = 0; # short option
  FIELDS["long"]  = 0; # long option
  FIELDS["arg"]   = 0; # option argument
  FIELDS["desc"]  = 0; # description
  FIELDS["func"]  = 0; # callback function
}



func PrintShell() {
  printf "OPTIONS=(\n# callback short long argument\n"
  for (i = 0; i < opt_count; i++)
    printf("'%s' '%s' '%s' '%s' '%s'\n",
        OPTIONS["func", i], OPTIONS["short", i],
        OPTIONS["long", i], OPTIONS["arg", i],
        OPTIONS["desc", i]);
  printf(")\n");
}

func PrintMan() {
  for (i = 0; i < opt_count; i++) {
    short = OPTIONS["short", i];
    long = OPTIONS["long", i];
    arg = OPTIONS["arg", i];
    desc = OPTIONS["desc", i];
    if (arg)
      printf(".TP\n.BI \"-%1s \" %s \", --%s=\" %s",
             short, arg, long, arg);
    else
      printf(".TP\n-%1s, --%s",
             short, long);
    printf("\n%s\n\n", desc);
  }
}




func EmptyEntry(entry) {
  #printf("Checking for empty entry at [%d]...\n", entry);
  for (type in FIELDS) {
    #printf("  Checking for empty field '%s'\n", type);
    if (OPTIONS[type, entry])
      return 0;
  }
  return 1;
}


/^\s*#/ { # comment
  next;
}


/^\s*$/ { # end of entry
  if (!EmptyEntry(opt_count))
    opt_count++;
  next;
}


/^\s*-/ { # option line
  for (i = 1; i <= NF; i++) {
    switch ($i) {
      case /^-+$/: # ignore fields with only dashes
        continue;
      case /^--\w[\w-]*/:  # long option
        sub(/^--/, "", $i);
        type = "long";
        break;
      case /^-\w+/:   # short option
        sub(/^-/, "", $i);
        type = "short";
        break;
      case /^\w+/:    # option argument
        type = "arg";
        break;
    }
    OPTIONS[type, opt_count] = $i;
  }
  
}


/^\s*@/ { # function callback line
  sub(/^\s*@\s*/, "");
  OPTIONS["func", opt_count] = $1;
  next;
}


/^\s*"/ {
  sub(/^\s*"\s*/, "");
  if (OPTIONS["desc", opt_count] !~ /\s$/)
    OPTIONS["desc", opt_count] += " ";
  OPTIONS["desc", opt_count] = $0;
  next;
}


END {
  if (!EmptyEntry(opt_count)) opt_count++;
  
  if (!OUTPUT) OUTPUT = "shell";
  switch (OUTPUT) {
    case "shell":
      PrintShell();
      break;
    case "man":
      PrintMan();
      break;
    default:
      printf("Unknown format '%s'", OUTPUT) > "/dev/stderr";
  }
}