Example #1
0
static int
str_utf8_isprint (const char *ch)
{
    gunichar uni = g_utf8_get_char_validated (ch, -1);
    return g_unichar_isprint (uni);
}
Example #2
0
void
s_check_text (const GList *obj_list, SYMCHECK *s_current)
{
  const GList *iter;
  OBJECT *o_current;
  gboolean overbar_started, escape, leave_parser;
  char *message;
  char *text_string, *ptr;
  gunichar current_char;

  for (iter = obj_list; iter != NULL; iter = g_list_next(iter)) {
    o_current = iter->data;

    if (o_current->type != OBJ_TEXT)
      continue;

    overbar_started = escape = leave_parser = FALSE;
    text_string = o_current->text->string;

    for (ptr = text_string;
         ptr != NULL && !leave_parser;
         ptr = g_utf8_find_next_char (ptr, NULL)) {

      current_char = g_utf8_get_char_validated (ptr, -1);

      /* state machine to interpret the string:
       * there are two independant state variables overbar_started and escape.
       */
      switch (current_char) {
      case '\0':
        /* end of the string */
        leave_parser = TRUE;
        break;
      case '\\':
        if (escape == TRUE) {
          escape = FALSE;
        } else {
          escape = TRUE;
        }
        break;
      case '_':
        if (escape == TRUE) {
          escape = FALSE;
          if (overbar_started == TRUE) {
            overbar_started = FALSE;
          } else {
            overbar_started = TRUE;
          }
        }
        break;
      default:
        if (escape == TRUE) {
          message = g_strdup_printf ("Found text with a '\\' in it: consider"
                                     " to escape it with '\\\\' [%s]\n",
                                     text_string);
          s_current->warning_messages = g_list_append(s_current->warning_messages,
                                                      message);
          s_current->warning_count++;
          escape = FALSE;
        }
      }
    }

    if (escape == TRUE) {
      message = g_strdup_printf ("Found text with a trailing '\': consider to "
                                 "escape it with '\\\\' [%s]\n",
                                 text_string);
      s_current->warning_messages = g_list_append(s_current->warning_messages,
                                                  message);
      s_current->warning_count++;
    }

    if (overbar_started == TRUE) {
      message = g_strdup_printf ("Found text with unbalanced overbar "
                                 "markers '\\_' in it' [%s]\n",
                                 text_string);
      s_current->warning_messages = g_list_append(s_current->warning_messages,
                                                  message);
      s_current->warning_count++;
    }
  }
}
Example #3
0
static int
str_utf8_isdigit (const char *text)
{
    gunichar uni = g_utf8_get_char_validated (text, -1);
    return g_unichar_isdigit (uni);
}
Example #4
0
static gboolean _rox_buffer_looks_like_text (const void  *data,
					    const size_t len)
{
  gchar *end;

  if (g_utf8_validate (data, len, (const gchar**)&end))
  {
    /* g_utf8_validate allows control characters */
    int i;
    for (i = 0; i < len; i++)
    {
      unsigned char c = ((const guchar *) data)[i];
      if (c < 32 && c != '\r' && c != '\n' && c != '\t')
	return FALSE;
    }
    return TRUE;

  } else {
    /* Check whether the string was truncated in the middle of
     * a valid UTF8 char, or if we really have an invalid
     * UTF8 string
     */
    gint remaining_bytes = len;

    remaining_bytes -= (end-((gchar*)data));

    if (g_utf8_get_char_validated(end, remaining_bytes) == -2)
      return TRUE;
#if defined(HAVE_WCTYPE_H) && defined (HAVE_MBRTOWC)
    else {
      size_t wlen;
      wchar_t wc;
      gchar *src, *end;
      mbstate_t state;

      src = data;
      end = data+len;
                       
      memset (&state, 0, sizeof (state));
      while (src < end) {
	/* Don't allow embedded zeros in textfiles */
	if (*src == 0)
	  return FALSE;
                               
	wlen = mbrtowc(&wc, src, end - src, &state);

	if (wlen == (size_t)(-1)) {
	  /* Illegal mb sequence */
	  return FALSE;
	}
                               
	if (wlen == (size_t)(-2)) {
	  /* No complete mb char before end
	   * Probably a cut off char which is ok */
	  return TRUE;
	}

	if (wlen == 0) {
	  /* Don't allow embedded zeros in textfiles */
	  return FALSE;
	}
        
	if (!iswspace (wc)  && !iswprint(wc)) {
	  /* Not a printable or whitspace
	   * Probably not a text file */
	  return FALSE;
	}
	
	src += wlen;
      }
      return TRUE;
    }
#endif /* defined(HAVE_WCTYPE_H) && defined (HAVE_MBRTOWC) */
  }
  return FALSE;
}
Example #5
0
/* utiliti function, that make string valid in utf8 and all characters printable
 * return width of string too*/
static const struct term_form *
str_utf8_make_make_term_form (const char *text, size_t length)
{
    static struct term_form result;
    gunichar uni;
    size_t left;
    char *actual;

    result.text[0] = '\0';
    result.width = 0;
    result.compose = FALSE;
    actual = result.text;

    /* check if text start with combining character,
     * add space at begin in this case */
    if (length != 0 && text[0] != '\0')
    {
        uni = g_utf8_get_char_validated (text, -1);
        if ((uni != (gunichar) (-1)) && (uni != (gunichar) (-2))
            && str_unichar_iscombiningmark (uni))
        {
            actual[0] = ' ';
            actual++;
            result.width++;
            result.compose = TRUE;
        }
    }

    while (length != 0 && text[0] != '\0')
    {
        uni = g_utf8_get_char_validated (text, -1);
        if ((uni != (gunichar) (-1)) && (uni != (gunichar) (-2)))
        {
            if (g_unichar_isprint (uni))
            {
                left = g_unichar_to_utf8 (uni, actual);
                actual += left;
                if (str_unichar_iscombiningmark (uni))
                    result.compose = TRUE;
                else
                {
                    result.width++;
                    if (g_unichar_iswide (uni))
                        result.width++;
                }
            }
            else
            {
                actual[0] = '.';
                actual++;
                result.width++;
            }
            text = g_utf8_next_char (text);
        }
        else
        {
            text++;
            /*actual[0] = '?'; */
            memcpy (actual, replch, strlen (replch));
            actual += strlen (replch);
            result.width++;
        }

        if (length != (size_t) (-1))
            length--;
    }
    actual[0] = '\0';

    return &result;
}
Example #6
0
void
mcview_display_hex (WView * view)
{
    const screen_dimen top = view->data_area.top;
    const screen_dimen left = view->data_area.left;
    const screen_dimen height = view->data_area.height;
    const screen_dimen width = view->data_area.width;
    const int ngroups = view->bytes_per_line / 4;
    /* 8 characters are used for the file offset, and every hex group
     * takes 13 characters. Starting at width of 80 columns, the groups
     * are separated by an extra vertical line. Starting at width of 81,
     * there is an extra space before the text column. There is always a
     * mostly empty column on the right, to allow overflowing CJKs.
     */
    const screen_dimen text_start = 8 + 13 * ngroups +
        ((width < 80) ? 0 : (width == 80) ? (ngroups - 1) : (ngroups - 1 + 1));

    int row;
    off_t from;
    mark_t boldflag_byte = MARK_NORMAL;
    mark_t boldflag_char = MARK_NORMAL;
    struct hexedit_change_node *curr = view->change_list;
#ifdef HAVE_CHARSET
    int cont_bytes = 0;         /* number of continuation bytes remanining from current UTF-8 */
    gboolean cjk_right = FALSE; /* whether the second byte of a CJK is to be processed */
#endif /* HAVE_CHARSET */
    gboolean utf8_changed = FALSE;      /* whether any of the bytes in the UTF-8 were changed */

    char hex_buff[10];          /* A temporary buffer for sprintf and mvwaddstr */

    mcview_display_clean (view);

    /* Find the first displayable changed byte */
    /* In UTF-8 mode, go back by 1 or maybe 2 lines to handle continuation bytes properly. */
    from = view->dpy_start;
    row = 0;
#ifdef HAVE_CHARSET
    if (view->utf8)
    {
        if (from >= view->bytes_per_line)
        {
            row--;
            from -= view->bytes_per_line;
        }
        if (view->bytes_per_line == 4 && from >= view->bytes_per_line)
        {
            row--;
            from -= view->bytes_per_line;
        }
    }
#endif /* HAVE_CHARSET */
    while (curr && (curr->offset < from))
    {
        curr = curr->next;
    }

    for (; mcview_get_byte (view, from, NULL) && row < (int) height; row++)
    {
        screen_dimen col = 0;
        size_t i;
        int bytes;              /* Number of bytes already printed on the line */

        /* Print the hex offset */
        if (row >= 0)
        {
            g_snprintf (hex_buff, sizeof (hex_buff), "%08" PRIXMAX " ", (uintmax_t) from);
            widget_move (view, top + row, left);
            tty_setcolor (VIEW_BOLD_COLOR);
            for (i = 0; col < width && hex_buff[i] != '\0'; col++, i++)
                tty_print_char (hex_buff[i]);
            tty_setcolor (VIEW_NORMAL_COLOR);
        }

        for (bytes = 0; bytes < view->bytes_per_line; bytes++, from++)
        {
            int c;
#ifdef HAVE_CHARSET
            int ch = 0;

            if (view->utf8)
            {
                struct hexedit_change_node *corr = curr;

                if (cont_bytes != 0)
                {
                    /* UTF-8 continuation bytes, print a space (with proper attributes)... */
                    cont_bytes--;
                    ch = ' ';
                    if (cjk_right)
                    {
                        /* ... except when it'd wipe out the right half of a CJK, then print nothing */
                        cjk_right = FALSE;
                        ch = -1;
                    }
                }
                else
                {
                    int j;
                    gchar utf8buf[UTF8_CHAR_LEN + 1];
                    int res;
                    int first_changed = -1;

                    for (j = 0; j < UTF8_CHAR_LEN; j++)
                    {
                        if (mcview_get_byte (view, from + j, &res))
                            utf8buf[j] = res;
                        else
                        {
                            utf8buf[j] = '\0';
                            break;
                        }
                        if (curr != NULL && from + j == curr->offset)
                        {
                            utf8buf[j] = curr->value;
                            if (first_changed == -1)
                                first_changed = j;
                        }
                        if (curr != NULL && from + j >= curr->offset)
                            curr = curr->next;
                    }
                    utf8buf[UTF8_CHAR_LEN] = '\0';

                    /* Determine the state of the current multibyte char */
                    ch = g_utf8_get_char_validated (utf8buf, -1);
                    if (ch == -1 || ch == -2)
                    {
                        ch = '.';
                    }
                    else
                    {
                        gchar *next_ch;

                        next_ch = g_utf8_next_char (utf8buf);
                        cont_bytes = next_ch - utf8buf - 1;
                        if (g_unichar_iswide (ch))
                            cjk_right = TRUE;
                    }

                    utf8_changed = (first_changed >= 0 && first_changed <= cont_bytes);
                    curr = corr;
                }
            }
#endif /* HAVE_CHARSET */

            /* For negative rows, the only thing we care about is overflowing
             * UTF-8 continuation bytes which were handled above. */
            if (row < 0)
            {
                if (curr != NULL && from == curr->offset)
                    curr = curr->next;
                continue;
            }

            if (!mcview_get_byte (view, from, &c))
                break;

            /* Save the cursor position for mcview_place_cursor() */
            if (from == view->hex_cursor && !view->hexview_in_text)
            {
                view->cursor_row = row;
                view->cursor_col = col;
            }

            /* Determine the state of the current byte */
            boldflag_byte = mcview_hex_calculate_boldflag (view, from, curr, FALSE);
            boldflag_char = mcview_hex_calculate_boldflag (view, from, curr, utf8_changed);

            /* Determine the value of the current byte */
            if (curr != NULL && from == curr->offset)
            {
                c = curr->value;
                curr = curr->next;
            }

            /* Select the color for the hex number */
            tty_setcolor (boldflag_byte == MARK_NORMAL ? VIEW_NORMAL_COLOR :
                          boldflag_byte == MARK_SELECTED ? VIEW_BOLD_COLOR :
                          boldflag_byte == MARK_CHANGED ? VIEW_UNDERLINED_COLOR :
                          /* boldflag_byte == MARK_CURSOR */
                          view->hexview_in_text ? VIEW_SELECTED_COLOR : VIEW_UNDERLINED_COLOR);

            /* Print the hex number */
            widget_move (view, top + row, left + col);
            if (col < width)
            {
                tty_print_char (hex_char[c / 16]);
                col += 1;
            }
            if (col < width)
            {
                tty_print_char (hex_char[c % 16]);
                col += 1;
            }

            /* Print the separator */
            tty_setcolor (VIEW_NORMAL_COLOR);
            if (bytes != view->bytes_per_line - 1)
            {
                if (col < width)
                {
                    tty_print_char (' ');
                    col += 1;
                }

                /* After every four bytes, print a group separator */
                if (bytes % 4 == 3)
                {
                    if (view->data_area.width >= 80 && col < width)
                    {
                        tty_print_one_vline (TRUE);
                        col += 1;
                    }
                    if (col < width)
                    {
                        tty_print_char (' ');
                        col += 1;
                    }
                }
            }

            /* Select the color for the character; this differs from the
             * hex color when boldflag == MARK_CURSOR */
            tty_setcolor (boldflag_char == MARK_NORMAL ? VIEW_NORMAL_COLOR :
                          boldflag_char == MARK_SELECTED ? VIEW_BOLD_COLOR :
                          boldflag_char == MARK_CHANGED ? VIEW_UNDERLINED_COLOR :
                          /* boldflag_char == MARK_CURSOR */
                          view->hexview_in_text ? VIEW_SELECTED_COLOR : MARKED_SELECTED_COLOR);


#ifdef HAVE_CHARSET
            if (mc_global.utf8_display)
            {
                if (!view->utf8)
                {
                    c = convert_from_8bit_to_utf_c ((unsigned char) c, view->converter);
                }
                if (!g_unichar_isprint (c))
                    c = '.';
            }
            else if (view->utf8)
                ch = convert_from_utf_to_current_c (ch, view->converter);
            else
#endif
            {
#ifdef HAVE_CHARSET
                c = convert_to_display_c (c);
#endif

                if (!is_printable (c))
                    c = '.';
            }

            /* Print corresponding character on the text side */
            if (text_start + bytes < width)
            {
                widget_move (view, top + row, left + text_start + bytes);
#ifdef HAVE_CHARSET
                if (view->utf8)
                    tty_print_anychar (ch);
                else
#endif
                    tty_print_char (c);
            }

            /* Save the cursor position for mcview_place_cursor() */
            if (from == view->hex_cursor && view->hexview_in_text)
            {
                view->cursor_row = row;
                view->cursor_col = text_start + bytes;
            }
        }
    }

    /* Be polite to the other functions */
    tty_setcolor (VIEW_NORMAL_COLOR);

    mcview_place_cursor (view);
    view->dpy_end = from;
}
Example #7
0
File: main.c Project: Tilka/ncdc
static void handle_input() {
  /* Mapping from get_wch() to input_key_t:
   *  KEY_CODE_YES -> KEY(code)
   *  KEY_CODE_NO:
   *    char == 127           -> KEY(KEY_BACKSPACE)
   *    char <= 31            -> CTRL(char)
   *    !'^['                 -> CHAR(char)
   *    ('^[', !)             -> KEY(KEY_ESCAPE)
   *    ('^[', !CHAR)         -> ignore both characters (1)
   *    ('^[', CHAR && '[')   -> ignore both characters and the character after that (2)
   *    ('^[', CHAR && !'[')  -> ALT(second char)
   *
   * 1. this is something like ctrl+alt+X, which we won't use
   * 2. these codes indicate a 'Key' that somehow wasn't captured with
   *    KEY_CODE_YES. We won't attempt to interpret these ourselves.
   *
   * There are still several unhandled issues:
   * - Ncurses does not catch all key codes, and there is no way of knowing how
   *   many bytes a key code spans. Things like ^[[1;3C won't be handled correctly. :-(
   * - Ncurses can actually return key codes > KEY_MAX, but does not provide
   *   any mechanism for figuring out which key it actually was.
   * - It may be useful to use define_key() for some special (and common) codes
   * - Modifier keys will always be a problem. Most alt+key things work, except
   *   for those that may start a control code. alt+[ is a famous one, but
   *   there are others (like alt+O on my system). This is system-dependent,
   *   and again we have no way of knowing these things. (except perhaps by
   *   reading termcap entries on our own?)
   */

  guint64 key;
  char buf[9];
  int r;
  wint_t code;
  int lastesc = 0, curignore = 0;
  while((r = get_wch(&code)) != ERR) {
    if(curignore) {
      curignore = 0;
      continue;
    }
    // we use SIGWINCH, so KEY_RESIZE can be ignored
    if(r == KEY_CODE_YES && code == KEY_RESIZE)
      continue;
    // backspace (outside of an escape sequence) is often sent as DEL control character, correct this
    if(!lastesc && r != KEY_CODE_YES && code == 127) {
      r = KEY_CODE_YES;
      code = KEY_BACKSPACE;
    }
    // backspace inside an escape sequence is also possible, convert the other way around
    if(lastesc && r == KEY_CODE_YES && code == KEY_BACKSPACE) {
      r = !KEY_CODE_YES;
      code = 127;
    }
    key = r == KEY_CODE_YES ? INPT_KEY(code) : code == 27 ? INPT_ALT(0) : code <= 31 ? INPT_CTRL(ctrl_to_ascii(code)) : INPT_CHAR(code);
    // convert wchar_t into gunichar
    if(INPT_TYPE(key) == 1) {
      if((r = wctomb(buf, code)) < 0)
        g_warning("Cannot encode character 0x%X", code);
      buf[r] = 0;
      key = INPT_CHAR(g_utf8_get_char_validated(buf, -1));
      if(INPT_CODE(key) == (gunichar)-1 || INPT_CODE(key) == (gunichar)-2) {
        g_warning("Invalid UTF-8 sequence in keyboard input. Are you sure you are running a UTF-8 locale?");
        continue;
      }
    }
    // check for escape sequence
    if(lastesc) {
      lastesc = 0;
      if(INPT_TYPE(key) != 1)
        continue;
      if(INPT_CODE(key) == '[') {
        curignore = 1;
        continue;
      }
      key |= (guint64)3<<32; // a not very nice way of saying "turn this key into a INPT_ALT"
      ui_input(key);
      continue;
    }
    if(INPT_TYPE(key) == 3) {
      lastesc = 1;
      continue;
    }
    ui_input(key);
  }
  if(lastesc)
    ui_input(INPT_KEY(KEY_ESCAPE));

  ui_draw();
}
Example #8
0
/**************************************************************************
  Refresh info label
**************************************************************************/
void update_info_label(void)
{
  GtkWidget *label;
  const struct player *pplayer = client.conn.playing;

  label = gtk_frame_get_label_widget(GTK_FRAME(main_frame_civ_name));
  if (pplayer != NULL) {
    const gchar *name;
    gunichar c;

    /* Capitalize the first character of the translated nation
     * plural name so that the frame label looks good. */
    name = nation_plural_for_player(pplayer);
    c = g_utf8_get_char_validated(name, -1);
    if ((gunichar) -1 != c && (gunichar) -2 != c) {
      gchar nation[MAX_LEN_NAME];
      gchar *next;
      gint len;

      len = g_unichar_to_utf8(g_unichar_toupper(c), nation);
      nation[len] = '\0';
      next = g_utf8_find_next_char(name, NULL);
      if (NULL != next) {
        sz_strlcat(nation, next);
      }
      gtk_label_set_text(GTK_LABEL(label), nation);
    } else {
      gtk_label_set_text(GTK_LABEL(label), name);
    }
  } else {
    gtk_label_set_text(GTK_LABEL(label), "-");
  }

  gtk_label_set_text(GTK_LABEL(main_label_info),
                     get_info_label_text(!gui_gtk3_small_display_layout));

  set_indicator_icons(client_research_sprite(),
		      client_warming_sprite(),
		      client_cooling_sprite(),
		      client_government_sprite());

  if (NULL != client.conn.playing) {
    int d = 0;

    for (; d < client.conn.playing->economic.luxury /10; d++) {
      struct sprite *sprite = get_tax_sprite(tileset, O_LUXURY);

      gtk_pixcomm_set_from_sprite(GTK_PIXCOMM(econ_label[d]), sprite);
    }
 
    for (; d < (client.conn.playing->economic.science
		+ client.conn.playing->economic.luxury) / 10; d++) {
      struct sprite *sprite = get_tax_sprite(tileset, O_SCIENCE);

      gtk_pixcomm_set_from_sprite(GTK_PIXCOMM(econ_label[d]), sprite);
    }
 
    for (; d < 10; d++) {
      struct sprite *sprite = get_tax_sprite(tileset, O_GOLD);

      gtk_pixcomm_set_from_sprite(GTK_PIXCOMM(econ_label[d]), sprite);
    }
  }
 
  update_timeout_label();

  /* update tooltips. */
  gtk_widget_set_tooltip_text(econ_ebox,
		       _("Shows your current luxury/science/tax rates; "
			 "click to toggle them."));

  gtk_widget_set_tooltip_text(bulb_ebox, get_bulb_tooltip());
  gtk_widget_set_tooltip_text(sun_ebox, get_global_warming_tooltip());
  gtk_widget_set_tooltip_text(flake_ebox, get_nuclear_winter_tooltip());
  gtk_widget_set_tooltip_text(government_ebox, get_government_tooltip());
}
Example #9
0
static int
parse_file (FILE * in, FILE * out, IspellMode_t mode, int countLines, gchar *dictionary)
{
	EnchantBroker * broker;
	EnchantDict * dict;
	
	GString * str, * word = NULL;
	GSList * tokens, *token_ptr;
	gchar * lang;
	size_t pos, lineCount = 0;

	gboolean was_last_line = FALSE, corrected_something = FALSE, terse_mode = FALSE;

	if (mode == MODE_A)
		print_version (out);

	if (dictionary) {
		lang = convert_language_code (dictionary);
	}
	else {
	        lang = enchant_get_user_language();
		if(!lang)
			return 1;
 	}

	/* Enchant will get rid of useless trailing garbage like de_DE@euro or de_DE.ISO-8859-15 */
	
	broker = enchant_broker_init ();
	dict = enchant_broker_request_dict (broker, lang);

	if (!dict) {
		fprintf (stderr, "Couldn't create a dictionary for %s\n", lang);
		g_free (lang);
		enchant_broker_free (broker);
		return 1;
	}

	g_free (lang);

	str = g_string_new (NULL);
	
	while (!was_last_line) {
		gboolean mode_A_no_command = FALSE;
		was_last_line = consume_line (in, str);

		if (countLines)
			lineCount++;

		if (str->len) {
			corrected_something = FALSE;

			if (mode == MODE_A) {
				switch (*str->str) {
				case '&': /* Insert uncapitalised in personal word list */
					if (str->len > 1) {
						gunichar c = g_utf8_get_char_validated(str->str + 1, str->len);
						if (c > 0) {
							str = g_string_erase(str, 1, g_utf8_next_char(str->str + 1) - (str->str + 1));
							g_string_insert_unichar(str, 1, g_unichar_tolower(c));
						}
					}
					/* FALLTHROUGH */
				case '*': /* Insert in personal word list */
					if (str->len == 1)
						goto empty_word;
					enchant_dict_add(dict, str->str + 1, -1);
					break;
				case '@': /* Accept for this session */
					if (str->len == 1)
						goto empty_word;
					enchant_dict_add_to_session(dict, str->str + 1, -1);
					break;

				case '%': /* Exit terse mode */
					terse_mode = FALSE;
					break;
				case '!': /* Enter terse mode */
					terse_mode = TRUE;
					break;

				/* Ignore these commands */
				case '#': /* Save personal word list (enchant does this automatically) */
				case '+': /* LaTeX mode */
				case '-': /* nroff mode [default] */
				case '~': /* change string character type (enchant is fixed to UTF-8) */
				case '`': /* Enter verbose-correction mode */
					break;

				case '$': /* Save correction for rest of session [aspell extension] */
					{ /* Syntax: $$ra <MISSPELLED>,<REPLACEMENT> */
						gchar *prefix = "$$ra ";
						if (g_str_has_prefix(str->str, prefix)) {
							gchar *comma = g_utf8_strchr(str->str, -1, (gunichar)',');
							char *mis = str->str + strlen(prefix);
							char *cor = comma + 1;
							ssize_t mis_len = comma - mis;
							ssize_t cor_len = strlen(str->str) - (cor - str->str);
							enchant_dict_store_replacement(dict, mis, mis_len, cor, cor_len);
						}
					}
					break;

				case '^': /* ^ is used as prefix to prevent interpretation of original
					     first character as a command */
					/* FALLTHROUGH */
				default: /* A word or words to check */
					mode_A_no_command = TRUE;
					break;

				empty_word:
					fprintf (out, "Error: The word \"\" is invalid. Empty string.\n");
				}
			}

			if (mode != MODE_A || mode_A_no_command) {
				token_ptr = tokens = tokenize_line (str);
				if (tokens == NULL)
					putc('\n', out);
				while (tokens != NULL) {
					corrected_something = TRUE;

					word = (GString *)tokens->data;
					tokens = tokens->next;
					pos = GPOINTER_TO_INT(tokens->data);
					tokens = tokens->next;

					if (mode == MODE_A)
						do_mode_a (out, dict, word, pos, lineCount, terse_mode);
					else if (mode == MODE_L)
						do_mode_l (out, dict, word, lineCount);

					g_string_free(word, TRUE);
				}
				if (token_ptr)
					g_slist_free (token_ptr);
			}
		} 
		
		if (mode == MODE_A && corrected_something) {
			fwrite ("\n", 1, 1, out);
		}
		g_string_truncate (str, 0);
		fflush (out);
	}

	enchant_broker_free_dict (broker, dict);
	enchant_broker_free (broker);

	g_string_free (str, TRUE);

	return 0;
}
Example #10
0
/* From gcoincoin */
static gchar *strutf8( const gchar *pc, guint uMaxChar )
{
	gunichar     uCode ;
	guchar       b ;
	gsize        uLen ;
	GString     *pString ;
	guint        uChar ;
	const gchar *pcEnd ;

	if(( pc == NULL )||( *pc == 0 ))
	{
		return NULL ;
	}

	if( uMaxChar == 0 )
	{
		uMaxChar = G_MAXUINT ;
	}

	uLen  = strlen( pc );
	pcEnd = &pc[ uLen ];
	uChar = 0 ;

	if( g_utf8_validate( pc, (gssize) uLen, NULL ) )
	{
		const gchar *pcStart = pc ;
		while(( pc < pcEnd )&&( uChar < uMaxChar ))
		{
			pc = g_utf8_next_char(pc);
			uChar++ ;
		}
		return g_strndup( pcStart, pc - pcStart );
	}

	pString = g_string_sized_new( uLen );
	while(( pc < pcEnd )&&( uChar < uMaxChar ))
	{
		b = (guchar) *pc ;
		if( b < 128 )
		{
			/* Keep ASCII characters, but remove all control characters
			 * but CR, LF and TAB. */

			if(( b > 31 )&&( b != 127 ))
			{
				g_string_append_c( pString, b );
			}
			else
			{
				switch( b )
				{
					case '\n':
					case '\r':
					case '\t':
						break ;
					default:
						b = ' ' ;
				}
				g_string_append_c( pString, b );
			}
			pc++ ;
		}
		else
		{
			uCode = g_utf8_get_char_validated( pc, -1 );
			if(( uCode != (gunichar)-1 )&&( uCode != (gunichar)-2 ))
			{
				/* Keep a valid UTF-8 character as is */
				g_string_append_unichar( pString, uCode );
				pc = g_utf8_next_char(pc);
			}
			else
			{
				/* Consider an invalid byte as an ISO-8859-1 character code.
				 * We get rid of ASCII & ISO-8859-1 control characters. */

				if(( b > 0x1F )&&( b < 0x7F ))
				{
					/* ASCII characters, excluding control characters */
					g_string_append_c( pString, b );
				}
				else if( b > 0x9F )
				{
					/* ISO-8859-1 character, excluding control character (0x7F-0x9F) */
					g_string_append_unichar( pString, (gunichar)b );
				}
				else
				{
					g_string_append_c( pString, ' ' );
				}
				pc++ ;
			}
		}
		uChar++ ;
	}

	#ifdef DEBUG
		g_assert( g_utf8_validate( pString->str, -1, NULL ) );
	#endif

	return g_string_free( pString, FALSE );
}
Example #11
0
/* Copied from tracker/src/libtracker-fts/tracker-parser-glib.c under the GPL
 * Originally written by Aleksander Morgado <*****@*****.**>
 */
char *
shell_util_normalize_casefold_and_unaccent (const char *str)
{
  char *tmp;
  gsize i = 0, j = 0, ilen;

  if (str == NULL)
    return NULL;

  /* Get the NFKD-normalized and casefolded string */
  tmp = shell_util_normalize_and_casefold (str);
  ilen = strlen (tmp);

  while (i < ilen)
    {
      gunichar unichar;
      gchar *next_utf8;
      gint utf8_len;

      /* Get next character of the word as UCS4 */
      unichar = g_utf8_get_char_validated (&tmp[i], -1);

      /* Invalid UTF-8 character or end of original string. */
      if (unichar == (gunichar) -1 ||
          unichar == (gunichar) -2)
        {
          break;
        }

      /* Find next UTF-8 character */
      next_utf8 = g_utf8_next_char (&tmp[i]);
      utf8_len = next_utf8 - &tmp[i];

      if (IS_CDM_UCS4 ((guint32) unichar))
        {
          /* If the given unichar is a combining diacritical mark,
           * just update the original index, not the output one */
          i += utf8_len;
          continue;
        }

      /* If already found a previous combining
       * diacritical mark, indexes are different so
       * need to copy characters. As output and input
       * buffers may overlap, need to use memmove
       * instead of memcpy */
      if (i != j)
        {
          memmove (&tmp[j], &tmp[i], utf8_len);
        }

      /* Update both indexes */
      i += utf8_len;
      j += utf8_len;
    }

  /* Force proper string end */
  tmp[j] = '\0';

  return tmp;
}
Example #12
0
int
mcview_get_utf (mcview_t * view, off_t byte_index, int *char_width, gboolean * result)
{
    gchar *str = NULL;
    int res = -1;
    gunichar ch;
    gchar *next_ch = NULL;
    gchar utf8buf[UTF8_CHAR_LEN + 1];

    *char_width = 0;
    *result = FALSE;

    switch (view->datasource)
    {
    case DS_STDIO_PIPE:
    case DS_VFS_PIPE:
        str = mcview_get_ptr_growing_buffer (view, byte_index);
        break;
    case DS_FILE:
        str = mcview_get_ptr_file (view, byte_index);
        break;
    case DS_STRING:
        str = mcview_get_ptr_string (view, byte_index);
        break;
    case DS_NONE:
        break;
    }

    if (str == NULL)
        return 0;

    res = g_utf8_get_char_validated (str, -1);

    if (res < 0)
    {
        /* Retry with explicit bytes to make sure it's not a buffer boundary */
        int i;
        for (i = 0; i < UTF8_CHAR_LEN; i++)
        {
            if (mcview_get_byte (view, byte_index + i, &res))
                utf8buf[i] = res;
            else
            {
                utf8buf[i] = '\0';
                break;
            }
        }
        utf8buf[UTF8_CHAR_LEN] = '\0';
        str = utf8buf;
        res = g_utf8_get_char_validated (str, -1);
    }

    if (res < 0)
    {
        ch = *str;
        *char_width = 1;
    }
    else
    {
        ch = res;
        /* Calculate UTF-8 char width */
        next_ch = g_utf8_next_char (str);
        if (next_ch)
            *char_width = next_ch - str;
        else
            return 0;
    }
    *result = TRUE;
    return ch;
}
Example #13
0
static int
key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2,
							struct session *sess)
{
	int len = 0, elen = 0, i = 0, cursor_pos, ent_start = 0, comp = 0, prefix_len, skip_len = 0;
	gboolean is_nick = FALSE, is_cmd = FALSE, found = FALSE, has_nick_prefix = FALSE;
	char ent[CHANLEN], *postfix = NULL, *result, *ch;
	GList *list = NULL, *tmp_list = NULL;
	const char *text;
	GCompletion *gcomp = NULL;
	GString *buf;

	/* force the IM Context to reset */
	SPELL_ENTRY_SET_EDITABLE (t, FALSE);
	SPELL_ENTRY_SET_EDITABLE (t, TRUE);

	text = SPELL_ENTRY_GET_TEXT (t);
	if (text[0] == 0)
		return 1;

	len = g_utf8_strlen (text, -1); /* must be null terminated */

	cursor_pos = SPELL_ENTRY_GET_POS (t);

	/* handle "nick: " or "nick " or "#channel "*/
	ch = g_utf8_find_prev_char(text, g_utf8_offset_to_pointer(text,cursor_pos));
	if (ch && ch[0] == ' ')
	{
		skip_len++;
		ch = g_utf8_find_prev_char(text, ch);
		if (!ch)
			return 2;

		cursor_pos = g_utf8_pointer_to_offset(text, ch);
		if (cursor_pos && (g_utf8_get_char_validated(ch, -1) == ':' || 
					g_utf8_get_char_validated(ch, -1) == ',' ||
					g_utf8_get_char_validated (ch, -1) == g_utf8_get_char_validated (prefs.hex_completion_suffix, -1)))
		{
			skip_len++;
		}
		else
			cursor_pos = g_utf8_pointer_to_offset(text, g_utf8_offset_to_pointer(ch, 1));
	}

	comp = skip_len;
	
	/* store the text following the cursor for reinsertion later */
	if ((cursor_pos + skip_len) < len)
		postfix = g_utf8_offset_to_pointer(text, cursor_pos + skip_len);

	for (ent_start = cursor_pos; ; --ent_start)
	{
		if (ent_start == 0)
			break;
		ch = g_utf8_offset_to_pointer(text, ent_start - 1);
		if (ch && ch[0] == ' ')
			break;
	}

	if (ent_start == 0 && text[0] == prefs.hex_input_command_char[0])
	{
		ent_start++;
		is_cmd = TRUE;
	}
	else if (strchr (sess->server->chantypes, text[ent_start]) == NULL)
	{
		is_nick = TRUE;
		if (strchr (sess->server->nick_prefixes, text[ent_start]) != NULL)
		{
			if (ent_start == 0)
				has_nick_prefix = TRUE;
			ent_start++;
		}
	}

	prefix_len = ent_start;
	elen = cursor_pos - ent_start;

	g_utf8_strncpy (ent, g_utf8_offset_to_pointer (text, prefix_len), elen);
	
	if (sess->type == SESS_DIALOG && is_nick)
	{
		/* tab in a dialog completes the other person's name */
		if (rfc_ncasecmp (sess->channel, ent, elen) == 0)
		{
			result =  sess->channel;
			is_nick = FALSE;
		}
		else
			return 2;
	}
	else
	{
		if (is_nick)
		{
			gcomp = g_completion_new((GCompletionFunc)gcomp_nick_func);
			tmp_list = userlist_double_list(sess); /* create a temp list so we can free the memory */
			if (prefs.hex_completion_sort == 1)	/* sort in last-talk order? */
				tmp_list = g_list_sort (tmp_list, (void *)talked_recent_cmp);
		}
		else
		{
			gcomp = g_completion_new (NULL);
			if (is_cmd)
			{
				tmp_list = cmdlist_double_list (command_list);
				for(i = 0; xc_cmds[i].name != NULL ; i++)
				{
					tmp_list = g_list_prepend (tmp_list, xc_cmds[i].name);
				}
				tmp_list = plugin_command_list(tmp_list);
			}
			else
				tmp_list = chanlist_double_list (sess_list);
		}
		tmp_list = g_list_reverse(tmp_list); /* make the comp entries turn up in the right order */
		g_completion_set_compare (gcomp, (GCompletionStrncmpFunc)rfc_ncasecmp);
		if (tmp_list)
		{
			g_completion_add_items (gcomp, tmp_list);
			g_list_free (tmp_list);
		}

		if (comp && !(rfc_ncasecmp(old_gcomp.data, ent, old_gcomp.elen) == 0))
		{
			key_action_tab_clean ();
			comp = 0;
		}
	
		list = g_completion_complete_utf8 (gcomp, comp ? old_gcomp.data : ent, &result);
		
		if (result == NULL) /* No matches found */
		{
			g_completion_free(gcomp);
			return 2;
		}

		if (comp) /* existing completion */
		{
			while(list) /* find the current entry */
			{
				if(rfc_ncasecmp(list->data, ent, elen) == 0)
				{
					found = TRUE;
					break;
				}
				list = list->next;
			}

			if (found)
			{
				if (!(d1 && d1[0])) /* not holding down shift */
				{
					if (g_list_next(list) == NULL)
						list = g_list_first(list);
					else
						list = g_list_next(list);
				}
				else
				{
					if (g_list_previous(list) == NULL)
						list = g_list_last(list);
					else
						list = g_list_previous(list);
				}
				g_free(result);
				result = (char*)list->data;
			}
			else
			{
				g_free(result);
				g_completion_free(gcomp);
				return 2;
			}
		}
		else
		{
			strcpy(old_gcomp.data, ent);
			old_gcomp.elen = elen;

			/* Get the first nick and put out the data for future nickcompletes */
			if (prefs.hex_completion_amount > 0 && g_list_length (list) <= (guint) prefs.hex_completion_amount)
			{
				g_free(result);
				result = (char*)list->data;
			}
			else
			{
				/* bash style completion */
				if (g_list_next(list) != NULL)
				{
					buf = g_string_sized_new (MAX(COMP_BUF, len + NICKLEN));
					if (strlen (result) > elen) /* the largest common prefix is larger than nick, change the data */
					{
						if (prefix_len)
							g_string_append_len (buf, text, offset_to_len (text, prefix_len));
						g_string_append (buf, result);
						cursor_pos = buf->len;
						g_free(result);
						if (postfix)
						{
							g_string_append_c (buf, ' ');
							g_string_append (buf, postfix);
						}
						SPELL_ENTRY_SET_TEXT (t, buf->str);
						SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, cursor_pos));
						g_string_erase (buf, 0, -1);
					}
					else
						g_free(result);

					while (list)
					{
						len = buf->len;
						elen = strlen (list->data);	/* next item to add */
						if (len + elen + 2 >= COMP_BUF) /* +2 is space + null */
						{
							PrintText (sess, buf->str);
							g_string_erase (buf, 0, -1);
						}
						g_string_append (buf, (char*)list->data);
						g_string_append_c (buf, ' ');
						list = list->next;
					}
					PrintText (sess, buf->str);
					g_completion_free(gcomp);
					g_string_free (buf, TRUE);
					return 2;
				}
				/* Only one matching entry */
				g_free(result);
				result = list->data;
			}
		}
	}
	
	if(result)
	{
		buf = g_string_sized_new (len + NICKLEN);
		if (prefix_len)
			g_string_append_len (buf, text, offset_to_len (text, prefix_len));
		g_string_append (buf, result);
		if((!prefix_len || has_nick_prefix) && is_nick && prefs.hex_completion_suffix[0] != '\0')
			g_string_append_unichar (buf, g_utf8_get_char_validated (prefs.hex_completion_suffix, -1));
		g_string_append_c (buf, ' ');
		cursor_pos = buf->len;
		if (postfix)
			g_string_append (buf, postfix);
		SPELL_ENTRY_SET_TEXT (t, buf->str);
		SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, cursor_pos));
		g_string_free (buf, TRUE);
	}
	if (gcomp)
		g_completion_free(gcomp);
	return 2;
}
/* FIXME: for our purposes it's probably enough to just check for the sync
 * marker - we just want to know if it's a header frame or not */
static gboolean
gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, guint8 * data, guint size,
    gint64 * last_sample_num)
{
  guint headerlen;
  guint sr_from_end = 0;        /* can be 0, 8 or 16 */
  guint bs_from_end = 0;        /* can be 0, 8 or 16 */
  guint32 val = 0;
  guint8 bs, sr, ca, ss, pb;

  if (size < 10)
    return FALSE;

  /* sync */
  if (data[0] != 0xFF || (data[1] & 0xFC) != 0xF8)
    return FALSE;
  if (data[1] & 1) {
    GST_WARNING_OBJECT (flacdec, "Variable block size FLAC unsupported");
    return FALSE;
  }

  bs = (data[2] & 0xF0) >> 4;   /* blocksize marker   */
  sr = (data[2] & 0x0F);        /* samplerate marker  */
  ca = (data[3] & 0xF0) >> 4;   /* channel assignment */
  ss = (data[3] & 0x0F) >> 1;   /* sample size marker */
  pb = (data[3] & 0x01);        /* padding bit        */

  GST_LOG_OBJECT (flacdec,
      "got sync, bs=%x,sr=%x,ca=%x,ss=%x,pb=%x", bs, sr, ca, ss, pb);

  if (bs == 0 || sr == 0x0F || ca >= 0x0B || ss == 0x03 || ss == 0x07) {
    return FALSE;
  }

  /* read block size from end of header? */
  if (bs == 6)
    bs_from_end = 8;
  else if (bs == 7)
    bs_from_end = 16;

  /* read sample rate from end of header? */
  if (sr == 0x0C)
    sr_from_end = 8;
  else if (sr == 0x0D || sr == 0x0E)
    sr_from_end = 16;

  val = data[4];
  /* This is slightly faster than a loop */
  if (!(val & 0x80)) {
    val = 0;
  } else if ((val & 0xc0) && !(val & 0x20)) {
    val = 1;
  } else if ((val & 0xe0) && !(val & 0x10)) {
    val = 2;
  } else if ((val & 0xf0) && !(val & 0x08)) {
    val = 3;
  } else if ((val & 0xf8) && !(val & 0x04)) {
    val = 4;
  } else if ((val & 0xfc) && !(val & 0x02)) {
    val = 5;
  } else if ((val & 0xfe) && !(val & 0x01)) {
    val = 6;
  } else {
    GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
    return FALSE;
  }

  val++;
  headerlen = 4 + val + (bs_from_end / 8) + (sr_from_end / 8);

  if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
    GST_LOG_OBJECT (flacdec, "invalid checksum");
    return FALSE;
  }

  if (!last_sample_num)
    return TRUE;

  /* FIXME: This is can be 36 bit if variable block size is used,
   * fortunately not encoder supports this yet and we check for that
   * above.
   */
  val = (guint32) g_utf8_get_char_validated ((gchar *) data + 4, -1);

  if (val == (guint32) - 1 || val == (guint32) - 2) {
    GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
    return FALSE;
  }

  if (flacdec->min_blocksize == flacdec->max_blocksize) {
    *last_sample_num = (val + 1) * flacdec->min_blocksize;
  } else {
    *last_sample_num = 0;       /* FIXME: + length of last block in samples */
  }

  /* FIXME: only valid for fixed block size streams */
  GST_DEBUG_OBJECT (flacdec, "frame number: %" G_GINT64_FORMAT,
      *last_sample_num);

  if (flacdec->info.rate > 0 && *last_sample_num != 0) {
    GST_DEBUG_OBJECT (flacdec, "last sample %" G_GINT64_FORMAT " = %"
        GST_TIME_FORMAT, *last_sample_num,
        GST_TIME_ARGS (*last_sample_num * GST_SECOND / flacdec->info.rate));
  }

  return TRUE;
}