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

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

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

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #45 : 12 Февраль 2016, 11:53:43 »
Вот, сделал скелет программы.  Она работает, только надо дописать все ключевые слова категорий по образцу, который там есть.
Пока там только Desktop и System, остальное дописывается точно так же.

Структура данных такая: заводятся два массива указателей, в одном файловые указатели на открытые выходные файлы,
а второй массив двумерный, в каждой строке содержит указатели на ключевые слова для отдельной категории, причем первым элементом в строке идет не ключевое слово, а имя выходного файла.  Размеры массива задаются константами CAT_MAX и KW_MAX,
если ключевых слов в строке меньше, последний элемент должен быть NULL, а если строк меньше CAT_MAX, первый элемент очередной строки равен NULL.  В образце это видно.  Получается аккуратная табличка.

В массивах лежат только указатели, так что даже при большой размерности много места они не займут ( длина указателя соответствует разрядности системы, 4 байта на 32-х разрядной) поэтому динамически отводить под них память смысла нет, можно константы выставить с запасом.

Выходные файлы все сразу открываются в начале и закрываются в конце, запись в соответствующий файл идет, когда в строке
Categories= очередного файла находится ключевое слово соответствующей категории.
Комментарии везде писал, так что разобраться, думаю, не сложно будет.
« Последнее редактирование: 12 Февраль 2016, 12:06:27 от ander »

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #46 : 12 Февраль 2016, 20:48:25 »
Код
# /home/C/tst
Ошибка сегментирования
# ls -l ~/.jwm/
total 0
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Calculate
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Desktop
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Filesystem
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Game
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Graphic
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Internet
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Multimedia
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Network
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Office
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Personal
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Setup
-rw-rw-r--    1 live     live             0 Feb 12 19:46 System
-rw-rw-r--    1 live     live             0 Feb 12 19:46 Utility
Создаёт пустышки
Моноблок 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
« Ответ #47 : 12 Февраль 2016, 22:04:51 »
Скелет столько не насоздавал бы.  Показывайте, как заполнили, где-то видимо NULL пропустили, иначе бы за пределы сегмента не вышло.

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #48 : 13 Февраль 2016, 09:19:53 »
Скелет столько не насоздавал бы.
 Скелет создавал два пустых файла и сегфолтился, так что ничего не изменилось.
Показывайте, как заполнили, где-то видимо NULL пропустили, иначе бы за пределы сегмента не вышло.
Код
#define CAT_MAX 15		// максимум категорий
#define KW_MAX 15 // максимум ключевых слов, включая имя файла, в категории
#define VLEN_MAX 96 // максимальная длина строки

int stringsearch(const char *buf, const char *str, char *savestr); // ищет в начале buf подстроку str, если есть, то все после '=' копирует в savestr

int main(int argc, char **argv)
{
int catIndex, wordIndex;

char *categorykw[CAT_MAX][KW_MAX] = {
{"/home/live/.jwm/Desktop", "Desktop", "Screensaver", "Accessibility", NULL},
{"/home/live/.jwm/System", "System","Monitor","Security","HardwareSettings","Core", NULL},
{"/home/live/.jwm/Setup","Setup","PackageManager", NULL},
{"/home/live/.jwm/Utility","Utility","Viewer","Development","Building","Debugger","IDE","Profiling","Translation","GUIDesigner","Archiving","TerminalEmulator","Shell", NULL},
{"/home/live/.jwm/Filesystem","File", NULL},
{"/home/live/.jwm/Graphic","Graphic","Photography","Presentation","Chart", NULL},
{"/home/live/.jwm/Office","Office","Document","WordProcessor","WebDevelopment","TextEditor","Dictionary", NULL},
{"/home/live/.jwm/Calculate","Calculat","Finance","Spreadsheet","ProjectManagement", NULL},
{"/home/live/.jwm/Personal","Personal","Calendar","ContactManagement", NULL},
{"/home/live/.jwm/Network","Network","Dialup","HamRadio","RemoteAccess", NULL},
{"/home/live/.jwm/Internet","Internet","WebBrowser","Email","News","InstantMessaging","Telephony","IRCClient","FileTransfer","P2P", NULL},
{"/home/live/.jwm/Multimedia","Video","Player","Music","Audio","Midi","Mixer","Sequencer","Tuner","TV","DiskBurning", NULL},
{"/home/live/.jwm/Game","Game","Amusement","RolePlaying","Simulation", NULL},
{ NULL }
};  // массив имен файлов категорий и ключевых слов к ним
Моноблок 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
« Ответ #49 : 13 Февраль 2016, 11:17:37 »
Хм.  А у меня работает хоть скелетом, хоть заполненной.  Сейчас посмотрю, может где не учел возможной глючности входных файлов.

UPD.  Может быть, натыкается на файлы с очень длинными строками?
Пробуем в функции stringsearch() в конце заменить
Код
strncpy(savestr, strchr(buf, '=')+1, VLEN_MAX);
на
Код
 strncpy(savestr, strchr(buf, '=')+1, VLEN_MAX-1);
 savestr[VLEN_MAX]=0;
чтобы ноль в конце гарантированно был.

И еще после fp=fopen(buf,"r"); дописать if( fp == NULL ){ printf("%s not open\n", buf); continue; }
А то возможно какой-то файл открыть не может.
« Последнее редактирование: 13 Февраль 2016, 11:48:59 от ander »

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #50 : 13 Февраль 2016, 12:40:49 »
 Не помогло.
Моноблок 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
« Ответ #51 : 13 Февраль 2016, 14:02:30 »
Ну даже не знаю...  Вот, скомпилируйте этот файлик, я там вставил вывод текущего desktop, посмотрим, на котором упадет.
У меня-то работает, собака.

Оффлайн k0l0p0k

  • Ветеран
  • *****
  • Сообщений: 1611
  • Репутация: +27/-1
Построитель меню JWM
« Ответ #52 : 13 Февраль 2016, 14:11:31 »
что если набросать какую нибудь простенькую функцию отладочную или просто printf("debug001..002..003..к примеру") и в каждый if else . или еще лучше чтоб в лог файл выводило.потом убрать их несложно будет.
1.пень G2020,8Gb,Radeon RX460 (Debian+openBox+LXPanel)
2.нетбук  Samsung N145 (Debian+openBox+LXPanel, ddr01)

Оффлайн k0l0p0k

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

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #54 : 13 Февраль 2016, 14:17:41 »
Код
# /home/C/tst
---Out files opened
---Read /usr/share/applications/Alsamixer-sound-mixer.desktop
---Read /usr/share/applications/BootManager-configure-bootup.desktop
---Read /usr/share/applications/Burniso2cd-burn-iso-file-to-CD-DVD.desktop
---Read /usr/share/applications/Desktop-drive-icons.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

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #55 : 13 Февраль 2016, 14:20:09 »
На Desktop-drive-icons.desktop стало быть, упал.
Что там в нем, приаттачить можете?

А пустышки скорее всего потому, что до корректного закрытия не дошло и буфера в файлы не сбросились.

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #56 : 13 Февраль 2016, 14:34:46 »
Код
[Desktop Entry]
Encoding=UTF-8
Name=Менеджер значков дисков
Icon=mini-hdisk.xpm
Comment=Менеджер значков дисков рабочего стола
Exec=eventmanager desktop
Terminal=false
Type=Application
Categories=X-Desktop
GenericName=eventmanager
Моноблок 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
« Ответ #57 : 13 Февраль 2016, 15:07:43 »
Не падает на таком.  Что у вас может отличаться-то еще?  :-\
после комментария //разобрали *.desktop файл вставьте строчку
fprintf(stderr, "---Read complete\nname=\"%s\", icon=\"%s\", exec=\"%s\", categories=\"%s\"\n", namestr, iconstr, execstr, categorystr);      /* debug */
Будем постепенно уточнять, на чем падает.

Еще можно попробовать функцию чуть изменить:
Код
int stringsearch(const char *buf, const char *str, char *savestr){	// ищет в начале buf подстроку str, если есть, то все после '=' копирует в savestr
char *tp;
if( strncmp( buf, str, strlen(str) ) == 0 && (tp=strchr(buf, '='))){
strncpy(savestr, tp+1, VLEN_MAX-1);
savestr[VLEN_MAX-1]=0;
return 1;
}
return 0;
}
В таком виде корректно отработает, если вдруг напорется на строчку без '='
« Последнее редактирование: 13 Февраль 2016, 15:57:24 от ander »

Оффлайн DdShurick

  • Это Риччи
  • Активный участник
  • Ветеран
  • ****
  • Сообщений: 8635
  • Репутация: +187/-2
  • Автор темы
  • Старый чайник
Построитель меню JWM
« Ответ #58 : 13 Февраль 2016, 16:39:20 »
Код
# /home/C/tst
---Out files opened
---Read /usr/share/applications/Alsamixer-sound-mixer.desktop
---Read complete
name="AlsaMixer -  аудио-микшер", icon="mini-sound.xpm", exec="xterm -e alsamixer", categories="AudioVideo;"
---Read /usr/share/applications/BootManager-configure-bootup.desktop
---Read complete
name="BootManager - настройка загрузки модулей ", icon="so.xpm", exec="bootmanager", categories="X-SystemSchedule"
---Read /usr/share/applications/Burniso2cd-burn-iso-file-to-CD-DVD.desktop
---Read complete
name="Burniso2cd - запись iso-файлов на CD", icon="mini-cd.xpm", exec="burniso2cd", categories="DiskBurning;"
---Read /usr/share/applications/Desktop-drive-icons.desktop
---Read complete
name="Менеджер значков дисков", icon="mini-hdisk.xpm", exec="eventmanager desktop", categories="X-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

Оффлайн ander

  • Активный участник
  • Старожил
  • ****
  • Сообщений: 300
  • Репутация: +16/-0
Построитель меню JWM
« Ответ #59 : 13 Февраль 2016, 19:11:03 »
Что-то сайт глючил, не давал ответ добавить.
Очередная идея.  buf имеет размер 64 байта, а может у вас длиннее имена встречаются.
Надо: проверить, что за файл идет следующим без сортировки:

ls -1U /usr/share/applications/

размер buf добавить, да и заполнять его лучше так:
Код
	buf[0]=0;                                               
strncat(buf, appdir, sizeof(buf)-1);                                    
strncat(buf,entry->d_name, sizeof(buf)-sizeof(appdir)-1);                              
fp=fopen(buf,"r");

Прикрепляю пока с отладочнми сообщениями, потом уберем.
« Последнее редактирование: 13 Февраль 2016, 19:22:38 от ander »