LINUX.ORG.RU
ФорумTalks

Где рассказать о своей библиотеке?


0

0

Вопрос: где лучше сказать о своей маленькой С библиотеке, чтобы заинтересовались, может стали пользоваться, или может пообсуждали, подсказали что, покритиковали? Речь идет о версии 0.99, предрелизный вариант, лежит на sourceforge. Возможностей две: (1) На форуме девелопмент (2) Подать в новость?

★★★

Весьма интересный PR, запостить новость о библиотеке в самый читаемый раздел форума Talks ;)

anonymous
()

ну а ссылка где?

anonymous
()

ты главное никаких ссылок и названий не давай - сначала лоровские телепаты должны отработать свой хлеб

geek ★★★
()
Ответ на: комментарий от anonymous

> весьма интересный PR, запостить новость о библиотеке в самый читаемый раздел форума Talks ;)

:) Не имел в виду, честно.

Вот библиотека, надо было сразу запостить, вы правы. Я ее выделил из другой, parse_conf, так как стал использовать в других приложениях. Это просто список, но как-бы продуманный :). Там есть подробная дока, правда на английском. Сам parse_conf пока не готов до конца - я все время переписываю куски, так как не нравиццо. О нем, в общем, позже. Я пока хотел список обсудить:

http://freshmeat.net/projects/abl/

atoku ★★★
() автор топика
Ответ на: комментарий от slav

а ещё лучше заделать это всё на красно-чёрных деревьях с поиском по хешу. хеши хранятся прямо в дефайнах. Ну, это я губы раскатал...

а если по делу: то, что в getopt.h уже не используется???

scyld
()
Ответ на: комментарий от slav

> И чем оно лучше std::list (кроме того, что написано на чистом C)?

Вообще говоря, идея была получить хороший список подо все на чистом ANSI C и чтобы был просто в заголовке, ни с чем чтобы не линковался (было надо тогда, а потом показалось интересной фичей). Да и не помню я, чтобы в std::list были функции высокого порядка типа map или filter. Впрочем, С++ не пользовал уже года три, может и не прав.

atoku ★★★
() автор топика
Ответ на: комментарий от scyld

> а ещё лучше заделать это всё на красно-чёрных деревьях с поиском по хешу. хеши хранятся прямо в дефайнах. Ну, это я губы раскатал...

Да, была мысля накатать что-то такое на M4, но вовремя одумался. Уж лучше тогда просто пользовать LISP.

> а если по делу: то, что в getopt.h уже не используется???

Вопрос вообще не понял. getopt.h довольно маленький файл, и служит вроде для парсинга опций, передаваемых программой. По крайней мере я его именно для того всегда использовал.

http://www.meer.net/~dougt/minimo_ce/nc/getopt.h

atoku ★★★
() автор топика
Ответ на: комментарий от generatorglukoff

> В новости

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

atoku ★★★
() автор топика
Ответ на: комментарий от atoku

да я читаю - parse_conf - у меня почему-то всплыли опции, вот и спросил.
сознаюсь, ступил.

а лисп тут причём? писать надо на Си. Он более гибкий, чем СИ++.
Qt, например - жуткий косяк. Говорить о том, что Qt - это круто может только человек, который на нём не программил. Ну или понатыкал в QtDesigner пару окошек, и думал, что программил.

scyld
()
Ответ на: комментарий от scyld

Зы. красно-чёрные деревья на Си уже в системе есть.

#include linux/rbtree.h

scyld
()
Ответ на: комментарий от scyld

> parse_conf - у меня почему-то всплыли опции

parse_conf - Это просто библиотека для парсинга стандартных ini файлов типа

[GROUP1]

x = 1 y =2 ...

Только будет версия с разрешением переменных, чуть боле продвинуто чем это в питоне. То есть можно ссылаться будет так:

x = 1 y = %(x)s

Или

y = $(x)

И так далее. Причем можно будет ссылаться на другие группы и не обязательно на переменные, объявленные выше. И вложенность ссылок может быть любая нерекурсивная.

atoku ★★★
() автор топика
Ответ на: комментарий от atoku

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

а ты сформулируй и напиши в новости, а там видно будет

generatorglukoff ★★
()

Довольно интересная библиотека. Сам делал когда-то давно что-то подобное для hash-table.

Теперь критика :). Просмотрел "по-диагонали" -- насторожило, что элементы списка должны быть выделены ка куче, т.е. собственный пул не получится использовать. Потому, что constructor/destructor на самом деле initializatior/finalizator.

k_andy ★★★
()
Ответ на: комментарий от k_andy

>насторожило, что элементы списка должны быть выделены ка куче, т.е. собственный пул не получится использовать. Потому, что constructor/destructor на самом деле initializatior/finalizator.

На самом деле список выделяет память сам под элементы. Вот когда в элементах есть указатели, надо самому заботиться о выделении памяти либо напрямую, либо при помощи конструктора. А вот в связи с критикой еще сразу два вопроса:

1 Где что можно посмотреть на тему выделения памяти из своего пула, эффективность этого по сравнению с кучей и тп. Коды и/или доки.

2 Как лучше назвать функции констр. и дестр.? Может и по остальным есть идеи?

atoku ★★★
() автор топика
Ответ на: комментарий от klalafuda

> 350kb архива чтобы установить файл заголовка на <31kb?

..и зачем для инсталляции статического хидера понадобились зависимости от ranlib и cc ? и зачем делать проверку на stdlib.h и string.h, если для "сборки" и установки они не требуются? это уже проблема дальнейшего пользователя..

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda


..и какой смысл задавать комментарии с расчётом под doxygen, если последний очень плохо дружит с препроцессором и не понимает куда как более простые конструкции?

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от atoku

Я бы сделал так, чтобы malloc и free вызывались внутри constructor/destructor, а с/d по-умолчанию были не NULL, а простыми обёртками над malloc/free.

Вот ещё: можно все malloc/realloc/free записать как xmalloc/xrealloc/xfree, а в начале заголовка написать что-то типа

#ifndef xmalloc

#define xmalloc(size) malloc(size)

#endif

...

k_andy ★★★
()
Ответ на: комментарий от klalafuda

>.и какой смысл задавать комментарии с расчётом под doxygen, если последний очень плохо дружит с препроцессором и не понимает куда как более простые конструкции?

Это не так. Я очень успешно подружил докси с моими прогами, надо было лишь редактировать настройки. Чуть позже я включу в доки примры. Получилось симпотично

atoku ★★★
() автор топика
Ответ на: комментарий от klalafuda

>.и зачем для инсталляции статического хидера понадобились зависимости от ranlib и cc ? и зачем делать проверку на stdlib.h и string.h, если для "сборки" и установки они не требуются? это уже проблема дальнейшего пользователя..

stdlib.h проверка идет для проверки есть ли в системе malloc, free. А прверка на string.h нужна для проверки на наличие memcpy. Размер архива великоват, но это скорее проблема автотулзов. Кроме того доки тоже занимают место и лицензии тоже :(

В целом критику понимаю, но что тут можно поделать? В конце концов никто не заставляет все ставить. Можно оставить один заголовок, а все остальное - выкмнуть.

atoku ★★★
() автор топика
Ответ на: комментарий от k_andy

>Я бы сделал так, чтобы malloc и free вызывались внутри constructor/destructor, а с/d по-умолчанию были не NULL, а простыми обёртками над malloc/free.

Ээто не подойдет, на самом деле с/д обычно не нужны. Скажем для списка целых чисел, библиотека сама позаботится о памяти. Проблема возникает исключительно когда в качестве элеметов списка вам нужны указатели или сструктуры с указателями. Мне кажется вы не очень еще поняли как работает этот список. Тут я виноват , писал длинные доки и приводил длинные примеры. Дайте простую задачку, а я приведу код для примера.

atoku ★★★
() автор топика
Ответ на: комментарий от atoku

Видимо, я не очень ясно выразился. В случае с простыми типами всё в порядке, а вот со сложными...

Я правильно понимаю, что именно для них функции с суффиксом _c? Вот в них хорошо чтобы вот это

pnew_car = malloc(sizeof(type_of_car));

делал конструктор, ему-то виднее, как и что создавать.

k_andy ★★★
()
Ответ на: комментарий от k_andy

Дно вот как конструктор будует знать сколько памяти нужно?

atoku ★★★
() автор топика
Ответ на: комментарий от k_andy

Нет, type_of_car, это как раз тот самый указатель. Под него память уже выделена без всякого конструктора.

atoku ★★★
() автор топика
Ответ на: комментарий от atoku

> Дно вот как конструктор будует знать сколько памяти нужно?

Ну это уже его проблемы.

> Нет, type_of_car, это как раз тот самый указатель. Под него память уже выделена без всякого конструктора.

Вот это и мешает хранить в этом списке, например, строки разной длины созданные strdup.

k_andy ★★★
()
Ответ на: комментарий от k_andy

>Вот это и мешает хранить в этом списке, например, строки разной длины созданные strdup.

да почему же? :0 Давайте я пример приведу. Сейчас на никиа набираю, а вот за комп сяду и приведу. Дайте для конкретики пример

atoku ★★★
() автор топика
Ответ на: комментарий от atoku

Нет, строго говоря, конечно же можно :) Только придётся выделять дополнительно память для хранения указателя. Т.е. CAR будет указывать на блок памяти размером sizeof(char*), а в нём уже указатель на строку.

На каждый элемент списка выделяется лишних sizeof(char*) байт, это очень маленький размер только фрагментирующий память.

k_andy ★★★
()
Ответ на: комментарий от k_andy

/* test6.c

   This test demonstrates usage of mapcar for printing the list
   elements and usage of constructor and destructor!

   This program creates a list of strings, add two elements "First
   String" and "Second String" to it, print the list content and then
   clean the list properly.

   This test is created to demonstrate how to allocate memory for the
   elements WITH constructor/destructor usage. This verstion uses
   strings directly in the constructor

 */

#include <stdio.h>
#include <stdlib.h>
#include <abl.h>

abl_typedef_list( char*, str_list )

void destructor( char **pstr )
{
  free( *pstr );
}

/* Constructor can allocate the memory for the element AND ALSO can
   initialize the element */
int constructor( char **pstr, void *inistr )
{
  *pstr = strdup((char*)inistr);

  if( !(*pstr) ) return ABL_ERR_ALLOC;
  return ABL_OK;
}

void sp( char** pstr )
{
  printf( "%s\n", *pstr );
}

/* We do not need to care about memory allocation. However, we need to
   specify the length of the string here when we create an element */
int main()
{
  str_list *lst = malloc( sizeof(str_list) );
  char* cc;
  size_t len;

  /* List initialization */
  str_list_init( lst );
  str_list_set_cd( lst, constructor, destructor );

  /* Set two list elements "First String" and "Second String" */
  str_list_create_head_c( lst, (void*)&"First String" );
  str_list_create_head_c( lst, (void*)&"Second String" );

  /* Print the list */
  str_list_mapcar( lst, sp );

  /* Delete all elements */
  str_list_clean( lst );

  free( lst );

  return 0;
}

atoku ★★★
() автор топика
Ответ на: комментарий от k_andy

> На каждый элемент списка выделяется лишних sizeof(char*) байт, это очень маленький размер только фрагментирующий память.

Внизу есть пример как можно сделать список. Действительно, из-за общности получаются издержки на хранение char*. Действительно, память фрагментируется. Если заботиться о нефрагментации, то теряется общность и усложняются некоторые операции, например, reverse.

Просто ABL не предназначен для супер-дюпер эффективной работы списков, занимающих больше половины оперативки. :) Ведь у каждой библиотеки есть своя область применения. Здесь я пытался сделать максимально общо и удобно, пусть иногда в ущерб эффективности и памяти.

По мне, так издержки не очень большие. Зато довольно удобно использовать список.

atoku ★★★
() автор топика
Ответ на: комментарий от k_andy

Кстати, спасибо за напоминание про strdup, я совсем о нем забыл! Теперь тесты куда как лучше выглядят чем с malloc/strlen

atoku ★★★
() автор топика
Ответ на: комментарий от atoku

Вот я и предлагаю избавится от издержек. Всё равно уже есть два набора функций, вот пусть функции без суффикса сами вызывают malloc (это для простых случаев), а с суффиксом '_c' пусть память выделяет конструктор (или просто передаётся указатель, который записывается в CAR).

k_andy ★★★
()
Ответ на: комментарий от k_andy

> а с суффиксом '_c' пусть память выделяет конструктор (или просто передаётся указатель, который записывается в CAR).

Хм, надо подумать как это сделать. Мысль вроде понятна :). То есть в функциях с суффиксом вообще не вызывать маллок для каров? Интересно. Может стоит ввести третий класс функций?

ЗЫ, Кстати, в программе две строчки лишние! len, cc не используются, просто артефакты.

atoku ★★★
() автор топика
Ответ на: комментарий от k_andy

Кстати, может без конструкторов/деструкторов код проще?

#include <stdio.h>
#include <stdlib.h>
#include <abl.h>

abl_typedef_list( char*, str_list )

int main()
{
  str_list *lst = malloc( sizeof(str_list) );
  char* cc;

  /* List initialization */
  str_list_init( lst );

  /* Set two list elements "First String" and "Second String" */
  cc = strdup("First String");
  str_list_add_head( lst, &cc );

  cc = strdup("Second String");
  str_list_add_head( lst, &cc );

  /* Print the list */
  ABL_BEGIN_LOOP( str_list, lst ) {
    printf( "%s\n", *str_list_get_point( lst ) );
  } ABL_END_LOOP( str_list, lst );

  /* Free the memory from each string */
  ABL_BEGIN_LOOP( str_list, lst ) {
    free( *str_list_get_point( lst ) );
  } ABL_END_LOOP( str_list, lst );

  /* Delete all elements */
  str_list_clean( lst );

  free( lst );

  return 0;
}

atoku ★★★
() автор топика
Ответ на: комментарий от k_andy

> Да, вот ещё что. с таким итератором не получится двойной цикл.

Двойной цикл по одному и тому же списку? А по списку списков отлично получится.

atoku ★★★
() автор топика
Ответ на: комментарий от k_andy

>> Двойной цикл по одному и тому же списку?

>Ну да, например, в целях сортировки.

Это нельзя сделать ни в каком языке: вложенный цикл "для каждого". Здесь LOOP просто замена, скажем, питоновского

for x in lst: blah,blah,blah

Как в питоне сделать вложенный цикл по одному и тому же списку без копирования этого списка? Да и надо ли?

Я лучше еще сорт напишу в нескольких вариантах.

atoku ★★★
() автор топика
Ответ на: комментарий от atoku

foreach конечно же вложенный нельзя. Но он и не нужен, ведь есть же map. 
А вот такое встречается частенько:

(defun double-loop (lst)
  (cond
    ((null lst)
       nil)
    (t
       (inner-loop (cdr lst) (car lst))))

или 

for (List::iterator outer = list.begin(); outer != list.end(); ++outer)
for (List::iterator inner = outer; inner != list.end(); ++inner)
{
   // ...
}

k_andy ★★★
()
Ответ на: комментарий от k_andy

Ага. Цикл по подсписку внутри большого цикла foreach. Тогда действительно ABL_LOOP для этого не годится совсем.

Безусловно, у меня LOOP это аналог mapcar, который просто появился совсем недавно, в принципе LOOP уже не нужен, просто может быть кому-то удобнее.

Насколько нужно часто делать такие вещи, как выше? В принципе, создать более сложные циклы не очень будет сложно. Надо лишь продумать семантику, или придумать map на часть списка... Ага! Это кажется выход.

Можно сделать операции подсписка (возвращать будет кудер от point), и map для части списка, начиная с point. Только это будет с версии 1.1

Такое решение нормально?

atoku ★★★
() автор топика
Ответ на: комментарий от k_andy

Конечно же имел в виду что-то типа.

(defun double-loop (lst) (cond ((null lst) nil) (t (cons (inner-loop (cdr lst) (car lst)) (double-loop (cdr lst))))))

k_andy ★★★
()
Ответ на: комментарий от k_andy

> Проще избавится от структуры name_of_list_type ## _s вообще, и оперировать только name_of_list_type ## _es.

Тогда (1) многое станет гораздо сложнее (2) пропадет элемент абстракции от типа элементов.

В любом случае я подумаю над всеми предложениями. Огромное спасибо за вдумчивый разбор.

atoku ★★★
() автор топика
Ответ на: комментарий от k_andy

Похоже я понял, что надо сделать, чтобы избежать проблемы с аллокацией лишней памяти, но не потерять общности. Спасибо за отличные наводки.

atoku ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.