Logo Search packages:      
Sourcecode: latrine version File versions  Download package

options.c

/* vim: set noet ts=4:
 *
 * Copyright (c) 2002-2006 Martin A. Godisch <martin@godisch.de>.
 *
 * This program 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 2 of the License, or (at your option) any later
 * version.
 *
 * This program 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
 * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
 * St, Fifth Floor, Boston, MA 02110-1301, USA.
 */
#include <data.h>
#include <getopt.h>
#include <latrine.h>
#include <memory.h>
#include <screen.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <zlib.h>

int  digraph      = 0;
int  direction    = 0;
int  ignore_case  = 0;
int  mode         = MODE_NORMAL;
char *keymap[2]   = {NULL, NULL};
char *language[2] = {NULL, NULL};

static char *fullpath(const char *arg)
{
      char buffer[BUFSIZE];
      char *res   = NULL;
      char *i, *j = NULL;
      size_t n;

      assert(arg);
      switch (*arg) {
      case '/':
            res = STRDUP(arg);
            break;
      case '~':
            if (arg[1] == '/') {
                  res = (char*)MALLOC(strlen(getenv("HOME")) + strlen(arg));
                  sprintf(res, "%s/%s", getenv("HOME"), arg + 2);
                  break;
            }
            /* no break */
      default:
            memset(buffer, 0, BUFSIZE);
            if (getcwd(buffer, BUFSIZE - 1) == NULL || (n = strlen(buffer) + strlen(arg) + 2) > BUFSIZE) {
                  errmsg(_("current working directory too long"));
                  exit(1);
            }
            res = (char*)MALLOC(n);
            sprintf(res, "%s/%s", buffer, arg);
      }
      while ((i = strstr(res, "/./"))  != NULL)
            memmove(i, i + 2, strlen(i) - 1);
      while ((i = strstr(res, "//"))   != NULL)
            memmove(i, i + 1, strlen(i));
      while ((i = strstr(res, "/../")) != NULL) {
            for (j = i - 1; i >= res && *j != '/'; j--);
            if (j < res) {
                  errmsg(_("invalid path: %s"), arg);
                  exit(1);
            }
            memmove(j, i + 3, strlen(i) - 2);
      }
      return res;
}

static char *mkdictfile(const char *arg)
{
      char *dict = NULL;
      struct stat dummy;

      if (arg == NULL)
            return NULL;
      if (index(arg, '/') == NULL) {
            dict = (char*)MALLOC(strlen(DICTDIR) + strlen(arg) + 10);
            sprintf(dict, "%s/%s.dict.dz", DICTDIR, arg);
            if (stat(dict, &dummy) == -1 && errno == ENOENT && stat(arg, &dummy) == 0) {
                  if (debug)
                        errmsg(_("cannot find %s in %s, assuming ./%s"), arg, DICTDIR, arg);
                  FREE(&dict);
                  return fullpath(arg);
            }
            return dict;
      } else
            return fullpath(arg);
}

static char *mkkeymap(const char *arg)
{
      if (arg == NULL)
            return NULL;
      return fullpath(arg);
}

static char *mkwordfile(const char *dict)
{
      char *word = NULL;
      char *home = NULL;
      char *i    = NULL;

      if (dict == NULL)
            return NULL;
      word = (char*)MALLOC(strlen(home = getenv("HOME")) + strlen(dict) + 14);
      sprintf(word, "%s/.latrine/%s.gz", home, dict);
      i = word + strlen(home) + 10;
      while ((i = index(i, '/')) != NULL)
            *i++ = '_';
      return word;
}

void do_conf(const char *rcfile)
{
      FILE *F = NULL;
      char
            buffer[BUFSIZE],
            *s      = NULL,
            *optarg = NULL;
      int line;

      if ((F = fopen(rcfile, "r")) == NULL) {
            if (errno != ENOENT)
                  errmsg(_("cannot open config file: %s"), strerror(errno));
            return;
      }
      for (line = 1; fgets(buffer, sizeof(buffer), F) != NULL; line++) {
            if ((s = index(buffer, '\n')) != NULL)
                  *s = '\0';
            while ((s = index(buffer, ' ')) || (s = index(buffer, '\t')))
                  do {
                        *s = *(s+1);
                  } while (*s++);
            if (*buffer == '\0' || *buffer == '#')
                  continue;
            if ((optarg = index(buffer, '=')) != NULL)
                  *optarg++ = '\0';
            if (strcmp(buffer, "dict") == 0 && optarg) {
                  dictfile = mkdictfile(optarg);
                  wordfile = mkwordfile(dictfile);
            } else if (strcmp(buffer, "debug") == 0) {
                  debug = 1;
            } else if (strcmp(buffer, "digraph") == 0) {
                  digraph = 1;
            } else if (strcmp(buffer, "direction") == 0 && optarg) {
                  direction = strtol(optarg, &s, 10);
                  if (*s != 0 || direction < 0 || direction >= 4) {
                        errmsg(_("invalid direction in %s line %d -- %s"), rcfile, line, optarg);
                        exit(1);
                  }
            } else if (strcmp(buffer, "force") == 0)
                  errmsg(_("ignoring --force in config file"));
            else if (strcmp(buffer, "ignore-case") == 0)
                  ignore_case = 1;
            else if (strcmp(buffer, "label") == 0 && optarg) {
                  if (*optarg == '/') {
                        language[1] = STRDUP(optarg + 1);
                  } else {
                        language[0] = STRDUP(optarg);
                        if ((s = index(language[0], '/')) != NULL) {
                              *s++  = 0;
                              language[1] = s;
                        }
                  }
            } else if (strcmp(buffer, "keymap1") == 0 && optarg) {
                  FREE(&keymap[0]);
                  keymap[0] = mkkeymap(optarg);
            } else if (strcmp(buffer, "keymap2") == 0 && optarg) {
                  FREE(&keymap[1]);
                  keymap[1] = mkkeymap(optarg);
            } else if (strcmp(buffer, "limit") == 0 && optarg) {
                  wordlimit = strtol(optarg, &s, 10);
                  if (*s != 0) {
                        errmsg(_("invalid memory limit in %s line %d -- %s"), rcfile, line, optarg);
                        exit(1);
                  }
            } else if (strcmp(buffer, "mode") == 0 && optarg) {
                  if (strcasecmp(optarg, "normal") == 0)
                        mode = MODE_NORMAL;
                  else if (strcasecmp(optarg, "reverse") == 0)
                        mode = MODE_REVERSE;
                  else if (strcasecmp(optarg, "mixed") == 0)
                        mode = MODE_MIXED;
                  else {
                        errmsg(_("invalid mode in %s line %d -- %s"), rcfile, line, optarg);
                        exit(1);
                  }
            } else if (strcmp(buffer, "random") == 0 && optarg) {
                  randcount = strtol(optarg, &s, 10);
                  if (*s != 0 || randcount <= 0) {
                        errmsg(_("invalid max. random index in %s line %d -- %s"), rcfile, line, optarg);
                        exit(1);
                  }
            } else if (strcmp(buffer, "help") == 0) {
                  errmsg(_("ignored --help in config file"));
            } else if (strcmp(buffer, "version") == 0) {
                  errmsg(_("ignored --version in config file"));
            } else {
                  errmsg(_("invalid or incomplete keyword in %s line %d"), rcfile, line);
                  exit(1);
            }
      }
      fclose(F);
}

void do_opts(int argc, char *argv[], int *force)
{
      static struct option long_opts[] = {
            {"debug",       0, NULL, 'd'},
            {"digraph",     0, NULL, 'g'},
            {"direction",   1, NULL,  1 },
            {"force",       0, NULL, 'f'},
            {"ignore-case", 0, NULL, 'i'},
            {"label",       1, NULL, 'a'},
            {"keymap1",     1, NULL, '1'},
            {"keymap2",     1, NULL, '2'},
            {"limit",       1, NULL, 'l'},
            {"mode",        1, NULL, 'm'},
            {"random",      1, NULL, 'r'},
            {"help",        0, NULL, 'h'},
            {"version",     0, NULL, 'v'},
            {NULL,          0, NULL,  0}};
      char *s;
      int  i;

      while ((i = getopt_long(argc, argv, "dgfia:1:2:l:m:r:hv", long_opts, NULL)) != -1) {
            switch (i) {
            case 'd':
                  debug = 1;
                  break;
            case 'g':
                  digraph = 1;
                  break;
            case  1 :
                  assert(optarg);
                  direction = strtol(optarg, &s, 10);
                  if (*s != 0 || direction < 0 || direction >= 4) {
                        errmsg(_("invalid direction -- %s"), optarg);
                        exit(1);
                  }
                  break;
            case 'f':
                  *force = 1;
                  break;
            case 'i':
                  ignore_case = 1;
                  break;
            case 'a':
                  assert(optarg);
                  if (*optarg == '/') {
                        language[1] = STRDUP(optarg + 1);
                  } else {
                        language[0] = STRDUP(optarg);
                        if ((s = index(language[0], '/')) != NULL) {
                              *s++  = 0;
                              language[1] = s;
                        }
                  }
                  break;
            case '1':
            case '2':
                  assert(optarg);
                  FREE(&keymap[i-'1']);
                  keymap[i-'1'] = mkkeymap(optarg);
                  break;
            case 'l':
                  assert(optarg);
                  wordlimit = strtol(optarg, &s, 10);
                  if (*s != 0) {
                        errmsg(_("invalid memory limit -- %s"), optarg);
                        exit(1);
                  }
                  break;
            case 'm':
                  assert(optarg);
                  if (strcasecmp(optarg, "normal") == 0)
                        mode = MODE_NORMAL;
                  else if (strcasecmp(optarg, "reverse") == 0)
                        mode = MODE_REVERSE;
                  else if (strcasecmp(optarg, "mixed") == 0)
                        mode = MODE_MIXED;
                  else {
                        errmsg(_("invalid mode -- %s"), optarg);
                        exit(1);
                  }
                  break;
            case 'r':
                  assert(optarg);
                  randcount = strtol(optarg, &s, 10);
                  if (*s != 0 || randcount <= 0) {
                        errmsg(_("invalid max. random index -- %s"), optarg);
                        exit(1);
                  }
                  break;
            case 'h':
                  printf(/* TRANSLATORS: Please wrap lines, which are longer than 80 characters. */
                        _("Usage: %s [options] [dictionary|path]\n"
                        "  -d, --debug                turn on debug mode,\n"
                        "      --direction={0|1|2|3}  initial direction for input fields,\n"
                        "  -g, --digraph              enable entering of digraphs,\n"
                        "  -f, --force                overwrite stale lock files,\n"
                        "  -h, --help                 display this command line summary,\n"
                        "  -i, --ignore-case          compare case-insensitively,\n"
                        "  -1, --keymap1=path         the input keymap for language 1,\n"
                        "  -2, --keymap2=path         the input keymap for language 2,\n"
                        "  -a, --label=lang1/lang2    the labels of the languages (max. %d chars each),\n"
                        "  -l, --limit=max            the number of phrases to hold in memory (%d),\n"
                        "  -m, --mode={normal|reverse|mixed}   specifies, in what direction to ask,\n"
                        "  -r, --random=max           the maximum random index (defaults to %d),\n"
                        "  -v, --version              display the version number.\n"
                        "Please read the manual page for further information.\n"),
                        argv[0], MAX_LANG, DEFAULT_WORDLIMIT, DEFAULT_RANDCOUNT);
                  exit(0);
            case 'v':
                  printf(_("%s, linked with %s, zlib %s%s\n"), PACKAGE_STRING, curses_version(), ZLIB_VERSION,
#ifdef HAVE_LIBMDB
                              ", libmdb");
#else
                              "");
#endif
                  printf("Copyright (c) 2002-2005 Martin A. Godisch <martin@godisch.de>\n");
                  printf(/* TRANSLATORS: Please add your own credits for your translation here. */
                        _("English localization by Martin A. Godisch <martin@godisch.de>\n"));
                  exit(0);
            case '?':
                  exit(1);
            }
      }
      if (argc > optind) {
            dictfile = mkdictfile(argv[optind++]);
            wordfile = mkwordfile(dictfile);
      }
      if (argc > optind) {
            errmsg(_("invalid argument -- %s"), argv[optind]);
            exit(1);
      }
      if (dictfile == NULL) {
            errmsg(_("dictionary missing"));
            exit(1);
      }
      if (wordlimit < randcount && wordlimit != 0) {
            if (debug)
                  errmsg(_("--limit=%d < --random=%d, adjusting --random"), wordlimit, randcount);
            randcount = wordlimit;
      }
}

Generated by  Doxygen 1.6.0   Back to index