blob: 0f30286d29fc751597d99a6ff7bb3e8c2151bfce [file] [log] [blame]
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001/* dirname - return directory portion of pathname */
2
3/* See Makefile for compilation details. */
4
Jari Aalto31859422009-01-12 13:36:28 +00005/*
6 Copyright (C) 1999-2009 Free Software Foundation, Inc.
7
8 This file is part of GNU Bash.
9 Bash is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Bash is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Bash. If not, see <http://www.gnu.org/licenses/>.
21*/
22
Jari Aaltoccc6cda1996-12-23 17:02:34 +000023#include "config.h"
24
25#if defined (HAVE_UNISTD_H)
26# include <unistd.h>
27#endif
28
29#include <stdio.h>
30#include "builtins.h"
31#include "shell.h"
Jari Aalto31859422009-01-12 13:36:28 +000032#include "common.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000033
34dirname_builtin (list)
35 WORD_LIST *list;
36{
37 int slen;
38 char *string;
39
40 if (list == 0 || list->next)
41 {
42 builtin_usage ();
43 return (EX_USAGE);
44 }
45
46 if (no_options (list))
47 return (EX_USAGE);
48
49 string = list->word->word;
50 slen = strlen (string);
51
52 /* Strip trailing slashes */
53 while (slen > 0 && string[slen - 1] == '/')
54 slen--;
55
56 /* (2) If string consists entirely of slash characters, string shall be
57 set to a single slash character. In this case, skip steps (3)
58 through (8). */
59 if (slen == 0)
60 {
61 fputs ("/\n", stdout);
62 return (EXECUTION_SUCCESS);
63 }
64
65 /* (3) If there are any trailing slash characters in string, they
66 shall be removed. */
67 string[slen] = '\0';
68
69 /* (4) If there are no slash characters remaining in string, string
70 shall be set to a single period character. In this case, skip
71 steps (5) through (8).
72
73 (5) If there are any trailing nonslash characters in string,
74 they shall be removed. */
75
76 while (--slen >= 0)
77 if (string[slen] == '/')
78 break;
79
Jari Aaltob72432f1999-02-19 17:11:39 +000080 if (slen < 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +000081 {
82 fputs (".\n", stdout);
83 return (EXECUTION_SUCCESS);
84 }
85
86 /* (7) If there are any trailing slash characters in string, they
87 shall be removed. */
88 while (--slen >= 0)
89 if (string[slen] != '/')
90 break;
91 string[++slen] = '\0';
92
93 /* (8) If the remaining string is empty, string shall be set to a single
94 slash character. */
95 printf ("%s\n", (slen == 0) ? "/" : string);
96 return (EXECUTION_SUCCESS);
97}
98
99char *dirname_doc[] = {
Jari Aalto31859422009-01-12 13:36:28 +0000100 "Display directory portion of pathname.",
101 "",
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000102 "The STRING is converted to the name of the directory containing",
103 "the filename corresponding to the last pathname component in STRING.",
104 (char *)NULL
105};
106
107/* The standard structure describing a builtin command. bash keeps an array
108 of these structures. */
109struct builtin dirname_struct = {
110 "dirname", /* builtin name */
111 dirname_builtin, /* function implementing the builtin */
112 BUILTIN_ENABLED, /* initial flags for builtin */
113 dirname_doc, /* array of long documentation strings. */
114 "dirname string", /* usage synopsis */
115 0 /* reserved for internal use */
116};