PyObject *
_pygi_marshal_to_py_unichar (PyGIInvokeState   *state,
                             PyGICallableCache *callable_cache,
                             PyGIArgCache      *arg_cache,
                             GIArgument        *arg)
{
    PyObject *py_obj = NULL;

    /* Preserve the bidirectional mapping between 0 and "" */
    if (arg->v_uint32 == 0) {
        py_obj = PYGLIB_PyUnicode_FromString ("");
    } else if (g_unichar_validate (arg->v_uint32)) {
        gchar utf8[6];
        gint bytes;

        bytes = g_unichar_to_utf8 (arg->v_uint32, utf8);
        py_obj = PYGLIB_PyUnicode_FromStringAndSize ((char*)utf8, bytes);
    } else {
        /* TODO: Convert the error to an exception. */
        PyErr_Format (PyExc_TypeError,
                      "Invalid unicode codepoint %" G_GUINT32_FORMAT,
                      arg->v_uint32);
    }

    return py_obj;
}
void strip_unicode(gchar * data, gsize len)
{
    gsize i = 0;

    if (data != NULL) {
        for (i = 0; i < len; i++) {
            if (!g_unichar_validate(data[i])) {
                data[i] = ' ';
            }
        }
    }
}
static gboolean
param_unichar_validate (GParamSpec *pspec,
		        GValue     *value)
{
  gunichar oval = value->data[0].v_uint;
  gboolean changed = FALSE;

  if (!g_unichar_validate (oval))
    {
      value->data[0].v_uint = 0;
      changed = TRUE;
    }

  return changed;
}
Beispiel #4
0
IBusText *
ibus_text_new_from_unichar (gunichar c)
{
    IBusText *text;
    gint len;

    if (!g_unichar_validate (c)) {
        return NULL;
    }

    text= g_object_new (IBUS_TYPE_TEXT, NULL);

    text->is_static = FALSE;
    text->text = (gchar *)g_malloc (12);
    len = g_unichar_to_utf8 (c, text->text);
    text->text[len] =  0;

    return text;
}
Beispiel #5
0
/* Converts \uxxxx or \Uxxxxyyyy escapes into their UTF-8 equivalents.
 * Returns a newly allocated string. The input string must be valid utf-8.
 */
char *str_unescape_unicode(const char *utf8_string)
{
    if(utf8_string == NULL)
        return NULL;

    dstring_t *unescaped = dstring_new(NULL);
    const char *p = utf8_string;
    while(p && *p)
    {
        gunichar uc = g_utf8_get_char(p);
        p = g_utf8_next_char(p);
        if(uc == '\\')
        {
            if(*p == 'u' && is_hex_string(p+1, 4))
            {
                p++;
                uc = htons(get_ucs4_16(p));
                p += 4;
            }
            else if(*p == 'U' && is_hex_string(p+1, 8))
            {
                p++;
                uc = htonl(get_ucs4_32(p));
                p += 8;
            }

            if(!g_unichar_validate(uc))
            {
                continue;
            }
        }

        char utf8_buf[6];
        int utf8_len = g_unichar_to_utf8(uc, utf8_buf);
        dstring_append_len(unescaped, utf8_buf, utf8_len);
    }
    char *result = unescaped->string;
    dstring_free(unescaped, 0);

    return result;
}
Beispiel #6
0
static gunichar
json_scanner_get_unichar (JsonScanner *scanner,
                          guint       *line_p,
                          guint       *position_p)
{
  gunichar uchar;
  gchar ch;
  gint i;

  uchar = 0;
  for (i = 0; i < 4; i++)
    {
      ch = json_scanner_get_char (scanner, line_p, position_p);

      if (is_hex_digit (ch))
        uchar += ((gunichar) to_hex_digit (ch) << ((3 - i) * 4));
      else
        break;
    }

  g_assert (g_unichar_validate (uchar) || g_unichar_type (uchar) == G_UNICODE_SURROGATE);

  return uchar;
}
Beispiel #7
0
void *validate_value(gint value_id, gint input_type, void *value)
{
	// Local variables
	guint				base_type;
	guint				capabilities;
	gboolean			capability_check;
	gchar				*conversion_buffer = NULL;			// Used when converting between unicode character types
	gchar				*decimal_point;
	GString				*error_string;
	gchar				input_char;
	gunichar			input_char_unicode;
	gchar				*input_ptr;
	struct lconv		*locale_info;
	gboolean			match_found;
	gint				output_gint;
	gint				*output_gint_ptr;
	gfloat				output_gfloat;
	gfloat				*output_gfloat_ptr;
	GString				*output_gstring;
	guint				output_guint;
	guint				*output_guint_ptr;
	guint				string_counter;
	gint				string_length;
	gint				string_max;
	guint				string_min;
	gfloat				value_max;
	gfloat				value_min;


	// Initialise various things
	base_type = get_valid_fields_base_type(value_id);
	capabilities = get_valid_fields_capabilities(value_id);
	input_ptr = (gchar *) value;
	output_gstring = g_string_new(NULL);
	locale_info = localeconv();
	decimal_point = locale_info->decimal_point;

	switch (base_type)
	{
		case V_CHAR:

			// * We're validating a char or string *

			// We can only validate string input for this type of value
			if (V_CHAR != input_type)
			{
				return NULL;
			}

			// Get the length of the input string
			string_max = get_valid_fields_max_value(value_id);
			string_min = get_valid_fields_min_value(value_id);
			string_length = g_utf8_strlen(input_ptr, -1);

			// If the length of the string isn't in the acceptable range, return NULL
			if (string_length < string_min)
				return NULL;
			if ((string_length > string_max) && (-1 != string_max))  // -1 for string_max means "no maximum limit"
				return NULL;
			if (0 == string_length)
			{
				// 0 length string, so we just return it
				return output_gstring;
			}

			// Sanitise each character of the input string
			for (string_counter = 0; string_counter < string_length; string_counter++)
			{
				// Get the next character
				input_char_unicode = g_utf8_get_char_validated(input_ptr, -1);
				if ((gunichar)-1 == input_char_unicode)
				{
					// The returned character was not a valid unicode character, so we indicate failure
					return NULL;
				}
				if ((gunichar)-2 == input_char_unicode)
				{
					// The returned character was not a valid unicode character, so we indicate failure
					return NULL;
				}

				// Convert the character to UTF-8 so we can process it
				conversion_buffer = g_ucs4_to_utf8(&input_char_unicode, 1, NULL, NULL, NULL);

				// Determine which character we're examining
				if (TRUE == g_unichar_isalnum(input_char_unicode))
				{
					// It's a standard unicode alphanumeric character, so we accept it as is
					g_string_append_printf(output_gstring, "%s", conversion_buffer);
					input_ptr = g_utf8_find_next_char(input_ptr, NULL);
				}
				else
				{
					// * The input wasn't a standard alphanumic character, so check if it *
					// * is one of the characters in the capabilities list for this field *
					match_found = FALSE;
					capability_check = V_ANY_UNICHAR & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have any valid unicode character
						if (TRUE == g_unichar_validate(input_char_unicode))
						{
							// Yes, this is a valid unicode character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_SPACES & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have spaces
						if (0 == g_strcmp0(" ", conversion_buffer))
						{
							// Yes, this is a space character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_FULL_STOP & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have full stops
						if (0 == g_strcmp0(".", conversion_buffer))
						{
							// Yes, this is a full stop character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_HYPENS & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have hypens
						if (0 == g_strcmp0("-", conversion_buffer))
						{
							// Yes, this is a hypen character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_UNDERSCORES & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have underscores
						if (0 == g_strcmp0("_", conversion_buffer))
						{
							// Yes, this is an underscore character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_PATH_SEP & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have path separator characters ('/', '\')
						if ((0 == g_strcmp0("/", conversion_buffer)) || (0 == g_strcmp0("\\", conversion_buffer)))
						{
							// Yes, this is a path separator character
							match_found = TRUE;
							output_gstring = g_string_append_c(output_gstring, G_DIR_SEPARATOR);  // Output the OS correct version
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_EQUALS & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have equals signs
						if (0 == g_strcmp0("=", conversion_buffer))
						{
							// Yes, this is an equals sign character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_FORWARD_SLASHES & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have forward slashes
						if (0 == g_strcmp0("/", conversion_buffer))
						{
							// Yes, this is a forward slash character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_NEW_LINES & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have new line characters
						if (0 == g_strcmp0("\n", conversion_buffer))
						{
							// Yes, this is a new line character
							match_found = TRUE;
							output_gstring = g_string_append_c(output_gstring, '\n');
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_PLUSES & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have pluses
						if (0 == g_strcmp0("+", conversion_buffer))
						{
							// Yes, this is a plus character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_PERCENT & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have the percent sign
						if (0 == g_strcmp0("%", conversion_buffer))
						{
							// Yes, this is a percent sign
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_COLON & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have colons
						if (0 == g_strcmp0(":", conversion_buffer))
						{
							// Yes, this is a colon character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_AT & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have the at symbol
						if (0 == g_strcmp0("@", conversion_buffer))
						{
							// Yes, this is an at character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_QUESTION & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have the question mark
						if (0 == g_strcmp0("?", conversion_buffer))
						{
							// Yes, this is a question mark character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}
					capability_check = V_AMPERSAND & capabilities;
					if (FALSE != capability_check)
					{
						// This field is allowed to have the ampersand character
						if (0 == g_strcmp0("&", conversion_buffer))
						{
							// Yes, this is an ampersand character
							match_found = TRUE;
							g_string_append_printf(output_gstring, "%s", conversion_buffer);
							input_ptr = g_utf8_find_next_char(input_ptr, NULL);
							continue;
						}
					}

					// The character we are checking is not in the list of valid inputs for this field
					if (FALSE == match_found)
					{
						g_free(conversion_buffer);
						g_string_free(output_gstring, TRUE);
						return NULL;
					}
				}
			}

			// Remove any leading and/or trailing white space
			output_gstring->str = g_strstrip(output_gstring->str);
			output_gstring->len = strlen(output_gstring->str);

			// Recheck the length of the output string
			if (output_gstring->len < string_min)
			{
				g_free(conversion_buffer);
				g_string_free(output_gstring, TRUE);
				return NULL;
			}

			// Free the memory used so far
			if (0 != string_length)
			{
				g_free(conversion_buffer);
			}

			// The string seems to be valid, so return it for use
			return output_gstring;

			break;

		case V_FLOAT_UNSIGNED:

			// * We're validating an unsigned float *

			// If we're working with string input, we need to convert it to a float first
			if (V_CHAR == input_type)
			{
				// * We're working with string input *

				// Get the length of the input string
				string_length = strlen((gchar *) value);
	
				// Sanitise each character of the input string
				for (string_counter = 0; string_counter < string_length; string_counter++)
				{
					input_char = ((gchar *) value)[string_counter];

					// Check for decimal digits
					if (TRUE == g_ascii_isdigit(input_char))
					{
						output_gstring = g_string_append_c(output_gstring, input_char);
					}
					else
					{
						// This field is allowed to have full stops.  Is this character a full stop?
						if (0 == g_ascii_strncasecmp(".", &input_char, 1))
						{
							// Yes, this is a full stop character
							output_gstring = g_string_append_c(output_gstring, *decimal_point);
							match_found = TRUE;
							continue;
						}

						// This field is allowed to have commas (equiv to full stop in some locales).  Is this character a comma?
						if (0 == g_ascii_strncasecmp(",", &input_char, 1))
						{
							// Yes, this is a comma character
							output_gstring = g_string_append_c(output_gstring, *decimal_point);
							match_found = TRUE;
							continue;
						}

						// The character we are checking is not in the list of valid inputs for this field
						if (FALSE == match_found)
						{
							g_string_free(output_gstring, TRUE);
							return NULL;
						}
					}
				}

				// Convert the string to a float
				output_gfloat = (gfloat) g_strtod(output_gstring->str, NULL);
			}
			else
			{
				// We're working with a float input, so just copy the value directly
				output_gfloat = *((gfloat *) value);
			}

			// Is the float value within the defined bounds?
			value_max = get_valid_fields_max_value(value_id);
			value_min = get_valid_fields_min_value(value_id);
			if ((output_gfloat < value_min) || (output_gfloat > value_max))
			{
				// Value is out of bounds, so fail
				g_string_free(output_gstring, TRUE);
				return NULL;
			}

			// The value looks ok, so we copy it to newly allocated memory, to pass it back
			output_gfloat_ptr = g_try_new0(gfloat, 1);
			if (NULL == output_gfloat_ptr)
			{
				// Unable to allocate memory for the new value, so fail
				g_string_free(output_gstring, TRUE);
				return NULL;
			}
			*output_gfloat_ptr = output_gfloat;

			// Free the string memory allocated in this function
			g_string_free(output_gstring, TRUE);

			return output_gfloat_ptr;

		case V_INT_UNSIGNED:

			// * We're validating an unsigned integer *

			// If we're working with string input, we need to convert it to an integer first
			if (V_CHAR == input_type)
			{
				// * We're working with string input *

				// Get the length of the input string
				string_length = strlen((gchar *) value);
	
				// Sanitise each character of the input string
				for (string_counter = 0; string_counter < string_length; string_counter++)
				{
					input_char = ((gchar *) value)[string_counter];

					// Check for decimal digits
					if (TRUE == g_ascii_isdigit(input_char))
					{
						output_gstring = g_string_append_c(output_gstring, input_char);
					}
					else
					{
						// This wasn't a valid character
						g_string_free(output_gstring, TRUE);
						return NULL;
					}
				}

				// Convert the string to an integer
				output_guint = atoi(output_gstring->str);
			}
			else
			{
				// We're working with integer input, so just copy the value directly
				output_guint = *((guint *) value);
			}

			// Is the integer value within the defined bounds?
			value_max = get_valid_fields_max_value(value_id);
			value_min = get_valid_fields_min_value(value_id);
			if ((output_guint < value_min) || (output_guint > value_max))
			{
				// Value is out of bounds, so fail
				g_string_free(output_gstring, TRUE);
				return NULL;
			}

			// The value looks ok, so we copy it to newly allocated memory, to pass it back
			output_guint_ptr = g_try_new0(guint, 1);
			if (NULL == output_guint_ptr)
			{
				// Unable to allocate memory for the new value, so fail
				g_string_free(output_gstring, TRUE);
				return NULL;
			}
			*output_guint_ptr = output_guint;

			// Free the string memory allocated in this function
			g_string_free(output_gstring, TRUE);

			return output_guint_ptr;

		case V_INT_SIGNED:

			// * We're validating a signed integer *

			// If we're working with string input, we need to convert it to an integer first
			if (V_CHAR == input_type)
			{
				// * We're working with string input *

				// Get the length of the input string
				string_length = strlen((gchar *) value);

				// Sanitise each character of the input string
				for (string_counter = 0; string_counter < string_length; string_counter++)
				{
					input_char = ((gchar *) value)[string_counter];

					// Check for decimal digits
					if (TRUE == g_ascii_isdigit(input_char))
					{
						output_gstring = g_string_append_c(output_gstring, input_char);
					}
					else
					{
						// * The input wasn't a standard digit character, so check if it *
						// * is one of the characters in the capabilities list for this field *
						match_found = FALSE;
						capability_check = V_HYPENS & capabilities;
						if (FALSE != capability_check)
						{
							// This field is allowed to have hypens
							if (0 == g_ascii_strncasecmp("-", &input_char, 1))
							{
								// Yes, this is a hypen character
								match_found = TRUE;
								g_string_append_printf(output_gstring, "%s", "-");
							}
						}

						// The character we are checking is not in the list of valid inputs for this field
						if (FALSE == match_found)
						{
							g_string_free(output_gstring, TRUE);
							return NULL;
						}
					}
				}

				// Convert the string to an integer
				output_gint = atoi(output_gstring->str);
			}
			else
			{
				// We're working with integer input, so just copy the value directly
				output_gint = *((gint *) value);
			}

			// Is the integer value within the defined bounds?
			value_max = get_valid_fields_max_value(value_id);
			value_min = get_valid_fields_min_value(value_id);
			if ((output_gint < value_min) || (output_gint > value_max))
			{
				// Value is out of bounds, so fail
				g_string_free(output_gstring, TRUE);
				return NULL;
			}

			// The value looks ok, so we copy it to newly allocated memory, to pass it back
			output_gint_ptr = g_try_new0(gint, 1);
			if (NULL == output_gint_ptr)
			{
				// Unable to allocate memory for the new value, so fail
				g_string_free(output_gstring, TRUE);
				return NULL;
			}
			*output_gint_ptr = output_gint;

			// Free the string memory allocated in this function
			g_string_free(output_gstring, TRUE);

			return output_gint_ptr;

		case V_RESOLUTION:

				// * We're working with a resolution (text string) input.  i.e. '1920x1200 pixels' *

				// Get the length of the input string
				string_length = strlen((gchar *) value);
				string_max = get_valid_fields_max_value(value_id);
				string_min = get_valid_fields_min_value(value_id);

				// If the length of the string isn't in the acceptable range, return NULL
				if ((string_length < string_min) || (string_length > string_max))
					return NULL;

				// Sanitise each character of the input string
				for (string_counter = 0; string_counter < string_length; string_counter++)
				{
					input_char = ((gchar *) value)[string_counter];

					// Check for decimal digits
					if (TRUE == g_ascii_isdigit(input_char))
					{
						output_gstring = g_string_append_c(output_gstring, input_char);
					}
					else
					{
						match_found = FALSE;

						// This field is allowed to have the ' ' and 'x' characters .  Is this character one of those?
						if (0 == g_ascii_strncasecmp(" ", &input_char, 1))
						{
							// Yes, this is a space character, so we've already collected the required resolution
							// info and we can just return the resolution part of the string so far

							// Remove any leading and/or trailing white space
							output_gstring->str = g_strstrip(output_gstring->str);
							output_gstring->len = strlen(output_gstring->str);

							// Recheck the length of the output string
							if ((string_length < string_min) || (string_length > string_max))
								return NULL;

							// The string seems to be valid, so return it for use
							return output_gstring;
						}
						if (0 == g_ascii_strncasecmp("x", &input_char, 1))
						{
							// Yes, this is a 'x' character
							output_gstring = g_string_append_c(output_gstring, 'x');
							match_found = TRUE;
							continue;
						}
						if (FALSE == match_found)
						{
							// This wasn't a valid character
							g_string_free(output_gstring, TRUE);
							return NULL;
						}
					}
				}

				// Remove any leading and/or trailing white space
				output_gstring->str = g_strstrip(output_gstring->str);
				output_gstring->len = strlen(output_gstring->str);

				// Recheck the length of the output string
				if ((string_length < string_min) || (string_length > string_max))
					return NULL;

				// The string seems to be valid, so return it for use
				return output_gstring;

		case V_ZOOM:

			// * We're working with a zoom level.  i.e. "100%" or "Fit to width" *

			// Get the length of the input string
			string_length = g_utf8_strlen((gchar *) value, -1);
			string_max = get_valid_fields_max_value(value_id);
			string_min = get_valid_fields_min_value(value_id);

			// If the length of the string isn't in the acceptable range, return NULL
			if ((string_length < string_min) || (string_length > string_max))
				return NULL;

			// If the string is "Fit to width" or a localised version of it
			if ((0 == g_strcmp0("Fit to width", (gchar *) value)) || (0 == g_strcmp0(_("Fit to width"), (gchar *) value)))
			{
				// Yes, this is the "Fit to width" value
				output_gstring = g_string_assign(output_gstring, value);
				return output_gstring;
			}

			// * The incoming string isn't the "Fit to width" value, *
			// * so should only consist of decimal characters and '%' *

			// Sanitise each character of the input string
			for (string_counter = 0; string_counter < string_length; string_counter++)
			{
				input_char = ((gchar *) value)[string_counter];

				// Check for decimal digits
				if (TRUE == g_ascii_isdigit(input_char))
				{
					output_gstring = g_string_append_c(output_gstring, input_char);
					continue;
				}
				// Check for '%' character
				if (0 == g_ascii_strncasecmp("%", &input_char, 1))
				{
					// Yes, this is a '%' character
					output_gstring = g_string_append_c(output_gstring, '%');
					continue;
				}
				// This wasn't a valid character
				g_string_free(output_gstring, TRUE);
				return NULL;
			}

			return output_gstring;

		default:

			// Unknown value type, we should never get here
			error_string = g_string_new(NULL);
			g_string_printf(error_string, "%s ED119: %s - '%s'", _("Error"), _("Unknown value passed to validation function"), get_valid_fields_name(value_id));
			display_warning(error_string->str);
			g_string_free(error_string, TRUE);

			return NULL;
	}

	// If we get here, then something went wrong!
	return NULL;
}
/* Wrapper, in case we want to support a newer unicode version than glib */
gboolean mcharmap_unichar_validate(gunichar ch)
{
    return g_unichar_validate(ch);
}
Beispiel #9
0
GSList *
parseTestFile (gchar * filename)
{
	/* open test file */
	GIOChannel *testFile = g_io_channel_new_file (filename, "r", NULL);
	if (testFile == NULL)
		return NULL;

	GSList *testPairs = NULL;
	GString *line = g_string_new(NULL);
	int linecount = 0;

	while (g_io_channel_read_line_string (testFile, line, NULL, NULL) == G_IO_STATUS_NORMAL)
	{
		linecount++;

		/* strip of comments and whitespace */
		for (int i = 0; i < line->len; i++)
		{
			if (line->str[i] == '#')
			{
				g_string_truncate (line, i);
				break;
			}
		}
		g_strstrip (line->str);

		/* skip line if blank */
		if (strlen (line->str) == 0)
			continue;

		/* initialize test pair */
		TestPair *testPair = g_malloc (sizeof (TestPair));
		testPair->linenr = linecount;
		testPair->line = g_strdup (line->str);
		testPair->keyevent = NULL;
		testPair->commands = NULL;

		TIL_Keyevent *keyevent = NULL;
		/*gboolean hit = FALSE;*/
		TIL_Keyevent_Type type;
		gboolean autorep = FALSE;
		gint modifiers = 0;

		/* extract the fields */
		gchar **fields = g_strsplit (line->str, "::", 0);
		if (fields[0] == NULL || fields[1] == NULL)
			goto parseError;

		/*
		 * FIELD 1 - EVENT TYPE
		 */
		g_strstrip (fields[0]);
		if (g_ascii_strcasecmp (fields[0], "press") == 0)
		{
			type = TIL_Event_Pressed;
		}
		else if (g_ascii_strcasecmp (fields[0], "pressrep") == 0)
		{
			type = TIL_Event_Pressed;
			autorep = TRUE;
		}
		else if (g_ascii_strcasecmp (fields[0], "release") == 0)
		{
			type = TIL_Event_Released;
		}
		/*else if (g_ascii_strcasecmp (fields[0], "hit") == 0)
		{
			type = TIL_Event_Pressed;
			hit = TRUE;
		}*/
		else
		{
			goto parseError;
		}

		/*
		 * FIELD 2 - KEY
		 */
		char *keystring = g_strstrip (fields[1]);
		TIL_Keycode code = TIL_Key_unknown;
		GString *text = g_string_new ("");
		gboolean hasNonPrintable = FALSE;	/* TRUE <=> the key sequence has non-printable chars */
		while (*keystring != '\0')
		{
			gunichar c = g_utf8_get_char_validated (keystring, -1);
			if (!g_unichar_validate (c))
				goto parseError;
			keystring = g_utf8_next_char (keystring);
			if (c == (gunichar) '<' && *keystring != '\0')
			{					/* an escaped key */
				gchar *esckey = keystring;
				/* go to the next '>' */
				gunichar ch;
				do
				{
					ch = g_utf8_get_char_validated (keystring, -1);
					if (!g_unichar_validate (ch))
						goto parseError;
					keystring = g_utf8_next_char (keystring);
				}
				while (*keystring != '\0' && ch != (gunichar) '>');

				if (*keystring == '\0' && ch != (gunichar) '>')
				{				/* string not finished with '>' */
					goto parseError;
				}
				/* overwrite the '>' with NULL character, so that esckey contains the string
				 * inside the brackets */
				*(keystring - 1) = '\0';
				TIL_Keycode tempcode = unescapeKey (esckey);
				if (tempcode == TIL_Key_unknown)
					goto parseError;
				c = keyToChar (tempcode);
				if (c == 0)
				{				/* non-printable character */
					if (code != TIL_Key_unknown)
						/* we already have a key - this is not valid */
						goto parseError;

					hasNonPrintable = TRUE;
					code = tempcode;
				}
			}

			if (c != 0)
			{
				if (hasNonPrintable)
					/* non-printable characters and text together is not valid */
					goto parseError;

				g_string_append_unichar (text, c);
			}
		}

		/*
		 * FIELD 3 - MODIFIERS
		 */

		gchar **modv = g_strsplit (fields[2], ",", 0);
		gint i = 0;
		while (modv[i] != NULL)
		{
			g_strstrip (modv[i]);
			switch (g_ascii_toupper (modv[i][0]))
			{
			case 'S':
				modifiers |= TIL_Mod_Shift;
				break;
			case 'C':
				modifiers |= TIL_Mod_Control;
				break;
			case 'A':
				modifiers |= TIL_Mod_Alt;
				break;
			case 'M':
				modifiers |= TIL_Mod_Meta;
				break;
			default:
				break;
			}
			i++;
		}
		g_strfreev (modv);

		/*
		 * CONSTRUCT THE KEY EVENTS
		 */
		keyevent = g_malloc (sizeof (TIL_Keyevent) + text->len + 1);
		keyevent->type = type;
		keyevent->autorep = autorep;
		keyevent->modifiers = modifiers;
		keyevent->keycode = code;
		strcpy (keyevent->text, text->str);

		/*
		 * REMAINING FIELDS: COMMANDS
		 */
		GSList *cmds = NULL;
		int numCmds = 0;
		if (fields[3] != NULL)
		{
			/* ignore the last field if it consists only of white space */
			g_strstrip (fields[3]);
			if (*fields[3] != '\0')
			{
				for (int i = 3; fields[i] != NULL; i++)
				{
					TIL_Cmd *cmd = cmdFromString (fields[i]);
					if (cmd == NULL)
					{
						GSList *work = cmds;
						while (work != NULL)
						{
							g_free(work->data);
							work = g_slist_next (work);
						}
						goto parseError;
					}
					cmds = g_slist_append (cmds, cmd);
					numCmds++;
				}
			}
		}

		/*
		 * BUILD THE TEST PAIR
		 */
		testPair->keyevent = keyevent;
		testPair->commands = g_malloc (sizeof (TIL_Cmd *) * (numCmds + 1));
		GSList *work = cmds;
		for (int j = 0; j < numCmds; j++)
		{
			testPair->commands[j] = work->data;
			work = g_slist_next (work);
		}
		testPair->commands[numCmds] = NULL;

		g_strfreev (fields);
		g_slist_free (cmds);
		testPairs = g_slist_append (testPairs, testPair);
		continue;

	  parseError:
		g_free (keyevent);
		testPairs = g_slist_append (testPairs, testPair);
	}							/* end while */

	/* cleanup */
	g_io_channel_shutdown (testFile, FALSE, NULL);
	g_io_channel_unref (testFile);
	g_string_free (line, FALSE);

	return testPairs;
}
Beispiel #10
0
static void
json_scanner_get_token_ll (JsonScanner *scanner,
                           GTokenType  *token_p,
                           GTokenValue *value_p,
                           guint       *line_p,
                           guint       *position_p)
{
  JsonScannerConfig *config;
  GTokenType	   token;
  gboolean	   in_comment_multi;
  gboolean	   in_comment_single;
  gboolean	   in_string_sq;
  gboolean	   in_string_dq;
  GString	  *gstring;
  GTokenValue	   value;
  guchar	   ch;
  
  config = scanner->config;
  (*value_p).v_int64 = 0;
  
  if ((scanner->text >= scanner->text_end && scanner->input_fd < 0) ||
      scanner->token == G_TOKEN_EOF)
    {
      *token_p = G_TOKEN_EOF;
      return;
    }
  
  in_comment_multi = FALSE;
  in_comment_single = FALSE;
  in_string_sq = FALSE;
  in_string_dq = FALSE;
  gstring = NULL;
  
  do /* while (ch != 0) */
    {
      gboolean dotted_float = FALSE;
      
      ch = json_scanner_get_char (scanner, line_p, position_p);
      
      value.v_int64 = 0;
      token = G_TOKEN_NONE;
      
      /* this is *evil*, but needed ;(
       * we first check for identifier first character, because	 it
       * might interfere with other key chars like slashes or numbers
       */
      if (config->scan_identifier &&
	  ch && strchr (config->cset_identifier_first, ch))
	goto identifier_precedence;
      
      switch (ch)
	{
	case 0:
	  token = G_TOKEN_EOF;
	  (*position_p)++;
	  /* ch = 0; */
	  break;
	  
	case '/':
	  if (!config->scan_comment_multi ||
	      json_scanner_peek_next_char (scanner) != '*')
	    goto default_case;
	  json_scanner_get_char (scanner, line_p, position_p);
	  token = G_TOKEN_COMMENT_MULTI;
	  in_comment_multi = TRUE;
	  gstring = g_string_new (NULL);
	  while ((ch = json_scanner_get_char (scanner, line_p, position_p)) != 0)
	    {
	      if (ch == '*' && json_scanner_peek_next_char (scanner) == '/')
		{
		  json_scanner_get_char (scanner, line_p, position_p);
		  in_comment_multi = FALSE;
		  break;
		}
	      else
		gstring = g_string_append_c (gstring, ch);
	    }
	  ch = 0;
	  break;
	  
	case '\'':
	  if (!config->scan_string_sq)
	    goto default_case;
	  token = G_TOKEN_STRING;
	  in_string_sq = TRUE;
	  gstring = g_string_new (NULL);
	  while ((ch = json_scanner_get_char (scanner, line_p, position_p)) != 0)
	    {
	      if (ch == '\'')
		{
		  in_string_sq = FALSE;
		  break;
		}
	      else
		gstring = g_string_append_c (gstring, ch);
	    }
	  ch = 0;
	  break;
	  
	case '"':
	  if (!config->scan_string_dq)
	    goto default_case;
	  token = G_TOKEN_STRING;
	  in_string_dq = TRUE;
	  gstring = g_string_new (NULL);
	  while ((ch = json_scanner_get_char (scanner, line_p, position_p)) != 0)
	    {
	      if (ch == '"')
		{
		  in_string_dq = FALSE;
		  break;
		}
	      else
		{
		  if (ch == '\\')
		    {
		      ch = json_scanner_get_char (scanner, line_p, position_p);
		      switch (ch)
			{
			  guint	i;
			  guint	fchar;
			  
			case 0:
			  break;
			  
			case '\\':
			  gstring = g_string_append_c (gstring, '\\');
			  break;
			  
			case 'n':
			  gstring = g_string_append_c (gstring, '\n');
			  break;
			  
			case 't':
			  gstring = g_string_append_c (gstring, '\t');
			  break;
			  
			case 'r':
			  gstring = g_string_append_c (gstring, '\r');
			  break;
			  
			case 'b':
			  gstring = g_string_append_c (gstring, '\b');
			  break;
			  
			case 'f':
			  gstring = g_string_append_c (gstring, '\f');
			  break;

                        case 'u':
                          fchar = json_scanner_peek_next_char (scanner);
                          if (is_hex_digit (fchar))
                            {
                              gunichar ucs;

                              ucs = json_scanner_get_unichar (scanner, line_p, position_p);

                              if (g_unichar_type (ucs) == G_UNICODE_SURROGATE)
                                {
                                  /* read next surrogate */
                                  if ('\\' == json_scanner_get_char (scanner, line_p, position_p)
                                      && 'u' == json_scanner_get_char (scanner, line_p, position_p))
                                    {
                                      gunichar ucs_lo = json_scanner_get_unichar (scanner, line_p, position_p);
                                      g_assert (g_unichar_type (ucs_lo) == G_UNICODE_SURROGATE);
                                      ucs = (((ucs & 0x3ff) << 10) | (ucs_lo & 0x3ff)) + 0x10000;
                                    }
                                }

                              g_assert (g_unichar_validate (ucs));
                              gstring = g_string_append_unichar (gstring, ucs);
                            }
                          break;
			  
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			  i = ch - '0';
			  fchar = json_scanner_peek_next_char (scanner);
			  if (fchar >= '0' && fchar <= '7')
			    {
			      ch = json_scanner_get_char (scanner, line_p, position_p);
			      i = i * 8 + ch - '0';
			      fchar = json_scanner_peek_next_char (scanner);
			      if (fchar >= '0' && fchar <= '7')
				{
				  ch = json_scanner_get_char (scanner, line_p, position_p);
				  i = i * 8 + ch - '0';
				}
			    }
			  gstring = g_string_append_c (gstring, i);
			  break;
			  
			default:
			  gstring = g_string_append_c (gstring, ch);
			  break;
			}
		    }
		  else
		    gstring = g_string_append_c (gstring, ch);
		}
	    }
	  ch = 0;
	  break;
	  
	case '.':
	  if (!config->scan_float)
	    goto default_case;
	  token = G_TOKEN_FLOAT;
	  dotted_float = TRUE;
	  ch = json_scanner_get_char (scanner, line_p, position_p);
	  goto number_parsing;
	  
	case '$':
	  if (!config->scan_hex_dollar)
	    goto default_case;
	  token = G_TOKEN_HEX;
	  ch = json_scanner_get_char (scanner, line_p, position_p);
	  goto number_parsing;
	  
	case '0':
	  if (config->scan_octal)
	    token = G_TOKEN_OCTAL;
	  else
	    token = G_TOKEN_INT;
	  ch = json_scanner_peek_next_char (scanner);
	  if (config->scan_hex && (ch == 'x' || ch == 'X'))
	    {
	      token = G_TOKEN_HEX;
	      json_scanner_get_char (scanner, line_p, position_p);
	      ch = json_scanner_get_char (scanner, line_p, position_p);
	      if (ch == 0)
		{
		  token = G_TOKEN_ERROR;
		  value.v_error = G_ERR_UNEXP_EOF;
		  (*position_p)++;
		  break;
		}
	      if (json_scanner_char_2_num (ch, 16) < 0)
		{
		  token = G_TOKEN_ERROR;
		  value.v_error = G_ERR_DIGIT_RADIX;
		  ch = 0;
		  break;
		}
	    }
	  else if (config->scan_binary && (ch == 'b' || ch == 'B'))
	    {
	      token = G_TOKEN_BINARY;
	      json_scanner_get_char (scanner, line_p, position_p);
	      ch = json_scanner_get_char (scanner, line_p, position_p);
	      if (ch == 0)
		{
		  token = G_TOKEN_ERROR;
		  value.v_error = G_ERR_UNEXP_EOF;
		  (*position_p)++;
		  break;
		}
	      if (json_scanner_char_2_num (ch, 10) < 0)
		{
		  token = G_TOKEN_ERROR;
		  value.v_error = G_ERR_NON_DIGIT_IN_CONST;
		  ch = 0;
		  break;
		}
	    }
	  else
	    ch = '0';
	  /* fall through */
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	number_parsing:
	{
          gboolean in_number = TRUE;
	  gchar *endptr;
	  
	  if (token == G_TOKEN_NONE)
	    token = G_TOKEN_INT;
	  
	  gstring = g_string_new (dotted_float ? "0." : "");
	  gstring = g_string_append_c (gstring, ch);
	  
	  do /* while (in_number) */
	    {
	      gboolean is_E;
	      
	      is_E = token == G_TOKEN_FLOAT && (ch == 'e' || ch == 'E');
	      
	      ch = json_scanner_peek_next_char (scanner);
	      
	      if (json_scanner_char_2_num (ch, 36) >= 0 ||
		  (config->scan_float && ch == '.') ||
		  (is_E && (ch == '+' || ch == '-')))
		{
		  ch = json_scanner_get_char (scanner, line_p, position_p);
		  
		  switch (ch)
		    {
		    case '.':
		      if (token != G_TOKEN_INT && token != G_TOKEN_OCTAL)
			{
			  value.v_error = token == G_TOKEN_FLOAT ? G_ERR_FLOAT_MALFORMED : G_ERR_FLOAT_RADIX;
			  token = G_TOKEN_ERROR;
			  in_number = FALSE;
			}
		      else
			{
			  token = G_TOKEN_FLOAT;
			  gstring = g_string_append_c (gstring, ch);
			}
		      break;
		      
		    case '0':
		    case '1':
		    case '2':
		    case '3':
		    case '4':
		    case '5':
		    case '6':
		    case '7':
		    case '8':
		    case '9':
		      gstring = g_string_append_c (gstring, ch);
		      break;
		      
		    case '-':
		    case '+':
		      if (token != G_TOKEN_FLOAT)
			{
			  token = G_TOKEN_ERROR;
			  value.v_error = G_ERR_NON_DIGIT_IN_CONST;
			  in_number = FALSE;
			}
		      else
			gstring = g_string_append_c (gstring, ch);
		      break;
		      
		    case 'e':
		    case 'E':
		      if ((token != G_TOKEN_HEX && !config->scan_float) ||
			  (token != G_TOKEN_HEX &&
			   token != G_TOKEN_OCTAL &&
			   token != G_TOKEN_FLOAT &&
			   token != G_TOKEN_INT))
			{
			  token = G_TOKEN_ERROR;
			  value.v_error = G_ERR_NON_DIGIT_IN_CONST;
			  in_number = FALSE;
			}
		      else
			{
			  if (token != G_TOKEN_HEX)
			    token = G_TOKEN_FLOAT;
			  gstring = g_string_append_c (gstring, ch);
			}
		      break;
		      
		    default:
		      if (token != G_TOKEN_HEX)
			{
			  token = G_TOKEN_ERROR;
			  value.v_error = G_ERR_NON_DIGIT_IN_CONST;
			  in_number = FALSE;
			}
		      else
			gstring = g_string_append_c (gstring, ch);
		      break;
		    }
		}
	      else
		in_number = FALSE;
	    }
	  while (in_number);
	  
	  endptr = NULL;
	  if (token == G_TOKEN_FLOAT)
	    value.v_float = g_strtod (gstring->str, &endptr);
	  else
	    {
	      guint64 ui64 = 0;
	      switch (token)
		{
		case G_TOKEN_BINARY:
		  ui64 = g_ascii_strtoull (gstring->str, &endptr, 2);
		  break;
		case G_TOKEN_OCTAL:
		  ui64 = g_ascii_strtoull (gstring->str, &endptr, 8);
		  break;
		case G_TOKEN_INT:
		  ui64 = g_ascii_strtoull (gstring->str, &endptr, 10);
		  break;
		case G_TOKEN_HEX:
		  ui64 = g_ascii_strtoull (gstring->str, &endptr, 16);
		  break;
		default: ;
		}
	      if (scanner->config->store_int64)
		value.v_int64 = ui64;
	      else
		value.v_int = ui64;
	    }
	  if (endptr && *endptr)
	    {
	      token = G_TOKEN_ERROR;
	      if (*endptr == 'e' || *endptr == 'E')
		value.v_error = G_ERR_NON_DIGIT_IN_CONST;
	      else
		value.v_error = G_ERR_DIGIT_RADIX;
	    }
	  g_string_free (gstring, TRUE);
	  gstring = NULL;
	  ch = 0;
	} /* number_parsing:... */
	break;
	
	default:
	default_case:
	{
	  if (config->cpair_comment_single &&
	      ch == config->cpair_comment_single[0])
	    {
	      token = G_TOKEN_COMMENT_SINGLE;
	      in_comment_single = TRUE;
	      gstring = g_string_new (NULL);
	      ch = json_scanner_get_char (scanner, line_p, position_p);
	      while (ch != 0)
		{
		  if (ch == config->cpair_comment_single[1])
		    {
		      in_comment_single = FALSE;
		      ch = 0;
		      break;
		    }
		  
		  gstring = g_string_append_c (gstring, ch);
		  ch = json_scanner_get_char (scanner, line_p, position_p);
		}
	      /* ignore a missing newline at EOF for single line comments */
	      if (in_comment_single &&
		  config->cpair_comment_single[1] == '\n')
		in_comment_single = FALSE;
	    }
	  else if (config->scan_identifier && ch &&
		   strchr (config->cset_identifier_first, ch))
	    {
	    identifier_precedence:
	      
	      if (config->cset_identifier_nth && ch &&
		  strchr (config->cset_identifier_nth,
			  json_scanner_peek_next_char (scanner)))
		{
		  token = G_TOKEN_IDENTIFIER;
		  gstring = g_string_new (NULL);
		  gstring = g_string_append_c (gstring, ch);
		  do
		    {
		      ch = json_scanner_get_char (scanner, line_p, position_p);
		      gstring = g_string_append_c (gstring, ch);
		      ch = json_scanner_peek_next_char (scanner);
		    }
		  while (ch && strchr (config->cset_identifier_nth, ch));
		  ch = 0;
		}
	      else if (config->scan_identifier_1char)
		{
		  token = G_TOKEN_IDENTIFIER;
		  value.v_identifier = g_new0 (gchar, 2);
		  value.v_identifier[0] = ch;
		  ch = 0;
		}
	    }
	  if (ch)
	    {
	      if (config->char_2_token)
		token = ch;
	      else
		{
		  token = G_TOKEN_CHAR;
		  value.v_char = ch;
		}
	      ch = 0;
	    }
	} /* default_case:... */
	break;
	}
      g_assert (ch == 0 && token != G_TOKEN_NONE); /* paranoid */
    }
  while (ch != 0);
  
  if (in_comment_multi || in_comment_single ||
      in_string_sq || in_string_dq)
    {
      token = G_TOKEN_ERROR;
      if (gstring)
	{
	  g_string_free (gstring, TRUE);
	  gstring = NULL;
	}
      (*position_p)++;
      if (in_comment_multi || in_comment_single)
	value.v_error = G_ERR_UNEXP_EOF_IN_COMMENT;
      else /* (in_string_sq || in_string_dq) */
	value.v_error = G_ERR_UNEXP_EOF_IN_STRING;
    }
  
  if (gstring)
    {
      value.v_string = g_string_free (gstring, FALSE);
      gstring = NULL;
    }
  
  if (token == G_TOKEN_IDENTIFIER)
    {
      if (config->scan_symbols)
	{
	  JsonScannerKey *key;
	  guint scope_id;
	  
	  scope_id = scanner->scope_id;
	  key = json_scanner_lookup_internal (scanner, scope_id, value.v_identifier);
	  if (!key && scope_id && scanner->config->scope_0_fallback)
	    key = json_scanner_lookup_internal (scanner, 0, value.v_identifier);
	  
	  if (key)
	    {
	      g_free (value.v_identifier);
	      token = G_TOKEN_SYMBOL;
	      value.v_symbol = key->value;
	    }
	}
      
      if (token == G_TOKEN_IDENTIFIER &&
	  config->scan_identifier_NULL &&
	  strlen (value.v_identifier) == 4)
	{
	  gchar *null_upper = "NULL";
	  gchar *null_lower = "null";
	  
	  if (scanner->config->case_sensitive)
	    {
	      if (value.v_identifier[0] == null_upper[0] &&
		  value.v_identifier[1] == null_upper[1] &&
		  value.v_identifier[2] == null_upper[2] &&
		  value.v_identifier[3] == null_upper[3])
		token = G_TOKEN_IDENTIFIER_NULL;
	    }
	  else
	    {
	      if ((value.v_identifier[0] == null_upper[0] ||
		   value.v_identifier[0] == null_lower[0]) &&
		  (value.v_identifier[1] == null_upper[1] ||
		   value.v_identifier[1] == null_lower[1]) &&
		  (value.v_identifier[2] == null_upper[2] ||
		   value.v_identifier[2] == null_lower[2]) &&
		  (value.v_identifier[3] == null_upper[3] ||
		   value.v_identifier[3] == null_lower[3]))
		token = G_TOKEN_IDENTIFIER_NULL;
	    }
	}
    }
  
  *token_p = token;
  *value_p = value;
}
Beispiel #11
0
static void update_view(PussVConsole* self) {
	VConsole* vcon = self->vcon;
	SMALL_RECT* range;
	DWORD i, j, h, w, sz;
	DWORD cx, cy;
	gchar text[(MAX_SCR_LEN+1)*6 + MAX_SCR_ROW];
	gchar* pd = text;
	CHAR_INFO* ps;
	GtkTextIter it, end;
	GtkTextView* txt_view = GTK_TEXT_VIEW(self->view);
	GtkTextBuffer* txt_buf = gtk_text_view_get_buffer(txt_view);

	if( !self->vcon || !self->need_update )
		return;
	self->need_update = FALSE;

	range = &(vcon->screen_info->srWindow);
	h = range->Bottom - range->Top + 1;
	w = range->Right - range->Left + 1;
	cy = vcon->screen_info->dwCursorPosition.Y - range->Top;
	cx = vcon->screen_info->dwCursorPosition.X - range->Left;

	// scroll bar update
	self->adjust->lower = 1;
	self->adjust->upper = vcon->screen_info->dwSize.Y;
	self->adjust->step_increment = 1;
	self->adjust->page_size = h;
	self->adjust->page_increment = h;
	self->adjust->value = range->Top;

	// screen buffer update
	ps = vcon->screen_buffer;
	for( i=0; i<h; ++i ) {
		for( j=0; j<w; ++j ) {
			if( ps->Char.UnicodeChar && g_unichar_validate(ps->Char.UnicodeChar) ) {
				sz = g_unichar_to_utf8(ps->Char.UnicodeChar, pd);
				pd += sz;
				if( ps->Char.UnicodeChar > 0xff ) {
					++j;
					if( cy==i )
						--cx;
				}
			} else {
				//g_print("unknown =  %d\n", ps->Char.UnicodeChar);
			}
			++ps;
		}

		// remove end space
		while(*(pd-1)=='\t' || *(pd-1)==' ' ) --pd;
		*pd = '\n';
		++pd;
	}
	*pd = '\0';
	sz = (DWORD)(pd - text);

	gtk_text_buffer_set_text(txt_buf, text, sz);

	// cursor update
	h = gtk_text_buffer_get_line_count(txt_buf);
	if( cy >= h ) {
		gtk_text_view_set_cursor_visible(txt_view, FALSE);

	} else {
		gtk_text_buffer_get_iter_at_line(txt_buf, &it, cy);
		end = it;
		if( gtk_text_iter_forward_chars(&end, cx) ) {
			it = end;
		} else {
			if( gtk_text_iter_forward_to_line_end(&end) ) {
				it = end;
			} else {
				gtk_text_buffer_get_iter_at_line(txt_buf, &it, cy);
			}
		}
		gtk_text_buffer_place_cursor(txt_buf, &it);
		gtk_text_view_set_cursor_visible(txt_view, TRUE);
	}

	gtk_adjustment_changed(self->adjust);
}
GtkTextBuffer *gtk_text_buffer_duplicate(GtkTextBuffer *source_buffer)
{
	// Local variables
	gchar				*conversion_buffer;			// Used when converting between unicode character types
	GtkTextIter			end_iter;
	GtkTextIter			end_iter_minus_one;
	gint				end_offset;
	gint				i;
	guint				loop_counter;
	GtkTextIter 		loop_iter;
	GtkTextBuffer		*new_text_buffer;
	guint				num_tags;
	GtkTextIter			source_buffer_end;
	GtkTextIter			source_buffer_start;
	gint				start_offset;
	GSList				*tag_list;
	GtkTextTag			*tag_ptr;
	gunichar			temp_char;
	GString				*temp_gstring;


	// Validate the tags in the source buffer
	text_layer_dialog_validate_buffer_tag_quantity(GTK_TEXT_BUFFER(source_buffer));

	// Initialise various things
	temp_gstring = g_string_new(NULL);

	// Create a new text buffer
	new_text_buffer = gtk_text_buffer_new(get_text_tags_table());

	// Get the bounds of the source buffer
	gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(source_buffer), &source_buffer_start, &source_buffer_end);
	gtk_text_iter_order(&source_buffer_start, &source_buffer_end);

	// Scan through the source text buffer one character at a time, getting the character and the tags that apply to it
	start_offset = gtk_text_iter_get_offset(&source_buffer_start);
	end_offset = gtk_text_iter_get_offset(&source_buffer_end);
	for (i = 0; i < end_offset; i++)
	{
		// Copy one character from the source text buffer to the new destination text buffer
		gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(source_buffer), &loop_iter, i);
		temp_char = gtk_text_iter_get_char(&loop_iter);
		conversion_buffer = g_ucs4_to_utf8(&temp_char, 1, NULL, NULL, NULL);
		if (NULL == conversion_buffer)
		{
			g_string_printf(temp_gstring, "%s ED441: %s", _("Error"), _("Could not convert unicode character from ucs4 to utf8."));
			display_warning(temp_gstring->str);
			continue;
		}

		// Validate the retrieved character
		if (TRUE != g_unichar_validate(temp_char))
		{
			// Something other than a unicode character was retrieved
			g_string_printf(temp_gstring, "%s ED442: %s", _("Error"), _("Invalid unicode character found in text."));
			display_warning(temp_gstring->str);
			continue;
		}
		gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(new_text_buffer), conversion_buffer, -1);
		g_free(conversion_buffer);

		// Copy the tags from the character in the source buffer to the new character in the destination buffer
		tag_list = gtk_text_iter_get_tags(&loop_iter);
		num_tags = g_slist_length(tag_list);
		gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(new_text_buffer), &end_iter);
		end_iter_minus_one = end_iter;
		gtk_text_iter_backward_char(&end_iter_minus_one);
		for (loop_counter = 0; loop_counter < num_tags; loop_counter++)
		{
			// Copy each tag from the source text buffer to the destination one
			tag_ptr = g_slist_nth_data(tag_list, loop_counter);
			gtk_text_buffer_apply_tag(GTK_TEXT_BUFFER(new_text_buffer), tag_ptr, &end_iter_minus_one, &end_iter);
		}
		g_slist_free(tag_list);
	}
	g_string_free(temp_gstring, TRUE);

	// Validate the tags in the duplicated buffer
	text_layer_dialog_validate_buffer_tag_quantity(GTK_TEXT_BUFFER(new_text_buffer));

	// Return the duplicated text buffer
	return new_text_buffer;
}
Beispiel #13
0
static gboolean
on_captured_event (ClutterText *text,
                   ClutterEvent *event,
                   gpointer      dummy G_GNUC_UNUSED)
{
  gboolean is_unicode_mode = FALSE;
  gunichar c;
  guint keyval;

  if (event->type != CLUTTER_KEY_PRESS)
    return FALSE;

  is_unicode_mode = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (text),
                                                        "unicode-mode"));

  c = clutter_event_get_key_unicode (event);
  keyval = clutter_event_get_key_symbol (event);
  if (keyval == CLUTTER_KEY_U)
    {
      if (is_unicode_mode)
        {
          GString *str = g_object_get_data (G_OBJECT (text), "unicode-str");

          clutter_text_set_preedit_string (text, NULL, NULL, 0);

          g_object_set_data (G_OBJECT (text), "unicode-mode",
                             GINT_TO_POINTER (FALSE));
          g_object_set_data (G_OBJECT (text), "unicode-str",
                             NULL);

          g_string_free (str, TRUE);

          return FALSE;
        }

      if (clutter_event_has_control_modifier (event))
        {
          PangoAttrList *attrs;
          PangoAttribute *a;
          GString *str = g_string_sized_new (5);

          g_string_append (str, "u");

          g_object_set_data (G_OBJECT (text),
                             "unicode-mode",
                             GINT_TO_POINTER (TRUE));
          g_object_set_data (G_OBJECT (text),
                             "unicode-str",
                             str);

          attrs = pango_attr_list_new ();

          a = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
          a->start_index = 0;
          a->end_index = str->len;
          pango_attr_list_insert (attrs, a);

          clutter_text_set_preedit_string (text, str->str, attrs, str->len);

          pango_attr_list_unref (attrs);

          return TRUE;
        }

      return FALSE;
    }
  else if (is_unicode_mode && is_hex_digit (c))
    {
      GString *str = g_object_get_data (G_OBJECT (text), "unicode-str");
      PangoAttrList *attrs;
      PangoAttribute *a;
      gchar buf[8];
      gsize len;

      len = g_unichar_to_utf8 (c, buf);
      buf[len] = '\0';

      g_string_append (str, buf);

      g_print ("added '%s' to '%s' (len:%d)\n",
               buf,
               str->str,
               (int) str->len);

      attrs = pango_attr_list_new ();

      a = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
      a->start_index = 0;
      a->end_index = str->len;
      pango_attr_list_insert (attrs, a);

      clutter_text_set_preedit_string (text, str->str, attrs, str->len);

      pango_attr_list_unref (attrs);

      return TRUE;
    }
  else if (is_unicode_mode && (keyval == CLUTTER_KEY_BackSpace))
    {
      GString *str = g_object_get_data (G_OBJECT (text), "unicode-str");
      PangoAttrList *attrs;
      PangoAttribute *a;

      g_string_truncate (str, str->len - 1);

      attrs = pango_attr_list_new ();

      a = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
      a->start_index = 0;
      a->end_index = str->len;
      pango_attr_list_insert (attrs, a);

      clutter_text_set_preedit_string (text, str->str, attrs, str->len);

      pango_attr_list_unref (attrs);

      return TRUE;
    }
  else if (is_unicode_mode &&
           (keyval == CLUTTER_KEY_Return ||
            keyval == CLUTTER_KEY_KP_Enter ||
            keyval == CLUTTER_KEY_ISO_Enter ||
            keyval == CLUTTER_KEY_KP_Space))
    {
      GString *str = g_object_get_data (G_OBJECT (text), "unicode-str");
      const gchar *contents = clutter_text_get_text (text);
      gunichar uchar = 0;
      gchar ch;
      gint i;

      clutter_text_set_preedit_string (text, NULL, NULL, 0);

      g_object_set_data (G_OBJECT (text), "unicode-mode",
                         GINT_TO_POINTER (FALSE));
      g_object_set_data (G_OBJECT (text), "unicode-str",
                         NULL);

      for (i = 0; i < str->len; i++)
        {
          ch = str->str[i];

          if (is_hex_digit (ch))
            uchar += ((gunichar) to_hex_digit (ch) << ((4 - i) * 4));
        }

      g_assert (g_unichar_validate (uchar));

      g_string_overwrite (str, 0, contents);
      g_string_insert_unichar (str,
                               clutter_text_get_cursor_position (text),
                               uchar);

      i = clutter_text_get_cursor_position (text);
      clutter_text_set_text (text, str->str);

      if (i >= 0)
        i += 1;
      else
        i = -1;

      clutter_text_set_cursor_position (text, i);
      clutter_text_set_selection_bound (text, i);

      g_string_free (str, TRUE);

      return TRUE;
    }
  else
    return FALSE;
}
Beispiel #14
0
/**
 * e_text_to_html_full:
 * @input: a NUL-terminated input buffer
 * @flags: some combination of the E_TEXT_TO_HTML_* flags defined
 * in e-html-utils.h
 * @color: color for citation highlighting
 *
 * This takes a buffer of text as input and produces a buffer of
 * "equivalent" HTML, subject to certain transformation rules.
 *
 * The set of possible flags is:
 *
 *   - E_TEXT_TO_HTML_PRE: wrap the output HTML in &lt;PRE&gt; and
 *     &lt;/PRE&gt;  Should only be used if @input is the entire
 *     buffer to be converted. If e_text_to_html is being called with
 *     small pieces of data, you should wrap the entire result in
 *     &lt;PRE&gt; yourself.
 *
 *   - E_TEXT_TO_HTML_CONVERT_NL: convert "\n" to "&lt;BR&gt;n" on
 *     output.  (Should not be used with E_TEXT_TO_HTML_PRE, since
 *     that would result in double-newlines.)
 *
 *   - E_TEXT_TO_HTML_CONVERT_SPACES: convert a block of N spaces
 *     into N-1 non-breaking spaces and one normal space. A space
 *     at the start of the buffer is always converted to a
 *     non-breaking space, regardless of the following character,
 *     which probably means you don't want to use this flag on
 *     pieces of data that aren't delimited by at least line breaks.
 *
 *     If E_TEXT_TO_HTML_CONVERT_NL and E_TEXT_TO_HTML_CONVERT_SPACES
 *     are both defined, then TABs will also be converted to spaces.
 *
 *   - E_TEXT_TO_HTML_CONVERT_URLS: wrap &lt;a href="..."&gt; &lt;/a&gt;
 *     around strings that look like URLs.
 *
 *   - E_TEXT_TO_HTML_CONVERT_ADDRESSES: wrap &lt;a href="mailto:..."&gt;
 *     &lt;/a&gt; around strings that look like mail addresses.
 *
 *   - E_TEXT_TO_HTML_MARK_CITATION: wrap &lt;font color="..."&gt;
 *     &lt;/font&gt; around citations (lines beginning with "> ", etc).
 *
 *   - E_TEXT_TO_HTML_ESCAPE_8BIT: flatten everything to US-ASCII
 *
 *   - E_TEXT_TO_HTML_CITE: quote the text with "> " at the start of each
 *     line.
 *
 * Returns: a newly-allocated string containing HTML
 **/
gchar *
e_text_to_html_full (const gchar *input,
                     guint flags,
                     guint32 color)
{
	const guchar *cur, *next, *linestart;
	gchar *buffer = NULL;
	gchar *out = NULL;
	gint buffer_size = 0, col;
	gboolean colored = FALSE, saw_citation = FALSE;

	/* Allocate a translation buffer.  */
	buffer_size = strlen (input) * 2 + 5;
	buffer = g_malloc (buffer_size);

	out = buffer;
	if (flags & E_TEXT_TO_HTML_PRE)
		out += sprintf (out, "<PRE>");

	col = 0;

	for (cur = linestart = (const guchar *) input; cur && *cur; cur = next) {
		gunichar u;

		if (flags & E_TEXT_TO_HTML_MARK_CITATION && col == 0) {
			saw_citation = is_citation (cur, saw_citation);
			if (saw_citation) {
				if (!colored) {
					gchar font[25];

					g_snprintf (font, 25, "<FONT COLOR=\"#%06x\">", color);

					out = check_size (&buffer, &buffer_size, out, 25);
					out += sprintf (out, "%s", font);
					colored = TRUE;
				}
			} else if (colored) {
				const gchar *no_font = "</FONT>";

				out = check_size (&buffer, &buffer_size, out, 9);
				out += sprintf (out, "%s", no_font);
				colored = FALSE;
			}

			/* Display mbox-mangled ">From" as "From" */
			if (*cur == '>' && !saw_citation)
				cur++;
		} else if (flags & E_TEXT_TO_HTML_CITE && col == 0) {
			out = check_size (&buffer, &buffer_size, out, 5);
			out += sprintf (out, "&gt; ");
		}

		u = g_utf8_get_char ((gchar *) cur);
		if (g_unichar_isalpha (u) &&
		    (flags & E_TEXT_TO_HTML_CONVERT_URLS)) {
			gchar *tmpurl = NULL, *refurl = NULL, *dispurl = NULL;

			if (!g_ascii_strncasecmp ((gchar *)cur, "http://", 7) ||
			    !g_ascii_strncasecmp ((gchar *)cur, "https://", 8) ||
			    !g_ascii_strncasecmp ((gchar *)cur, "ftp://", 6) ||
			    !g_ascii_strncasecmp ((gchar *)cur, "nntp://", 7) ||
			    !g_ascii_strncasecmp ((gchar *)cur, "mailto:", 7) ||
			    !g_ascii_strncasecmp ((gchar *)cur, "news:", 5) ||
			    !g_ascii_strncasecmp ((gchar *)cur, "file:", 5) ||
			    !g_ascii_strncasecmp ((gchar *)cur, "callto:", 7) ||
			    !g_ascii_strncasecmp ((gchar *)cur, "h323:", 5) ||
			    !g_ascii_strncasecmp ((gchar *)cur, "sip:", 4) ||
			    !g_ascii_strncasecmp ((gchar *)cur, "webcal:", 7)) {
				tmpurl = url_extract (&cur, TRUE);
				if (tmpurl) {
					refurl = e_text_to_html (tmpurl, 0);
					dispurl = g_strdup (refurl);
				}
			} else if (!g_ascii_strncasecmp ((gchar *)cur, "www.", 4) &&
				   is_url_char (*(cur + 4))) {
				tmpurl = url_extract (&cur, FALSE);
				if (tmpurl) {
					dispurl = e_text_to_html (tmpurl, 0);
					refurl = g_strdup_printf ("http://%s",
								  dispurl);
				}
			}

			if (tmpurl) {
				out = check_size (&buffer, &buffer_size, out,
						  strlen (refurl) +
						  strlen (dispurl) + 15);
				out += sprintf (out,
						"<a href=\"%s\">%s</a>",
						refurl, dispurl);
				col += strlen (tmpurl);
				g_free (tmpurl);
				g_free (refurl);
				g_free (dispurl);
			}

			if (!*cur)
				break;
			u = g_utf8_get_char ((gchar *) cur);
		}

		if (u == '@' && (flags & E_TEXT_TO_HTML_CONVERT_ADDRESSES)) {
			gchar *addr, *dispaddr, *outaddr;

			addr = email_address_extract (&cur, &out, linestart);
			if (addr) {
				dispaddr = e_text_to_html (addr, 0);
				outaddr = g_strdup_printf ("<a href=\"mailto:%s\">%s</a>",
							   addr, dispaddr);
				out = check_size (&buffer, &buffer_size, out, strlen (outaddr));
				out += sprintf (out, "%s", outaddr);
				col += strlen (addr);
				g_free (addr);
				g_free (dispaddr);
				g_free (outaddr);

				if (!*cur)
					break;
				u = g_utf8_get_char ((gchar *) cur);
			}
		}

		if (!g_unichar_validate (u)) {
			/* Sigh. Someone sent undeclared 8-bit data.
			 * Assume it's iso-8859-1.
			 */
			u = *cur;
			next = cur + 1;
		} else
			next = (const guchar *) g_utf8_next_char (cur);

		out = check_size (&buffer, &buffer_size, out, 10);

		switch (u) {
		case '<':
			strcpy (out, "&lt;");
			out += 4;
			col++;
			break;

		case '>':
			strcpy (out, "&gt;");
			out += 4;
			col++;
			break;

		case '&':
			strcpy (out, "&amp;");
			out += 5;
			col++;
			break;

		case '"':
			strcpy (out, "&quot;");
			out += 6;
			col++;
			break;

		case '\n':
			if (flags & E_TEXT_TO_HTML_CONVERT_NL) {
				strcpy (out, "<br>");
				out += 4;
			}
			*out++ = *cur;
			linestart = cur;
			col = 0;
			break;

		case '\t':
			if (flags & (E_TEXT_TO_HTML_CONVERT_SPACES |
				     E_TEXT_TO_HTML_CONVERT_NL)) {
				do {
					out = check_size (&buffer, &buffer_size,
						    out, 7);
					strcpy (out, "&nbsp;");
					out += 6;
					col++;
				} while (col % 8);
				break;
			}
			/* otherwise, FALL THROUGH */

		case ' ':
			if (flags & E_TEXT_TO_HTML_CONVERT_SPACES) {
				if (cur == (const guchar *) input ||
				    *(cur + 1) == ' ' || *(cur + 1) == '\t' ||
				    *(cur - 1) == '\n') {
					strcpy (out, "&nbsp;");
					out += 6;
					col++;
					break;
				}
			}
			/* otherwise, FALL THROUGH */

		default:
			if ((u >= 0x20 && u < 0x80) ||
			    (u == '\r' || u == '\t')) {
				/* Default case, just copy. */
				*out++ = u;
			} else {
				if (flags & E_TEXT_TO_HTML_ESCAPE_8BIT)
					*out++ = '?';
				else
					out += g_snprintf(out, 9, "&#%d;", u);
			}
			col++;
			break;
		}
	}

	out = check_size (&buffer, &buffer_size, out, 7);
	if (flags & E_TEXT_TO_HTML_PRE)
		strcpy (out, "</PRE>");
	else
		*out = '\0';

	return buffer;
}