Exemple #1
0
/** returns the position where text was found in the start buffer 
 * or 0 if not found
 */
static const char *
search_string (const char *start, const char *text)
{
    const char *result = NULL;
    char *local_text = g_strdup (text);
    char *d = local_text;
    const char *e = start;

    /* fmt sometimes replaces a space with a newline in the help file */
    /* Replace the newlines in the link name with spaces to correct the situation */
    while (*d != '\0')
    {
        if (*d == '\n')
            *d = ' ';
        str_next_char (&d);
    }

    /* Do search */
    for (d = local_text; *e; e++)
    {
        if (*d == *e)
            d++;
        else
            d = local_text;
        if (*d == '\0')
        {
            result = e + 1;
            break;
        }
    }

    g_free (local_text);
    return result;
}
Exemple #2
0
/** Check if directory completion is needed */
static gboolean
check_is_cd (const char *text, int lc_start, input_complete_t flags)
{
    char *p, *q;

    SHOW_C_CTX ("check_is_cd");

    if ((flags & INPUT_COMPLETE_CD) == 0)
        return FALSE;

    /* Skip initial spaces */
    p = (char *) text;
    q = (char *) text + lc_start;
    while (p < q && p[0] != '\0' && str_isspace (p))
        str_next_char (&p);

    /* Check if the command is "cd" and the cursor is after it */
    return (p[0] == 'c' && p[1] == 'd' && str_isspace (p + 2) && p + 2 < q);
}
Exemple #3
0
static void
fetch_hosts (const char *filename)
{
    FILE *file = fopen (filename, "r");
    char buffer[256], *name;
    char *lc_start;
    char *bi;

    if (!file)
        return;

    while (fgets (buffer, 255, file) != NULL)
    {
        /* Skip to first character. */
        for (bi = buffer; bi[0] != '\0' && str_isspace (bi); str_next_char (&bi));

        /* Ignore comments... */
        if (bi[0] == '#')
            continue;
        /* Handle $include. */
        if (!strncmp (bi, "$include ", 9))
        {
            char *includefile = bi + 9;
            char *t;

            /* Find start of filename. */
            while (*includefile && whitespace (*includefile))
                includefile++;
            t = includefile;

            /* Find end of filename. */
            while (t[0] != '\0' && !str_isspace (t))
                str_next_char (&t);
            *t = '\0';

            fetch_hosts (includefile);
            continue;
        }

        /* Skip IP #s. */
        while (bi[0] != '\0' && !str_isspace (bi))
            str_next_char (&bi);

        /* Get the host names separated by white space. */
        while (bi[0] != '\0' && bi[0] != '#')
        {
            while (bi[0] != '\0' && str_isspace (bi))
                str_next_char (&bi);
            if (bi[0] == '#')
                continue;
            for (lc_start = bi; bi[0] != '\0' && !str_isspace (bi); str_next_char (&bi));

            if (bi - lc_start == 0)
                continue;

            name = g_strndup (lc_start, bi - lc_start);
            {
                char **host_p;

                if (hosts_p - hosts >= hosts_alloclen)
                {
                    int j;

                    j = hosts_p - hosts;
                    hosts_alloclen += 30;
                    hosts = g_renew (char *, hosts, hosts_alloclen + 1);
                    hosts_p = hosts + j;
                }
                for (host_p = hosts; host_p < hosts_p; host_p++)
                    if (!strcmp (name, *host_p))
                        break;  /* We do not want any duplicates */
                if (host_p == hosts_p)
                {
                    *(hosts_p++) = name;
                    *hosts_p = NULL;
                }
                else
                    g_free (name);
            }
        }
    }
Exemple #4
0
static int
complete_engine (WInput * in, int what_to_do)
{
    if (in->completions != NULL && str_offset_to_pos (in->buffer, in->point) != end)
        input_free_completions (in);
    if (in->completions == NULL)
    {
        char *s;

        end = str_offset_to_pos (in->buffer, in->point);

        s = in->buffer;
        if (in->point != 0)
        {
            /* get symbol before in->point */
            size_t i;
            for (i = in->point - 1; i > 0; i--)
                str_next_char (&s);
        }

        for (; s >= in->buffer; str_prev_char (&s))
        {
            start = s - in->buffer;
            if (strchr (" \t;|<>", *s) != NULL)
                break;
        }

        if (start < end)
        {
            str_next_char (&s);
            start = s - in->buffer;
        }

        in->completions = try_complete (in->buffer, &start, &end, in->completion_flags);
    }

    if (in->completions != NULL)
    {
        if (what_to_do & DO_INSERTION || ((what_to_do & DO_QUERY) && !in->completions[1]))
        {
            char *lc_complete = in->completions[0];
            if (insert_text (in, lc_complete, strlen (lc_complete)))
            {
                if (in->completions[1])
                    tty_beep ();
                else
                    input_free_completions (in);
            }
            else
                tty_beep ();
        }
        if ((what_to_do & DO_QUERY) && in->completions && in->completions[1])
        {
            int maxlen = 0, i, count = 0;
            int x, y, w, h;
            int start_x, start_y;
            char **p, *q;
            Dlg_head *query_dlg;
            WListbox *query_list;

            for (p = in->completions + 1; *p != NULL; count++, p++)
            {
                i = str_term_width1 (*p);
                if (i > maxlen)
                    maxlen = i;
            }
            start_x = in->widget.x;
            start_y = in->widget.y;
            if (start_y - 2 >= count)
            {
                y = start_y - 2 - count;
                h = 2 + count;
            }
            else
            {
                if (start_y >= LINES - start_y - 1)
                {
                    y = 0;
                    h = start_y;
                }
                else
                {
                    y = start_y + 1;
                    h = LINES - start_y - 1;
                }
            }
            x = start - in->term_first_shown - 2 + start_x;
            w = maxlen + 4;
            if (x + w > COLS)
                x = COLS - w;
            if (x < 0)
                x = 0;
            if (x + w > COLS)
                w = COLS;
            input = in;
            min_end = end;
            query_height = h;
            query_width = w;
            query_dlg = create_dlg (TRUE, y, x, query_height, query_width,
                                    dialog_colors, query_callback, NULL,
                                    "[Completion]", NULL, DLG_COMPACT);
            query_list = listbox_new (1, 1, h - 2, w - 2, FALSE, NULL);
            add_widget (query_dlg, query_list);
            for (p = in->completions + 1; *p; p++)
                listbox_add_item (query_list, LISTBOX_APPEND_AT_END, 0, *p, NULL);
            run_dlg (query_dlg);
            q = NULL;
            if (query_dlg->ret_value == B_ENTER)
            {
                listbox_get_current (query_list, &q, NULL);
                if (q)
                    insert_text (in, q, strlen (q));
            }
            if (q || end != min_end)
                input_free_completions (in);
            i = query_dlg->ret_value;   /* B_USER if user wants to start over again */
            destroy_dlg (query_dlg);
            if (i == B_USER)
                return 1;
        }
    }
    else
        tty_beep ();
    return 0;
}
Exemple #5
0
static cb_ret_t
query_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data)
{
    static char buff[MB_LEN_MAX] = "";
    static int bl = 0;

    switch (msg)
    {
    case DLG_KEY:
        switch (parm)
        {
        case KEY_LEFT:
        case KEY_RIGHT:
            bl = 0;
            h->ret_value = 0;
            dlg_stop (h);
            return MSG_HANDLED;

        case KEY_BACKSPACE:
            bl = 0;
            /* exit from completion list if input line is empty */
            if (end == 0)
            {
                h->ret_value = 0;
                dlg_stop (h);
            }
            /* Refill the list box and start again */
            else if (end == min_end)
            {
                end = str_get_prev_char (&input->buffer[end]) - input->buffer;
                input_handle_char (input, parm);
                h->ret_value = B_USER;
                dlg_stop (h);
                return MSG_HANDLED;
            }
            else
            {
                int new_end;
                int i;
                GList *e;

                new_end = str_get_prev_char (&input->buffer[end]) - input->buffer;

                for (i = 0, e = ((WListbox *) h->current->data)->list;
                     e != NULL; i++, e = g_list_next (e))
                {
                    WLEntry *le = (WLEntry *) e->data;

                    if (strncmp (input->buffer + start, le->text, new_end - start) == 0)
                    {
                        listbox_select_entry ((WListbox *) h->current->data, i);
                        end = new_end;
                        input_handle_char (input, parm);
                        send_message ((Widget *) h->current->data, WIDGET_DRAW, 0);
                        break;
                    }
                }
            }
            return MSG_HANDLED;

        default:
            if (parm < 32 || parm > 255)
            {
                bl = 0;
                if (input_key_is_in_map (input, parm) != 2)
                    return MSG_NOT_HANDLED;

                if (end == min_end)
                    return MSG_HANDLED;

                /* This means we want to refill the list box and start again */
                h->ret_value = B_USER;
                dlg_stop (h);
                return MSG_HANDLED;
            }
            else
            {
                GList *e;
                int i;
                int need_redraw = 0;
                int low = 4096;
                char *last_text = NULL;

                buff[bl++] = (char) parm;
                buff[bl] = '\0';
                switch (str_is_valid_char (buff, bl))
                {
                case -1:
                    bl = 0;
                    /* fallthrough */
                case -2:
                    return MSG_HANDLED;
                }

                for (i = 0, e = ((WListbox *) h->current->data)->list;
                     e != NULL; i++, e = g_list_next (e))
                {
                    WLEntry *le = (WLEntry *) e->data;

                    if (strncmp (input->buffer + start, le->text, end - start) == 0
                        && strncmp (&le->text[end - start], buff, bl) == 0)
                    {
                        if (need_redraw == 0)
                        {
                            need_redraw = 1;
                            listbox_select_entry ((WListbox *) h->current->data, i);
                            last_text = le->text;
                        }
                        else
                        {
                            char *si, *sl;
                            int si_num = 0;
                            int sl_num = 0;

                            /* count symbols between start and end */
                            for (si = le->text + start; si < le->text + end;
                                 str_next_char (&si), si_num++)
                                ;
                            for (sl = last_text + start; sl < last_text + end;
                                 str_next_char (&sl), sl_num++)
                                ;

                            /* pointers to next symbols */
                            si = &le->text[str_offset_to_pos (le->text, ++si_num)];
                            sl = &last_text[str_offset_to_pos (last_text, ++sl_num)];

                            while (si[0] != '\0' && sl[0] != '\0')
                            {
                                char *nexti, *nextl;

                                nexti = str_get_next_char (si);
                                nextl = str_get_next_char (sl);

                                if (nexti - si != nextl - sl || strncmp (si, sl, nexti - si) != 0)
                                    break;

                                si = nexti;
                                sl = nextl;

                                si_num++;
                            }

                            last_text = le->text;

                            si = &last_text[str_offset_to_pos (last_text, si_num)];
                            if (low > si - last_text)
                                low = si - last_text;

                            need_redraw = 2;
                        }
                    }
                }

                if (need_redraw == 2)
                {
                    insert_text (input, last_text, low);
                    send_message ((Widget *) h->current->data, WIDGET_DRAW, 0);
                }
                else if (need_redraw == 1)
                {
                    h->ret_value = B_ENTER;
                    dlg_stop (h);
                }
                bl = 0;
            }
            return MSG_HANDLED;
        }
        break;

    default:
        return default_dlg_callback (h, sender, msg, parm, data);
    }
}
Exemple #6
0
gboolean
user_menu_cmd (struct WEdit * edit_widget, const char *menu_file, int selected_entry)
{
    char *p;
    char *data, **entries;
    int max_cols, menu_lines, menu_limit;
    int col, i, accept_entry = 1;
    int selected, old_patterns;
    gboolean res = FALSE;
    gboolean interactive = TRUE;

    if (!vfs_current_is_local ())
    {
        message (D_ERROR, MSG_ERROR, "%s", _("Cannot execute commands on non-local filesystems"));
        return FALSE;
    }
    if (menu_file != NULL)
        menu = g_strdup (menu_file);
    else
        menu = g_strdup (edit_widget ? EDIT_LOCAL_MENU : MC_LOCAL_MENU);
    if (!exist_file (menu) || !menu_file_own (menu))
    {
        if (menu_file != NULL)
        {
            message (D_ERROR, MSG_ERROR, _("Cannot open file %s\n%s"), menu,
                     unix_error_string (errno));
            MC_PTR_FREE (menu);
            return FALSE;
        }

        g_free (menu);
        if (edit_widget)
            menu = mc_config_get_full_path (EDIT_HOME_MENU);
        else
            menu = mc_config_get_full_path (MC_USERMENU_FILE);


        if (!exist_file (menu))
        {
            g_free (menu);
            menu =
                mc_build_filename (mc_config_get_home_dir (),
                                   edit_widget ? EDIT_GLOBAL_MENU : MC_GLOBAL_MENU, NULL);
            if (!exist_file (menu))
            {
                g_free (menu);
                menu =
                    mc_build_filename (mc_global.sysconfig_dir,
                                       edit_widget ? EDIT_GLOBAL_MENU : MC_GLOBAL_MENU, NULL);
                if (!exist_file (menu))
                {
                    g_free (menu);
                    menu = mc_build_filename
                        (mc_global.share_data_dir, edit_widget ? EDIT_GLOBAL_MENU : MC_GLOBAL_MENU,
                         NULL);
                }
            }
        }
    }

    if (!g_file_get_contents (menu, &data, NULL, NULL))
    {
        message (D_ERROR, MSG_ERROR, _("Cannot open file%s\n%s"), menu, unix_error_string (errno));
        MC_PTR_FREE (menu);
        return FALSE;
    }

    max_cols = 0;
    selected = 0;
    menu_limit = 0;
    entries = 0;

    /* Parse the menu file */
    old_patterns = easy_patterns;
    p = check_patterns (data);
    for (menu_lines = col = 0; *p; str_next_char (&p))
    {
        if (menu_lines >= menu_limit)
        {
            char **new_entries;

            menu_limit += MAX_ENTRIES;
            new_entries = g_try_realloc (entries, sizeof (new_entries[0]) * menu_limit);

            if (new_entries == NULL)
                break;

            entries = new_entries;
            new_entries += menu_limit;
            while (--new_entries >= &entries[menu_lines])
                *new_entries = NULL;
        }
        if (col == 0 && !entries[menu_lines])
        {
            if (*p == '#')
            {
                /* show prompt if first line of external script is #interactive */
                if (selected_entry >= 0 && strncmp (p, "#silent", 7) == 0)
                    interactive = FALSE;
                /* A commented menu entry */
                accept_entry = 1;
            }
            else if (*p == '+')
            {
                if (*(p + 1) == '=')
                {
                    /* Combined adding and default */
                    p = test_line (edit_widget, p + 1, &accept_entry);
                    if (selected == 0 && accept_entry)
                        selected = menu_lines;
                }
                else
                {
                    /* A condition for adding the entry */
                    p = test_line (edit_widget, p, &accept_entry);
                }
            }
            else if (*p == '=')
            {
                if (*(p + 1) == '+')
                {
                    /* Combined adding and default */
                    p = test_line (edit_widget, p + 1, &accept_entry);
                    if (selected == 0 && accept_entry)
                        selected = menu_lines;
                }
                else
                {
                    /* A condition for making the entry default */
                    i = 1;
                    p = test_line (edit_widget, p, &i);
                    if (selected == 0 && i)
                        selected = menu_lines;
                }
            }
            else if (*p != ' ' && *p != '\t' && str_isprint (p))
            {
                /* A menu entry title line */
                if (accept_entry)
                    entries[menu_lines] = p;
                else
                    accept_entry = 1;
            }
        }
        if (*p == '\n')
        {
            if (entries[menu_lines])
            {
                menu_lines++;
                accept_entry = 1;
            }
            max_cols = max (max_cols, col);
            col = 0;
        }
        else
        {
            if (*p == '\t')
                *p = ' ';
            col++;
        }
    }

    if (menu_lines == 0)
    {
        message (D_ERROR, MSG_ERROR, _("No suitable entries found in %s"), menu);
        res = FALSE;
    }
    else
    {
        if (selected_entry >= 0)
            selected = selected_entry;
        else
        {
            Listbox *listbox;

            max_cols = min (max (max_cols, col), MAX_ENTRY_LEN);

            /* Create listbox */
            listbox = create_listbox_window (menu_lines, max_cols + 2, _("User menu"),
                                             "[Menu File Edit]");
            /* insert all the items found */
            for (i = 0; i < menu_lines; i++)
            {
                p = entries[i];
                LISTBOX_APPEND_TEXT (listbox, (unsigned char) p[0],
                                     extract_line (p, p + MAX_ENTRY_LEN), p);
            }
            /* Select the default entry */
            listbox_select_entry (listbox->list, selected);

            selected = run_listbox (listbox);
        }
        if (selected >= 0)
        {
            execute_menu_command (edit_widget, entries[selected], interactive);
            res = TRUE;
        }

        do_refresh ();
    }

    easy_patterns = old_patterns;
    MC_PTR_FREE (menu);
    g_free (entries);
    g_free (data);
    return res;
}