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

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

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

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #15 : 06 Февраль 2016, 11:36:32 »
Ну, с комментариями и вообще встречающимися не на месте словами можно примерно так:
Код
else if ((tpoint=strstr(str,"Exec"))!=0 && tpoint==str ) strncpy(execstr, strchr(tpoint, '=')+1, sizeof(execstr)-1);
То есть добавилось дополнительное условие, если указатели tpoint и str равны - значит ключевое слово начинается прямо с начала
строки.  А не с начала - ничего отсюда не берем, это либо под комментарием либо что-то вообще другое.
Споткнуться может, если встретит какой-нибудь Execute с начала строки, но вроде бы такого не встречалось.  Можно попробовать
"Exec=" искать.

С последним значением можно так.
Сначала, там где в строки нули вписываются, добавим еще ноль в начало:
Код
namestr[64]=iconstr[64]=execstr[64]=0; /* чтоб в любом случае в конце был, даже если строка длиннее окажется */
namestr[0]=0; /* а здесь и в начале тоже - будем проверять на пустое значение */
А поиск "Name" обставим дополнительными условиями:
Код
else if ((tpoint=strstr(str,"Name"))!=0 && tpoint==str && ( namestr[0]==0 || strncmp(tpoint+5, "[ru]", 4)==0 )) 
strncpy(namestr, strchr(tpoint, '=')+1, sizeof(namestr)-1); /* найденную строку сохранили */
То есть из строчки с "Name" строку сохраняем либо если в namestr еще вообще ничего нет, либо если сразу за "Name" идет "[ru]"
Тут может споткнуться, если Name[ru] нет вообще, а первым идет какой-нибудь Name[jp].  Не знаю, встречается ли такое.

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 7650
  • Репутация: +174/-2
  • Старый чайник
Построитель меню JWM
« Ответ #16 : 06 Февраль 2016, 15:40:28 »
namestr[0]=0; не катит, запоминает самое первое имя, в данном случае Alsamixer, и лепит его ко всем подряд.
Моноблок Lenovo IdeaCentre c200 (Intel Atom D525, Intel GMA 3150) Richy64
Netbook Acer 722 c6ckk (AMD C-50 Ontario, Radeon HD 6250) Simply p8
Nettop Asus Eee Box PC EB1007 (Intel Atom D425, Intel GMA 3150) Richy32

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #17 : 06 Февраль 2016, 17:18:09 »
А, ну да, надо его перед чтением каждого файла сбрасывать:
Код
namestr[0]=0;
while (fgets(str,sizeof(str),fp)!=0) {
...
« Последнее редактирование: 06 Февраль 2016, 17:36:33 от ander »

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 7650
  • Репутация: +174/-2
  • Старый чайник
Построитель меню JWM
« Ответ #18 : 06 Февраль 2016, 18:04:24 »
 Вот этот вариант почему-то стал работать корректно и даже по русски
Код
while (fgets(str,sizeof(str),fp)!=0) {
if ((lf=strchr(str, '\n'))!=0 ) *lf=0;
if ((tpoint=strstr(str,"Name"))!=0) strncpy(namestr,strchr(tpoint,'=')+1,sizeof(namestr)-1);
else if ((tpoint=strstr(str,"Icon"))!=0) strncpy(iconstr,strchr(tpoint,'=')+1,sizeof(iconstr)-1);
else if ((tpoint=strstr(str,"Exec"))!=0) strncpy(execstr,strchr(tpoint,'=')+1,sizeof(execstr)-1);
else if (strstr(str,argv[1])!=0) printf("\t<Program label=\"%s\" icon=\"%s\">%s</Program>\n",namestr,iconstr,execstr);
}
но остаётся ощущение какого-то скрытого подвоха.
Моноблок Lenovo IdeaCentre c200 (Intel Atom D525, Intel GMA 3150) Richy64
Netbook Acer 722 c6ckk (AMD C-50 Ontario, Radeon HD 6250) Simply p8
Nettop Asus Eee Box PC EB1007 (Intel Atom D425, Intel GMA 3150) Richy32

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #19 : 06 Февраль 2016, 21:56:07 »
Все зависит от *.desktop файлов.  Если строка категорий идет после Name Icon и Exec, если нет закомментированых некорректных ключевых слов, если ключевые слова не встретятся где-то в составе слова, то это отработает нормально.  Если Name[ru] будет последним Name, то даже по русски.  Попадется файл этим условиям не удовлетворяющий - пойдет лажа.

Мой вариант не смотрели?  Он хоть к комментариям и изменению порядка строк должен быть устойчив.  И к турецким Name, которые, если встретятся, будут после русских.

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 7650
  • Репутация: +174/-2
  • Старый чайник
Построитель меню JWM
« Ответ #20 : 07 Февраль 2016, 09:34:45 »
Все зависит от *.desktop файлов.  Если строка категорий идет после Name Icon и Exec, если нет закомментированых некорректных ключевых слов, если ключевые слова не встретятся где-то в составе слова, то это отработает нормально.  Если Name[ru] будет последним Name, то даже по русски.  Попадется файл этим условиям не удовлетворяющий - пойдет лажа.
Да, я это уже сам понял.
Мой вариант не смотрели?  Он хоть к комментариям и изменению порядка строк должен быть устойчив.  И к турецким Name, которые, если встретятся, будут после русских.
Да, посмотрел и проверил в реальной работе. В отличие от моего варианта, работает без ошибок. Пора выкладывать на github, если вы не против.
Моноблок Lenovo IdeaCentre c200 (Intel Atom D525, Intel GMA 3150) Richy64
Netbook Acer 722 c6ckk (AMD C-50 Ontario, Radeon HD 6250) Simply p8
Nettop Asus Eee Box PC EB1007 (Intel Atom D425, Intel GMA 3150) Richy32

Оффлайн sfs

  • Администратор
  • Ветеран
  • *****
  • Сообщений: 28881
  • Репутация: +195/-0
    • PuppyRus-A
Построитель меню JWM
« Ответ #21 : 07 Февраль 2016, 09:43:37 »
Код
char *appdir="/usr/share/applications/";
хорошо бы /usr/local/share/applications/ добавить и еще из /home/live/.local/share/applications/
« Последнее редактирование: 07 Февраль 2016, 09:56:49 от sfs »

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 7650
  • Репутация: +174/-2
  • Старый чайник
Построитель меню JWM
« Ответ #22 : 07 Февраль 2016, 10:31:26 »
хорошо бы /usr/local/share/applications/ добавить и еще из /home/live/.local/share/applications/
Хорошо бы, чтоб их вообще не было, ибо незачем плодить сущности. Теоретически это сделать можно, но это увеличит время развёртывания меню, а оно нам надо? Проще все *.desktop загнать в одну "резервацию".
Моноблок Lenovo IdeaCentre c200 (Intel Atom D525, Intel GMA 3150) Richy64
Netbook Acer 722 c6ckk (AMD C-50 Ontario, Radeon HD 6250) Simply p8
Nettop Asus Eee Box PC EB1007 (Intel Atom D425, Intel GMA 3150) Richy32

Оффлайн sfs

  • Администратор
  • Ветеран
  • *****
  • Сообщений: 28881
  • Репутация: +195/-0
    • PuppyRus-A
Построитель меню JWM
« Ответ #23 : 07 Февраль 2016, 10:39:56 »
Хорошо бы, чтоб их вообще не было, ибо незачем плодить сущности. Теоретически это сделать можно, но это увеличит время развёртывания меню, а оно нам надо? Проще все *.desktop загнать в одну "резервацию".
Тут 2 пути:
1. сделать попроще
2. соблюсти стандарт http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #24 : 07 Февраль 2016, 12:25:42 »
А в чем конечная задача?  Не настраивал jwm, поэтому не понял толком, чего пытаетесь добиться.
Зачем все это надо генерить на C?  Если время критично, то почему нельзя все эти <jwm>...</jwm> сгенерировать заранее?  Состав *.desktop ведь не меняется постоянно, только если новый модуль подключить.
И почему программа выбирает только одну категорию?  Ведь если все же необходимо генерировать на ходу, не логичнее ли создать файлы сразу для нескольких категорий за один проход по *.desktop файлам?

Оффлайн sfs

  • Администратор
  • Ветеран
  • *****
  • Сообщений: 28881
  • Репутация: +195/-0
    • PuppyRus-A

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 7650
  • Репутация: +174/-2
  • Старый чайник
Построитель меню JWM
« Ответ #26 : 07 Февраль 2016, 13:11:07 »
А в чем конечная задача?
Научиться. Чтоб не зависеть от чужого дяди.
Моноблок Lenovo IdeaCentre c200 (Intel Atom D525, Intel GMA 3150) Richy64
Netbook Acer 722 c6ckk (AMD C-50 Ontario, Radeon HD 6250) Simply p8
Nettop Asus Eee Box PC EB1007 (Intel Atom D425, Intel GMA 3150) Richy32

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 7650
  • Репутация: +174/-2
  • Старый чайник
Построитель меню JWM
« Ответ #27 : 07 Февраль 2016, 13:56:09 »
Вот нашёл решение, как обрезать путь (basename)
Код
//взято из libbb/get_last_path_component.c, подпилено
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
const char *cp = strrchr(argv[1], '/')+1;
if (cp)
printf("%s\n",cp);
/* return cp; #В первоисточнике*/
}
Работает:
Код
bash-4.3# ./name /usr/share/applications/cups.desktop 
cups.desktop
Моноблок Lenovo IdeaCentre c200 (Intel Atom D525, Intel GMA 3150) Richy64
Netbook Acer 722 c6ckk (AMD C-50 Ontario, Radeon HD 6250) Simply p8
Nettop Asus Eee Box PC EB1007 (Intel Atom D425, Intel GMA 3150) Richy32

Оффлайн k0l0p0k

  • Ветеран
  • *****
  • Сообщений: 1412
  • Репутация: +20/-1
Построитель меню JWM
« Ответ #28 : 07 Февраль 2016, 14:00:25 »
все правильно
strrchr ищет первый справа слэш
1.нетбук  Samsung N145 (Debian+openBox+LXPanel, ddr01)
2.core2duo,4Gb,Radeon HD7850,(ubuntu+openBox+LXPanel, ddr01)

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #29 : 07 Февраль 2016, 15:15:10 »
Не все правильно.  Если слеша не найдется вовсе, то strrchr(argv[1], '/') вернет, как и положено, null (ноль, попросту говоря), а потом к нему добавится единица, условие под if всегда выполнится и выведется полная чушь - все, что лежит по адресу 1 до первого попавшегося нуля.
А return там изначально потому, что это была раньше не main(), которая int возвращать должна, а какая-то функция, возвращающая указатель.