Commit | Line | Data |
---|---|---|
7833f723 KB |
1 | /*- |
2 | * Copyright (c) 1991 The Regents of the University of California. | |
a7bbb248 KB |
3 | * All rights reserved. |
4 | * | |
f15db449 | 5 | * %sccs.include.redist.c% |
a7bbb248 KB |
6 | */ |
7 | ||
8 | #ifndef lint | |
9 | char copyright[] = | |
7833f723 | 10 | "@(#) Copyright (c) 1991 The Regents of the University of California.\n\ |
a7bbb248 KB |
11 | All rights reserved.\n"; |
12 | #endif /* not lint */ | |
13 | ||
14 | #ifndef lint | |
7833f723 | 15 | static char sccsid[] = "@(#)dirname.c 5.6 (Berkeley) %G%"; |
a7bbb248 KB |
16 | #endif /* not lint */ |
17 | ||
b0368404 | 18 | #include <stdio.h> |
7833f723 | 19 | #include <stdlib.h> |
b0368404 | 20 | |
a7bbb248 KB |
21 | main(argc, argv) |
22 | int argc; | |
23 | char **argv; | |
24 | { | |
7833f723 KB |
25 | extern int optind; |
26 | register char *p; | |
27 | int ch; | |
a7bbb248 | 28 | |
7833f723 KB |
29 | while ((ch = getopt(argc, argv, "")) != EOF) |
30 | switch(ch) { | |
31 | case '?': | |
32 | default: | |
33 | usage(); | |
34 | } | |
35 | argc -= optind; | |
36 | argv += optind; | |
37 | ||
38 | if (argc != 1) | |
39 | usage(); | |
40 | ||
41 | /* | |
42 | * (1) If string is //, skip steps (2) through (5). | |
43 | * (2) If string consists entirely of slash characters, string | |
44 | * shall be set to a single slash character. In this case, | |
45 | * skip steps (3) through (8). | |
46 | */ | |
47 | for (p = *argv;; ++p) { | |
48 | if (!*p) { | |
49 | if (p > *argv) | |
50 | (void)printf("/\n"); | |
51 | else | |
52 | (void)printf(".\n"); | |
53 | exit(0); | |
54 | } | |
55 | if (*p != '/') | |
56 | break; | |
57 | } | |
58 | ||
59 | /* | |
60 | * (3) If there are any trailing slash characters in string, they | |
61 | * shall be removed. | |
62 | */ | |
63 | for (; *p; ++p); | |
64 | while (*--p == '/'); | |
65 | *++p = '\0'; | |
66 | ||
67 | /* | |
68 | * (4) If there are no slash characters remaining in string, | |
69 | * string shall be set to a single period character. In this | |
70 | * case skip steps (5) through (8). | |
71 | * | |
72 | * (5) If there are any trailing nonslash characters in string, | |
73 | * they shall be removed. | |
74 | */ | |
75 | while (--p >= *argv) | |
76 | if (*p == '/') | |
77 | break; | |
78 | ++p; | |
79 | if (p == *argv) { | |
80 | (void)printf(".\n"); | |
81 | exit(0); | |
b0368404 | 82 | } |
7833f723 KB |
83 | |
84 | /* | |
85 | * (6) If the remaining string is //, it is implementation defined | |
86 | * whether steps (7) and (8) are skipped or processed. | |
87 | * | |
88 | * This case has already been handled, as part of steps (1) and (2). | |
89 | */ | |
90 | ||
91 | /* | |
92 | * (7) If there are any trailing slash characters in string, they | |
93 | * shall be removed. | |
94 | */ | |
95 | while (--p >= *argv) | |
96 | if (*p != '/') | |
97 | break; | |
98 | ++p; | |
99 | ||
100 | /* | |
101 | * (8) If the remaining string is empty, string shall be set to | |
102 | * a single slash character. | |
103 | */ | |
104 | *p = '\0'; | |
105 | (void)printf("%s\n", p == *argv ? "/" : *argv); | |
a7bbb248 KB |
106 | exit(0); |
107 | } | |
7833f723 KB |
108 | |
109 | usage() | |
110 | { | |
111 | (void)fprintf(stderr, "usage: dirname path\n"); | |
112 | exit(1); | |
113 | } |