1/* dirname - return directory portion of pathname */
2
3/* See Makefile for compilation details. */
4
5#include "config.h"
6
7#if defined (HAVE_UNISTD_H)
8#  include <unistd.h>
9#endif
10
11#include <stdio.h>
12#include "builtins.h"
13#include "shell.h"
14
15dirname_builtin (list)
16     WORD_LIST *list;
17{
18  int slen;
19  char *string;
20
21  if (list == 0 || list->next)
22    {
23      builtin_usage ();
24      return (EX_USAGE);
25    }
26
27  if (no_options (list))
28    return (EX_USAGE);
29
30  string = list->word->word;
31  slen = strlen (string);
32
33  /* Strip trailing slashes */
34  while (slen > 0 && string[slen - 1] == '/')
35    slen--;
36
37  /* (2) If string consists entirely of slash characters, string shall be
38	 set to a single slash character.  In this case, skip steps (3)
39	 through (8). */
40  if (slen == 0)
41    {
42      fputs ("/\n", stdout);
43      return (EXECUTION_SUCCESS);
44    }
45
46  /* (3) If there are any trailing slash characters in string, they
47	 shall be removed. */
48  string[slen] = '\0';
49
50  /* (4) If there are no slash characters remaining in string, string
51	 shall be set to a single period character.  In this case, skip
52	 steps (5) through (8).
53
54     (5) If there are any trailing nonslash characters in string,
55	 they shall be removed. */
56
57  while (--slen >= 0)
58    if (string[slen] == '/')
59      break;
60
61  if (slen < 0)
62    {
63      fputs (".\n", stdout);
64      return (EXECUTION_SUCCESS);
65    }
66
67  /* (7) If there are any trailing slash characters in string, they
68	 shall be removed. */
69  while (--slen >= 0)
70    if (string[slen] != '/')
71      break;
72  string[++slen] = '\0';
73
74  /* (8) If the remaining string is empty, string shall be set to a single
75	 slash character. */
76  printf ("%s\n", (slen == 0) ? "/" : string);
77  return (EXECUTION_SUCCESS);
78}
79
80char *dirname_doc[] = {
81	"The STRING is converted to the name of the directory containing",
82	"the filename corresponding to the last pathname component in STRING.",
83	(char *)NULL
84};
85
86/* The standard structure describing a builtin command.  bash keeps an array
87   of these structures. */
88struct builtin dirname_struct = {
89	"dirname",		/* builtin name */
90	dirname_builtin,	/* function implementing the builtin */
91	BUILTIN_ENABLED,	/* initial flags for builtin */
92	dirname_doc,		/* array of long documentation strings. */
93	"dirname string",	/* usage synopsis */
94	0			/* reserved for internal use */
95};
96