| 1 | From jwe@che.utexas.edu Wed Sep 21 17:23:40 1994
|
|---|
| 2 | Flags: 10
|
|---|
| 3 | Return-Path: jwe@che.utexas.edu
|
|---|
| 4 | Received: from po.CWRU.Edu (root@po.CWRU.Edu [129.22.4.2]) by odin.INS.CWRU.Edu with ESMTP (8.6.8.1+cwru/CWRU-2.1-ins)
|
|---|
| 5 | id RAA04010; Wed, 21 Sep 1994 17:23:39 -0400 (from jwe@che.utexas.edu for <chet@odin.INS.CWRU.Edu>)
|
|---|
| 6 | Received: from life.ai.mit.edu (life.ai.mit.edu [128.52.32.80]) by po.CWRU.Edu with SMTP (8.6.8.1+cwru/CWRU-2.2)
|
|---|
| 7 | id RAA02121; Wed, 21 Sep 1994 17:23:28 -0400 (from jwe@che.utexas.edu for <chet@po.cwru.edu>)
|
|---|
| 8 | Received: from schoch.che.utexas.edu by life.ai.mit.edu (4.1/AI-4.10) for chet@po.cwru.edu id AA09989; Wed, 21 Sep 94 17:23:17 EDT
|
|---|
| 9 | Received: from localhost (jwe@localhost) by schoch.che.utexas.edu (8.6.8.1/8.6) with SMTP id QAA05737; Wed, 21 Sep 1994 16:22:01 -0500
|
|---|
| 10 | Message-Id: <199409212122.QAA05737@schoch.che.utexas.edu>
|
|---|
| 11 | To: march@tudor.com
|
|---|
| 12 | Cc: bug-bash@prep.ai.mit.edu
|
|---|
| 13 | Subject: Re: Completion feature possible?
|
|---|
| 14 | In-Reply-To: Your message of 21 Sep 94 13:30:22 EDT
|
|---|
| 15 | Date: Wed, 21 Sep 94 16:22:00 EDT
|
|---|
| 16 | From: John Eaton <jwe@che.utexas.edu>
|
|---|
| 17 |
|
|---|
| 18 | Gregory F. March <march@tudor.com> wrote:
|
|---|
| 19 |
|
|---|
| 20 | : I was having a discussion about MH with one of my friends the other
|
|---|
| 21 | : day and I got to thinking that the +folder/subfolder scheme for naming
|
|---|
| 22 | : mail folders is a real pain because completion doesn't work on
|
|---|
| 23 | : them. Someone then mentioned that zsh (I think) has the ability to
|
|---|
| 24 | : specify how to complete (I guess where to look for the files) for
|
|---|
| 25 | : different prefixes. Bash right now knows about '@', '~', and '$' (any
|
|---|
| 26 | : others?). It would be really helpful if one could define something
|
|---|
| 27 | : like:
|
|---|
| 28 | :
|
|---|
| 29 | : completion '+' "$HOME/Mail"
|
|---|
| 30 | :
|
|---|
| 31 | : in a config file someplace. Would this be easy? Is there a list of
|
|---|
| 32 | : TODO item that someone might want to add this to?
|
|---|
| 33 |
|
|---|
| 34 | It would be nice to have a general completion feature like this.
|
|---|
| 35 |
|
|---|
| 36 | Until that happens, maybe you will find the following patch useful.
|
|---|
| 37 | It makes MH folder name completion work with bash. The diffs are
|
|---|
| 38 | relative to version 1.14.2.
|
|---|
| 39 |
|
|---|
| 40 | I realize that changes to readline.c and and complete.c are not good
|
|---|
| 41 | since they add some MH-specific stuff to the readline code and not to
|
|---|
| 42 | bash, but when I first wrote this, I had no idea what else to do.
|
|---|
| 43 |
|
|---|
| 44 | Chet, would you consider adding this if it were cleaned up a bit?
|
|---|
| 45 | Made optional with cpp conditionals?
|
|---|
| 46 |
|
|---|
| 47 | This feature has been very useful to me for the last several years
|
|---|
| 48 | (since about 1.05 or 1.06, I think).
|
|---|
| 49 |
|
|---|
| 50 | Thanks,
|
|---|
| 51 |
|
|---|
| 52 | --
|
|---|
| 53 | John W. Eaton | 4.3BSD is not perfect. -- Leffler, et al. (1989).
|
|---|
| 54 | jwe@che.utexas.edu |
|
|---|
| 55 |
|
|---|
| 56 |
|
|---|
| 57 | -------------------------------cut here-------------------------------
|
|---|
| 58 | diff -rc bash-1.14.2/bashline.c bash-1.14.2.local/bashline.c
|
|---|
| 59 | *** bash-1.14.2/bashline.c Wed Aug 3 09:32:45 1994
|
|---|
| 60 | --- bash-1.14.2.local/bashline.c Wed Sep 21 15:39:04 1994
|
|---|
| 61 | ***************
|
|---|
| 62 | *** 58,63 ****
|
|---|
| 63 | --- 58,64 ----
|
|---|
| 64 | static char *hostname_completion_function ();
|
|---|
| 65 | static char *command_word_completion_function ();
|
|---|
| 66 | static char *command_subst_completion_function ();
|
|---|
| 67 | + static char *mh_folder_completion_function ();
|
|---|
| 68 |
|
|---|
| 69 | static void snarf_hosts_from_file (), add_host_name ();
|
|---|
| 70 | static void sort_hostname_list ();
|
|---|
| 71 | ***************
|
|---|
| 72 | *** 90,95 ****
|
|---|
| 73 | --- 91,98 ----
|
|---|
| 74 | bash_complete_username_internal (),
|
|---|
| 75 | bash_complete_hostname (), bash_possible_hostname_completions (),
|
|---|
| 76 | bash_complete_hostname_internal (),
|
|---|
| 77 | + bash_complete_mh_folder (), bash_possible_mh_folder_completions (),
|
|---|
| 78 | + bash_complete_mh_folder_internal (),
|
|---|
| 79 | bash_complete_variable (), bash_possible_variable_completions (),
|
|---|
| 80 | bash_complete_variable_internal (),
|
|---|
| 81 | bash_complete_command (), bash_possible_command_completions (),
|
|---|
| 82 | ***************
|
|---|
| 83 | *** 134,140 ****
|
|---|
| 84 | rl_terminal_name = get_string_value ("TERM");
|
|---|
| 85 | rl_instream = stdin;
|
|---|
| 86 | rl_outstream = stderr;
|
|---|
| 87 | ! rl_special_prefixes = "$@";
|
|---|
| 88 |
|
|---|
| 89 | /* Allow conditional parsing of the ~/.inputrc file. */
|
|---|
| 90 | rl_readline_name = "Bash";
|
|---|
| 91 | --- 137,143 ----
|
|---|
| 92 | rl_terminal_name = get_string_value ("TERM");
|
|---|
| 93 | rl_instream = stdin;
|
|---|
| 94 | rl_outstream = stderr;
|
|---|
| 95 | ! rl_special_prefixes = "$@+";
|
|---|
| 96 |
|
|---|
| 97 | /* Allow conditional parsing of the ~/.inputrc file. */
|
|---|
| 98 | rl_readline_name = "Bash";
|
|---|
| 99 | ***************
|
|---|
| 100 | *** 193,198 ****
|
|---|
| 101 | --- 196,207 ----
|
|---|
| 102 | rl_bind_key_in_map ('@', bash_possible_hostname_completions,
|
|---|
| 103 | emacs_ctlx_keymap);
|
|---|
| 104 |
|
|---|
| 105 | + rl_add_defun ("complete-mh-folder", bash_complete_mh_folder, META('+'));
|
|---|
| 106 | + rl_add_defun ("possible-mh-folder-completions",
|
|---|
| 107 | + bash_possible_mh_folder_completions, -1);
|
|---|
| 108 | + rl_bind_key_in_map ('+', bash_possible_mh_folder_completions,
|
|---|
| 109 | + emacs_ctlx_keymap);
|
|---|
| 110 | +
|
|---|
| 111 | rl_add_defun ("complete-variable", bash_complete_variable, -1);
|
|---|
| 112 | rl_bind_key_in_map ('$', bash_complete_variable, emacs_meta_keymap);
|
|---|
| 113 | rl_add_defun ("possible-variable-completions",
|
|---|
| 114 | ***************
|
|---|
| 115 | *** 656,661 ****
|
|---|
| 116 | --- 665,677 ----
|
|---|
| 117 | if (!matches && *text == '@')
|
|---|
| 118 | matches = completion_matches (text, hostname_completion_function);
|
|---|
| 119 |
|
|---|
| 120 | + /* Another one. Why not? If the word starts in '+', then look for
|
|---|
| 121 | + matching mh folders for completion first. */
|
|---|
| 122 | + if (!matches && *text == '+')
|
|---|
| 123 | + {
|
|---|
| 124 | + matches = completion_matches (text, mh_folder_completion_function);
|
|---|
| 125 | + }
|
|---|
| 126 | +
|
|---|
| 127 | /* And last, (but not least) if this word is in a command position, then
|
|---|
| 128 | complete over possible command names, including aliases, functions,
|
|---|
| 129 | and command names. */
|
|---|
| 130 | ***************
|
|---|
| 131 | *** 1077,1082 ****
|
|---|
| 132 | --- 1093,1185 ----
|
|---|
| 133 | return ((char *)NULL);
|
|---|
| 134 | }
|
|---|
| 135 |
|
|---|
| 136 | + /* How about a completion function for mh folders? */
|
|---|
| 137 | + static char *
|
|---|
| 138 | + mh_folder_completion_function (text, state)
|
|---|
| 139 | + int state;
|
|---|
| 140 | + char *text;
|
|---|
| 141 | + {
|
|---|
| 142 | + extern int rl_filename_completion_desired;
|
|---|
| 143 | +
|
|---|
| 144 | + extern char *get_mh_path ();
|
|---|
| 145 | +
|
|---|
| 146 | + static char *mh_path = (char *)NULL;
|
|---|
| 147 | + static int len;
|
|---|
| 148 | + static int istate;
|
|---|
| 149 | + static char *val;
|
|---|
| 150 | + char *hint;
|
|---|
| 151 | +
|
|---|
| 152 | + static char *mh_folder_hint = (char *)NULL;
|
|---|
| 153 | +
|
|---|
| 154 | + /* If we don't have any state, make some. */
|
|---|
| 155 | + if (!state)
|
|---|
| 156 | + {
|
|---|
| 157 | + val = (char *)NULL;
|
|---|
| 158 | +
|
|---|
| 159 | + if (mh_path)
|
|---|
| 160 | + free (mh_path);
|
|---|
| 161 | +
|
|---|
| 162 | + mh_path = get_mh_path ();
|
|---|
| 163 | + if (!mh_path && !(hint[1] == '/' || hint[1] == '.'))
|
|---|
| 164 | + return ((char *)NULL);
|
|---|
| 165 | +
|
|---|
| 166 | + len = strlen (mh_path);
|
|---|
| 167 | + }
|
|---|
| 168 | +
|
|---|
| 169 | + if (mh_folder_hint)
|
|---|
| 170 | + free (mh_folder_hint);
|
|---|
| 171 | +
|
|---|
| 172 | + hint = text;
|
|---|
| 173 | + if (*hint == '+')
|
|---|
| 174 | + hint++;
|
|---|
| 175 | +
|
|---|
| 176 | + mh_folder_hint = (char *)xmalloc (2 + len + strlen (hint));
|
|---|
| 177 | + if (*hint == '/' || *hint == '.') {
|
|---|
| 178 | + len = -1;
|
|---|
| 179 | + sprintf (mh_folder_hint, "%s", hint);
|
|---|
| 180 | + } else
|
|---|
| 181 | + sprintf (mh_folder_hint, "%s/%s", mh_path, hint);
|
|---|
| 182 | +
|
|---|
| 183 | + istate = (val != (char *)NULL);
|
|---|
| 184 | +
|
|---|
| 185 | + again:
|
|---|
| 186 | + val = filename_completion_function (mh_folder_hint, istate);
|
|---|
| 187 | + istate = 1;
|
|---|
| 188 | +
|
|---|
| 189 | + if (!val)
|
|---|
| 190 | + {
|
|---|
| 191 | + return ((char *)NULL);
|
|---|
| 192 | + }
|
|---|
| 193 | + else
|
|---|
| 194 | + {
|
|---|
| 195 | + char *ptr = val + len + 1, *temp;
|
|---|
| 196 | + struct stat sb;
|
|---|
| 197 | + int status = stat (val, &sb);
|
|---|
| 198 | +
|
|---|
| 199 | + if (status != 0)
|
|---|
| 200 | + return ((char *)NULL);
|
|---|
| 201 | +
|
|---|
| 202 | + if ((sb.st_mode & S_IFDIR) == S_IFDIR)
|
|---|
| 203 | + {
|
|---|
| 204 | + temp = (char *)xmalloc (2 + strlen (ptr));
|
|---|
| 205 | + *temp = '+';
|
|---|
| 206 | + strcpy (temp + 1, ptr);
|
|---|
| 207 | +
|
|---|
| 208 | + free (val);
|
|---|
| 209 | + val = "";
|
|---|
| 210 | +
|
|---|
| 211 | + rl_filename_completion_desired = 1;
|
|---|
| 212 | +
|
|---|
| 213 | + return (temp);
|
|---|
| 214 | + }
|
|---|
| 215 | + else
|
|---|
| 216 | + {
|
|---|
| 217 | + free (val);
|
|---|
| 218 | + }
|
|---|
| 219 | + goto again;
|
|---|
| 220 | + }
|
|---|
| 221 | + }
|
|---|
| 222 | +
|
|---|
| 223 | /* History and alias expand the line. */
|
|---|
| 224 | static char *
|
|---|
| 225 | history_expand_line_internal (line)
|
|---|
| 226 | ***************
|
|---|
| 227 | *** 1628,1633 ****
|
|---|
| 228 | --- 1731,1773 ----
|
|---|
| 229 | {
|
|---|
| 230 | bash_specific_completion
|
|---|
| 231 | (what_to_do, (Function *)username_completion_function);
|
|---|
| 232 | + }
|
|---|
| 233 | +
|
|---|
| 234 | + static void
|
|---|
| 235 | + bash_complete_mh_folder (ignore, ignore2)
|
|---|
| 236 | + int ignore, ignore2;
|
|---|
| 237 | + {
|
|---|
| 238 | + bash_complete_mh_folder_internal (TAB);
|
|---|
| 239 | + }
|
|---|
| 240 | +
|
|---|
| 241 | + static void
|
|---|
| 242 | + bash_possible_mh_folder_completions (ignore, ignore2)
|
|---|
| 243 | + int ignore, ignore2;
|
|---|
| 244 | + {
|
|---|
| 245 | + bash_complete_mh_folder_internal ('?');
|
|---|
| 246 | + }
|
|---|
| 247 | +
|
|---|
| 248 | + static void
|
|---|
| 249 | + bash_complete_mh_folder_internal (what_to_do)
|
|---|
| 250 | + int what_to_do;
|
|---|
| 251 | + {
|
|---|
| 252 | + Function *orig_func;
|
|---|
| 253 | + CPPFunction *orig_attempt_func;
|
|---|
| 254 | + char *orig_rl_completer_word_break_characters;
|
|---|
| 255 | + extern char *rl_completer_word_break_characters;
|
|---|
| 256 | +
|
|---|
| 257 | + orig_func = rl_completion_entry_function;
|
|---|
| 258 | + orig_attempt_func = rl_attempted_completion_function;
|
|---|
| 259 | + orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
|
|---|
| 260 | + rl_completion_entry_function = (Function *)mh_folder_completion_function;
|
|---|
| 261 | + rl_attempted_completion_function = (CPPFunction *)NULL;
|
|---|
| 262 | + rl_completer_word_break_characters = " \t\n\"\'";
|
|---|
| 263 | +
|
|---|
| 264 | + rl_complete_internal (what_to_do);
|
|---|
| 265 | +
|
|---|
| 266 | + rl_completion_entry_function = orig_func;
|
|---|
| 267 | + rl_attempted_completion_function = orig_attempt_func;
|
|---|
| 268 | + rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
|
|---|
| 269 | }
|
|---|
| 270 |
|
|---|
| 271 | static void
|
|---|
| 272 | Only in bash-1.14.2.local: bashline.c.orig
|
|---|
| 273 | diff -rc bash-1.14.2/lib/readline/complete.c bash-1.14.2.local/lib/readline/complete.c
|
|---|
| 274 | *** bash-1.14.2/lib/readline/complete.c Tue Jul 26 12:59:57 1994
|
|---|
| 275 | --- bash-1.14.2.local/lib/readline/complete.c Wed Sep 21 15:41:19 1994
|
|---|
| 276 | ***************
|
|---|
| 277 | *** 733,751 ****
|
|---|
| 278 | if (rl_filename_completion_desired)
|
|---|
| 279 | {
|
|---|
| 280 | struct stat finfo;
|
|---|
| 281 | ! char *filename = tilde_expand (matches[0]);
|
|---|
| 282 |
|
|---|
| 283 | ! if ((stat (filename, &finfo) == 0) && S_ISDIR (finfo.st_mode))
|
|---|
| 284 | {
|
|---|
| 285 | ! if (rl_line_buffer[rl_point] != '/')
|
|---|
| 286 | ! rl_insert_text ("/");
|
|---|
| 287 | }
|
|---|
| 288 | ! else
|
|---|
| 289 | {
|
|---|
| 290 | ! if (rl_point == rl_end)
|
|---|
| 291 | ! rl_insert_text (temp_string);
|
|---|
| 292 | }
|
|---|
| 293 | - free (filename);
|
|---|
| 294 | }
|
|---|
| 295 | else
|
|---|
| 296 | {
|
|---|
| 297 | --- 733,768 ----
|
|---|
| 298 | if (rl_filename_completion_desired)
|
|---|
| 299 | {
|
|---|
| 300 | struct stat finfo;
|
|---|
| 301 | ! char *tilde_expand ();
|
|---|
| 302 | ! char *plus_expand ();
|
|---|
| 303 | ! char *filename = (char *) NULL;
|
|---|
| 304 |
|
|---|
| 305 | ! switch (*matches[0])
|
|---|
| 306 | {
|
|---|
| 307 | ! case '+':
|
|---|
| 308 | ! filename = plus_expand (matches[0]);
|
|---|
| 309 | ! break;
|
|---|
| 310 | ! case '~':
|
|---|
| 311 | ! default:
|
|---|
| 312 | ! filename = tilde_expand (matches[0]);
|
|---|
| 313 | ! break;
|
|---|
| 314 | }
|
|---|
| 315 | !
|
|---|
| 316 | ! if (filename)
|
|---|
| 317 | {
|
|---|
| 318 | ! if ((stat (filename, &finfo) == 0)
|
|---|
| 319 | ! && S_ISDIR (finfo.st_mode))
|
|---|
| 320 | ! {
|
|---|
| 321 | ! if (rl_line_buffer[rl_point] != '/')
|
|---|
| 322 | ! rl_insert_text ("/");
|
|---|
| 323 | ! }
|
|---|
| 324 | ! else
|
|---|
| 325 | ! {
|
|---|
| 326 | ! if (rl_point == rl_end)
|
|---|
| 327 | ! rl_insert_text (temp_string);
|
|---|
| 328 | ! }
|
|---|
| 329 | ! free (filename);
|
|---|
| 330 | }
|
|---|
| 331 | }
|
|---|
| 332 | else
|
|---|
| 333 | {
|
|---|
| 334 | Only in bash-1.14.2.local/lib/readline: diffs
|
|---|
| 335 | diff -rc bash-1.14.2/lib/readline/readline.c bash-1.14.2.local/lib/readline/readline.c
|
|---|
| 336 | *** bash-1.14.2/lib/readline/readline.c Fri Aug 12 12:47:46 1994
|
|---|
| 337 | --- bash-1.14.2.local/lib/readline/readline.c Wed Sep 21 15:36:07 1994
|
|---|
| 338 | ***************
|
|---|
| 339 | *** 23,28 ****
|
|---|
| 340 | --- 23,29 ----
|
|---|
| 341 | #define READLINE_LIBRARY
|
|---|
| 342 |
|
|---|
| 343 | #include <stdio.h>
|
|---|
| 344 | + #include <string.h>
|
|---|
| 345 | #include <sys/types.h>
|
|---|
| 346 | #include <fcntl.h>
|
|---|
| 347 | #if !defined (NO_SYS_FILE)
|
|---|
| 348 | ***************
|
|---|
| 349 | *** 3518,3523 ****
|
|---|
| 350 | --- 3519,3616 ----
|
|---|
| 351 | }
|
|---|
| 352 |
|
|---|
| 353 | #endif /* TEST */
|
|---|
| 354 | +
|
|---|
| 355 | + #define cr_whitespace(c) ((c) == '\r' || (c) == '\n' || whitespace(c))
|
|---|
| 356 | +
|
|---|
| 357 | + char *
|
|---|
| 358 | + get_mh_path ()
|
|---|
| 359 | + {
|
|---|
| 360 | + static FILE *fp = (FILE *)NULL;
|
|---|
| 361 | + char buf[512]; /* XXX */
|
|---|
| 362 | + char profile[512]; /* XXX */
|
|---|
| 363 | + char *bp;
|
|---|
| 364 | + char *temp_home;
|
|---|
| 365 | + char *temp_path;
|
|---|
| 366 | +
|
|---|
| 367 | + temp_home = (char *)getenv ("HOME");
|
|---|
| 368 | + if (!temp_home)
|
|---|
| 369 | + return ((char *)NULL);
|
|---|
| 370 | +
|
|---|
| 371 | + strcpy (profile, temp_home);
|
|---|
| 372 | + strcat (profile, "/.mh_profile");
|
|---|
| 373 | +
|
|---|
| 374 | + if (fp)
|
|---|
| 375 | + fclose (fp);
|
|---|
| 376 | +
|
|---|
| 377 | + fp = fopen (profile, "r");
|
|---|
| 378 | + if (fp == (FILE *)NULL)
|
|---|
| 379 | + return ((char *)NULL);
|
|---|
| 380 | +
|
|---|
| 381 | + while (fgets (buf, 512, fp) != (char *)NULL) /* XXX */
|
|---|
| 382 | + {
|
|---|
| 383 | + if ((bp = strstr (buf, "Path:")) != (char *)NULL)
|
|---|
| 384 | + {
|
|---|
| 385 | + bp += 5;
|
|---|
| 386 | + while (whitespace (*bp))
|
|---|
| 387 | + bp++;
|
|---|
| 388 | +
|
|---|
| 389 | + if (*bp == '\0')
|
|---|
| 390 | + return ((char *)NULL);
|
|---|
| 391 | +
|
|---|
| 392 | + temp_path = (char *)xmalloc (3 + strlen (bp) + strlen (temp_home));
|
|---|
| 393 | +
|
|---|
| 394 | + strcpy (temp_path, temp_home);
|
|---|
| 395 | + strcat (temp_path, "/");
|
|---|
| 396 | + strcat (temp_path, bp);
|
|---|
| 397 | +
|
|---|
| 398 | + bp = temp_path;
|
|---|
| 399 | +
|
|---|
| 400 | + while (!(cr_whitespace (*bp)))
|
|---|
| 401 | + bp++;
|
|---|
| 402 | +
|
|---|
| 403 | + *bp = '\0';
|
|---|
| 404 | +
|
|---|
| 405 | + return temp_path;
|
|---|
| 406 | + }
|
|---|
| 407 | + }
|
|---|
| 408 | +
|
|---|
| 409 | + return ((char *)NULL);
|
|---|
| 410 | + }
|
|---|
| 411 | +
|
|---|
| 412 | + /* Expand FILENAME if it begins with a plus. This always returns
|
|---|
| 413 | + a new string. */
|
|---|
| 414 | + char *
|
|---|
| 415 | + plus_expand (filename)
|
|---|
| 416 | + char *filename;
|
|---|
| 417 | + {
|
|---|
| 418 | + static char *dirname = (char *)NULL;
|
|---|
| 419 | +
|
|---|
| 420 | + if (filename && *filename == '+')
|
|---|
| 421 | + {
|
|---|
| 422 | + char *mh_path = get_mh_path ();
|
|---|
| 423 | +
|
|---|
| 424 | + if (filename[1] == '/' || filename[1] == '.')
|
|---|
| 425 | + {
|
|---|
| 426 | + dirname = (char *)xmalloc (1 + strlen (filename));
|
|---|
| 427 | +
|
|---|
| 428 | + strcpy(dirname, filename+1);
|
|---|
| 429 | +
|
|---|
| 430 | + return dirname;
|
|---|
| 431 | + }
|
|---|
| 432 | +
|
|---|
| 433 | + if (mh_path)
|
|---|
| 434 | + {
|
|---|
| 435 | + dirname = (char *)xmalloc (1 + strlen (filename) + strlen (mh_path));
|
|---|
| 436 | +
|
|---|
| 437 | + strcpy (dirname, mh_path);
|
|---|
| 438 | + strcat (dirname, "/");
|
|---|
| 439 | + strcat (dirname, filename+1);
|
|---|
| 440 | +
|
|---|
| 441 | + return dirname;
|
|---|
| 442 | + }
|
|---|
| 443 | + }
|
|---|
| 444 | + return (char *)NULL;
|
|---|
| 445 | + }
|
|---|
| 446 |
|
|---|
| 447 | |
|---|
| 448 |
|
|---|
| 449 | /*
|
|---|
| 450 |
|
|---|