Сайт | Скачать | Видео | Wiki

Автор Тема: Построитель меню JWM на C  (Прочитано 29585 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #30 : 07 Февраль 2016, 15:26:22 »
Не все правильно.  Если слеша не найдется вовсе
Будет ошибка сегментации. Уже исправил
Код
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
char *cp = strrchr(argv[1], '/');
if (cp) printf("%s\n",cp+1);
else printf("%s\n",argv[1]);
}
А return там изначально потому, что это была раньше не main(), которая int возвращать должна, а какая-то функция, возвращающая указатель.
Я на это и намекнул.
Моноблок Lenovo IdeaCentre c200 (Intel Atom D525, Intel GMA 3150, 2 Gb RAM) Richy64
Nettop Acer Aspire Revo R3610 (Atom N330, nVidia GeForce 9400, 3 Gb RAM) Richy64

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #31 : 07 Февраль 2016, 15:31:18 »
А в чем конечная задача?
Научиться. Чтоб не зависеть от чужого дяди.
Я не о том.

"Программа запускается <оттуда-то> <с такими-то параметрами> должна на выходе выдавать <то-то>, информацию беря при этом из /usr/share/applications/*.desktop".  Примерно так.

sfs, конечно, дал ссылки на форумы, но чтобы что-то там понять, это надо сначала jwm изучить.

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #32 : 07 Февраль 2016, 17:41:23 »
 Запуск программы прописан в ~/.jwmrc
Код
...........
<Dynamic label="Рабочий стол" icon="x48">exec:jwm-dynmenu.bin DesktopSettings</Dynamic>
<Dynamic label="Система" icon="pc48">exec:jwm-dynmenu.bin System</Dynamic>
<Dynamic label="Настройки" icon="configuration48">exec:jwm-dynmenu.bin Settings</Dynamic>
.............
Вывод на стандартный вывод такого вида
Код
<JWM>
<Program label="Partview view partition sizes" icon="mini-hdisk.xpm">partview</Program>
<Program label="Xfdiff-cut" icon="xfdiff.png">xfdiff-cut</Program>
<Program label="gFnRename" icon="gfnrename.png">gfnrename</Program>
<Program label="Gcolor2" icon="gcolor2.png">gcolor2</Program>
<Program label="Сохранить настройки в sfs" icon="mini-ray.xpm">loginroot mksavesfs</Program>
<Program label="Менеджер буфера обмена" icon="parcellite.png">parcellite</Program>
<Program label="PTM Timer" icon="mini-clock.xpm">ptmtimer</Program>
<Program label="puppyPDF convert file to PDF" icon="mini-pdf.xpm">puppypdf</Program>
<Program label="Xdelta - менеджер различий файлов" icon="/usr/share/icons/so.xpm">xdelta_gui</Program>
<Program label="ePDFView PDF viewer" icon="epdfview24.png">epdfview</Program>
<Program label="mtPaint-snapshot screen capture" icon="mini-camera.xpm">mtpaintsnapshot.sh</Program>
</JWM>
Моноблок Lenovo IdeaCentre c200 (Intel Atom D525, Intel GMA 3150, 2 Gb RAM) Richy64
Nettop Acer Aspire Revo R3610 (Atom N330, nVidia GeForce 9400, 3 Gb RAM) Richy64

Оффлайн k0l0p0k

  • Ветеран
  • *****
  • Сообщений: 1611
  • Репутация: +27/-1
Построитель меню JWM
« Ответ #33 : 07 Февраль 2016, 19:20:20 »
я бы добавил в начало проверку наличия аргументов
if (argc<2) return 1;
без аргуметов ошибка сегментирования - нехорошо

Код
#include <stdio.h>
#include <string.h>
//аналог basename
int main(int argc, char *argv[]) {
        if (argc<2) return 1;
char *cp = strrchr(argv[1], '/');
if (cp) printf("%s\n",cp+1);
else printf("%s\n",argv[1]);
}
« Последнее редактирование: 07 Февраль 2016, 19:46:25 от k0l0p0k »
1.пень G2020,8Gb,Radeon RX460 (Debian+openBox+LXPanel)
2.нетбук  Samsung N145 (Debian+openBox+LXPanel, ddr01)

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #34 : 07 Февраль 2016, 21:02:42 »
Запуск программы прописан в ~/.jwmrc
Код
...........
<Dynamic label="Рабочий стол" icon="x48">exec:jwm-dynmenu.bin DesktopSettings</Dynamic>
Вывод на стандартный вывод такого вида
Код
<JWM>
<Program label="Partview view partition sizes" icon="mini-hdisk.xpm">partview</Program>
</JWM>

Мне не очень понятно, почему нельзя <JWM><Program label=......</JWM> записать в файл, а в <Dynamic label="Рабочий стол" icon="x48">exec:jwm-dynmenu.bin DesktopSettings</Dynamic> просто выплевывать этот файл.  Тогда скорость создания становится не такой критичной, пересоздаваться эти файлы должны только при загрузке или подключении/отключении модуля с *.desktop файлами.
И нагрузка снижается - не надо при каждом открытии подменю обращаться к файловой системе, перебирать кучу файлов.
А сгенерировать все эти временные файлы для всех категорий можно вообще за один проход по *.desktop, просто в зависимости от найденной категории отправлять вывод в соответствующий файл.

Оффлайн sfs

  • Администратор
  • Ветеран
  • *****
  • Сообщений: 33965
  • Репутация: +231/-0
    • PuppyRus-A
Построитель меню JWM
« Ответ #35 : 07 Февраль 2016, 21:21:17 »
почему нельзя <JWM><Program label=......</JWM> записать в файл, а в <Dynamic label="Рабочий стол" icon="x48">exec:jwm-dynmenu.bin DesktopSettings</Dynamic> просто выплевывать этот файл. 
Примерно так и было в jwm2.2.. Делал это fixmenus. В jwm2.3 появилась эта фишка и иллюзия избавиться от fixmenus
Думаю - если избавляться - смотреть в сторону переделки openbox-menu (работает через menu-cached) под jwm
Без кэша и демона быстро вряд ли будет

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #36 : 08 Февраль 2016, 09:34:54 »
Мне не очень понятно, почему нельзя
Можно. Я тоже думал об этом и пришёл к такому же выводу, лучше записывать в файл. Вместо <Dynamic> использовать <Include>, как это было раньше. В каталоге $HOME/.jwm/ создавать файлы категорий, тогда всё можно будет записать за один проход.
Моноблок Lenovo IdeaCentre c200 (Intel Atom D525, Intel GMA 3150, 2 Gb RAM) Richy64
Nettop Acer Aspire Revo R3610 (Atom N330, nVidia GeForce 9400, 3 Gb RAM) Richy64

Оффлайн neobht

  • Ветеран
  • *****
  • Сообщений: 1031
  • Репутация: +15/-0
Построитель меню JWM
« Ответ #37 : 08 Февраль 2016, 16:01:13 »
Если бы не интерес научиться писать на С, то я бы вам рекомендовал эти штуки писать реализацию на Python.

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #38 : 08 Февраль 2016, 17:20:03 »
Да и питон в pra, к примеру, обычно не подключен. К тому же разбор не такой уж сложный и тащить ради него немалых размеров питоновские библиотеки просто нерационально.  

Оффлайн k0l0p0k

  • Ветеран
  • *****
  • Сообщений: 1611
  • Репутация: +27/-1
Построитель меню JWM
« Ответ #39 : 08 Февраль 2016, 17:25:24 »
у меня подключен  :) .Постоянно.
проще на Питоне писать - соответственно ошибок меньше, исходники проще читаются.
готовых рецептов море.
гуи легко пишется.
один минус - лишние 5-10 Мб (очень несущественный уже сейчас)
тем не менее Си знать надо  :)
кстати модули на Си легко к питоновским программам подключаются если скорость нужна
« Последнее редактирование: 11 Февраль 2016, 09:45:29 от k0l0p0k »
1.пень G2020,8Gb,Radeon RX460 (Debian+openBox+LXPanel)
2.нетбук  Samsung N145 (Debian+openBox+LXPanel, ddr01)

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #40 : 11 Февраль 2016, 09:17:19 »
 Очередная корявая попытка: jwm-incmenu. Должен быть каталог ~/.jwm. Запускается командой jwm-incmenu, аналогично с fixmenus. Работает мгновенно.
Моноблок Lenovo IdeaCentre c200 (Intel Atom D525, Intel GMA 3150, 2 Gb RAM) Richy64
Nettop Acer Aspire Revo R3610 (Atom N330, nVidia GeForce 9400, 3 Gb RAM) Richy64

Оффлайн k0l0p0k

  • Ветеран
  • *****
  • Сообщений: 1611
  • Репутация: +27/-1
Построитель меню JWM
« Ответ #41 : 11 Февраль 2016, 10:16:09 »
из мелких придирок : строки 70-96( if else if)  длинные - читать тяжело  :(
если не ошибаюсь Си позволяет разбивать логические строки на сколько угодно физических.
например:
Код
else if (strstr(categorystr,"Office") || strstr(categorystr,"Document") ||\
         strstr(categorystr,"WordProcessor") || strstr(categorystr,"WebDevelopment") ||\
         strstr(categorystr,"TextEditor") || strstr(categorystr,"Dictionary"))
      categorystr="Office";
и условие сразу все видно и действие
« Последнее редактирование: 11 Февраль 2016, 10:25:21 от k0l0p0k »
1.пень G2020,8Gb,Radeon RX460 (Debian+openBox+LXPanel)
2.нетбук  Samsung N145 (Debian+openBox+LXPanel, ddr01)

Оффлайн dim-kut

  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 1021
  • Репутация: +41/-0
Построитель меню JWM
« Ответ #42 : 11 Февраль 2016, 10:18:49 »
Может есть какая-нибудь библиотека популярная для обработки строк в С ?
Обработка строк - это явно не конёк С в чистом его виде. Сам когда-то возился.
Engineering is the art of making what you want from things you can get.

Оффлайн k0l0p0k

  • Ветеран
  • *****
  • Сообщений: 1611
  • Репутация: +27/-1
Построитель меню JWM
« Ответ #43 : 11 Февраль 2016, 10:22:04 »
это точно :)
скорее всего придумано - поискать просто надо готовые рецепты
1.пень G2020,8Gb,Radeon RX460 (Debian+openBox+LXPanel)
2.нетбук  Samsung N145 (Debian+openBox+LXPanel, ddr01)

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #44 : 11 Февраль 2016, 12:40:34 »
Да тут не настолько сложный разбор, чтобы требовались какие-нибудь библиотеки типа поиска по регулярным выражениям.
Алгорим причесать и будет нормально.
Тут надо сначала продумать структуру данных, тогда страшные условия выделятся в функцию и все будет красиво.
Например, меня удивило, что вы выходные файлы открываете/закрываете многократно.  Я бы открыл их сразу все, сложил файловые указатели в массив и по индексу к ним обращался, когда понадобилось в ту или иную категорию записать.
Или можно вообще завести массив структур.  Каждая структура отвечает за свой выходной файл:
Код
	int catIndex, wordIndex;
char *keyword;
char *keywords_Desktop[5]={"Desktop", "Screensaver", "Accessibility", NULL}; //массив из 5 указателей на строки, 3 указывают, четвертый нулевой,
// 5 пофиг, дальше зануленного не пойдем.
struct outfile {
   char *filename;
   FILE *fp;
   char **keyword;  // указатель на массив строк
};                             //создали тип структуры

struct outfile outfiles[10];    // завели массив из 10 таких структур

outfiles[0].filename="/home/live/.jwm/Desktop";
outfiles[0].keyword=keywords_Desktop; // записали адрес массива строк
// ...
outfiles[7].filename=NULL;  // не весь массив использовали

for(catIndex=0; catIndex<10; catIndex++){       // по всем категориям
if( outfiles[catIndex].filename == NULL ) break;   // если пусто, категории кончились
outfiles[catIndex].fp = fopen(outfiles[catIndex].filename, "w");
} // пооткрывали сразу все файлы, потом в конце таким же циклом надо закрыть

// Тут цикл перебора *.desktop
// здесь ищем name и exec
for(catIndex=0; catIndex<10; catIndex++){
if( outfiles[catIndex].filename == NULL ) break;
for(wordIndex=0; wordIndex<5; wordIndex++){     // по всем ключевым словам категории
keyword=outfiles[catIndex].keyword[wordIndex];  // слово, которое будем в строке категорий искать
if(keyword == NULL) break;         // ключевые слова закончились, выходим из их перебора
if (strstr(categorystr, keyword)){
fprintf(outfiles[catIndex].fp, "......."); // если категория нашлась, вывели в соответствующий файл
break; // и дальше слова можно не перебирать
}
}
}


UPD.  Лучше даже будет filename отдельным полем структуры не держать, а вписать в массив слов первым словом, вся инициализация будет в одном месте.
Тогда при открытии файла делаем outfiles[catIndex].fp = fopen(outfiles[catIndex].keyword[0], "w");,
а цикл по словам начинаем не с нуля, а с единицы:for(wordIndex=1; wordIndex<5; wordIndex++)
« Последнее редактирование: 11 Февраль 2016, 12:51:31 от ander »