Exemplo n.º 1
0
/**
 * This reads the next token from the input into token.
 * Return 1 if a character was read, else return 0 (and print a warning).
 */
static int link_advance(Dictionary dict)
{
	wchar_t c;
	int nr, i;
	int quote_mode;

	dict->is_special = FALSE;

	if (dict->already_got_it != '\0')
	{
		dict->is_special = is_special(dict->already_got_it, &dict->mbss);
		if (dict->already_got_it == WEOF) {
			dict->token[0] = '\0';
		} else {
			dict->token[0] = dict->already_got_it; /* specials are one byte */
			dict->token[1] = '\0';
		}
		dict->already_got_it = '\0';
		return 1;
	}

	do { c = get_character(dict, FALSE); } while (iswspace(c));

	quote_mode = FALSE;

	i = 0;
	for (;;)
	{
		if (i > MAX_TOKEN_LENGTH-3) {  /* 3 for multi-byte tokens */
			dict_error(dict, "Token too long");
			return 0;
		}
		if (quote_mode) {
			if (c == '\"') {
				quote_mode = FALSE;
				dict->token[i] = '\0';
				return 1;
			}
			if (iswspace(c)) {
				dict_error(dict, "White space inside of token");
				return 0;
			}

			/* Although we read wide chars, we store UTF8 internally, always. */
			nr = wcrtomb(&dict->token[i], c, &dict->mbss);
			if (nr < 0) {
#ifndef _WIN32
				dict_error2(dict, "Unable to read UTF8 string in current locale",
				         nl_langinfo(CODESET));
				fprintf (stderr, "\tTry setting the locale with \"export LANG=en_US.UTF-8\"\n");
#else
				dict_error(dict, "Unable to read UTF8 string in current locale");
#endif
				return 0;
			}
			i += nr;
		} else {
			if (is_special(c, &dict->mbss))
			{
				if (i == 0)
				{
					dict->token[0] = c;  /* special toks are one char always */
					dict->token[1] = '\0';
					dict->is_special = TRUE;
					return 1;
				}
				dict->token[i] = '\0';
				dict->already_got_it = c;
				return 1;
			}
			if (c == 0x0) {
				if (i == 0) {
					dict->token[0] = '\0';
					return 1;
				}
				dict->token[i] = '\0';
				dict->already_got_it = c;
				return 1;
			}
			if (iswspace(c)) {
				dict->token[i] = '\0';
				return 1;
			}
			if (c == '\"') {
				quote_mode = TRUE;
			} else {
				/* store UTF8 internally, always. */
				nr = wctomb_check(&dict->token[i], c, &dict->mbss);
				if (nr < 0) {
#ifndef _WIN32
					dict_error2(dict, "Unable to read UTF8 string in current locale",
					         nl_langinfo(CODESET));
					fprintf (stderr, "\tTry setting the locale with \"export LANG=en_US.UTF-8\"\n");
#else
					dict_error(dict, "Unable to read UTF8 string in current locale");
#endif
					return 0;
				}
				i += nr;
			}
		}
		c = get_character(dict, quote_mode);
	}
	return 1;
}
Exemplo n.º 2
0
char *
weechat_aspell_modifier_cb (void *data, const char *modifier,
                            const char *modifier_data, const char *string)
{
    long unsigned int value;
    struct t_gui_buffer *buffer;
    char *result, *ptr_string, *pos_space, *ptr_end, save_end;
    const char *color_normal, *color_error;
    int buffer_has_changed, utf8_char_int, char_size;
    int length, index_result, length_word, word_ok;
    int length_color_normal, length_color_error, rc;

    /* make C compiler happy */
    (void) data;
    (void) modifier;

    if (!aspell_enabled)
        return NULL;

    if (!string || !string[0])
        return NULL;

    rc = sscanf (modifier_data, "%lx", &value);
    if ((rc == EOF) || (rc == 0))
        return NULL;

    buffer = (struct t_gui_buffer *)value;

    buffer_has_changed = 0;
    if (buffer != aspell_buffer_spellers)
    {
        weechat_aspell_create_spellers (buffer);
        aspell_buffer_spellers = buffer;
        buffer_has_changed = 1;
    }

    if (!weechat_aspell_spellers)
        return NULL;

    /* check text search only if option is enabled */
    if (weechat_buffer_get_integer (buffer, "text_search")
        && !weechat_config_boolean (weechat_aspell_config_check_during_search))
        return NULL;

    /*
     * for performance: return last string built if input string is the
     * same (for example user just change cursor position, or input text is
     * refreshed with same content)
     */
    if (!buffer_has_changed
        && aspell_last_modifier_string
        && (strcmp (string, aspell_last_modifier_string) == 0))
    {
        return (aspell_last_modifier_result) ?
            strdup (aspell_last_modifier_result) : NULL;
    }

    /* free last modifier string and result */
    if (aspell_last_modifier_string)
    {
        free (aspell_last_modifier_string);
        aspell_last_modifier_string = NULL;
    }
    if (aspell_last_modifier_result)
    {
        free (aspell_last_modifier_result);
        aspell_last_modifier_result = NULL;
    }

    /* save last modifier string received */
    aspell_last_modifier_string = strdup (string);

    color_normal = weechat_color ("bar_fg");
    length_color_normal = strlen (color_normal);
    color_error = weechat_color (weechat_config_string (weechat_aspell_config_look_color));
    length_color_error = strlen (color_error);

    length = strlen (string);
    result = malloc (length + (length * length_color_error) + 1);

    if (result)
    {
        result[0] = '\0';

        ptr_string = aspell_last_modifier_string;
        index_result = 0;

        /* check if string is a command */
        if (!weechat_string_input_for_buffer (ptr_string))
        {
            char_size = weechat_utf8_char_size (ptr_string);
            ptr_string += char_size;
            pos_space = ptr_string;
            while (pos_space && pos_space[0] && (pos_space[0] != ' '))
            {
                pos_space = weechat_utf8_next_char (pos_space);
            }
            if (!pos_space || !pos_space[0])
            {
                free (result);
                return NULL;
            }

            pos_space[0] = '\0';

            /* exit if command is not authorized for spell checking */
            if (!weechat_aspell_command_authorized (ptr_string))
            {
                free (result);
                return NULL;
            }
            memcpy (result + index_result, aspell_last_modifier_string, char_size);
            index_result += char_size;
            strcpy (result + index_result, ptr_string);
            index_result += strlen (ptr_string);

            pos_space[0] = ' ';
            ptr_string = pos_space;
        }

        while (ptr_string[0])
        {
            /* find start of word */
            utf8_char_int = weechat_utf8_char_int (ptr_string);
            while ((!iswalnum (utf8_char_int) && (utf8_char_int != '\'')
                    && (utf8_char_int != '-'))
                   || iswspace (utf8_char_int))
            {
                char_size = weechat_utf8_char_size (ptr_string);
                memcpy (result + index_result, ptr_string, char_size);
                index_result += char_size;
                ptr_string += char_size;
                if (!ptr_string[0])
                    break;
                utf8_char_int = weechat_utf8_char_int (ptr_string);
            }
            if (!ptr_string[0])
                break;

            ptr_end = weechat_utf8_next_char (ptr_string);
            utf8_char_int = weechat_utf8_char_int (ptr_end);
            while (iswalnum (utf8_char_int) || (utf8_char_int == '\'')
                   || (utf8_char_int == '-'))
            {
                ptr_end = weechat_utf8_next_char (ptr_end);
                if (!ptr_end[0])
                    break;
                utf8_char_int = weechat_utf8_char_int (ptr_end);
            }
            word_ok = 0;
            if (weechat_aspell_string_is_url (ptr_string))
            {
                /*
                 * word is an URL, then it is ok, and search for next space
                 * (will be end of word)
                 */
                word_ok = 1;
                if (ptr_end[0])
                {
                    utf8_char_int = weechat_utf8_char_int (ptr_end);
                    while (!iswspace (utf8_char_int))
                    {
                        ptr_end = weechat_utf8_next_char (ptr_end);
                        if (!ptr_end[0])
                            break;
                        utf8_char_int = weechat_utf8_char_int (ptr_end);
                    }
                }
            }
            save_end = ptr_end[0];
            ptr_end[0] = '\0';
            length_word = ptr_end - ptr_string;

            if (!word_ok)
            {
                if ((save_end != '\0')
                    || (weechat_config_integer (weechat_aspell_config_check_real_time)))
                    word_ok = weechat_aspell_check_word (buffer, ptr_string);
                else
                    word_ok = 1;
            }

            /* add error color */
            if (!word_ok)
            {
                strcpy (result + index_result, color_error);
                index_result += length_color_error;
            }

            /* add word */
            strcpy (result + index_result, ptr_string);
            index_result += length_word;

            /* add normal color (after misspelled word) */
            if (!word_ok)
            {
                strcpy (result + index_result, color_normal);
                index_result += length_color_normal;
            }

            if (save_end == '\0')
                break;

            ptr_end[0] = save_end;
            ptr_string = ptr_end;
        }

        result[index_result] = '\0';
    }

    if (!result)
        return NULL;

    aspell_last_modifier_result = strdup (result);
    return result;
}
Exemplo n.º 3
0
// ----------------------------------------------------------------------------
//
std::vector<CString> SimpleJsonParser::tokenize( LPCSTR value, LPCSTR break_chars, bool store_breaks ) 
{
    std::vector<CString> tokens;

    LPCSTR start;
    LPCSTR head;
    CString token;

    bool in_quotes = false;
    bool in_token = false;
    bool must_break = false;

    char last_char = '\0';

    for ( head=start=value; *head; head++ ) {
        if ( in_quotes ) {
            if ( *head == '"' && last_char != '\\' ) {
                in_quotes = false;
                must_break = true;
                token = extract_token( start, head );
            }
        }
        else if ( iswspace(*head) ) {
            if ( in_token && !must_break ) {
                token = extract_token( start, head-1 );
                must_break = true;
            } 
            else if ( !in_token )
                start = head+1;
            else
                ; // Ignore WS between tokens and breaks
        }
        else if ( strchr( break_chars, *head ) != NULL ) {
            if ( in_token && !must_break )  // Non-quoted literal
                token = extract_token( start, head-1 );

            if ( in_token )
                tokens.push_back( token );

            if ( store_breaks )
                tokens.push_back( extract_token( head, head ) );

            start = head+1;
            in_token = must_break = false;
        }
        else if ( must_break )
            throw std::exception( "Parse error" );
        else {
            in_token = true;
            
            if ( *head == '"'  && last_char != '\\' )
                in_quotes = true;
        }

        last_char = *head;
    }
    
    if ( in_token ) {
        if ( in_quotes )
            throw std::exception( "Unterminate quotes" );

        if ( !must_break )  // Non-quoted literal
            token = extract_token( start, head-1 );

        tokens.push_back( token );
    }

    return tokens;
}
Exemplo n.º 4
0
/*!
	指定行のテキストを指定した文字数からゲットする
	ポインタだけ渡してこっちでメモリ確保する。開放は呼んだ側で
	@param[in]	rdLine		対象の行番号・絶対0インデックスか
	@param[in]	iStart		開始文字位置0インデックス・この文字から開始・常時0でよい?
	@param[out]	*pstTexts	文字とスタイルを格納するバッファを作るためのポインターへのポインター・NULLなら必要文字数だけ返す
	@param[out]	pchLen		確保した文字数・NULLターミネータはノーカン・バイトじゃないぞ
	@param[out]	pdFlag		文字列について・普通のとか連続空白とか・NULL不可
	@return					文字列の使用ドット数
*/
INT DocLineDataGetAlloc( INT rdLine, INT iStart, LPLETTER *pstTexts, PINT pchLen, PUINT pdFlag )
{
	INT		iSize, i = 0, j, dotCnt;
	INT_PTR	iCount, iLines;

	//	始点と終点を使えるようにする	//	−1なら末端

	LINE_ITR	itLine;

	iLines = DocNowFilePageLineCount( );
	if( iLines <=  rdLine )	return -1;


	itLine = gitFileIt->vcCont.at( gixFocusPage ).ltPage.begin();
	std::advance( itLine, rdLine );

	iCount = itLine->vcLine.size( );
	*pdFlag = 0;

	if( 0 == iCount )	//	文字列の中身がない
	{
		*pchLen = 0;
		dotCnt  = 0;
	}
	else
	{
		if( iStart >= iCount )	return 0;	//	通り過ぎた

		iSize = iCount - iStart;	//	文字数を入れる
		//	色換えの必要があるところまでとか、一塊ずつで面倒見るように
		*pchLen = iSize;
		iSize++;	//	NULLターミネータの為に増やす

		if( !pstTexts )	return 0;	//	入れるところないならここで終わる

		*pstTexts = (LPLETTER)malloc( iSize * sizeof(LETTER) );
		if( !( *pstTexts ) ){	TRACE( TEXT("malloc error") );	return 0;	}

		ZeroMemory( *pstTexts, iSize * sizeof(LETTER) );

		dotCnt = 0;
		for( i = iStart, j = 0; iCount > i; i++, j++ )
		{
			(*pstTexts)[j].cchMozi = itLine->vcLine.at( i ).cchMozi;
			(*pstTexts)[j].rdWidth = itLine->vcLine.at( i ).rdWidth;
			(*pstTexts)[j].mzStyle = itLine->vcLine.at( i ).mzStyle;

			dotCnt += itLine->vcLine.at( i ).rdWidth;
		}

		//	末端がspaceかどうか確認
		if( iswspace( itLine->vcLine.at( iCount-1 ).cchMozi ) )
		{	*pdFlag |= CT_LASTSP;	}
	}

	if( iLines - 1 >  rdLine )	*pdFlag |= CT_RETURN;	//	次の行があるなら改行
	else						*pdFlag |= CT_EOF;		//	ないならこの行末端がEOF

	//	改行の状態を確保
	*pdFlag |= itLine->dStyle;

	return dotCnt;
}
Exemplo n.º 5
0
void env_init(const struct config_paths_t *paths /* or NULL */)
{
    /*
      env_read_only variables can not be altered directly by the user
    */

    const wchar_t * const ro_keys[] =
    {
        L"status",
        L"history",
        L"version",
        L"_",
        L"LINES",
        L"COLUMNS",
        L"PWD",
        //L"SHLVL", // will be inserted a bit lower down
        L"FISH_VERSION",
    };
    for (size_t i=0; i < sizeof ro_keys / sizeof *ro_keys; i++)
    {
        env_read_only.insert(ro_keys[i]);
    }

    /*
       Names of all dynamically calculated variables
       */
    env_electric.insert(L"history");
    env_electric.insert(L"status");
    env_electric.insert(L"umask");
    env_electric.insert(L"COLUMNS");
    env_electric.insert(L"LINES");

    top = new env_node_t;
    global_env = top;
    global = &top->env;

    /*
      Now the environemnt variable handling is set up, the next step
      is to insert valid data
    */

    /*
      Import environment variables
    */
    for (char **p = (environ ? environ : __environ); p && *p; p++)
    {
        const wcstring key_and_val = str2wcstring(*p); //like foo=bar
        size_t eql = key_and_val.find(L'=');
        if (eql == wcstring::npos)
        {
            // no equals found
            if (is_read_only(key_and_val) || is_electric(key_and_val)) continue;
            env_set(key_and_val, L"", ENV_EXPORT | ENV_GLOBAL);
        }
        else
        {
            wcstring key = key_and_val.substr(0, eql);
            if (is_read_only(key) || is_electric(key)) continue;
            wcstring val = key_and_val.substr(eql + 1);
            if (variable_is_colon_delimited_array(key))
            {
                std::replace(val.begin(), val.end(), L':', ARRAY_SEP);
            }

            env_set(key, val.c_str(), ENV_EXPORT | ENV_GLOBAL);
        }
    }

    /* Set the given paths in the environment, if we have any */
    if (paths != NULL)
    {
        env_set(FISH_DATADIR_VAR, paths->data.c_str(), ENV_GLOBAL | ENV_EXPORT);
        env_set(FISH_SYSCONFDIR_VAR, paths->sysconf.c_str(), ENV_GLOBAL | ENV_EXPORT);
        env_set(FISH_HELPDIR_VAR, paths->doc.c_str(), ENV_GLOBAL | ENV_EXPORT);
        env_set(FISH_BIN_DIR, paths->bin.c_str(), ENV_GLOBAL | ENV_EXPORT);
    }

    /*
      Set up the PATH variable
    */
    setup_path();

    /*
      Set up the USER variable
    */
    if (env_get_string(L"USER").missing_or_empty())
    {
        const struct passwd *pw = getpwuid(getuid());
        if (pw && pw->pw_name)
        {
            const wcstring uname = str2wcstring(pw->pw_name);
            env_set(L"USER", uname.c_str(), ENV_GLOBAL | ENV_EXPORT);
        }
    }

    /*
      Set up the version variables
    */
    wcstring version = str2wcstring(get_fish_version());
    env_set(L"version", version.c_str(), ENV_GLOBAL);
    env_set(L"FISH_VERSION", version.c_str(), ENV_GLOBAL);

    /*
      Set up SHLVL variable
    */
    const env_var_t shlvl_str = env_get_string(L"SHLVL");
    wcstring nshlvl_str = L"1";
    if (! shlvl_str.missing())
    {
        wchar_t *end;
        long shlvl_i = wcstol(shlvl_str.c_str(), &end, 10);
        while (iswspace(*end)) ++end; /* skip trailing whitespace */
        if (shlvl_i >= 0 && *end == '\0')
        {
            nshlvl_str = to_string<long>(shlvl_i + 1);
        }
    }
    env_set(L"SHLVL", nshlvl_str.c_str(), ENV_GLOBAL | ENV_EXPORT);
    env_read_only.insert(L"SHLVL");

    /* Set up the HOME variable */
    if (env_get_string(L"HOME").missing_or_empty())
    {
        const env_var_t unam = env_get_string(L"USER");
        char *unam_narrow = wcs2str(unam.c_str());
        struct passwd *pw = getpwnam(unam_narrow);
        if (pw->pw_dir != NULL)
        {
            const wcstring dir = str2wcstring(pw->pw_dir);
            env_set(L"HOME", dir.c_str(), ENV_GLOBAL | ENV_EXPORT);
        }
        free(unam_narrow);
    }

    /* Set PWD */
    env_set_pwd();

    /* Set up universal variables. The empty string means to use the deafult path. */
    assert(s_universal_variables == NULL);
    s_universal_variables = new env_universal_t(L"");
    s_universal_variables->load();

    /* Set g_log_forks */
    env_var_t log_forks = env_get_string(L"fish_log_forks");
    g_log_forks = ! log_forks.missing_or_empty() && from_string<bool>(log_forks);

    /* Set g_use_posix_spawn. Default to true. */
    env_var_t use_posix_spawn = env_get_string(L"fish_use_posix_spawn");
    g_use_posix_spawn = (use_posix_spawn.missing_or_empty() ? true : from_string<bool>(use_posix_spawn));

    /* Set fish_bind_mode to "default" */
    env_set(FISH_BIND_MODE_VAR, DEFAULT_BIND_MODE, ENV_GLOBAL);

    /*
      Now that the global scope is fully initialized, add a toplevel local
      scope. This same local scope will persist throughout the lifetime of the
      fish process, and it will ensure that `set -l` commands run at the
      command-line don't affect the global scope.
    */
    env_push(false);
}
Exemplo n.º 6
0
bool move_word_state_machine_t::consume_char_path_components(wchar_t c) {
    enum {
        s_initial_punctuation,
        s_whitespace,
        s_separator,
        s_slash,
        s_path_component_characters,
        s_end
    };

    // fwprintf(stdout, L"state %d, consume '%lc'\n", state, c);
    bool consumed = false;
    while (state != s_end && !consumed) {
        switch (state) {
            case s_initial_punctuation: {
                if (!is_path_component_character(c)) {
                    consumed = true;
                }
                state = s_whitespace;
                break;
            }
            case s_whitespace: {
                if (iswspace(c)) {
                    consumed = true;  // consumed whitespace
                } else if (c == L'/' || is_path_component_character(c)) {
                    state = s_slash;  // path component
                } else {
                    state = s_separator;  // path separator
                }
                break;
            }
            case s_separator: {
                if (!iswspace(c) && !is_path_component_character(c)) {
                    consumed = true;  // consumed separator
                } else {
                    state = s_end;
                }
                break;
            }
            case s_slash: {
                if (c == L'/') {
                    consumed = true;  // consumed slash
                } else {
                    state = s_path_component_characters;
                }
                break;
            }
            case s_path_component_characters: {
                if (is_path_component_character(c)) {
                    consumed = true;  // consumed string character except slash
                } else {
                    state = s_end;
                }
                break;
            }
            case s_end:
            default: { break; }
        }
    }
    return consumed;
}
Exemplo n.º 7
0
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars,
							   EWordWrapStyle end_on_word_boundary, const BOOL use_embedded,
							   F32* drawn_pixels) const
{
	if (!wchars || !wchars[0] || max_chars == 0)
	{
		return 0;
	}

	//llassert(max_pixels >= 0.f);
	//llassert(max_chars >= 0);	
	if(max_pixels < 0.f || max_chars < 0) {
		return 0;
	}
	
	BOOL clip = FALSE;
	F32 cur_x = 0;
	F32 drawn_x = 0;

	S32 start_of_last_word = 0;
	BOOL in_word = FALSE;

	// avoid S32 overflow when max_pixels == S32_MAX by staying in floating point
	F32 scaled_max_pixels =	max_pixels * sScaleX;
	F32 width_padding = 0.f;
	
	LLFontGlyphInfo* next_glyph = NULL;

	S32 i;
	for (i=0; (i < max_chars); i++)
	{
		llwchar wch = wchars[i];

		if(wch == 0)
		{
			// Null terminator.  We're done.
			break;
		}
			
		const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
		if (ext_data)
		{
			if (in_word)
			{
				in_word = FALSE;
			}
			else
			{
				start_of_last_word = i;
			}
			cur_x += getEmbeddedCharAdvance(ext_data);
			
			if (scaled_max_pixels < cur_x)
			{
				clip = TRUE;
				break;
			}
			
			if (((i+1) < max_chars) && wchars[i+1])
			{
				cur_x += EXT_KERNING * sScaleX;
			}

			if( scaled_max_pixels < cur_x )
			{
				clip = TRUE;
				break;
			}
		}
		else
		{
			if (in_word)
			{
				if (iswspace(wch))
				{
					in_word = FALSE;
				}
			}
			else
			{
				start_of_last_word = i;
				if (!iswspace(wch))
				{
					in_word = TRUE;
				}
			}

			LLFontGlyphInfo* fgi = next_glyph;
			next_glyph = NULL;
			if(!fgi)
			{
				fgi = mFontFreetype->getGlyphInfo(wch);
			}

			// account for glyphs that run beyond the starting point for the next glyphs
			width_padding = llmax(	0.f,													// always use positive padding amount
									width_padding - fgi->mXAdvance,							// previous padding left over after advance of current character
									(F32)(fgi->mWidth + fgi->mXBearing) - fgi->mXAdvance);	// difference between width of this character and advance to next character

			cur_x += fgi->mXAdvance;
		
			// clip if current character runs past scaled_max_pixels (using width_padding)
			if (scaled_max_pixels < cur_x + width_padding)
			{
				clip = TRUE;
				break;
			}

			if (((i+1) < max_chars) && wchars[i+1])
			{
				// Kern this puppy.
				next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1]);
				cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
			}
		}
		// Round after kerning.
		cur_x = (F32)llround(cur_x);
		drawn_x = cur_x;
	}


	if( clip )
	{
		switch (end_on_word_boundary)
		{
		case ONLY_WORD_BOUNDARIES:
			i = start_of_last_word;
			break;
		case WORD_BOUNDARY_IF_POSSIBLE:
			if (start_of_last_word != 0)
			{
				i = start_of_last_word;
			}
			break;
		default:
		case ANYWHERE:
			// do nothing
			break;
		}
	}

	if (drawn_pixels)
	{
		*drawn_pixels = drawn_x;
	}
	return i;
}
Exemplo n.º 8
0
int
iswgraph (wint_t c)
{
  return (iswprint (c) && !iswspace (c));
}
Exemplo n.º 9
0
/**
  Extract indexes from a destination argument of the form name[index1 index2...]

  \param indexes the list to insert the new indexes into
  \param src the source string to parse
  \param name the name of the element. Return null if the name in \c src does not match this name
  \param var_count the number of elements in the array to parse.

  \return the total number of indexes parsed, or -1 on error
*/
static int parse_index(std::vector<long> &indexes,
                       const wchar_t *src,
                       const wchar_t *name,
                       size_t var_count)
{
    size_t len;

    int count = 0;
    const wchar_t *src_orig = src;

    if (src == 0)
    {
        return 0;
    }

    while (*src != L'\0' && (iswalnum(*src) || *src == L'_'))
    {
        src++;
    }

    if (*src != L'[')
    {
        append_format(stderr_buffer, _(BUILTIN_SET_ARG_COUNT), L"set");
        return 0;
    }

    len = src-src_orig;

    if ((wcsncmp(src_orig, name, len)!=0) || (wcslen(name) != (len)))
    {
        append_format(stderr_buffer,
                      _(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"),
                      L"set",
                      name,
                      len,
                      src_orig);
        return 0;
    }

    src++;

    while (iswspace(*src))
    {
        src++;
    }

    while (*src != L']')
    {
        wchar_t *end;

        long l_ind;

        errno = 0;

        l_ind = wcstol(src, &end, 10);

        if (end==src || errno)
        {
            append_format(stderr_buffer, _(L"%ls: Invalid index starting at '%ls'\n"), L"set", src);
            return 0;
        }

        if (l_ind < 0)
        {
            l_ind = var_count+l_ind+1;
        }

        src = end;
        if (*src==L'.' && *(src+1)==L'.')
        {
            src+=2;
            long l_ind2 = wcstol(src, &end, 10);
            if (end==src || errno)
            {
                return 1;
            }
            src = end;

            if (l_ind2 < 0)
            {
                l_ind2 = var_count+l_ind2+1;
            }
            int direction = l_ind2<l_ind ? -1 : 1 ;
            for (long jjj = l_ind; jjj*direction <= l_ind2*direction; jjj+=direction)
            {
                // debug(0, L"Expand range [set]: %i\n", jjj);
                indexes.push_back(jjj);
                count++;
            }
        }
        else
        {
            indexes.push_back(l_ind);
            count++;
        }
        while (iswspace(*src)) src++;
    }

    return count;
}
Exemplo n.º 10
0
//------------------------------------------------------------------------------
int begin_doskey(wchar_t* chars, unsigned max_chars)
{
    // Find the alias for which to retrieve text for.
    wchar_t alias[64];
    {
        int i, n;
        int found_word = 0;
        const wchar_t* read = chars;
        for (i = 0, n = min(sizeof_array(alias) - 1, max_chars); i < n && *read; ++i)
        {
            if (!!iswspace(*read) == found_word)
            {
                if (!found_word)
                    found_word = 1;
                else
                    break;
            }

            alias[i] = *read++;
        }

        alias[i] = '\0';
    }

    // Find the alias' text.
    {
        int bytes;
        wchar_t* exe;
        wchar_t exe_path[MAX_PATH];

        GetModuleFileNameW(NULL, exe_path, sizeof_array(exe_path));
        exe = wcsrchr(exe_path, L'\\');
        exe = (exe != NULL) ? (exe + 1) : exe_path;

        // Check it exists.
        if (!GetConsoleAliasW(alias, exe_path, 1, exe))
            return 0;

        // It does. Allocate space and fetch it.
        bytes = max_chars * sizeof(wchar_t);
        g_state.alias_text = malloc(bytes * 2);
        GetConsoleAliasW(alias, g_state.alias_text, bytes, exe);

        // Copy the input and tokenise it. Lots of pointer aliasing here...
        g_state.input = g_state.alias_text + max_chars;
        memcpy(g_state.input, chars, bytes);

        g_state.token_count = tokenise(g_state.input, g_state.tokens,
                                       sizeof_array(g_state.tokens));

        g_state.alias_next = g_state.alias_text;
    }

    // Expand all '$?' codes except those that expand into arguments.
    {
        wchar_t* read = g_state.alias_text;
        wchar_t* write = read;
        while (*read)
        {
            if (read[0] != '$')
            {
                *write++ = *read++;
                continue;
            }

            ++read;
            switch (*read)
            {
            case '$':
                *write++ = '$';
                break;
            case 'g':
            case 'G':
                *write++ = '>';
                break;
            case 'l':
            case 'L':
                *write++ = '<';
                break;
            case 'b':
            case 'B':
                *write++ = '|';
                break;
            case 't':
            case 'T':
                *write++ = '\1';
                break;

            default:
                *write++ = '$';
                *write++ = *read;
            }

            ++read;
        }

        *write = '\0';
    }

    return continue_doskey(chars, max_chars);
}
Exemplo n.º 11
0
char *
weechat_aspell_modifier_cb (const void *pointer, void *data,
                            const char *modifier,
                            const char *modifier_data, const char *string)
{
    long unsigned int value;
    struct t_gui_buffer *buffer;
    struct t_aspell_speller_buffer *ptr_speller_buffer;
    char *result, *ptr_string, *ptr_string_orig, *pos_space;
    char *ptr_end, *ptr_end_valid, save_end;
    char *word_for_suggestions, *old_suggestions, *suggestions;
    char *word_and_suggestions;
    const char *color_normal, *color_error, *ptr_suggestions;
    int code_point, char_size;
    int length, index_result, length_word, word_ok;
    int length_color_normal, length_color_error, rc;
    int input_pos, current_pos, word_start_pos, word_end_pos, word_end_pos_valid;

    /* make C compiler happy */
    (void) pointer;
    (void) data;
    (void) modifier;

    if (!aspell_enabled)
        return NULL;

    if (!string)
        return NULL;

    rc = sscanf (modifier_data, "%lx", &value);
    if ((rc == EOF) || (rc == 0))
        return NULL;

    buffer = (struct t_gui_buffer *)value;

    /* check text during search only if option is enabled */
    if (weechat_buffer_get_integer (buffer, "text_search")
        && !weechat_config_boolean (weechat_aspell_config_check_during_search))
        return NULL;

    /* get structure with speller info for buffer */
    ptr_speller_buffer = weechat_hashtable_get (weechat_aspell_speller_buffer,
                                                buffer);
    if (!ptr_speller_buffer)
    {
        ptr_speller_buffer = weechat_aspell_speller_buffer_new (buffer);
        if (!ptr_speller_buffer)
            return NULL;
    }
    if (!ptr_speller_buffer->spellers)
        return NULL;

    /*
     * for performance: return last string built if input string is the
     * same (and cursor position is the same, if suggestions are enabled)
     */
    input_pos = weechat_buffer_get_integer (buffer, "input_pos");
    if (ptr_speller_buffer->modifier_string
        && (strcmp (string, ptr_speller_buffer->modifier_string) == 0)
        && ((weechat_config_integer (weechat_aspell_config_check_suggestions) < 0)
            || (input_pos == ptr_speller_buffer->input_pos)))
    {
        return (ptr_speller_buffer->modifier_result) ?
            strdup (ptr_speller_buffer->modifier_result) : NULL;
    }

    /* free last modifier string and result */
    if (ptr_speller_buffer->modifier_string)
    {
        free (ptr_speller_buffer->modifier_string);
        ptr_speller_buffer->modifier_string = NULL;
    }
    if (ptr_speller_buffer->modifier_result)
    {
        free (ptr_speller_buffer->modifier_result);
        ptr_speller_buffer->modifier_result = NULL;
    }

    word_for_suggestions = NULL;

    /* save last modifier string received */
    ptr_speller_buffer->modifier_string = strdup (string);
    ptr_speller_buffer->input_pos = input_pos;

    color_normal = weechat_color ("bar_fg");
    length_color_normal = strlen (color_normal);
    color_error = weechat_color (weechat_config_string (weechat_aspell_config_color_misspelled));
    length_color_error = strlen (color_error);

    length = strlen (string);
    result = malloc (length + (length * length_color_error) + 1);

    if (result)
    {
        result[0] = '\0';

        ptr_string = ptr_speller_buffer->modifier_string;
        index_result = 0;

        /* check if string is a command */
        if (!weechat_string_input_for_buffer (ptr_string))
        {
            char_size = weechat_utf8_char_size (ptr_string);
            ptr_string += char_size;
            pos_space = ptr_string;
            while (pos_space && pos_space[0] && (pos_space[0] != ' '))
            {
                pos_space = (char *)weechat_utf8_next_char (pos_space);
            }
            if (!pos_space || !pos_space[0])
            {
                free (result);
                return NULL;
            }

            pos_space[0] = '\0';

            /* exit if command is not authorized for spell checking */
            if (!weechat_aspell_command_authorized (ptr_string))
            {
                free (result);
                return NULL;
            }
            memcpy (result + index_result,
                    ptr_speller_buffer->modifier_string,
                    char_size);
            index_result += char_size;
            strcpy (result + index_result, ptr_string);
            index_result += strlen (ptr_string);

            pos_space[0] = ' ';
            ptr_string = pos_space;
        }

        current_pos = 0;
        while (ptr_string[0])
        {
            ptr_string_orig = NULL;

            /* find start of word: it must start with an alphanumeric char */
            code_point = weechat_utf8_char_int (ptr_string);
            while ((!iswalnum (code_point)) || iswspace (code_point))
            {
                if (!ptr_string_orig && !iswspace (code_point))
                    ptr_string_orig = ptr_string;
                char_size = weechat_utf8_char_size (ptr_string);
                memcpy (result + index_result, ptr_string, char_size);
                index_result += char_size;
                ptr_string += char_size;
                current_pos++;
                if (!ptr_string[0])
                    break;
                code_point = weechat_utf8_char_int (ptr_string);
            }
            if (!ptr_string[0])
                break;
            if (!ptr_string_orig)
                ptr_string_orig = ptr_string;

            word_start_pos = current_pos;
            word_end_pos = current_pos;
            word_end_pos_valid = current_pos;

            /* find end of word: ' and - allowed in word, but not at the end */
            ptr_end_valid = ptr_string;
            ptr_end = (char *)weechat_utf8_next_char (ptr_string);
            code_point = weechat_utf8_char_int (ptr_end);
            while (iswalnum (code_point) || (code_point == '\'')
                   || (code_point == '-'))
            {
                word_end_pos++;
                if (iswalnum (code_point))
                {
                    /* pointer to last alphanumeric char in the word */
                    ptr_end_valid = ptr_end;
                    word_end_pos_valid = word_end_pos;
                }
                ptr_end = (char *)weechat_utf8_next_char (ptr_end);
                if (!ptr_end[0])
                    break;
                code_point = weechat_utf8_char_int (ptr_end);
            }
            ptr_end = (char *)weechat_utf8_next_char (ptr_end_valid);
            word_end_pos = word_end_pos_valid;
            word_ok = 0;
            if (weechat_aspell_string_is_url (ptr_string)
                || weechat_aspell_string_is_nick (buffer, ptr_string_orig))
            {
                /*
                 * word is an URL or a nick, then it is OK: search for next
                 * space (will be end of word)
                 */
                word_ok = 1;
                if (ptr_end[0])
                {
                    code_point = weechat_utf8_char_int (ptr_end);
                    while (!iswspace (code_point))
                    {
                        ptr_end = (char *)weechat_utf8_next_char (ptr_end);
                        if (!ptr_end[0])
                            break;
                        code_point = weechat_utf8_char_int (ptr_end);
                    }
                }
            }
            save_end = ptr_end[0];
            ptr_end[0] = '\0';
            length_word = ptr_end - ptr_string;

            if (!word_ok)
            {
                if ((save_end != '\0')
                    || (weechat_config_integer (weechat_aspell_config_check_real_time)))
                {
                    word_ok = weechat_aspell_check_word (ptr_speller_buffer,
                                                         ptr_string);
                    if (!word_ok && (input_pos >= word_start_pos))
                    {
                        /*
                         * if word is misspelled and that cursor is after
                         * the beginning of this word, save the word (we will
                         * look for suggestions after this loop)
                         */
                        if (word_for_suggestions)
                            free (word_for_suggestions);
                        word_for_suggestions = strdup (ptr_string);
                    }
                }
                else
                    word_ok = 1;
            }

            /* add error color */
            if (!word_ok)
            {
                strcpy (result + index_result, color_error);
                index_result += length_color_error;
            }

            /* add word */
            strcpy (result + index_result, ptr_string);
            index_result += length_word;

            /* add normal color (after misspelled word) */
            if (!word_ok)
            {
                strcpy (result + index_result, color_normal);
                index_result += length_color_normal;
            }

            if (save_end == '\0')
                break;

            ptr_end[0] = save_end;
            ptr_string = ptr_end;
            current_pos = word_end_pos + 1;
        }
        result[index_result] = '\0';
    }

    /* save old suggestions in buffer */
    ptr_suggestions = weechat_buffer_get_string (buffer,
                                                 "localvar_aspell_suggest");
    old_suggestions = (ptr_suggestions) ? strdup (ptr_suggestions) : NULL;

    /* if there is a misspelled word, get suggestions and set them in buffer */
    if (word_for_suggestions)
    {
        suggestions = weechat_aspell_get_suggestions (ptr_speller_buffer,
                                                      word_for_suggestions);
        if (suggestions)
        {
            length = strlen (word_for_suggestions) + 1 /* ":" */
                + strlen (suggestions) + 1;
            word_and_suggestions = malloc (length);
            if (word_and_suggestions)
            {
                snprintf (word_and_suggestions, length, "%s:%s",
                          word_for_suggestions, suggestions);
                weechat_buffer_set (buffer, "localvar_set_aspell_suggest",
                                    word_and_suggestions);
                free (word_and_suggestions);
            }
            else
            {
                weechat_buffer_set (buffer, "localvar_del_aspell_suggest", "");
            }
            free (suggestions);
        }
        else
        {
            weechat_buffer_set (buffer, "localvar_del_aspell_suggest", "");
        }
        free (word_for_suggestions);
    }
    else
    {
        weechat_buffer_set (buffer, "localvar_del_aspell_suggest", "");
    }

    /*
     * if suggestions have changed, update the bar item
     * and send signal "aspell_suggest"
     */
    ptr_suggestions = weechat_buffer_get_string (buffer,
                                                 "localvar_aspell_suggest");
    if ((old_suggestions && !ptr_suggestions)
        || (!old_suggestions && ptr_suggestions)
        || (old_suggestions && ptr_suggestions
            && (strcmp (old_suggestions, ptr_suggestions) != 0)))
    {
        weechat_bar_item_update ("aspell_suggest");
        (void) weechat_hook_signal_send ("aspell_suggest",
                                         WEECHAT_HOOK_SIGNAL_POINTER, buffer);
    }
    if (old_suggestions)
        free (old_suggestions);

    if (!result)
        return NULL;

    ptr_speller_buffer->modifier_result = strdup (result);

    return result;
}
Exemplo n.º 12
0
int
ni_file_write_safe(FILE *fp, const ni_buffer_t *wbuf)
{
	const unsigned char *string = ni_buffer_head(wbuf);
	unsigned int left = ni_buffer_count(wbuf);
	mbstate_t mbstate;
	size_t written = 0;
	ni_bool_t saw_newline = TRUE;

	if (left == 0)
		return 0;

	memset(&mbstate, 0, sizeof(mbstate));
	while (left != 0) {
		unsigned int nbytes;
		wchar_t wc;

		/* Scan until we hit the first non-printable character.
		 * Assume the test node uses the same locale as we do */
		for (nbytes = 0; nbytes < left; ) {
			ssize_t n;

			saw_newline = FALSE;

			n = mbrtowc(&wc, (char *) string + nbytes, left - nbytes, &mbstate);
			if (n < 0) {
				/* We hit a bad path of string.
				 * If this is preceded by one or more printable
				 * chars, write those out first, then come back here.
				 */
				if (nbytes != 0)
					break;

				/* write one byte, and try to re-sync */
				wc = ((unsigned char *) string)[nbytes++];
				if (__ni_file_write_wchar_escaped(fp, wc) < 0)
					return -1;

				memset(&mbstate, 0, sizeof(mbstate));
				goto consumed_some;
			}

			if (!iswprint(wc) && !iswspace(wc)) {
				/* If this is preceded by one or more printable
				 * chars, write those out first */
				if (nbytes != 0)
					break;

				if (__ni_file_write_wchar_escaped(fp, wc) < 0)
					return -1;
				nbytes += n;
				goto consumed_some;
			}

			if (wc == '\n')
				saw_newline = TRUE;

			nbytes += n;
		}

		ni_assert(nbytes);
		if (__ni_file_write_partial(fp, string, nbytes) < 0)
			return -1;

consumed_some:
		string += nbytes;
		left -= nbytes;
	}

	/* Make sure we're writing a newline at the end of our output */
	if (!saw_newline)
		fputc('\n', fp);

	fflush(fp);
	return written;
}
Exemplo n.º 13
0
HRESULT CMainFrameDropTarget::PasteHTMLDocument(IHTMLDocument2* doc, PASTEURLDATA* /*pPaste*/)
{
	HRESULT hrPasteResult = S_FALSE; // default: nothing was pasted
	int iURLElements = 0;

	// get_links		HREF	all <LINK> and <AREA> elements -> that's *wrong* it also contains all <A> elements!
	// get_anchors		HREF	all <A> elements which have a NAME or ID value!

	//
	// Links
	//
	CComPtr<IHTMLElementCollection> links;
	if (doc->get_links(&links) == S_OK)
	{
		long lLinks;
		if (links->get_length(&lLinks) == S_OK && lLinks > 0)
		{
			iURLElements += lLinks;
			CComVariant vaIndex((long)0);
			CComVariant vaNull((long)0);
			for (long i = 0; i < lLinks; i++)
			{
				vaIndex.lVal = i;
				CComPtr<IDispatch> item;
				if (links->item(vaIndex, vaNull, &item) == S_OK)
				{
					CComPtr<IHTMLAnchorElement> anchor;
					if (SUCCEEDED(item->QueryInterface(&anchor)))
					{
						CComBSTR bstrHref;
						if (anchor->get_href(&bstrHref) == S_OK && bstrHref.Length() > 0 && IsUrlSchemeSupportedW(bstrHref))
						{
							theApp.emuledlg->ProcessED2KLink(CString(bstrHref));
							hrPasteResult = S_OK;
						}
						anchor.Release(); // conserve memory
					}
				}
			}
		}
		links.Release(); // conserve memory
	}

	//
	// Text
	//
	// The explicit handling of text is needed, if we're looking at contents which were copied
	// to the clipboard in HTML format -- although it is simple raw text!! This situation applies,
	// if the user opens the "View Partial Source" HTML window for some selected HTML contents,
	// and copies some text (e.g. an URL) to the clipboard. In that case we'll get the raw text
	// as HTML contents!!!
	//
	// PROBLEM: We can *not* always process the HTML elements (anchors, ...) *and* the inner text.
	// The following example (a rather *usual* one) would lead to the adding of the same URL twice
	// because the URL is noted as a HREF *and* as the inner text.
	//
	// <P><A href="http://www.domain.com/image.gif">http://www.domain.com/image.gif</A></P>
	//
	// So, in practice, the examination of the 'innerText' is only done, if there were no other
	// HTML elements in the document.
	//
	if (iURLElements == 0)
	{
		CComPtr<IHTMLElement> el;
		if (doc->get_body(&el) == S_OK)
		{
			CComBSTR bstr;
			if (el->get_innerText(&bstr) == S_OK && bstr.Length() > 0)
			{
				LPCWSTR pwsz = bstr;
				while (*pwsz != L'\0' && iswspace(*pwsz)) // Skip white spaces
					pwsz++;

				// PROBLEM: The 'innerText' does not contain any HTML tags, but it *MAY* contain
				// HTML comments like "<!--StartFragment-->...<!--EndFragment-->". Those
				// tags have to be explicitly parsed to get the real raw text contents.
				// Those Start- and End-tags are available if the text is copied into the clipboard
				// from a HTML window which was open with "View Partial Source"!
				static const WCHAR _wszStartFrag[] = L"<!--StartFragment-->";
				if (wcsncmp(pwsz, _wszStartFrag, ARRSIZE(_wszStartFrag)-1) == 0)
				{
					pwsz += ARRSIZE(_wszStartFrag)-1;

					// If there's a Start-tag, search for an End-tag.
					static const WCHAR _wszEndFrag[] = L"<!--EndFragment-->";
					LPWSTR pwszEnd = (LPWSTR)bstr + bstr.Length();
					pwszEnd -= ARRSIZE(_wszEndFrag)-1;
					if (pwszEnd >= pwsz)
					{
						if (wcsncmp(pwszEnd, _wszEndFrag, ARRSIZE(_wszEndFrag)-1) == 0)
							*pwszEnd = L'\0'; // Ugly but efficient, terminate the BSTR!
					}
				}

				// Search all white-space terminated strings and check for a valid URL-scheme
				while (*pwsz != L'\0')
				{
					while (*pwsz != L'\0' && iswspace(*pwsz)) // Skip white spaces
						pwsz++;

					if (IsUrlSchemeSupportedW(pwsz))
					{
						LPCWSTR pwszEnd = pwsz;
						while (*pwszEnd != L'\0' && !iswspace(*pwszEnd)) // Search next white space (end of current string)
							pwszEnd++;
						int iLen = pwszEnd - pwsz;
						if (iLen > 0)
						{
							CString strURL(pwsz, iLen);
							theApp.emuledlg->ProcessED2KLink(strURL);
							hrPasteResult = S_OK;
							pwsz += iLen;
						}
					}
					else
					{
						while (*pwsz != L'\0' && !iswspace(*pwsz)) // Search next white space (end of current string)
							pwsz++;
					}

					while (*pwsz != L'\0' && iswspace(*pwsz)) // Skip white spaces
						pwsz++;
				}
			}
		}
	}

	return hrPasteResult;
}
Exemplo n.º 14
0
	std::wstring InsertLineFeed(const char *text, int count, unsigned wrapAt, Real* outWidth, unsigned* outLines)
	{
		if (count < 0)
			count = GetTextLength(text);

		unsigned lines = 1;
		std::vector<Real> maxes;
		Real dummyMax = 0;
		Real curX = 0;
		std::wstring multilineString;
		unsigned inputBeforeSpace = 0;
		Real lengthAfterSpace = 0;
		for (int n = 0; n < count;)
		{
			TextTags::Enum tag = TextTags::Num;
			int imgLen = 0;
			int numSkip = SkipTags(&text[n], &tag, &imgLen);
			if (numSkip)
			{
				do
				{
					if (tag == TextTags::Img)
					{
						curX += imgLen;
						lengthAfterSpace += imgLen;
					}
					int startN = n;
					for (; n < startN + numSkip;)
					{
						int charId = GetTextChar(text, n, &n);
						++inputBeforeSpace;
						multilineString.push_back(charId);
					}
					numSkip = SkipTags(&text[n], &tag, &imgLen);

				} while (numSkip);
				if (n >= count)
					break;
			}

			int charId = GetTextChar(text, n, &n);
			if (charId == L'\n')
			{
				maxes.push_back(curX);
				curX = 0;
				lengthAfterSpace = 0;
				++lines;
			}
			else
			{
				SCharDescr *ch = GetChar(charId);
				if (ch == 0) ch = &mDefChar;
				Real length = (mScale * (ch->xAdv));
				if (n < count)
					length += AdjustForKerningPairs(charId, GetTextChar(text, n));
				curX += length;
				lengthAfterSpace += length;
			}

			if (curX > wrapAt)
			{
				multilineString.insert(multilineString.end() - inputBeforeSpace, L'\n');
				maxes.push_back(curX - lengthAfterSpace);
				curX = lengthAfterSpace;
				multilineString.push_back(charId);
				++lines;
				inputBeforeSpace = 0;
				lengthAfterSpace = 0;
			}
			else
			{
				if (iswspace(charId))
				{
					inputBeforeSpace = 0;
					lengthAfterSpace = 0;
				}
				else
				{
					++inputBeforeSpace;
				}
				multilineString.push_back(charId);
			}
			dummyMax = std::max(dummyMax, curX);
		}
		maxes.push_back(curX);

		if (outWidth)
		{
			if (maxes.empty())
				*outWidth = dummyMax;
			else
			{
				Real biggest = 0;
				for (auto val : maxes)
				{
					biggest = std::max(biggest, val);
					*outWidth = biggest;
				}
			}
		}

		if (outLines)
			*outLines = lines;

		return multilineString;
	}
Exemplo n.º 15
0
		std::unique_ptr<Token> Lexer::next_token()
		{
			if (!token_buffer_.empty())
			{
				auto next = std::move(token_buffer_.front());
				token_buffer_.pop();
				return next;
			}

			while (file_->good())
			{
				if (iswspace(current_char_))
				{
					consume();
					continue;
				}
				else if(current_char_ == L'/' && file_->peek_char() == L'/')
				{
					comment();
					continue;
				}
				else if(iswalpha(current_char_))
				{
					return alpha();
				}
				else if (iswdigit(current_char_))
				{
					return number();
				}

				switch (current_char_)
				{
				case L'"': {
					return string();
				}
				case L'\'': {
					return char_l();
				}
				case L'{': {
					return match_token(L'{', TokenType::LBracket);
				}
				case L'}': {
					return match_token(L'}', TokenType::RBracket);
				}
				case L'[': {
					return match_token(L'[', TokenType::LSBracket);
				}
				case L']': {
					return match_token(L']', TokenType::RSBracket);
				}
				case L'(': {
					return match_token(L'(', TokenType::LParen);
				}
				case L')': {
					return match_token(L')', TokenType::RParen);
				}
				case L';': {
					return match_token(L';', TokenType::Semicolon);
				}
				case L'.': {
					return match_token(L'.', TokenType::Dot);
				}
				case L',': {
					return match_token(L',', TokenType::Comma);
				}
				case L':': {
					auto t = try_match_tokens(L':', L':', TokenType::DoubleColon);
					if (t != nullptr)
						return t;

					return match_token(L':', TokenType::Colon);
				}
				case L'=': {
					auto t = try_match_tokens(L'=', L'=', TokenType::DoubleEquals);
					if (t != nullptr)
						return t;

					return match_token(L'=', TokenType::Equals);
				}
				case L'+': {
					auto t = try_match_tokens(L'+', L'+', TokenType::PlusPlus);
					if (t != nullptr)
						return t;

					auto t2 = try_match_tokens(L'+', L'=', TokenType::PlusEquals);
					if (t2 != nullptr)
						return t2;

					return match_token(L'+', TokenType::Plus);
				}
				case L'-': {
					auto t = try_match_tokens(L'-', L'-', TokenType::MinusMinus);
					if (t != nullptr)
						return t;

					auto t2 = try_match_tokens(L'-', L'=', TokenType::MinusEquals);
					if (t2 != nullptr)
						return t2;

					if (iswdigit(file_->peek_char()))
					{
						consume();
						return number(true);
					}

					return match_token(L'-', TokenType::Minus);
				}
				case L'*': {
					auto t = try_match_tokens(L'*', L'=', TokenType::AsterixEquals);
					if (t != nullptr)
						return t;

					return match_token(L'*', TokenType::Asterix);
				}
				case L'/': {
					auto t = try_match_tokens(L'/', L'=', TokenType::SlashEquals);
					if (t != nullptr)
						return t;

					return match_token(L'/', TokenType::Slash);
				}
				case L'!': {
					auto t = try_match_tokens(L'!', L'=', TokenType::NotEquals);
					if (t != nullptr)
						return t;

					return match_token(L'!', TokenType::Exclamation);
				}
				case L'<': {
					auto t = try_match_tokens(L'<', L'=', TokenType::LessThanEquals);
					if (t != nullptr)
						return t;

					t = try_match_tokens(L'<', L'<', TokenType::DoubleLessThan);
					if (t != nullptr)
						return t;

					return match_token(L'<', TokenType::LessThan);
				}
				case L'>': {
					auto t = try_match_tokens(L'>', L'=', TokenType::GreaterThanEquals);
					if (t != nullptr)
						return t;

					t = try_match_tokens(L'>', L'>', TokenType::DoubleGreaterThan);
					if (t != nullptr)
						return t;

					return match_token(L'>', TokenType::GreaterThan);
				}
				case L'%': {
					return match_token(L'%', TokenType::Percent);
				}
				case L'&': {
					auto t = try_match_tokens(L'&', L'&', TokenType::DoubleAmpersand);
					if (t != nullptr)
						return t;

					return match_token(L'&', TokenType::Ampersand);
				}
				case L'|': {
					auto t = try_match_tokens(L'|', L'|', TokenType::DoubleVerticalBar);
					if (t != nullptr)
						return t;

					return match_token(L'|', TokenType::VerticalBar);
				}
				default:
					throw ElsaException("Unknown token");
				}
			}

			return std::make_unique<Token>(TokenType::END, L"", line_number_, file_->get_file_name());
		}
Exemplo n.º 16
0
/**
 * Get a single property line, from the property name through the
 * final new line, and include any continuation lines
 */
char *icalparser_get_line(icalparser *parser,
                          icalparser_line_gen_func line_gen_func)
{
    char *line;
    char *line_p;
    size_t buf_size = parser->tmp_buf_size;

    line_p = line = icalmemory_new_buffer(buf_size);
    line[0] = '\0';

    /* Read lines by calling line_gen_func and putting the data into
       parser->temp. If the line is a continuation line ( begins with a
       space after a newline ) then append the data onto line and read
       again. Otherwise, exit the loop. */

    while (1) {

        /* The first part of the loop deals with the temp buffer,
           which was read on he last pass through the loop. The
           routine is split like this because it has to read lone line
           ahead to determine if a line is a continuation line. */

        /* The tmp buffer is not clear, so transfer the data in it to the
           output. This may be left over from a previous call */
        if (parser->temp[0] != '\0') {

            /* If the last position in the temp buffer is occupied,
               mark the buffer as full. The means we will do another
               read later, because the line is not finished */
            if (parser->temp[parser->tmp_buf_size - 1] == 0 &&
                parser->temp[parser->tmp_buf_size - 2] != '\n' &&
                parser->temp[parser->tmp_buf_size - 2] != 0) {
                parser->buffer_full = 1;
            } else {
                parser->buffer_full = 0;
            }

            /* Copy the temp to the output and clear the temp buffer. */
            if (parser->continuation_line == 1) {
                /* back up the pointer to erase the continuation characters */
                parser->continuation_line = 0;
                line_p--;

                if (*(line_p - 1) == '\r') {
                    line_p--;
                }

                /* copy one space up to eliminate the leading space */
                icalmemory_append_string(&line, &line_p, &buf_size, parser->temp + 1);

            } else {
                icalmemory_append_string(&line, &line_p, &buf_size, parser->temp);
            }

            parser->temp[0] = '\0';
        }

        parser->temp[parser->tmp_buf_size - 1] = 1;     /* Mark end of buffer */

        /****** Here is where the routine gets string data ******************/
        if ((*line_gen_func) (parser->temp, parser->tmp_buf_size, parser->line_gen_data)
            == 0) {     /* Get more data */

            /* If the first position is clear, it means we didn't get
               any more data from the last call to line_ge_func */
            if (parser->temp[0] == '\0') {

                if (line[0] != '\0') {
                    /* There is data in the output, so fall trhough and process it */
                    break;
                } else {
                    /* No data in output; return and signal that there
                       is no more input */
                    free(line);
                    return 0;
                }
            }
        }

        /* If the output line ends in a '\n' and the temp buffer
           begins with a ' ' or tab, then the buffer holds a continuation
           line, so keep reading.  RFC 5545, section 3.1 */

        if (line_p > line + 1 && *(line_p - 1) == '\n'
            && (parser->temp[0] == ' ' || parser->temp[0] == '\t')) {

            parser->continuation_line = 1;

        } else if (parser->buffer_full == 1) {

            /* The buffer was filled on the last read, so read again */

        } else {

            /* Looks like the end of this content line, so break */
            break;
        }
    }

    /* Erase the final newline and/or carriage return */
    if (line_p > line + 1 && *(line_p - 1) == '\n') {
        *(line_p - 1) = '\0';
        if (*(line_p - 2) == '\r') {
            *(line_p - 2) = '\0';
        }

    } else {
        *(line_p) = '\0';
    }

    while ((*line_p == '\0' || iswspace((wint_t) * line_p)) && line_p > line) {
        *line_p = '\0';
        line_p--;
    }

    return line;
}
Exemplo n.º 17
0
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars,
							   BOOL end_on_word_boundary, const BOOL use_embedded,
							   F32* drawn_pixels) const
{
	if (!wchars || !wchars[0] || max_chars == 0)
	{
		return 0;
	}
	
	llassert(max_pixels >= 0.f);
	llassert(max_chars >= 0);
	
	BOOL clip = FALSE;
	F32 cur_x = 0;
	F32 drawn_x = 0;

	S32 start_of_last_word = 0;
	BOOL in_word = FALSE;

	F32 scaled_max_pixels =	(F32)llceil(max_pixels * sScaleX);

	S32 i;
	for (i=0; (i < max_chars); i++)
	{
		llwchar wch = wchars[i];

		if(wch == 0)
		{
			// Null terminator.  We're done.
			break;
		}
			
		const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
		if (ext_data)
		{
			if (in_word)
			{
				in_word = FALSE;
			}
			else
			{
				start_of_last_word = i;
			}
			cur_x += getEmbeddedCharAdvance(ext_data);
			
			if (scaled_max_pixels < cur_x)
			{
				clip = TRUE;
				break;
			}
			
			if (((i+1) < max_chars) && wchars[i+1])
			{
				cur_x += EXT_KERNING * sScaleX;
			}

			if( scaled_max_pixels < cur_x )
			{
				clip = TRUE;
				break;
			}
		}
		else
		{
			if (in_word)
			{
				if (iswspace(wch))
				{
					in_word = FALSE;
				}
			}
			else
			{
				start_of_last_word = i;
				if (!iswspace(wch))
				{
					in_word = TRUE;
				}
			}

			cur_x += getXAdvance(wch);
			
			if (scaled_max_pixels < cur_x)
			{
				clip = TRUE;
				break;
			}

			if (((i+1) < max_chars) && wchars[i+1])
			{
				// Kern this puppy.
				cur_x += getXKerning(wch, wchars[i+1]);
			}
		}
		// Round after kerning.
		cur_x = (F32)llfloor(cur_x + 0.5f);
		drawn_x = cur_x;
	}

	if( clip && end_on_word_boundary && (start_of_last_word != 0) )
	{
		i = start_of_last_word;
	}
	if (drawn_pixels)
	{
		*drawn_pixels = drawn_x;
	}
	return i;
}
Exemplo n.º 18
0
/*!
	行頭全角空白及びユニコード空白を削除する
	@param[in]	pXdot	今のドット位置を受けて戻す・削除に巻き込まれた対応
	@param[in]	dLine	今の行数
	@return		HRESULT	終了状態コード
*/
HRESULT DocTopSpaceErase( PINT pXdot, INT dLine )
{
	UINT_PTR	iLines;
	INT			iTop, iBottom, i;
	BOOLEAN		bFirst = TRUE, bSeled = FALSE;
	TCHAR		ch;

	LETR_ITR	vcLtrItr;

	LINE_ITR	itLine;

	//	範囲確認
	iLines  = DocNowFilePageLineCount( );
	iTop    = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineTop;
	iBottom = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineBottom;
	if( 0 <= iTop &&  0 <= iBottom )	bSeled = TRUE;

	if( 0 > iTop )		iTop = 0;
	if( 0 > iBottom )	iBottom = iLines - 1;

	TRACE( TEXT("行頭空白を削除") );
	//	選択範囲は、操作した行全体を選択状態にする

	itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin();
	std::advance( itLine, iTop );	//	位置合わせ

	for( i = iTop; iBottom >= i; i++, itLine++ )	//	範囲内の各行について
	{
		//	文字があるなら操作する
		if( 0 != itLine->vcLine.size(  ) )
		{
			vcLtrItr = itLine->vcLine.begin( );
			ch = vcLtrItr->cchMozi;

			//	空白かつ半角ではない
			if( ( iswspace( ch ) && TEXT(' ') != ch ) )
			{
				SqnAppendLetter( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_DELETE, ch, 0, i, bFirst );
				bFirst = FALSE;

				DocIterateDelete( vcLtrItr, i );
			}
		}

		if( bSeled )
		{
			DocRangeSelStateToggle( -1, -1, i, 1 );	//	該当行全体を選択状態にする
			DocReturnSelStateToggle( i, 1 );	//	改行も選択で
		}

		DocBadSpaceCheck( i );	//	状態をリセット
		ViewRedrawSetLine( i );
	}

	//	キャレット位置ずれてたら適当に調整
	*pXdot = 0;
	DocLetterPosGetAdjust( pXdot, dLine, 0 );	//	キャレット位置適当に調整
	ViewDrawCaret( *pXdot, dLine, 1 );


	DocPageInfoRenew( -1, 1 );

	return S_OK;
}
Exemplo n.º 19
0
static
VOID
ShowFailureActions(
    HWND hwndDlg,
    PRECOVERYDATA pRecoveryData)
{
    WCHAR szBuffer[256];
    PWSTR startPtr, endPtr;
    INT i, index, id, length;

    for (i = 0; i < min(pRecoveryData->pServiceFailure->cActions, 3); i++)
    {
        index = -1;

        switch (pRecoveryData->pServiceFailure->lpsaActions[i].Type)
        {
            case SC_ACTION_NONE:
                index = 0;
                break;

            case SC_ACTION_RESTART:
                index = 1;

                wsprintf(szBuffer, L"%lu", pRecoveryData->pServiceFailure->lpsaActions[i].Delay / 60000);
                SendDlgItemMessageW(hwndDlg,
                                    IDC_RESTART_TIME,
                                    WM_SETTEXT,
                                    0,
                                    (LPARAM)szBuffer);

                for (id = IDC_RESTART_TEXT1; id <= IDC_RESTART_TEXT2; id++)
                     EnableWindow(GetDlgItem(hwndDlg, id), TRUE);
                break;

            case SC_ACTION_REBOOT:
                index = 3;

                EnableWindow(GetDlgItem(hwndDlg, IDC_RESTART_OPTIONS), TRUE);
                break;

            case SC_ACTION_RUN_COMMAND:
                index = 2;

                for (id = IDC_RUN_GROUPBOX; id <= IDC_ADD_FAILCOUNT; id++)
                    EnableWindow(GetDlgItem(hwndDlg, id), TRUE);
                break;
        }

        if (index != -1)
        {
            SendDlgItemMessageW(hwndDlg,
                                IDC_FIRST_FAILURE + i,
                                CB_SETCURSEL,
                                index,
                                0);
        }
    }

    wsprintf(szBuffer, L"%lu", pRecoveryData->pServiceFailure->dwResetPeriod / 86400);
    SendDlgItemMessageW(hwndDlg,
                        IDC_RESET_TIME,
                        WM_SETTEXT,
                        0,
                        (LPARAM)szBuffer);

    if (pRecoveryData->pServiceFailure->lpCommand != NULL)
    {
        ZeroMemory(szBuffer, sizeof(szBuffer));

        startPtr = pRecoveryData->pServiceFailure->lpCommand;
        if (*startPtr == L'\"')
            startPtr++;

        endPtr = wcschr(startPtr, L'\"');
        if (endPtr != NULL)
        {
            length = (INT)((LONG_PTR)endPtr - (LONG_PTR)startPtr);
            CopyMemory(szBuffer, startPtr, length);
        }
        else
        {
            wcscpy(szBuffer, startPtr);
        }

        SendDlgItemMessageW(hwndDlg,
                            IDC_PROGRAM,
                            WM_SETTEXT,
                            0,
                            (LPARAM)szBuffer);

        ZeroMemory(szBuffer, sizeof(szBuffer));

        if (endPtr != NULL)
        {
            startPtr = endPtr + 1;
            while (iswspace(*startPtr))
                startPtr++;

            endPtr = wcsstr(pRecoveryData->pServiceFailure->lpCommand, L"/fail=%1%");
            if (endPtr != NULL)
            {
                while (iswspace(*(endPtr - 1)))
                    endPtr--;

                length = (INT)((LONG_PTR)endPtr - (LONG_PTR)startPtr);
                CopyMemory(szBuffer, startPtr, length);
            }
            else
            {
                wcscpy(szBuffer, startPtr);
            }

            SendDlgItemMessageW(hwndDlg,
                                IDC_PARAMETERS,
                                WM_SETTEXT,
                                0,
                                (LPARAM)szBuffer);

            endPtr = wcsstr(pRecoveryData->pServiceFailure->lpCommand, L"/fail=%1%");
            if (endPtr != NULL)
            {
                SendDlgItemMessageW(hwndDlg,
                                    IDC_ADD_FAILCOUNT,
                                    BM_SETCHECK,
                                    BST_CHECKED,
                                    0);
            }
        }
    }
}
Exemplo n.º 20
0
/*!
	行末文字を削除する。ただし空白だったら削除しない
	@param[in]	pXdot	今のドット位置を受けて戻す・削除に巻き込まれた対応
	@param[in]	dLine	今の行数
	@return		HRESULT	終了状態コード
*/
HRESULT DocLastLetterErase( PINT pXdot, INT dLine )
{
	UINT_PTR	iLines;
	INT			iTop, iBottom, i, xDot = 0;
	TCHAR		ch;
	BOOLEAN		bFirst = TRUE, bSeled = FALSE;
	RECT		rect;

	LETR_ITR	vcLtrItr;

	LINE_ITR	itLine;

	//	範囲確認
	iLines  = DocNowFilePageLineCount( );
	iTop    = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineTop;
	iBottom = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineBottom;
	if( 0 <= iTop &&  0 <= iBottom )	bSeled = TRUE;

	if( 0 > iTop )		iTop = 0;
	if( 0 > iBottom )	iBottom = iLines - 1;

	TRACE( TEXT("行末文字削除") );
	//	選択してる場合は、操作行を全選択状態にする
	itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin();
	std::advance( itLine, iTop );	//	位置合わせ

	for( i = iTop; iBottom >= i; i++, itLine++ )	//	範囲内の各行について
	{
		//	文字があるなら操作する
		if( 0 != itLine->vcLine.size( ) )
		{
			vcLtrItr = itLine->vcLine.end( );
			vcLtrItr--;	//	終端の一個前が末端文字
			ch = vcLtrItr->cchMozi;

			rect.top    = i * LINE_HEIGHT;
			rect.bottom = rect.top + LINE_HEIGHT;

			if( !( iswspace( ch ) ) )
			{
				xDot  = DocLineParamGet( i, NULL, NULL );

				xDot -= vcLtrItr->rdWidth;

				SqnAppendLetter( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_DELETE, ch, xDot, i, bFirst );
				bFirst = FALSE;

				DocIterateDelete( vcLtrItr, i );

				rect.left  = xDot;
				rect.right = xDot + 40;	//	壱文字+改行・適当でよろし

				ViewRedrawSetRect( &rect );	//	末端だけ書き換えればいい?

				DocBadSpaceCheck( i );	//	良くないスペースを調べておく
			}
		}

		if( bSeled )
		{
			DocRangeSelStateToggle( -1, -1, i , 1 );	//	該当行全体を選択状態にする
			DocReturnSelStateToggle( i, 1 );	//	改行も選択で
		}
	}

	//	キャレット位置適当に調整
	*pXdot = 0;
	DocLetterPosGetAdjust( pXdot, dLine, 0 );	//	キャレット位置適当に調整
	ViewDrawCaret( *pXdot, dLine, 1 );

	DocPageInfoRenew( -1, 1 );

	return S_OK;
}
Exemplo n.º 21
0
BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
{
	BOOL	handled = FALSE;

	// let scrollbar have first dibs
	handled = LLView::childrenHandleDoubleClick(x, y, mask) != NULL;

	if( !handled && mTakesNonScrollClicks)
	{
		if( allowsEmbeddedItems() )
		{
			const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
			if( cur_segment && cur_segment->getStyle()->getIsEmbeddedItem() )
			{
				if( openEmbeddedItemAtPos( cur_segment->getStart() ) )
				{
					deselect();
					setFocus( FALSE );
					return TRUE;
				}
			}
		}
	
		setCursorAtLocalPos( x, y, FALSE );
		deselect();

		const LLWString &text = getWText();
		
		if( isPartOfWord( text[mCursorPos] ) )
		{
			// Select word the cursor is over
			while ((mCursorPos > 0) && isPartOfWord(text[mCursorPos-1]))
			{
				mCursorPos--;
			}
			startSelection();

			while ((mCursorPos < (S32)text.length()) && isPartOfWord( text[mCursorPos] ) )
			{
				mCursorPos++;
			}
		
			mSelectionEnd = mCursorPos;
		}
		else if ((mCursorPos < (S32)text.length()) && !iswspace( text[mCursorPos]) )
		{
			// Select the character the cursor is over
			startSelection();
			mCursorPos++;
			mSelectionEnd = mCursorPos;
		}

		// We don't want handleMouseUp() to "finish" the selection (and thereby
		// set mSelectionEnd to where the mouse is), so we finish the selection here.
		mIsSelecting = FALSE;  

		// delay cursor flashing
		resetKeystrokeTimer();

		// take selection to 'primary' clipboard
		updatePrimary();

		handled = TRUE;
	}
	return handled;
}
Exemplo n.º 22
0
/*!
	AA全体を、1dotずつずらす。文字なら空白に置き換えながら
	@param[in]	vk		方向・右か左か
	@param[in]	pXdot	今のドット位置を受けて戻す
	@param[in]	dLine	今の行数
	@return		HRESULT	終了状態コード
*/
HRESULT DocPositionShift( UINT vk, PINT pXdot, INT dLine )
{
	UINT_PTR	iLines, cchSz;
	INT			iTop, iBottom, i;
	INT			wid, iDot, iLin, iMzCnt;
	INT			iTgtWid, iLefDot, iRitDot;
	BOOLEAN		bFirst = TRUE, bSeled = FALSE, bDone = FALSE;
	BOOLEAN		bRight;	//	非0右へ 0左へ
	BOOLEAN		bIsSp;
	LPTSTR		ptRepl;
	TCHAR		ch, chOneSp;

	LPUNDOBUFF	pstUndoBuff;	

	LETR_ITR	vcLtrItr;
	LINE_ITR	itLine;



	chOneSp = gaatPaddingSpDotW[1][0];

	pstUndoBuff = &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog);


	TRACE( TEXT("全体ずらし") );

	if( VK_RIGHT == vk )		bRight = TRUE;
	else if( VK_LEFT == vk )	bRight = FALSE;
	else	return E_INVALIDARG;

	//	範囲確認
	iLines  = DocNowFilePageLineCount( );
	iTop    = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineTop;
	iBottom = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineBottom;
	if( 0 <= iTop &&  0 <= iBottom )	bSeled = TRUE;

	if( 0 > iTop )		iTop = 0;
	if( 0 > iBottom )	iBottom = iLines - 1;

	//	そのままだと容量が狂う・一旦選択状態を解除して計算しなおす
	if( bSeled ){	DocPageSelStateToggle( -1 );	}

	//	壱行ずつ面倒見ていく
	itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin();
	std::advance( itLine, iTop );	//	位置合わせ

	for( i = iTop; iBottom >= i; i++, itLine++ )
	{
		//	文字があるなら操作する
		if( 0 != itLine->vcLine.size(  ) )
		{
			//	先頭文字を確認
			vcLtrItr = itLine->vcLine.begin( );
			ch  = vcLtrItr->cchMozi;
			wid = vcLtrItr->rdWidth;	//	文字幅

			bDone = FALSE;

			if( !(iswspace(ch)) )	//	空白ではなく
			{
				if( bRight )	//	右ずらしなら
				{
					//	先頭に1dotスペース足せばおk
					DocInputLetter( 0, i, chOneSp );
					SqnAppendLetter( pstUndoBuff, DO_INSERT, chOneSp, 0, i, bFirst );	bFirst = FALSE;
					bDone = TRUE;	//	処理しちゃった
				}
				else	//	左イクなら、先頭文字を空白にして調整する
				{
					ptRepl = DocPaddingSpaceMake( wid );	//	必要な空白確保
					StringCchLength( ptRepl, STRSAFE_MAX_CCH, &cchSz );
					//	今の文字を削除
					SqnAppendLetter( pstUndoBuff, DO_DELETE, ch, 0, i, bFirst );	bFirst = FALSE;
					DocIterateDelete( vcLtrItr, i );
					//	そして先頭に空白をアッー!
					iDot = 0;	iLin = i;
					DocStringAdd( &iDot, &iLin, ptRepl, cchSz );
					SqnAppendString( pstUndoBuff, DO_INSERT, ptRepl, 0, i, bFirst );	bFirst = FALSE;
					FREE(ptRepl);	//	開放忘れないように
				}
			}
			//	この先Beginイテレータ無効

			if( !(bDone) )	//	未処理であるなら・この時点で、先頭文字は空白確定
			{
				//	空白範囲を確認
				iTgtWid = DocLineStateCheckWithDot( 0, i, &iLefDot, &iRitDot, NULL, &iMzCnt, &bIsSp );
				if( bRight )	iTgtWid++;	//	方向に合わせて
				else			iTgtWid--;	//	ドット数を求める
				if( 0 > iTgtWid )	iTgtWid = 0;	//	マイナスは無いと思うけど念のため

				ptRepl = DocPaddingSpaceMake( iTgtWid );	//	必要な空白確保
				//	ターゲット幅が0ならNULLなので、先頭文字の削除だけでおk

				DocRangeDeleteByMozi( 0, i, 0, iMzCnt, &bFirst );	//	元の部分削除して

				if( ptRepl )	//	必要な文字を入れる
				{
					StringCchLength( ptRepl, STRSAFE_MAX_CCH, &cchSz );
					iDot = 0;	iLin = i;
					DocStringAdd( &iDot, &iLin, ptRepl, cchSz );
					SqnAppendString( pstUndoBuff, DO_INSERT, ptRepl, 0, i, bFirst );	bFirst = FALSE;
					FREE(ptRepl);	//	開放忘れないように
				}
			}

			if( bSeled )	//	選択状態でヤッてたのなら、選択状態を維持する
			{
				DocRangeSelStateToggle( -1, -1, i , 1 );	//	該当行全体を選択状態にする
				//	次の行があるなら改行も選択で
				if( iBottom > i )	DocReturnSelStateToggle( i, 1 );
			}

			DocBadSpaceCheck( i );	//	状態をリセット
			ViewRedrawSetLine( i );
		}
	}

	if( bSeled )	//	選択範囲はり直し
	{
		(*gitFileIt).vcCont.at( gixFocusPage ).dSelLineTop    = iTop;
		(*gitFileIt).vcCont.at( gixFocusPage ).dSelLineBottom = iBottom;
	}


	//	キャレット位置調整
	iDot = 0;
	DocLetterPosGetAdjust( &iDot, dLine, 0 );	//	キャレット位置適当に調整
	ViewDrawCaret( iDot, dLine, 1 );

	DocPageByteCount( gitFileIt, gixFocusPage, NULL, NULL );
	DocPageInfoRenew( -1, 1 );

	return S_OK;
}
Exemplo n.º 23
0
int
json_get_token (const wchar_t * z, const size_t len, int *tokenType,
		double *number)
{
  wchar_t *p;
  int i;
  if (!z || !tokenType || len == 0 || !number)
    {
      return -1;
    }

  *tokenType = TK_ILLEGAL;

  if (iswspace (z[0]))
    {
      for (i = 1; iswspace (z[i]); i++)
	{
	}
      *tokenType = TK_SPACE;
      return i;
    }

  switch (*z)
    {
    case '"':
      {
	/* NOTE: See RFC 4627 Section 2.5 */
	for (i = 1; i < len; i++)
	  {
	    /* Check if we're at the end of the string */
	    if (z[i] == '"')
	      {
		*tokenType = TK_STRING;
		return i + 1;
	      }
	    /* Check for characters that are allowed unescaped */
	    else if (z[i] == 0x20 || z[i] == 0x21 ||
		     (z[i] >= 0x23 && z[i] <= 0x5B) ||
		     (z[i] >= 0x5D && z[i] <= 0x10FFFF))
	      {
		continue;
	      }
	    /* Check for allowed escaped characters */
	    else if (z[i] == '\\')
	      {
		if (++i >= len)
		  {
		    return -1;
		  }

		switch (z[i])
		  {
		  case '"':
		  case '\\':
		  case '/':
		  case 'b':
		  case 'f':
		  case 'n':
		  case 'r':
		  case 't':
		    break;
		  case 'u':
		    {
		      int offset;
		      i += 4;
		      if (i >= len)
			{
			  return -1;
			}

		      /* Check the four characters following \u are valid hex */
		      for (offset = 3; offset >= 0; offset--)
			{
			  if (!iswxdigit (z[i - offset]))
			    {
			      /* Illegal non-hex character after \u */
			      return -1;
			    }
			}
		      break;
		    }

		  default:
		    /* Illegal escape value */
		    return -1;
		  }
	      }
	    else
	      {
		/* Illegal code */
		return -1;
	      }
	  }
	break;
      }
    case ':':
      {
	*tokenType = TK_COLON;
	return 1;
      }
    case ',':
      {
	*tokenType = TK_COMMA;
	return 1;
      }
    case '{':
      {
	*tokenType = TK_LCURLY;
	return 1;
      }
    case '}':
      {
	*tokenType = TK_RCURLY;
	return 1;
      }
    case '[':
      {
	*tokenType = TK_LBRACKET;
	return 1;
      }
    case ']':
      {
	*tokenType = TK_RBRACKET;
	return 1;
      }
    }

  /* Check for keywords */
  for (i = 0; i < NUM_KEYWORDS; i++)
    {
      struct keyword *kw = keywords + i;
      if (wcsncmp (z, kw->z, kw->len) == 0)
	{
	  *tokenType = kw->tokenType;
	  return kw->len;
	}
    }

  /* Check for number */
  *number = wcstod (z, &p);
  if (p != z)
    {
      *tokenType = TK_NUMBER;
      return (p - z);
    }

  /* ???? */
  *tokenType = TK_ILLEGAL;
  return -1;
}
Exemplo n.º 24
0
/*!
	キャレット位置から、左右に1dotずつずらす。文字なら空白に置き換えながら
	@param[in]	vk		方向・右か左か
	@param[in]	pXdot	今のドット位置を受けて戻す
	@param[in]	dLine	今の行数
	@return		HRESULT	終了状態コード
*/
HRESULT DocCentreWidthShift( UINT vk, PINT pXdot, INT dLine )
{
	UINT_PTR	iLines, cchSz;
	UINT		dRslt, dFirst;
	INT			iBaseDot, iTop, iBottom, iBufDot;
	INT			wid, iDot, iLin, iMzCnt;
	INT			iFnlDot;
	BOOLEAN		bSeled = FALSE;
	BOOLEAN		bRight;	//	非0右へ 0左へ
	LPTSTR		ptRepl;
	TCHAR		ch, chOneSp;

	LPUNDOBUFF	pstUndoBuff;	

	LETR_ITR	vcLtrItr;
	LINE_ITR	itLine;

	chOneSp = gaatPaddingSpDotW[1][0];	//	幅1dot・文字間に挿入

	//中心部分が空白なら、その空白を伸び縮みさせる。
	//文字と文字の間開けるなら、抽芯になってる字の左側を開けるようにする
	//潰すときは、抽芯字を空白に置き換えて、それを縮める

	pstUndoBuff = &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog);

	iBaseDot = *pXdot;	//	基準点、なるべく動かないようにせないかん
	TRACE( TEXT("中間ずらし %dDOT"), iBaseDot );

	iFnlDot = iBaseDot;

	if( VK_RIGHT == vk )		bRight = TRUE;
	else if( VK_LEFT == vk )	bRight = FALSE;
	else	return E_INVALIDARG;

	if(  0 == iBaseDot )	//	基準が0なら、全体左右ずらしってこと
	{
		return DocPositionShift( vk, pXdot, dLine );
	}

	//	範囲確認
	iLines  = DocNowFilePageLineCount( );
	iTop    = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineTop;
	iBottom = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineBottom;
	if( 0 <= iTop &&  0 <= iBottom )	bSeled = TRUE;

	if( 0 > iTop )		iTop = 0;
	if( 0 > iBottom )	iBottom = iLines - 1;

	//	そのままだと容量が狂う・一旦選択状態を解除して計算しなおす
	if( bSeled ){	DocPageSelStateToggle( -1 );	}

	//	壱行ずつ面倒見ていく
	itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin();
	std::advance( itLine, iTop );	//	位置合わせ

//なんか時々連続空白ができる

	dFirst = TRUE;
	//	順番に処理していく
	for( iLin = iTop; iBottom >= iLin; iLin++, itLine++ )
	{
		iDot = itLine->iDotCnt;
		if( iBaseDot >=  iDot ){	continue;	}
		//	操作位置に満たないのなら、何もする必要は無い

		//	操作開始
		iDot = iBaseDot;	//	調整位置確定
		iMzCnt = DocLetterPosGetAdjust( &iDot, iLin, -1 );	//	常に左側をみる
		//	操作する位置の文字確認

		//	該当位置が空白なら、伸び縮み兼用
		iBufDot = iDot;	//	値ズレるのでそのまま使うとイケない
		dRslt = DocSpaceDifference( vk, &iBufDot, iLin, dFirst );	//	iBufDotはズラしたら使えない
		if( dRslt  )	//	ズラし成功
		{
			if( iLin == dLine ){	iFnlDot =  iBaseDot;	}	//	ずらした後の位置の面倒見る
			dFirst = FALSE;
		}
		else	//	返り値0なら、文字なので処理を
		{
			vcLtrItr = itLine->vcLine.begin( );
			std::advance( vcLtrItr, iMzCnt );	//	注目位置の文字まで移動して
			ch  = vcLtrItr->cchMozi;
			wid = vcLtrItr->rdWidth;	//	該当の文字の幅を確認

			if( bRight )	//	右に動かす
			{
				if( iswspace( ch ) )	//	右側の文字は空白であったら
				{
					iBufDot = iDot + wid;	//	その空白を延ばす
					DocSpaceDifference( vk, &iBufDot, iLin, dFirst );	//	iBufDotは使えない
					if( iLin == dLine ){	iFnlDot =  iBaseDot;	}	//	ずらした後の位置の面倒見る
				}
				else
				{
					SqnAppendLetter( pstUndoBuff, DO_INSERT, chOneSp, iDot, iLin, dFirst );
					DocInputLetter( iDot, iLin, chOneSp );	//	その場所に1dotスペース足せばおk
					if( iLin == dLine ){	iFnlDot = iDot +  1;	}	//	ずらした後の位置の面倒見る
				}
				dFirst = FALSE;
			}
			else	//	左に動かす
			{
				if( iLin == dLine ){	iFnlDot =  iDot;	}	//	ずらす前の位置の面倒見る

				//	今の文字を削除
				SqnAppendLetter( pstUndoBuff, DO_DELETE, ch, iDot, iLin, dFirst );	dFirst = FALSE;
				DocIterateDelete( vcLtrItr , iLin );
				if( 2 <= wid )	//	幅が1なら、削除だけでおk
				{
					ptRepl = DocPaddingSpaceMake( wid-1 );	//	必要な空白確保
					StringCchLength( ptRepl , STRSAFE_MAX_CCH, &cchSz );	//	文字数確認
					SqnAppendString( pstUndoBuff, DO_INSERT, ptRepl, iDot, iLin, dFirst );	dFirst = FALSE;
					DocStringAdd( &iDot, &iLin, ptRepl, cchSz );	//	そして先頭に空白をアッー!
					FREE(ptRepl);	//	開放忘れないように
				}
			}
		}

		if( bSeled )	//	選択状態でヤッてたのなら、選択状態を維持する
		{
			if( iLin == iTop )
			{
				iDot = iBaseDot;
				DocLetterPosGetAdjust( &iDot, iLin, 0 );	//	キャレット位置適当に調整
				DocRangeSelStateToggle( iDot, -1, iLin , 1 );	//	該当行全体を選択状態にする
			}
			else
			{
				DocRangeSelStateToggle( -1, -1, iLin , 1 );	//	該当行全体を選択状態にする
			}

			//	次の行があるなら改行も選択で
			if( iBottom > iLin )	DocReturnSelStateToggle( iLin, 1 );
		}

		DocBadSpaceCheck( iLin );	//	状態をリセット
		ViewRedrawSetLine( iLin );
	}

	if( bSeled )	//	選択範囲はり直し
	{
		(*gitFileIt).vcCont.at( gixFocusPage ).dSelLineTop    = iTop;
		(*gitFileIt).vcCont.at( gixFocusPage ).dSelLineBottom = iBottom;
	}

	//	キャレット位置調整
	DocLetterPosGetAdjust( &iFnlDot, dLine, 0 );	//	キャレット位置適当に調整
	*pXdot = iFnlDot;	//	位置を戻す
	ViewDrawCaret( iFnlDot, dLine, 1 );
	//	再描画
	DocPageByteCount( gitFileIt, gixFocusPage, NULL, NULL );
	DocPageInfoRenew( -1, 1 );

	return S_OK;
}
Exemplo n.º 25
0
int advance(Dictionary dict) {
   /* this reads the next token from the input into token */
    wint_t c;
	int i, quote_mode;

    dict->is_special = FALSE;

    if (dict->already_got_it != L'\0') {
		dict->is_special = (wcschr(SPECIAL, dict->already_got_it) != NULL);
		
		if (dict->already_got_it == WEOF) {
			dict->token[0] = L'\0';
		} else {
			dict->token[0] = dict->already_got_it;
			dict->token[1] = L'\0';
		}
		
		dict->already_got_it = L'\0';
		return 1;
    }

    do c=get_character(dict, FALSE); while (iswspace(c));

    quote_mode = FALSE;

    i = 0;
    for (;;) {
	if (i > MAX_TOKEN_LENGTH-1) {
	    dict_error(dict, L"Token too long");
	    return 0;
	}
	if (quote_mode) {
	    if (c == L'\"') {
		quote_mode = FALSE;
		dict->token[i] = L'\0';
		return 1;
	    }
	    if (iswspace(c)) {
		dict_error(dict, L"White space inside of token");
		return 0;
	    }	     
	    dict->token[i] = c;
	    i++;
	} else {
	    if (wcschr(SPECIAL, c) != NULL) {
		if (i==0) {
		    dict->token[0] = c;
		    dict->token[1] = L'\0';
		    dict->is_special = TRUE;
		    return 1;
		}
		dict->token[i] = L'\0';
		dict->already_got_it = c;
		return 1;
	    }
	    if (c==WEOF) {
		if (i==0) {
		    dict->token[0] = L'\0';
		    return 1;
		}
		dict->token[i] = L'\0';
		dict->already_got_it = c;
		return 1;
	    }
	    if (iswspace(c)) {
		dict->token[i] = L'\0';
		return 1;
	    }
	    if (c == L'\"') {
		quote_mode = TRUE;
	    } else {
		dict->token[i] = c;
		i++;
	    }
	}
	c = get_character(dict, quote_mode);
    }
    return 1;
}
Exemplo n.º 26
0
/*!
	指定ドット位置が含まれている、スペースか非スペースの文字の始点終点ドット数確保
	@param[in]	dDot	指定ドット・これの左の文字で判断
	@param[in]	rdLine	行数
	@param[out]	pLeft	始点ドット・行頭かも
	@param[out]	pRight	終点ドット・行末かも
	@param[out]	pStCnt	開始地点の文字数・NULLでも可
	@param[out]	pCount	間の文字数・NULLでも可
	@param[out]	pIsSp	該当はスペースであるか?
	@return		該当範囲のドット数
*/
INT DocLineStateCheckWithDot( INT dDot, INT rdLine, PINT pLeft, PINT pRight, PINT pStCnt, PINT pCount, PBOOLEAN pIsSp )
{
	UINT_PTR	iCount;
	INT		bgnDot, endDot;
	INT		iBgnCnt, iRngCnt;
	TCHAR	ch, chb;
	UINT	dMozis;
	INT		bSpace;
	LETR_ITR	itMozi, itHead, itTail, itTemp;

	LINE_ITR	itLine;

	itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin();
	std::advance( itLine, rdLine );

	if( !(pLeft) || !(pRight) || !(pIsSp) ){	return 0;	}

	itMozi = itLine->vcLine.begin( );
	iCount = itLine->vcLine.size( );	//	この行の文字数確認

	//	中身が無いならエラー
	if( 0 >= iCount ){	*pIsSp =  FALSE;	*pLeft =  0;	*pRight = 0;	return 0;	}

	dMozis = DocLetterPosGetAdjust( &dDot , rdLine, 0 );	//	今の文字位置を確認

	if( 1 <= dMozis ){	itMozi += (dMozis-1);	}	//	キャレットの位置の左文字で判定
	//	最初から先頭ならなにもしなくておk
	ch = itMozi->cchMozi;
	bSpace = iswspace( ch );


	//	その場所から頭方向に辿って、途切れ目を探す
	itHead = itLine->vcLine.begin( );

	for( ; itHead != itMozi; itMozi-- )
	{
		chb = itMozi->cchMozi;
		if( iswspace( chb ) != bSpace ){	itMozi++;	break;	}
	}
	//	先頭までイッちゃった場合・これが抜けてた
	if( itHead == itMozi )
	{
		chb = itMozi->cchMozi;
		if( iswspace( chb ) != bSpace ){	itMozi++;	}
	}
	//	基準と異なる文字にヒットしたか、先頭位置である

	//	先頭から、ヒット位置まで辿ってドット数と文字数確認
	bgnDot = 0;
	iBgnCnt = 0;
	for( itTemp = itHead; itTemp != itMozi; itTemp++ )
	{
		bgnDot += itTemp->rdWidth;	//	文字幅増やして
		iBgnCnt++;	//	文字数も増やす
	}//もし最初から先頭なら両方0のまま

	itTail = itLine->vcLine.end( );

	//	その場所から、同じグループの所まで確認
	endDot = bgnDot;
	iRngCnt = 0;
	for( ; itTemp != itTail; itTemp++ )
	{
		chb = itTemp->cchMozi;	//	同じタイプである間加算続ける
		if( iswspace( chb ) != bSpace ){	break;	}

		endDot += itTemp->rdWidth;
		iRngCnt++;
	}

	*pLeft  = bgnDot;
	*pRight = endDot;
	*pIsSp  = bSpace ? TRUE : FALSE;

	if( pCount )	*pCount = iRngCnt;
	if( pStCnt )	*pStCnt = iBgnCnt;

	return (endDot - bgnDot);
}
Exemplo n.º 27
0
static int
cnt(const char *file)
{
	struct stat sb;
	uintmax_t linect, wordct, charct, llct, tmpll;
	int fd, len, warned;
	size_t clen;
	short gotsp;
	u_char *p;
	u_char buf[MAXBSIZE];
	wchar_t wch;
	mbstate_t mbs;

	linect = wordct = charct = llct = tmpll = 0;
	if (file == NULL) {
		fd = STDIN_FILENO;
	} else {
		if ((fd = open(file, O_RDONLY)) < 0) {
			warn("%s: open", file);
			return (1);
		}
		if (doword || (domulti && MB_CUR_MAX != 1))
			goto word;
		/*
		 * Line counting is split out because it's a lot faster to get
		 * lines than to get words, since the word count requires some
		 * logic.
		 */
		if (doline) {
			while ((len = read(fd, buf, MAXBSIZE))) {
				if (len == -1) {
					warn("%s: read", file);
					close(fd);
					return (1);
				}
				if (siginfo) {
					show_cnt(file, linect, wordct, charct,
					    llct);
				}
				charct += len;
				for (p = buf; len--; ++p) {
					if (*p == '\n') {
						if (tmpll > llct)
							llct = tmpll;
						tmpll = 0;
						++linect;
					} else
						tmpll++;
				}
			}
			reset_siginfo();
			tlinect += linect;
			if (dochar)
				tcharct += charct;
			if (dolongline) {
				if (llct > tlongline)
					tlongline = llct;
			}
			show_cnt(file, linect, wordct, charct, llct);
			close(fd);
			return (0);
		}
		/*
		 * If all we need is the number of characters and it's a
		 * regular file, just stat the puppy.
		 */
		if (dochar || domulti) {
			if (fstat(fd, &sb)) {
				warn("%s: fstat", file);
				close(fd);
				return (1);
			}
			if (S_ISREG(sb.st_mode)) {
				reset_siginfo();
				charct = sb.st_size;
				show_cnt(file, linect, wordct, charct, llct);
				tcharct += charct;
				close(fd);
				return (0);
			}
		}
	}

	/* Do it the hard way... */
word:	gotsp = 1;
	warned = 0;
	memset(&mbs, 0, sizeof(mbs));
	while ((len = read(fd, buf, MAXBSIZE)) != 0) {
		if (len == -1) {
			warn("%s: read", file != NULL ? file : "stdin");
			close(fd);
			return (1);
		}
		p = buf;
		while (len > 0) {
			if (siginfo)
				show_cnt(file, linect, wordct, charct, llct);
			if (!domulti || MB_CUR_MAX == 1) {
				clen = 1;
				wch = (unsigned char)*p;
			} else if ((clen = mbrtowc(&wch, p, len, &mbs)) ==
			    (size_t)-1) {
				if (!warned) {
					errno = EILSEQ;
					warn("%s",
					    file != NULL ? file : "stdin");
					warned = 1;
				}
				memset(&mbs, 0, sizeof(mbs));
				clen = 1;
				wch = (unsigned char)*p;
			} else if (clen == (size_t)-2)
				break;
			else if (clen == 0)
				clen = 1;
			charct++;
			if (wch != L'\n')
				tmpll++;
			len -= clen;
			p += clen;
			if (wch == L'\n') {
				if (tmpll > llct)
					llct = tmpll;
				tmpll = 0;
				++linect;
			}
			if (iswspace(wch))
				gotsp = 1;
			else if (gotsp) {
				gotsp = 0;
				++wordct;
			}
		}
	}
	reset_siginfo();
	if (domulti && MB_CUR_MAX > 1)
		if (mbrtowc(NULL, NULL, 0, &mbs) == (size_t)-1 && !warned)
			warn("%s", file != NULL ? file : "stdin");
	if (doline)
		tlinect += linect;
	if (doword)
		twordct += wordct;
	if (dochar || domulti)
		tcharct += charct;
	if (dolongline) {
		if (llct > tlongline)
			tlongline = llct;
	}
	show_cnt(file, linect, wordct, charct, llct);
	close(fd);
	return (0);
}
Exemplo n.º 28
0
char*
fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags)
{
	register unsigned char*	s = (unsigned char*)as;
	register unsigned char*	e = s + n;
	register char*		b;
	register int		c;
	register int		m;
	register int		escaped;
	register int		spaced;
	register int		doublequote;
	register int		singlequote;
	int			shell;
	char*			f;
	char*			buf;

	c = 4 * (n + 1);
	if (qb)
		c += strlen((char*)qb);
	if (qe)
		c += strlen((char*)qe);
	b = buf = fmtbuf(c);
	shell = 0;
	doublequote = 0;
	singlequote = 0;
	if (qb)
	{
		if (qb[0] == '$' && qb[1] == '\'' && qb[2] == 0)
			shell = 1;
		else if ((flags & FMT_SHELL) && qb[1] == 0)
		{
			if (qb[0] == '"')
				doublequote = 1;
			else if (qb[0] == '\'')
				singlequote = 1;
		}
		while (*b = *qb++)
			b++;
	}
	else if (flags & FMT_SHELL)
		doublequote = 1;
	f = b;
	escaped = spaced = !!(flags & FMT_ALWAYS);
	while (s < e)
	{
		if ((m = mbsize(s)) > 1 && (s + m) <= e)
		{
#if _hdr_wchar && _hdr_wctype
			c = mbchar(s);
			if (!spaced && !escaped && (iswspace(c) || iswcntrl(c)))
				spaced = 1;
			s -= m;
#endif
			while (m--)
				*b++ = *s++;
		}
		else
		{
			c = *s++;
			if (!(flags & FMT_ESCAPED) && (iscntrl(c) || !isprint(c) || c == '\\'))
			{
				escaped = 1;
				*b++ = '\\';
				switch (c)
				{
				case CC_bel:
					c = 'a';
					break;
				case '\b':
					c = 'b';
					break;
				case '\f':
					c = 'f';
					break;
				case '\n':
					c = 'n';
					break;
				case '\r':
					c = 'r';
					break;
				case '\t':
					c = 't';
					break;
				case CC_vt:
					c = 'v';
					break;
				case CC_esc:
					c = 'E';
					break;
				case '\\':
					break;
				default:
					if (!(flags & FMT_WIDE) || !(c & 0200))
					{
						*b++ = '0' + ((c >> 6) & 07);
						*b++ = '0' + ((c >> 3) & 07);
						c = '0' + (c & 07);
					}
					else
						b--;
					break;
				}
			}
Exemplo n.º 29
0
//---------------------------------------------------------------------------
UnicodeString WrapText(const UnicodeString & Line, intptr_t MaxWidth)
{
  UnicodeString Result;

  intptr_t LenBuffer = 0;
  intptr_t SpaceLeft = MaxWidth;

  if (MaxWidth == 0)
  {
    MaxWidth = 78;
  }
  if (MaxWidth < 5)
  {
    MaxWidth = 5;
  }

  /* two passes through the input. the first pass updates the buffer length.
   * the second pass creates and populates the buffer
   */
  while (Result.Length() == 0)
  {
    intptr_t LineCount = 0;

    if (LenBuffer)
    {
      /* second pass, so create the wrapped buffer */
      Result.SetLength(LenBuffer + 1);
      if (Result.Length() == 0)
      {
        break;
      }
    }
    wchar_t * w = const_cast<wchar_t *>(Result.c_str());

    /* for each Word in Text
         if Width(Word) > SpaceLeft
           insert line break before Word in Text
           SpaceLeft := LineWidth - Width(Word)
         else
           SpaceLeft := SpaceLeft - Width(Word) + SpaceWidth
    */
    const wchar_t * s = NextWord(Line.c_str());
    while (*s)
    {
      SpaceLeft = MaxWidth;

      /* force the first word to always be completely copied */
      while (*s)
      {
        if (Result.Length() == 0)
        {
          ++LenBuffer;
        }
        else
        {
          *(w++) = *s;
        }
        --SpaceLeft;
        ++s;
      }
      if (!*s)
      {
        s = NextWord(nullptr);
      }

      /* copy as many words as will fit onto the current line */
      while (*s && static_cast<intptr_t>(wcslen(s) + 1) <= SpaceLeft)
      {
        if (Result.Length() == 0)
        {
          ++LenBuffer;
        }
        --SpaceLeft;

        /* then copy the word */
        while (*s)
        {
          if (Result.Length() == 0)
          {
            ++LenBuffer;
          }
          else
          {
            *(w++) = *s;
          }
          --SpaceLeft;
          ++s;
        }
        if (!*s)
        {
          s = NextWord(nullptr);
        }
      }
      if (!*s)
      {
        s = NextWord(nullptr);
      }

      if (*s)
      {
        /* add a new line here */
        if (Result.Length() == 0)
        {
          ++LenBuffer;
        }
        else
        {
          *(w++) = L'\n';
        }
        // Skip whitespace before first word on new line
        while (iswspace(*s))
        {
          ++s;
        }
      }

      ++LineCount;
    }

    LenBuffer += 2;

    if (w)
    {
      *w = 0;
    }
  }

  return Result;
}
Exemplo n.º 30
0
Arquivo: iwatch.c Projeto: iij/iwatch
int
display(BUFFER * cur, BUFFER * prev, reverse_mode_t reverse)
{
	int	 i, val, screen_x, screen_y, cw, line, rl;
	char	*ct;

	erase();

	move(0, 0);
	if ((int)strlen(cmdstr) > COLS - 47)
		printw("\"%-.*s..\" ", COLS - 49, cmdstr);
	else
		printw("\"%s\" ", cmdstr);
	if (pause_status)
		printw("--PAUSE--");
	else if (opt_interval.tv_sec == 1 && opt_interval.tv_usec == 0)
		printw("on every second");
	else if (opt_interval.tv_usec == 0)
		printw("on every %d seconds", (int)opt_interval.tv_sec);
	else {
		for (i = NUM_FRAQ_DIGITS_USEC, val = opt_interval.tv_usec;
		    val % 10 == 0; val /= 10)
			i--;
		printw("on every %d.%0*d seconds",
		    (int)opt_interval.tv_sec, i, val);
	}

	ct = ctime(&lastupdate);
	ct[24] = '\0';
	move(0, COLS - strlen(ct));
	addstr(ct);

#define MODELINE(HOTKEY,SWITCH,MODE)				\
	do {							\
		printw(HOTKEY);					\
		if (reverse == SWITCH) attron(style);		\
		printw(MODE);					\
		if (reverse == SWITCH) attrset(A_NORMAL);	\
	} while (0/* CONSTCOND */)

	move(1, COLS - 47);
	printw("Reverse mode:");
	MODELINE(" [w]", REVERSE_WORD, "word");
	MODELINE(" [e]", REVERSE_LINE, "line");
	MODELINE(" [r]", REVERSE_CHAR, "char");
	printw(" [t]toggle");

	move(1, 1);
	if (prefix >= 0) {
		if (decimal_point > 0) {
			int power10;

			for (i = 0, power10 = 1; i < decimal_point; i++)
				power10 *= 10;

			printw("%d.%0*d", prefix / power10, decimal_point,
			    prefix % power10);
		} else if (decimal_point == 0)
			printw("%d. ", prefix);
		else
			printw("%d ", prefix);
	}

	if (start_line != 0 || start_column != 0)
		printw("(%d, %d)", start_line, start_column);

	if (!prev || (cur == prev))
		reverse = REVERSE_NONE;

	for (line = start_line, screen_y = 2;
	    screen_y < LINES && line < MAXLINE && (*cur)[line][0];
	    line++, screen_y++) {
		wchar_t	*cur_line, *prev_line, *p, *pp;

		rl = 0;	/* reversing line */
		cur_line = (*cur)[line];
		prev_line = (*prev)[line];

		for (p = cur_line, cw = 0; cw < start_column; p++)
			cw += WCWIDTH(*p);
		screen_x = cw - start_column;
		for (pp = prev_line, cw = 0; cw < start_column; pp++)
			cw += WCWIDTH(*pp);

		switch (reverse) {
		case REVERSE_LINE:
			if (wcscmp(cur_line, prev_line)) {
				attron(style);
				rl = 1;
				for (i = 0; i < screen_x; i++) {
					move(screen_y, i);
					addch(' ');
				}
			}
			/* FALLTHROUGH */

		case REVERSE_NONE:
			move(screen_y, screen_x);
			while (screen_x < COLS) {
				if (*p && *p != L'\n') {
					cw = wcwidth(*p);
					if (screen_x + cw >= COLS)
						break;
					addwch(*p++);
					pp++;
					screen_x += cw;
				} else if (rl) {
					addch(' ');
					screen_x++;
				} else
					break;
			}
			attrset(A_NORMAL);
			break;

		case REVERSE_WORD:
		case REVERSE_CHAR:
			move(screen_y, screen_x);
			while (*p && screen_x < COLS) {
				cw = wcwidth(*p);
				if (screen_x + cw >= COLS)
					break;
				if (*p == *pp) {
					addwch(*p++);
					pp++;
					screen_x += cw;
					continue;
				}
				/*
				 * This method to reverse by word unit is not
				 * very fancy but it was easy to implement.  If
				 * you are urged to rewrite this algorithm, it
				 * is right thing and don't hesitate to do so!
				 */
				/*
				 * If the word reverse option is specified and
				 * the current character is not a space, track
				 * back to the beginning of the word.
				 */
				if (reverse == REVERSE_WORD && !iswspace(*p)) {
					while (cur_line + start_column < p &&
					    !iswspace(*(p - 1))) {
						p--;
						pp--;
						screen_x -= wcwidth(*p);
					}
					move(screen_y, screen_x);
				}
				attron(style);

				/* Print character itself.  */
				cw = wcwidth(*p);
				addwch(*p++);
				pp++;
				screen_x += cw;

				/*
				 * If the word reverse option is specified, and
				 * the current character is not a space, print
				 * the whole word which includes current
				 * character.
				 */
				if (reverse == REVERSE_WORD) {
					while (*p && !iswspace(*p) &&
					    screen_x < COLS) {
						cw = wcwidth(*p);
						addwch(*p++);
						pp++;
						screen_x += cw;
					}
				}
				attrset(A_NORMAL);
			}
			break;
		}
	}
	move(1, 0);
	refresh();
	return (1);
}