summaryrefslogtreecommitdiffstats
path: root/examples/loadables/basename.c
blob: 29dd1a6db68ef833fabf68a04227861de5b93bf4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* basename - return nondirectory portion of pathname */

/* See Makefile for compilation details. */

/*
   Copyright (C) 1999-2020 Free Software Foundation, Inc.

   This file is part of GNU Bash.
   Bash is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   Bash is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "config.h"

#if defined (HAVE_UNISTD_H)
#  include <unistd.h>
#endif

#include <stdio.h>
#include "builtins.h"
#include "shell.h"
#include "common.h"
#include "bashgetopt.h"

int
basename_builtin (list)
     WORD_LIST *list;
{
  int slen, sufflen, off;
  char *string, *suffix, *fn;

  if (no_options (list))
    return (EX_USAGE);
  list = loptend;
  if (list == 0)
    {
      builtin_usage ();
      return (EX_USAGE);
    }    

  string = list->word->word;
  suffix = (char *)NULL;
  if (list->next)
    {
      list = list->next;
      suffix = list->word->word;
    }

  if (list->next)
    {
      builtin_usage ();
      return (EX_USAGE);
    }

  slen = strlen (string);

  /* Strip trailing slashes */
  while (slen > 0 && string[slen - 1] == '/')
    slen--;

  /* (2) If string consists entirely of slash characters, string shall be
	 set to a single slash character.  In this case, skip steps (3)
	 through (5). */
  if (slen == 0)
    {
      fputs ("/\n", stdout);
      return (EXECUTION_SUCCESS);
    }

  /* (3) If there are any trailing slash characters in string, they
	 shall be removed. */
  string[slen] = '\0';

  /* (4) If there are any slash characters remaining in string, the prefix
	 of string up to an including the last slash character in string
	 shall be removed. */
  while (--slen >= 0)
    if (string[slen] == '/')
      break;

  fn = string + slen + 1;

  /* (5) If the suffix operand is present, is not identical to the
	 characters remaining in string, and is identical to a suffix
	 of the characters remaining in string, the suffix suffix
	 shall be removed from string.  Otherwise, string shall not be
	 modified by this step. */
  if (suffix)
    {
      sufflen = strlen (suffix);
      slen = strlen (fn);
      if (sufflen < slen)
        {
          off = slen - sufflen;
          if (strcmp (fn + off, suffix) == 0)
            fn[off] = '\0';
        }
    }
  printf ("%s\n", fn);
  return (EXECUTION_SUCCESS);
}

char *basename_doc[] = {
	"Return non-directory portion of pathname.",
	"",
	"The STRING is converted to a filename corresponding to the last",
	"pathname component in STRING.  If the suffix string SUFFIX is",
	"supplied, it is removed.",
	(char *)NULL
};

/* The standard structure describing a builtin command.  bash keeps an array
   of these structures. */
struct builtin basename_struct = {
	"basename",		/* builtin name */
	basename_builtin,	/* function implementing the builtin */
	BUILTIN_ENABLED,	/* initial flags for builtin */
	basename_doc,		/* array of long documentation strings. */
	"basename string [suffix]",	/* usage synopsis */
	0			/* reserved for internal use */
};