]> git.ipfire.org Git - thirdparty/readline.git/blame - examples/hist_purgecmd.c
readline-8.0 distribution sources and documentation
[thirdparty/readline.git] / examples / hist_purgecmd.c
CommitLineData
7628b745
CR
1/* hist_purgecmd -- remove all instances of command or pattern from history
2 file */
3
4/* Copyright (C) 2011 Free Software Foundation, Inc.
5
6 This file is part of the GNU Readline Library (Readline), a library for
7 reading lines of text with interactive input and history editing.
8
9 Readline 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 Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
21*/
22#ifndef READLINE_LIBRARY
23#define READLINE_LIBRARY 1
24#endif
25
26#include <unistd.h>
27#include <stdlib.h>
28#include <stdio.h>
29
30#include <regex.h>
31
32#ifdef READLINE_LIBRARY
33# include "history.h"
34#else
35# include <readline/history.h>
36#endif
37
38#include <string.h>
39
40#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0)
41#define STREQN(a, b, n) ((n == 0) ? (1) \
42 : ((a)[0] == (b)[0] && strncmp(a, b, n) == 0))
43
7628b745
CR
44#define PURGE_REGEXP 0x01
45
8e6ccd03
CR
46int hist_purgecmd (char *, int);
47
7628b745
CR
48static void
49usage()
50{
51 fprintf (stderr, "hist_purgecmd: usage: hist_purgecmd [-r] [-t] [-f filename] command-spec\n");
52 exit (2);
53}
54
55int
56main (argc, argv)
57 int argc;
58 char **argv;
59{
60 char *fn;
61 int r, flags;
62
63 flags = 0;
64 fn = 0;
65 while ((r = getopt (argc, argv, "f:rt")) != -1)
66 {
67 switch (r)
68 {
69 case 'f':
70 fn = optarg;
71 break;
72 case 'r':
73 flags |= PURGE_REGEXP;
74 break;
75 case 't':
76 history_write_timestamps = 1;
77 break;
78 default:
79 usage ();
80 }
81 }
82 argv += optind;
83 argc -= optind;
84
85 if (fn == 0)
86 fn = getenv ("HISTFILE");
87 if (fn == 0)
88 {
89 fprintf (stderr, "hist_purgecmd: no history file\n");
90 usage ();
91 }
92
93 if ((r = read_history (fn)) != 0)
94 {
95 fprintf (stderr, "hist_purgecmd: read_history: %s: %s\n", fn, strerror (r));
96 exit (1);
97 }
98
99 for (r = 0; r < argc; r++)
100 hist_purgecmd (argv[r], flags);
101
102 if ((r = write_history (fn)) != 0)
103 {
104 fprintf (stderr, "hist_purgecmd: write_history: %s: %s\n", fn, strerror (r));
105 exit (1);
106 }
107
108 exit (0);
109}
110
111int
112hist_purgecmd (cmd, flags)
113 char *cmd;
114 int flags;
115{
116 int r, n, rflags;
117 HIST_ENTRY *temp;
118 regex_t regex = { 0 };
119
120 if (flags & PURGE_REGEXP)
121 {
122 rflags = REG_EXTENDED|REG_NOSUB;
123 if (regcomp (&regex, cmd, rflags))
124 {
125 fprintf (stderr, "hist_purgecmd: %s: invalid regular expression\n", cmd);
126 return -1;
127 }
128 }
129
130 r = 0;
131 using_history ();
132 r = where_history ();
133 for (n = 0; n < r; n++)
134 {
135 temp = history_get (n+history_base);
136 if (((flags & PURGE_REGEXP) && (regexec (&regex, temp->line, 0, 0, 0) == 0)) ||
137 ((flags & PURGE_REGEXP) == 0 && STREQ (temp->line, cmd)))
138 {
139 remove_history (n);
140 r--; /* have to get one fewer now */
141 n--; /* compensate for above increment */
142 history_offset--; /* moving backwards in history list */
143 }
144 }
145 using_history ();
146
147 if (flags & PURGE_REGEXP)
148 regfree (&regex);
149
150 return r;
151}