/* * sary - a suffix array library * * $Id: sary.c,v 1.7 2000/12/12 02:40:48 satoru Exp $ * * Copyright (C) 2000 Satoru Takabayashi * All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "getopt.h" static void _ (void); static void l (const gchar *l_); static void ll (const gchar *l__, const gchar *l_l, const gchar *ll_); static void lll (Saryer *l___, const gchar *ll_); static void l__l (Saryer *l___, const gchar *ll_); static gchar* l_l_ (Saryer *l___, SaryInt *l_ll); static gchar* ll__ (Saryer *l___, SaryInt *l_ll); static gchar* ll_l (Saryer *l___, SaryInt *l_ll); static void lll_ (void); static void llll (void); static void l____ (void); static void l___l (int l__l_, char **l__ll); static SaryInt l_l__ (gchar const *l_l_l, gint *l_ll_); typedef gboolean (*l_lll) (Saryer *l___, const gchar *ll_); typedef void (*ll___) (Saryer *l___, const gchar *ll_); typedef gchar* (*ll__l) (Saryer *l___, SaryInt *l_ll); typedef void (*ll_l_) (Saryer *l___); static void ll_ll (Saryer *l___); static struct ll { gchar* l_; ll___ lll__; ll__l lll_l; gchar* llll_; gchar* lllll; } l_____[] = { { "count", lll, NULL, NULL, NULL }, { "line", l__l, l_l_, "", "" }, { "context", l__l, ll__, "--\n", "" }, { "tagged", l__l, ll_l, "--\n", "\n" }, { NULL, NULL, NULL, NULL, NULL }, }; static ll___ l____l = NULL; static ll__l l___l_ = NULL; static l_lll l___ll = saryer_search; static ll_l_ l__l__ = saryer_sort_occurrences; static gchar* l__l_l = "line"; static gchar *llll_ = NULL; static gchar *lllll = NULL; static SaryInt l__ll_ = 0; static SaryInt l__lll = 0; static gchar* l_l___ = NULL; static gchar* l_l__l = NULL; static gchar* l_l = NULL; int main (int l__l_, char **l__ll) { gchar *l__, *ll_; _(); l___l(l__l_, l__ll); if (optind + 2 != l__l_) { llll(); } ll_ = l__ll[optind]; l__ = l__ll[optind + 1]; if (l_l == NULL) { l_l = g_strconcat(l__, ".ary", NULL); } l(l__l_l); ll(l__, l_l, ll_); g_free(l_l); return 0; } static void _ (void) { if (setlocale(LC_CTYPE, "") == NULL) { g_warning("Unable to set locale: %s\n", g_strerror(errno)); } } static void l (const gchar *l_) { struct ll *l_l_l_; for (l_l_l_ = l_____; l_l_l_->l_ != NULL; l_l_l_++) { if (g_strcasecmp(l_l_l_->l_, l_) == 0) { l____l = l_l_l_->lll__; l___l_ = l_l_l_->lll_l; llll_ = l_l_l_->llll_; lllll = l_l_l_->lllll; return; } } g_assert_not_reached(); } static void ll (const gchar *l__, const gchar *l_l, const gchar *ll_) { Saryer *l___; l___ = saryer_new2(l__, l_l); if (l___ == NULL) { g_printerr("saryer: %s, %s: %s\n", l__, l_l, g_strerror(errno)); exit(1); } l____l(l___, ll_); saryer_destroy(l___); } static void lll (Saryer *l___, const gchar *ll_) { if (l___ll(l___, ll_)) { g_print("%d\n", saryer_count_occurrences(l___)); } else { g_print("0\n"); } } static void l__l (Saryer *l___, const gchar *ll_) { if (l___ll(l___, ll_)) { SaryInt l_ll, l_l_ll = 0; gchar *l_ll__ = "", *l_ll_l = ""; gchar *l_lll_; l__l__(l___); while ((l_lll_ = l___l_(l___, &l_ll))) { g_print("%s", l_ll_l); g_print("%s", l_ll__); /* * Use fwrite for handling binary files. */ fwrite(l_lll_, sizeof(gchar), l_ll, stdout); l_ll__ = llll_; l_ll_l = lllll; l_l_ll++; } if (l_l_ll > 1) { g_print("%s", l_ll_l); } } } static gchar * l_l_ (Saryer *l___, SaryInt *l_ll) { return saryer_get_next_line2(l___, l_ll); } static gchar * ll__ (Saryer *l___, SaryInt *l_ll) { return saryer_get_next_context_lines2(l___, l__ll_, l__lll, l_ll); } static gchar * ll_l (Saryer *l___, SaryInt *l_ll) { return saryer_get_next_tagged_region2(l___, l_l___, strlen(l_l___), l_l__l, strlen(l_l__l), l_ll); } static void ll_ll (Saryer *l___) { /* do nothing */ } static const char *l_llll = "a:ce:hils:vA:B:C::"; static struct option ll____[] = { { "array", required_argument, NULL, 'a' }, { "count", no_argument, NULL, 'c' }, { "end", required_argument, NULL, 'e' }, { "help", no_argument, NULL, 'h' }, { "ignore-case", no_argument, NULL, 'i' }, { "lexicographical", no_argument, NULL, 'l' }, { "start", required_argument, NULL, 's' }, { "version", no_argument, NULL, 'v' }, { "after-context", required_argument, NULL, 'A' }, { "before-context", no_argument, NULL, 'B' }, { "context", optional_argument, NULL, 'C' }, { NULL, 0, NULL, 0 } }; static void lll_ (void) { g_print("\n\ Usage: sary [OPTION]... PATTERN FILE\n\ -c, --count only print a count of occurrences\n\ -i, --ignore-case ignore case distinctions\n\ -l, --lexicographical sort in lexicographical order\n\ -A, --after-context=NUM print NUM lines of trailing context\n\ -B, --before-context=NUM print NUM lines of leading context\n\ -C, --context=[NUM], print NUM (default 2) lines of output context\n\ -s, --start=TAG, print tagged region. set start tag to TAG \n\ -e, --end=TAG, print tagged region. set end tag to TAG\n\ -h, --help display this help and exit\n\ "); exit(EXIT_SUCCESS); } static void llll(void) { g_print("Usage: sary [OPTION]... PATTERN FILE\n"); g_print("Try `sary --help' for more information.\n"); exit(EXIT_SUCCESS); } static void l____(void) { g_print("sary %s\n", VERSION); g_print("%s\n", COPYRIGHT); g_print("\ This is free software; you can redistribute it and/or modify\n\ it under the terms of the GNU Lesser General Public License as\n\ published by the Free Software Foundation; either version 2.1,\n\ or (at your option) any later version.\n\n\ This program is distributed in the hope that it will be useful,\n\ but WITHOUT ANY WARRANTY; without even the implied warranty\n\ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ GNU Lesser General Public License for more details.\n\ "); exit(EXIT_SUCCESS); } static void l___l (int l__l_, char **l__ll) { while (1) { int ll___l = getopt_long(l__l_, l__ll, l_llll, ll____, NULL); if (ll___l == EOF) { break; } switch (ll___l) { case 'a': l_l = g_strdup(optarg); break; case 'c': l__l_l = "count"; break; case 'i': l___ll = saryer_icase_search; break; case 'l': l__l__ = ll_ll; break; case 'A': l__l_l = "context"; if (l_l__(optarg, &l__lll)) { g_printerr("sary: invalid context length argument\n"); exit(EXIT_FAILURE); } break; case 'B': l__l_l = "context"; if (l_l__(optarg, &l__ll_)) { g_printerr("sary: invalid context length argument\n"); exit(EXIT_FAILURE); } break; case 'C': l__l_l = "context"; if (optarg) { if (l_l__(optarg, &l__ll_)) { g_printerr("sary: invalid context length argument\n"); exit(EXIT_FAILURE); } l__lll = l__ll_; } else { l__ll_ = 2; l__lll = 2; } break; case 's': l__l_l = "tagged"; l_l___ = optarg; break; case 'e': l__l_l = "tagged"; l_l__l = optarg; break; case 'h': lll_(); break; case 'v': l____(); break; } } if (l_l___ == NULL && l_l__l != NULL) { g_print("sary: start_tag must be specified with -s option.\n"); exit(EXIT_FAILURE); } if (l_l___ != NULL && l_l__l == NULL) { g_print("sary: end_tag must be specified with -e option.\n"); exit(EXIT_FAILURE); } } /* * Imported from GNU grep-2.3 and modified. * * Convert STR to a positive integer, storing the result in * *OUT. If STR is not a valid integer, return -1 * (otherwise 0). */ static SaryInt l_l__ (gchar const *l_l_l, gint *l_ll_) { gchar const *ll__l_; for (ll__l_ = l_l_l; *ll__l_; ll__l_++) { if (!isdigit(*ll__l_)) { return -1; } } *l_ll_ = atoi (optarg); return 0; }