tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

replist.cxx (6396B)


      1 /* ***** BEGIN LICENSE BLOCK *****
      2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
      3 *
      4 * Copyright (C) 2002-2022 Németh László
      5 *
      6 * The contents of this file are subject to the Mozilla Public License Version
      7 * 1.1 (the "License"); you may not use this file except in compliance with
      8 * the License. You may obtain a copy of the License at
      9 * http://www.mozilla.org/MPL/
     10 *
     11 * Software distributed under the License is distributed on an "AS IS" basis,
     12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
     13 * for the specific language governing rights and limitations under the
     14 * License.
     15 *
     16 * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
     17 *
     18 * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
     19 * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád,
     20 * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter,
     21 * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls,
     22 * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen
     23 *
     24 * Alternatively, the contents of this file may be used under the terms of
     25 * either the GNU General Public License Version 2 or later (the "GPL"), or
     26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
     27 * in which case the provisions of the GPL or the LGPL are applicable instead
     28 * of those above. If you wish to allow use of your version of this file only
     29 * under the terms of either the GPL or the LGPL, and not to allow others to
     30 * use your version of this file under the terms of the MPL, indicate your
     31 * decision by deleting the provisions above and replace them with the notice
     32 * and other provisions required by the GPL or the LGPL. If you do not delete
     33 * the provisions above, a recipient may use your version of this file under
     34 * the terms of any one of the MPL, the GPL or the LGPL.
     35 *
     36 * ***** END LICENSE BLOCK ***** */
     37 /*
     38 * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
     39 * And Contributors.  All rights reserved.
     40 *
     41 * Redistribution and use in source and binary forms, with or without
     42 * modification, are permitted provided that the following conditions
     43 * are met:
     44 *
     45 * 1. Redistributions of source code must retain the above copyright
     46 *    notice, this list of conditions and the following disclaimer.
     47 *
     48 * 2. Redistributions in binary form must reproduce the above copyright
     49 *    notice, this list of conditions and the following disclaimer in the
     50 *    documentation and/or other materials provided with the distribution.
     51 *
     52 * 3. All modifications to the source code must be clearly marked as
     53 *    such.  Binary redistributions based on modified source code
     54 *    must be clearly marked as modified versions in the documentation
     55 *    and/or other materials provided with the distribution.
     56 *
     57 * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
     58 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     59 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     60 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
     61 * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     62 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     63 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     64 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68 * SUCH DAMAGE.
     69 */
     70 
     71 #include <stdlib.h>
     72 #include <string.h>
     73 #include <stdio.h>
     74 #include <limits>
     75 
     76 #include "replist.hxx"
     77 #include "csutil.hxx"
     78 
     79 RepList::RepList(int n) {
     80  dat = (replentry**)malloc(sizeof(replentry*) * n);
     81  if (dat == 0)
     82    size = 0;
     83  else
     84    size = n;
     85  pos = 0;
     86 }
     87 
     88 RepList::~RepList() {
     89  for (int i = 0; i < pos; i++) {
     90    delete dat[i];
     91  }
     92  free(dat);
     93 }
     94 
     95 replentry* RepList::item(int n) {
     96  return dat[n];
     97 }
     98 
     99 int RepList::find(const char* word) {
    100  int p1 = 0;
    101  int p2 = pos - 1;
    102  int ret = -1;
    103  while (p1 <= p2) {
    104    int m = ((unsigned)p1 + (unsigned)p2) >> 1;
    105    int c = strncmp(word, dat[m]->pattern.c_str(), dat[m]->pattern.size());
    106    if (c < 0)
    107      p2 = m - 1;
    108    else if (c > 0)
    109      p1 = m + 1;
    110    else {      // scan in the right half for a longer match
    111      ret = m;
    112      p1 = m + 1;
    113    }
    114  }
    115  return ret;
    116 }
    117 
    118 std::string RepList::replace(const char* word, int ind, bool atstart) {
    119  int type = atstart ? 1 : 0;
    120  if (ind < 0)
    121    return std::string();
    122  if (strlen(word) == dat[ind]->pattern.size())
    123    type = atstart ? 3 : 2;
    124  while (type && dat[ind]->outstrings[type].empty())
    125    type = (type == 2 && !atstart) ? 0 : type - 1;
    126  return dat[ind]->outstrings[type];
    127 }
    128 
    129 int RepList::add(const std::string& in_pat1, const std::string& pat2) {
    130  if (pos >= size || in_pat1.empty() || pat2.empty()) {
    131    return 1;
    132  }
    133  // analyse word context
    134  int type = 0;
    135  std::string pat1(in_pat1);
    136  if (pat1[0] == '_') {
    137    pat1.erase(0, 1);
    138    type = 1;
    139  }
    140  if (!pat1.empty() && pat1[pat1.size() - 1] == '_') {
    141    type = type + 2;
    142    pat1.erase(pat1.size() - 1);
    143  }
    144  mystrrep(pat1, "_", " ");
    145 
    146  // find existing entry
    147  int m = find(pat1.c_str());
    148  if (m >= 0 && dat[m]->pattern == pat1) {
    149    // since already used
    150    dat[m]->outstrings[type] = pat2;
    151    mystrrep(dat[m]->outstrings[type], "_", " ");
    152    return 0;
    153  }
    154 
    155  // make a new entry if none exists
    156  replentry* r = new replentry;
    157  if (r == NULL)
    158    return 1;
    159  r->pattern = pat1;
    160  r->outstrings[type] = pat2;
    161  mystrrep(r->outstrings[type], "_", " ");
    162  dat[pos++] = r;
    163  // sort to the right place in the list
    164  int i;
    165  for (i = pos - 1; i > 0; i--) {
    166    if (strcmp(r->pattern.c_str(), dat[i - 1]->pattern.c_str()) < 0) {
    167      dat[i] = dat[i - 1];
    168    } else
    169      break;
    170  }
    171  dat[i] = r;
    172  return 0;
    173 }
    174 
    175 bool RepList::conv(const std::string& in_word, std::string& dest) {
    176  dest.clear();
    177 
    178  size_t wordlen = in_word.size();
    179  const char* word = in_word.c_str();
    180 
    181  bool change = false;
    182  for (size_t i = 0; i < wordlen; ++i) {
    183    int n = find(word + i);
    184    std::string l = replace(word + i, n, i == 0);
    185    if (!l.empty()) {
    186      dest.append(l);
    187      i += dat[n]->pattern.size() - 1;
    188      change = true;
    189    } else {
    190      dest.push_back(word[i]);
    191    }
    192  }
    193 
    194  return change;
    195 }