1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <unistd.h> 21 22 23 extern void handle_usage_help(FILE *out_fp, const char *prog_name); 24 extern int handle_command_help(int argc, char *argv[], int arg_start); 25 extern void handle_usage_dump(FILE *out_fp, const char *prog_name); 26 extern int handle_command_dump(int argc, char *argv[], int arg_start); 27 extern void handle_usage_create(FILE *out_fp, const char *prog_name); 28 extern int handle_command_create(int argc, char *argv[], int arg_start); 29 extern void handle_usage_cfg_create(FILE *out_fp, const char *prog_name); 30 extern int handle_command_cfg_create(int argc, char *argv[], int arg_start); 31 32 33 struct command_info { 34 const char *command; 35 void (*usage)(FILE *out_fp, const char *prog_name); 36 int (*handler)(int argc, char *argv[], int arg_start); 37 }; 38 39 static const struct command_info command_infos[] = { 40 { "help", handle_usage_help, handle_command_help }, 41 { "dump", handle_usage_dump, handle_command_dump }, 42 { "create", handle_usage_create, handle_command_create }, 43 { "cfg_create", handle_usage_cfg_create, handle_command_cfg_create }, 44 { NULL, NULL, NULL } 45 }; 46 47 static const struct command_info *search_command(const char *command) { 48 const struct command_info *info; 49 for (info = command_infos; info->command != NULL; info++) { 50 if (strcmp(command, info->command) == 0) { 51 break; 52 } 53 } 54 if (info->command == NULL) { 55 fprintf(stderr, "Unknown command: %s\n", command); 56 return NULL; 57 } 58 return info; 59 } 60 61 static void print_all_commands(FILE *out_fp) { 62 const struct command_info *info; 63 for (info = command_infos; info->command != NULL; info++) { 64 if (info != command_infos) { 65 fprintf(out_fp, ", "); 66 } 67 fprintf(out_fp, "%s", info->command); 68 } 69 fprintf(out_fp, "\n"); 70 } 71 72 static void output_all_usage(FILE *out_fp, const char *prog_name) { 73 fprintf(out_fp, " %s <command>\n\n", prog_name); 74 fprintf(out_fp, " commands:\n "); 75 print_all_commands(out_fp); 76 fprintf(out_fp, "\n"); 77 78 const struct command_info *info; 79 for (info = command_infos; info->command != NULL; info++) { 80 info->usage(out_fp, prog_name); 81 fprintf(out_fp, "\n"); 82 } 83 } 84 85 void handle_usage_help(FILE *out_fp, const char *prog_name) { 86 fprintf(out_fp, " %s help all\n", prog_name); 87 fprintf(out_fp, " %s help <command>\n\n", prog_name); 88 fprintf(out_fp, " commands:\n "); 89 print_all_commands(out_fp); 90 } 91 92 int handle_command_help(int argc, char *argv[], int arg_start) { 93 const char *prog_name = argv[0]; 94 95 if (argc - arg_start < 1) { 96 handle_usage_help(stderr, prog_name); 97 return 1; 98 } 99 100 if (strcmp(argv[arg_start], "all") == 0) { 101 output_all_usage(stdout, prog_name); 102 return 0; 103 } 104 105 const struct command_info *info = search_command(argv[arg_start]); 106 if (info == NULL) { 107 handle_usage_help(stderr, prog_name); 108 return 1; 109 } 110 111 info->usage(stdout, prog_name); 112 113 return 0; 114 } 115 116 int main(int argc, char *argv[]) { 117 if (argc <= 1) { 118 output_all_usage(stderr, argv[0]); 119 return 1; 120 } 121 122 const char *command = argv[1]; 123 const struct command_info *info = search_command(argv[1]); 124 if (info == NULL) { 125 return 1; 126 } 127 128 /* skip 2 arguments, argv[0] and argv[1] */ 129 return info->handler(argc, argv, 2); 130 } 131