00001 /* 00002 * gethist.c: for remembering the command line, and the date of execution 00003 *............................................................................. 00004 * version 1: May 1989 Piet Hut email: piet@iassns.bitnet 00005 * Institute for Advanced Study, Princeton, NJ, USA 00006 * version 2: Dec 1992 Piet Hut -- adopted to the new C++-based starlab 00007 *............................................................................. 00008 * non-local function: 00009 * gethist 00010 *............................................................................. 00011 * A string is returned which contains the date at which a command is 00012 * invoked followed with the full command line, including all arguments. 00013 *............................................................................. 00014 */ 00015 00020 00021 #include <time.h> 00022 #include "stdinc.h" 00023 00024 #ifndef TOOLBOX 00025 00026 /*----------------------------------------------------------------------------- 00027 * contains_white -- returns TRUE of the string contains one or more 00028 * white spaces; returns FALSE otherwise. 00029 *----------------------------------------------------------------------------- 00030 */ 00031 local bool contains_white(char * s) 00032 { 00033 while (*s != '\0') 00034 if (*s++ == ' ') 00035 return(TRUE); 00036 00037 return(FALSE); 00038 } 00039 00040 /*----------------------------------------------------------------------------- 00041 * eff_length -- effective length, needed to stored a command line argument: 00042 * one for each character, and two extra for the surrounding 00043 * "" quotes, in case the string contains one or more 00044 * internal white spaces. 00045 * example: 00046 * "hi" --> hi 00047 * "hi there" --> "hi there" 00048 * 00049 * eff_length("hi") = 2 00050 * eff_length("hi there") = 10 00051 *----------------------------------------------------------------------------- 00052 */ 00053 local int eff_length(char * s) 00054 { 00055 if (contains_white(s)) 00056 return(strlen(s) + 2); 00057 else 00058 return(strlen(s)); 00059 } 00060 00061 /*----------------------------------------------------------------------------- 00062 * DATE_TOT_LENGTH -- total length, in characters, of the date plus the 00063 * date separator; this is the length reserved in total 00064 * for the date information by gethist(). 00065 * DATE_STR_LENGTH -- The fixed standard length of the date containing 00066 * string, as returned by the UNIX operating system, 00067 * apart from the last NULL character; 00068 * DATE_SEPARATOR -- This string can be changed whenever desired: 00069 * when chosing a new DATE_SEPARATOR string, all date 00070 * length macros will be automatically adjusted. 00071 *----------------------------------------------------------------------------- 00072 */ 00073 #define INTRO_PART " ===> " 00074 #define INTRO_LENGTH strlen(INTRO_PART) 00075 #define STARLAB_PART "Starlab " 00076 #define STARLAB_LENGTH strlen(STARLAB_PART) 00077 #define VERSION_PART STARLAB_VERSION 00078 #define VERSION_LENGTH strlen(VERSION_PART) 00079 #define DATE_STR_LENGTH 24 00080 #define DATE_SEPARATOR "\n " 00081 #define DATE_SEP_LENGTH strlen(DATE_SEPARATOR) 00082 #define VERSION_SEPARATOR " : " 00083 #define VERSION_SEP_LENGTH strlen(VERSION_SEPARATOR) 00084 #define DATE_TOT_LENGTH INTRO_LENGTH + STARLAB_LENGTH + VERSION_LENGTH \ 00085 + DATE_STR_LENGTH + DATE_SEP_LENGTH + VERSION_SEP_LENGTH 00086 00087 #define USER_HEAD " (user " 00088 00089 /*----------------------------------------------------------------------------- 00090 * gethist -- returns a newly allocated string containing the date at which 00091 * the command of the calling program was given, and the full 00092 * command line. 00093 * note: 00094 * simply printing successive command line arguments does not 00095 * provide the full information, since the following two commands 00096 * gobble this thing and gobble "this thing" 00097 * would both be printed as gobble this thing . 00098 * Therefore, all command line arguments are first checked for 00099 * the presence of internal white space, in which case they are 00100 * provided with the "" quotes. 00101 *----------------------------------------------------------------------------- 00102 */ 00103 char *gethist(int argc, char ** argv) 00104 { 00105 int i, j, k; 00106 int n; 00107 long int clock; /* will contain time in seconds since 1970 */ 00108 char *hist_string; /* will point to newly allocated string */ 00109 /* 00110 * determine length of new character array, and allocate memory for it: 00111 */ 00112 n = DATE_TOT_LENGTH; 00113 for (i = 0; i < argc; i++) /* total length, apart from the white */ 00114 n += eff_length(argv[i]); /* spaces separating the commands */ 00115 n += argc; /* one for each white space delimiter, */ 00116 /* and a final NULL to end the hist_string */ 00117 00118 // Added by Steve (7/01): 00119 00120 char *user_part = getenv("USER"); 00121 int user_length = 0; 00122 00123 if (user_part) user_length = strlen(user_part) + strlen(USER_HEAD) + 1; 00124 // ')' 00125 00126 n += user_length; 00127 hist_string = new char[n]; 00128 00129 if (hist_string == NULL) 00130 { 00131 cerr << "gethist: not enough memory left for hist_string\n"; 00132 exit (1); 00133 } 00134 /* 00135 * write the date: 00136 */ 00137 strcpy(hist_string, INTRO_PART); 00138 clock = (long int)time(0); /* see time(2), UNIX manual */ 00139 strcpy(hist_string + INTRO_LENGTH, ctime((time_t*)&clock)); 00140 /* see ctime(3C), UNIX manual */ 00141 strcpy(hist_string + INTRO_LENGTH + DATE_STR_LENGTH, DATE_SEPARATOR); 00142 strcpy(hist_string + INTRO_LENGTH + DATE_STR_LENGTH + DATE_SEP_LENGTH, 00143 STARLAB_PART); 00144 strcpy(hist_string + INTRO_LENGTH + DATE_STR_LENGTH + DATE_SEP_LENGTH 00145 + STARLAB_LENGTH, VERSION_PART); 00146 00147 if (user_part) { 00148 00149 // Add in the name of the user running the program: 00150 00151 char tmp[1024]; 00152 strcpy(tmp, USER_HEAD); 00153 strcat(tmp, user_part); 00154 strcat(tmp, ")"); 00155 00156 strcpy(hist_string + INTRO_LENGTH + DATE_STR_LENGTH + DATE_SEP_LENGTH 00157 + STARLAB_LENGTH + VERSION_LENGTH, tmp); 00158 } 00159 00160 strcpy(hist_string + INTRO_LENGTH + DATE_STR_LENGTH + DATE_SEP_LENGTH 00161 + STARLAB_LENGTH + VERSION_LENGTH + user_length, VERSION_SEPARATOR); 00162 /* 00163 * write the command line: 00164 */ 00165 j = DATE_TOT_LENGTH + user_length; 00166 for (i = 0; i < argc; i++) 00167 { 00168 k = 0; 00169 if (contains_white(argv[i])) 00170 hist_string[j++] = '"'; 00171 while (argv[i][k] != '\0') 00172 hist_string[j++] = argv[i][k++]; 00173 if (contains_white(argv[i])) 00174 hist_string[j++] = '"'; 00175 hist_string[j++] = ' '; /* white space delimiter */ 00176 } 00177 hist_string[--j] = '\0'; /* providing the string terminator */ 00178 /* by overwriting the last ' ' */ 00179 /* 00180 * done: 00181 */ 00182 return(hist_string); 00183 } 00184 00185 /*===========================================================================*/ 00186 00187 #else 00188 00189 /*----------------------------------------------------------------------------- 00190 * main -- driver to test gethist() . 00191 * for example: 00192 * gethist these are words "but this is a single string" 00193 *----------------------------------------------------------------------------- 00194 */ 00195 main(int argc, char ** argv) 00196 { 00197 check_help(); 00198 printf("%s\n", gethist(argc, argv)); 00199 } 00200 00201 #endif 00202 00203 /*===========================================================================*/ 00204 00205 /* endof: gethist.c */