Blame view

examples/listop.c 7.63 KB
1
/* GNU Mailutils -- a suite of utilities for electronic mail
2
   Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
3 4 5

   GNU Mailutils is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
6
   the Free Software Foundation; either version 3, or (at your option)
7 8 9 10 11 12 13 14 15
   any later version.

   GNU Mailutils 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 GNU Mailutils; if not, write to the Free Software
16 17
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   MA 02110-1301 USA */
18

19 20 21
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <mailutils/argcv.h>
#include <mailutils/mailutils.h>

void
usage(int code)
{
  printf ("usage: listop [item..]\n");
  exit (code);
}

void
lperror (char *text, int rc)
{
  fprintf (stderr, "%s: %s\n", text, mu_strerror (rc));
  exit (1);
}

void
43
print (mu_list_t list)
44
{
45
  mu_iterator_t itr;
46 47
  int rc;
  
48
  rc = mu_list_get_iterator (list, &itr);
49
  if (rc)
50
    lperror ("mu_list_get_iterator", rc);
51

52
  for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr))
53 54 55
    {
      char *text;

56
      rc = mu_iterator_current (itr, (void**) &text);
57
      if (rc)
58
	lperror ("mu_iterator_current", rc);
59 60
      printf ("%s\n", text);
    }
61
  mu_iterator_destroy (&itr);
62 63 64
}

void
65
next (mu_iterator_t itr, char *arg)
66 67 68 69 70 71
{
  int skip = arg ? strtoul (arg, NULL, 0) :  1;

  if (skip == 0)
    fprintf (stderr, "next arg?\n");
  while (skip--)
72
    mu_iterator_next (itr);
73 74 75
}

void
76
delete (mu_list_t list, int argc, char **argv)
77 78 79 80 81 82 83 84 85 86 87
{
  int rc;

  if (argc == 1)
    {
      fprintf (stderr, "del arg?\n");
      return;
    }

  while (--argc)
    {
88
      rc = mu_list_remove (list, strdup (*++argv));
89
      if (rc)
90
	fprintf (stderr, "mu_list_remove(%s): %s\n", *argv, mu_strerror (rc));
91 92 93 94
    }
}

void
95
add (mu_list_t list, int argc, char **argv)
96 97 98 99 100 101 102 103 104 105 106
{
  int rc;
  
  if (argc == 1)
    {
      fprintf (stderr, "add arg?\n");
      return;
    }

  while (--argc)
    {
107
      rc = mu_list_append (list, strdup (*++argv));
108
      if (rc)
109
	fprintf (stderr, "mu_list_append: %s\n", mu_strerror (rc));
110 111 112 113
    }
}

void
114
prep (mu_list_t list, int argc, char **argv)
115 116 117 118 119 120 121 122 123 124 125
{
  int rc;
  
  if (argc == 1)
    {
      fprintf (stderr, "add arg?\n");
      return;
    }

  while (--argc)
    {
126
      rc = mu_list_prepend (list, strdup (*++argv));
127
      if (rc)
128
	fprintf (stderr, "mu_list_append: %s\n", mu_strerror (rc));
129 130 131 132
    }
}

void
133
ins (mu_list_t list, int argc, char **argv)
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
{
  int rc;
  char *item;
  char *new_item;
  
  if (argc < 3 || argc > 4)
    {
      fprintf (stderr, "ins [before] item new_item?\n");
      return;
    }

  if (argc == 4)
    {
      if (strcmp (argv[1], "before"))
	{
	  fprintf (stderr, "ins before item new_item?\n");
	  return;
	}
	
      item = argv[2];
      new_item = argv[3];
    }
  else
    {
      item = argv[1];
      new_item = argv[2];
    }
  
162
  rc = mu_list_insert (list, item, strdup (new_item), argc == 4);
163
  if (rc)
164
    fprintf (stderr, "mu_list_insert: %s\n", mu_strerror (rc));
165 166 167 168
}


void
169
repl (mu_list_t list, int argc, char **argv)
170 171 172 173 174 175 176 177 178
{
  int rc;
  
  if (argc != 3)
    {
      fprintf (stderr, "repl src dst?\n");
      return;
    }

179
  rc = mu_list_replace (list, argv[1], strdup (argv[2]));
180
  if (rc)
181
    fprintf (stderr, "mu_list_replace: %s\n", mu_strerror (rc));
182 183 184 185
}

#define NITR 4

186
int
187 188 189 190 191 192 193
iter (int *pnum, int argc, char **argv)
{
  int n;
  
  if (argc != 2)
    {
      fprintf (stderr, "iter num?\n");
194
      return 1;
195 196 197 198 199 200
    }

  n = strtoul (argv[1], NULL, 0);
  if (n < 0 || n >= NITR)
    {
      fprintf (stderr, "iter [0-3]?\n");
201
      return 1;
202 203
    }
  *pnum = n;
204
  return 0;
205 206 207
}

void
208
find (mu_iterator_t itr, char *arg)
209 210 211 212 213 214 215 216 217
{
  char *text;
  
  if (!arg)
    {
      fprintf (stderr, "find item?\n");
      return;
    }

218 219
  mu_iterator_current (itr, (void**)&text);
  for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr))
220 221 222
    {
      char *item;

223
      mu_iterator_current (itr, (void**)&item);
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
      if (strcmp (arg, item) == 0)
	return;
    }

  fprintf (stderr, "%s not in list\n", arg);
}

void
help ()
{
  printf ("next [count]\n");
  printf ("first\n");
  printf ("find item\n");
  printf ("del item [item...]\n");
  printf ("add item [item...]\n");
  printf ("prep item [item...]\n");
  printf ("repl old_item new_item\n");
241
  printf ("ins [before] item new_item\n");
242 243 244 245 246 247 248 249
  printf ("print\n");
  printf ("quit\n");
  printf ("iter num\n");
  printf ("help\n");
  printf ("NUMBER\n");
}

void
250
shell (mu_list_t list)
251 252
{
  int num = 0;
253
  mu_iterator_t itr[NITR];
254 255
  int rc;

Sergey Poznyakoff authored
256
  memset (&itr, 0, sizeof itr);
257 258 259 260 261 262 263
  num = 0;
  while (1)
    {
      char *text;
      char buf[80];
      int argc;
      char **argv;
Sergey Poznyakoff authored
264 265 266 267 268 269 270 271

      if (!itr[num])
	{
	  rc = mu_list_get_iterator (list, &itr[num]);
	  if (rc)
	    lperror ("mu_list_get_iterator", rc);
	  mu_iterator_first (itr[num]);
	}
272
      
273
      rc = mu_iterator_current (itr[num], (void**) &text);
274
      if (rc)
275
	lperror ("mu_iterator_current", rc);
276 277 278 279 280

      printf ("%d:(%s)> ", num, text ? text : "NULL");
      if (fgets (buf, sizeof buf, stdin) == NULL)
	return;

281
      rc = mu_argcv_get (buf, "", "#", &argc, &argv);
282
      if (rc)
283
	lperror ("mu_argcv_get", rc);
284 285 286 287 288 289

      if (argc > 0)
	{
	  if (strcmp (argv[0], "next") == 0)
	    next (itr[num], argv[1]);
	  else if (strcmp (argv[0], "first") == 0)
290
	    mu_iterator_first (itr[num]);
291 292 293 294 295 296
	  else if (strcmp (argv[0], "del") == 0)
	    delete (list, argc, argv);
	  else if (strcmp (argv[0], "add") == 0)
	    add (list, argc, argv);
	  else if (strcmp (argv[0], "prep") == 0)
	    prep (list, argc, argv);
297 298
	  else if (strcmp (argv[0], "ins") == 0)
	    ins (list, argc, argv);
299 300 301 302 303 304 305
	  else if (strcmp (argv[0], "repl") == 0)
	    repl (list, argc, argv);
	  else if (strcmp (argv[0], "print") == 0)
	    print (list);
	  else if (strcmp (argv[0], "quit") == 0)
	    return;
	  else if (strcmp (argv[0], "iter") == 0)
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
	    {
	      int n;
	      if (iter (&n, argc, argv) == 0 && !itr[n])
		{
		  rc = mu_list_get_iterator (list, &itr[n]);
		  if (rc)
		    lperror ("mu_list_get_iterator", rc);
		  mu_iterator_first (itr[n]);
		}
	      num = n;
	    }
	  else if (strcmp (argv[0], "close") == 0)
	    {
	      int n;
	      if (iter (&n, argc, argv) == 0)
		{
		  mu_iterator_destroy (&itr[n]);
		  if (n == num && ++num == NITR)
		    num = 0;
		}
	    }
327 328 329 330 331 332 333 334 335 336 337 338
	  else if (strcmp (argv[0], "find") == 0)
	    find (itr[num], argv[1]);
	  else if (strcmp (argv[0], "help") == 0)
	    help ();
	  else if (argc == 1)
	    {
	      char *p;
	      size_t n = strtoul (argv[0], &p, 0);
	      if (*p != 0)
		fprintf (stderr, "?\n");
	      else
		{
339
		  rc = mu_list_get (list, n, (void**) &text);
340
		  if (rc)
341
		    fprintf (stderr, "mu_list_get: %s\n", mu_strerror (rc));
342 343 344 345 346 347 348
		  else
		    printf ("%s\n", text);
		}
	    }
	  else
	    fprintf (stderr, "?\n");
	}
349
      mu_argcv_free (argc, argv);
350 351 352 353 354 355 356 357 358 359 360 361
    }
}

static int
string_comp (const void *item, const void *value)
{
  return strcmp (item, value);
}

int
main (int argc, char **argv)
{
362
  mu_list_t list;
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
  int rc;
  
  while ((rc = getopt (argc, argv, "h")) != EOF)
    switch (rc)
      {
      case 'h':
	usage (0);
	
      default:
	usage (1);
      }

  argc -= optind;
  argv += optind;

378
  rc = mu_list_create (&list);
379
  if (rc)
380 381
    lperror ("mu_list_create", rc);
  mu_list_set_comparator (list, string_comp);
382 383 384

  while (argc--)
    {
385
      rc = mu_list_append (list, *argv++);
386
      if (rc)
387
	lperror ("mu_list_append", rc);
388 389 390 391 392 393
    }

  shell (list);
  
  return 0;
}