• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

ink_args.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /****************************************************************************
00025 Process arguments
00026 
00027 ****************************************************************************/
00028 
00029 #include "libts.h"
00030 
00031 //
00032 //  Global variables
00033 //
00034 
00035 const char *file_arguments[MAX_FILE_ARGUMENTS] = { 0 };
00036 const char *program_name = (char *) "Traffic Server";
00037 unsigned n_file_arguments = 0;
00038 
00039 //
00040 //  Local variables
00041 //
00042 
00043 static const char *argument_types_keys = (char *) "ISDfFTL";
00044 static const char *argument_types_descriptions[] = {
00045   (char *) "int  ",
00046   (char *) "str  ",
00047   (char *) "dbl  ",
00048   (char *) "off  ",
00049   (char *) "on   ",
00050   (char *) "tog  ",
00051   (char *) "i64  ",
00052   (char *) "     "
00053 };
00054 
00055 //
00056 // Functions
00057 //
00058 
00059 static void
00060 process_arg(const ArgumentDescription * argument_descriptions,
00061             unsigned n_argument_descriptions, int i, char ***argv, const char *usage_string)
00062 {
00063   char *arg = NULL;
00064   if (argument_descriptions[i].type) {
00065     char type = argument_descriptions[i].type[0];
00066     if (type == 'F' || type == 'f')
00067       *(int *) argument_descriptions[i].location = type == 'F' ? 1 : 0;
00068     else if (type == 'T')
00069       *(int *) argument_descriptions[i].location = !*(int *) argument_descriptions[i].location;
00070     else {
00071       arg = *++(**argv) ? **argv : *++(*argv);
00072       if (!arg)
00073         usage(argument_descriptions, n_argument_descriptions, usage_string);
00074       switch (type) {
00075       case 'I':
00076         *(int *) argument_descriptions[i].location = atoi(arg);
00077         break;
00078       case 'D':
00079         *(double *) argument_descriptions[i].location = atof(arg);
00080         break;
00081       case 'L':
00082         *(int64_t *) argument_descriptions[i].location = ink_atoi64(arg);
00083         break;
00084       case 'S':
00085         if (argument_descriptions[i].type[1] == '*') {
00086           char ** out = (char **)argument_descriptions[i].location;
00087           *out = ats_strdup(arg);
00088         } else {
00089           ink_strlcpy((char *) argument_descriptions[i].location, arg, atoi(argument_descriptions[i].type + 1));
00090         }
00091         break;
00092       default:
00093         ink_fatal(1, (char *) "bad argument description");
00094         break;
00095       }
00096       **argv += strlen(**argv) - 1;
00097     }
00098   }
00099   if (argument_descriptions[i].pfn)
00100     argument_descriptions[i].pfn(argument_descriptions, n_argument_descriptions, arg);
00101 }
00102 
00103 
00104 void
00105 show_argument_configuration(const ArgumentDescription * argument_descriptions, unsigned n_argument_descriptions)
00106 {
00107   printf("Argument Configuration\n");
00108   for (unsigned i = 0; i < n_argument_descriptions; i++) {
00109     if (argument_descriptions[i].type) {
00110       printf("  %-34s ", argument_descriptions[i].description);
00111       switch (argument_descriptions[i].type[0]) {
00112       case 'F':
00113       case 'f':
00114       case 'T':
00115         printf(*(int *) argument_descriptions[i].location ? "TRUE" : "FALSE");
00116         break;
00117       case 'I':
00118         printf("%d", *(int *) argument_descriptions[i].location);
00119         break;
00120       case 'D':
00121         printf("%f", *(double *) argument_descriptions[i].location);
00122         break;
00123       case 'L':
00124         printf("%" PRId64 "", *(int64_t *) argument_descriptions[i].location);
00125         break;
00126       case 'S':
00127         printf("%s", (char *) argument_descriptions[i].location);
00128         break;
00129       default:
00130         ink_fatal(1, (char *) "bad argument description");
00131         break;
00132       }
00133       printf("\n");
00134     }
00135   }
00136 }
00137 
00138 void
00139 process_args(const ArgumentDescription * argument_descriptions, unsigned n_argument_descriptions, char **argv, const char *usage_string)
00140 {
00141   unsigned i = 0;
00142   //
00143   // Grab Environment Variables
00144   //
00145   for (i = 0; i < n_argument_descriptions; i++)
00146     if (argument_descriptions[i].env) {
00147       char type = argument_descriptions[i].type[0];
00148       char *env = getenv(argument_descriptions[i].env);
00149       if (!env)
00150         continue;
00151       switch (type) {
00152       case 'f':
00153       case 'F':
00154       case 'I':
00155         *(int *) argument_descriptions[i].location = atoi(env);
00156         break;
00157       case 'D':
00158         *(double *) argument_descriptions[i].location = atof(env);
00159         break;
00160       case 'L':
00161         *(int64_t *) argument_descriptions[i].location = atoll(env);
00162         break;
00163       case 'S':
00164         ink_strlcpy((char *) argument_descriptions[i].location, env, atoi(argument_descriptions[i].type + 1));
00165         break;
00166       }
00167     }
00168   //
00169   // Grab Command Line Arguments
00170   //
00171   program_name = argv[0];
00172   while (*++argv) {
00173     if (**argv == '-') {
00174       if ((*argv)[1] == '-') {
00175         for (i = 0; i < n_argument_descriptions; i++)
00176           if (!strcmp(argument_descriptions[i].name, (*argv) + 2)) {
00177             *argv += strlen(*argv) - 1;
00178             process_arg(argument_descriptions, n_argument_descriptions, i, &argv, usage_string);
00179             break;
00180           }
00181         if (i >= n_argument_descriptions)
00182           usage(argument_descriptions, n_argument_descriptions, usage_string);
00183       } else {
00184         while (*++(*argv))
00185           for (i = 0; i < n_argument_descriptions; i++)
00186             if (argument_descriptions[i].key == **argv) {
00187               process_arg(argument_descriptions, n_argument_descriptions, i, &argv, usage_string);
00188               break;
00189             }
00190         if (i >= n_argument_descriptions)
00191           usage(argument_descriptions, n_argument_descriptions, usage_string);
00192       }
00193     } else {
00194       if (n_file_arguments >= countof(file_arguments)) {
00195         ink_fatal(1, "too many files");
00196       }
00197       file_arguments[n_file_arguments++] = *argv;
00198       file_arguments[n_file_arguments] = NULL;
00199     }
00200   }
00201 }
00202 
00203 void
00204 usage(const ArgumentDescription * argument_descriptions, unsigned n_argument_descriptions, const char *usage_string)
00205 {
00206   (void) argument_descriptions;
00207   (void) n_argument_descriptions;
00208   (void) usage_string;
00209   if (usage_string)
00210     fprintf(stderr, "%s\n", usage_string);
00211   else
00212     fprintf(stderr, "Usage: %s [--SWITCH [ARG]]\n", program_name);
00213   fprintf(stderr, "  switch__________________type__default___description\n");
00214   for (unsigned i = 0; i < n_argument_descriptions; i++) {
00215     if (!argument_descriptions[i].description)
00216       continue;
00217 
00218     fprintf(stderr, "  ");
00219 
00220     if ('-' == argument_descriptions[i].key) fprintf(stderr, "   ");
00221     else fprintf(stderr, "-%c,", argument_descriptions[i].key);
00222                                                
00223     fprintf(stderr, " --%-17s %s",
00224             argument_descriptions[i].name,
00225             argument_types_descriptions[argument_descriptions[i].type ?
00226                                         strchr(argument_types_keys,
00227                                                argument_descriptions[i].type[0]) -
00228                                         argument_types_keys : strlen(argument_types_keys)
00229             ]);
00230     switch (argument_descriptions[i].type ? argument_descriptions[i].type[0] : 0) {
00231     case 0:
00232       fprintf(stderr, "          ");
00233       break;
00234     case 'L':
00235       fprintf(stderr, " %-9" PRId64 "", *(int64_t *) argument_descriptions[i].location);
00236       break;
00237     case 'S':
00238       if (*(char *) argument_descriptions[i].location) {
00239         if (strlen((char *) argument_descriptions[i].location) < 10)
00240           fprintf(stderr, " %-9s", (char *) argument_descriptions[i].location);
00241         else {
00242           ((char *) argument_descriptions[i].location)[7] = 0;
00243           fprintf(stderr, " %-7s..", (char *) argument_descriptions[i].location);
00244         }
00245       } else
00246         fprintf(stderr, " (null)   ");
00247       break;
00248     case 'D':
00249       fprintf(stderr, " %-9.3f", *(double *) argument_descriptions[i].location);
00250       break;
00251     case 'I':
00252       fprintf(stderr, " %-9d", *(int *) argument_descriptions[i].location);
00253       break;
00254     case 'T':
00255     case 'f':
00256     case 'F':
00257       fprintf(stderr, " %-9s", *(int *) argument_descriptions[i].location ? "true " : "false");
00258       break;
00259     }
00260     fprintf(stderr, " %s\n", argument_descriptions[i].description);
00261   }
00262   _exit(1);
00263 }

Generated by  doxygen 1.7.1