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

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

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

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #16 : 06 Февраль 2016, 15:40:28 »
namestr[0]=0; не катит, запоминает самое первое имя, в данном случае Alsamixer, и лепит его ко всем подряд.
Моноблок 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
« Ответ #17 : 06 Февраль 2016, 17:18:09 »
А, ну да, надо его перед чтением каждого файла сбрасывать:
Код
namestr[0]=0;
while (fgets(str,sizeof(str),fp)!=0) {
...
« Последнее редактирование: 06 Февраль 2016, 17:36:33 от ander »

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-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, 2 Gb RAM) Richy64
Nettop Acer Aspire Revo R3610 (Atom N330, nVidia GeForce 9400, 3 Gb RAM) Richy64

Оффлайн ander

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

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

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-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, 2 Gb RAM) Richy64
Nettop Acer Aspire Revo R3610 (Atom N330, nVidia GeForce 9400, 3 Gb RAM) Richy64

Оффлайн sfs

  • Администратор
  • Ветеран
  • *****
  • Сообщений: 33965
  • Репутация: +231/-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

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-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, 2 Gb RAM) Richy64
Nettop Acer Aspire Revo R3610 (Atom N330, nVidia GeForce 9400, 3 Gb RAM) Richy64

Оффлайн sfs

  • Администратор
  • Ветеран
  • *****
  • Сообщений: 33965
  • Репутация: +231/-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 файлам?


Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #26 : 07 Февраль 2016, 13:11:07 »
А в чем конечная задача?
Научиться. Чтоб не зависеть от чужого дяди.
Моноблок 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

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-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, 2 Gb RAM) Richy64
Nettop Acer Aspire Revo R3610 (Atom N330, nVidia GeForce 9400, 3 Gb RAM) Richy64

Оффлайн k0l0p0k

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

Оффлайн ander

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