Commit e35a763a91cef5b3af0107d341b27ed1c8e60e86

Authored by Georg Hopp
1 parent d509dada

Initial repository layout

Too many changes to show.

To preserve performance only 57 of 57+ files are displayed.

  1 +2006-08-17 Georg Steffers [GST] <georg@steffers.org>
  2 +
  3 + * src/stream_pool.c src/posix/stream_pool.c src/win32/stream_pool.c
  4 + include/stream_pool.h include/posix/stream_pool.h
  5 + include/win32/stream_pool.h src/Makefile.am include/Makefile.am
  6 + and various others (this is a major change):
  7 + Sorry, this is in german and much to declarative...this was a
  8 + thoughts-list that is now realized completely. I will rewrite it when
  9 + i find the time.
  10 +
  11 + OK, ich fang mal wieder damit an meine Gedanken aufzunehmen.
  12 + Das Problem das ich jetzt bekomme ist, das es streams unter
  13 + windows nicht gibt...bzw. verschieden arten von streams unterschiedlich
  14 + gehandhabt werden müssen. Hinzu kommt, das WaitForMultipleObject
  15 + nur max. 64 Objekte werwalten kann. Will man mehr verwalten muß man
  16 + das in mehreren streads tun.
  17 +
  18 + Daher muß ein stream_pool, anders als andere event listener nicht
  19 + nur aus einem thread bestehen sondern aus einem pro 64 gleicher
  20 + streams und einem Kontoll-Thread. (Hmm, für viele andere event listener
  21 + gilt das gleiche, wenn ich unter Windows mehr als 64 Objekte
  22 + überwachen will. z.B. der fs_watcher. Gerade beim fs_watcher ist
  23 + es aber nun so, daß der unter Windows eh komplett anders
  24 + geschrieben werden muß.)
  25 +
  26 + Startet man einen stream_pool_listener, so wird der Kontroll Thread
  27 + gestartet, welcher seinerseits alle weiteren threads startet.
  28 +
  29 + Added man einen stream, so muß zunächst nachgesehen werden ob es
  30 + bereits einen <<stream pool>> für diesen stream_type gibt der außerdem
  31 + noch nicht 64 streams enthält, falls es so einen stream pool gibt
  32 + kann man den stream zu diesem hinzufügen, anderenfalls muß ein
  33 + neuer stream pool angelegt werden.
  34 + Nachdem der stream geadded wurde muß nur der stream pool, zu dem
  35 + der stream hinzugefügt wurde neu gestartet werden.
  36 +
  37 + Will man einen stream aus einem stream pool entfernen, so muß dieser
  38 + zunächst in allen stream pools gesucht werden, dann muß der thread
  39 + zu dem stream pool in dem sich der stream befindet gestoppt werden
  40 + woraufhin der stream entfernt werden kann. Danach muß der stream pool
  41 + thread wieder gestartet werden.
  42 +
  43 + Für UNIX brauche ich nur einen einzige thread methode für alle stream
  44 + pool typen, nämlich die, welche select nutzt.
  45 + Für Windows muß ich je nach dem welcher Art von streams ein stream pool
  46 + enthält unterschiedliche thread methoden nutzen:
  47 + - select für sockets
  48 + - WaitForMultipleObject für andere (Wie stell ich dabei fest was genau
  49 + mit dem Objekt passiert ist? OK, für pipes ist das Einfach, da es
  50 + eh ein Wege Kommunikation ist.)
  51 + - und möglicherweise noch andere.
... ...
  1 +DEFS = -DHAS_CONFIG @DEFS@
  2 +
  3 +ACLOCAL_AMFLAGS = -I m4
  4 +
  5 +EXTRA_DIST = config/config.rpath config/mkinstalldirs \
  6 + include/scot_common.h \
  7 + include/scot/stream_pool_fraction.h \
  8 + include/scot/win32/thread.h \
  9 + include/scot/win32/memory.h \
  10 + include/scot/win32/dir.h \
  11 + include/scot/win32/scot_types.h \
  12 + include/scot/posix/thread.h \
  13 + include/scot/posix/memory.h \
  14 + include/scot/posix/dir.h \
  15 + include/scot/posix/scot_types.h \
  16 + src/win32/thread.c \
  17 + src/win32/dir.c \
  18 + src/win32/memory.c \
  19 + src/win32/spf_thread_impl.c \
  20 + src/win32/stream_ctl.c \
  21 + src/posix/thread.c \
  22 + src/posix/dir.c \
  23 + src/posix/spf_thread_impl.c \
  24 + src/posix/stream_ctl.c \
  25 + design/scot-event-subsystem.dia
  26 +
  27 +SUBDIRS = m4 include src src/po test test/po
... ...
  1 +2006-08-07
  2 +Es gibt noch einen bug im exception handling. Ich kann im Moment noch
  3 +nicht genau sagen was passiert, evtl. ist es auch nur ein bug im testprogramm.
  4 +Jedenfalls bekomme ich eine Fehlermeldung von wegen THROW kann nur in
  5 +einem TRY-CATCH block aufgerufen werden wenn der stream_pool thread mit
  6 +exit beendet.
  7 +Ich weiß zur Zeit noch nicht ob dieser Fehler im Hauptthread oder im
  8 +stream_pool thread passiert, ich vermute aber im Hauptthread, da der
  9 +CATCH-Bereich des stream_pool threads ausgeführt wird.
  10 +
  11 +Möglicherweise ist das aber auch ein genereller Bug im exception system,
  12 +der auftritt sobald man exit () in einem catch bereich nutzt. (Was eigentlich
  13 +auch nicht wirklich ne gute Idee ist (meistens jedenfalls)...trotzdem sollte
  14 +es möglich sein. im zweifelsfall durch eine eigene Funktion exc_exit oder so.
  15 +
  16 +OK, der richtige excenv stack sollte selectiert werden...daran liegts nicht.
  17 +Trotzdem scheint es kein excenv mehr in diesem stack zu geben nachdem ich
  18 +in den CATCH Block von scot_stream_pool_main_loop gekommen bin.
  19 +
  20 +AHA, die event_listener_fini methode throwed evtl. eine exception, und zwar
  21 +ganau dann wenn sie von ihrem eigenen main loop aufgerufen wurde. Was
  22 +hier passierte...allerdings schon aus dem CATCH Teil der main_loop
  23 +methode, wodurch kein excenv mehr da war.
  24 +Nachdem ich einen TRY-CATCH Block um den betreffenden Teil in
  25 +event_listener_fini gemacht habe war das Problem behoben.
  26 +
  27 +--------------------
  28 +
  29 +Der fs_watcher code funktioniert so nicht. Man kann von dem notify descriptor
  30 +leider nicht genau so lesen wie von einem file descriptor.
  31 +Ich werde also code in scot stream integrieren, der die besonderheiten
  32 +von inotify descriptoren berücksichtigt.
  33 +Schließlich soll scot stream genau für sowas eine abstraction liefern.
  34 +
  35 +--------------------
  36 +
  37 +2006-08-23
  38 +
  39 +OK, fs-watcher mit inotify functioniert gröstenteils. Das heißt auf einer
  40 +single cpu maschine läuft es problemlos, auf meiner alten SMP Maschine kommt
  41 +der thread der die filesystem events überwacht ab und zu irgendwie in einen
  42 +busy loop oder so was, jedenfalls reagiert er nicht mehr und zieht nahezu
  43 +100% CPU time auf einer CPU.
  44 +
  45 +---------------------
  46 +
  47 +Und hier jetzt der Knüller des Jahrhunderts.
  48 + ### select von winsock2 ist kein cancellation point ###
  49 + ### und (noch besser) kann nicht unterbrochen werden ###
  50 +Unerwartete und nervig. Seit Winsock2 ist select nicht mehr unterbrechbar. Das
  51 +macht es quasi unbrauchbar für threads wenn diese von Zeit zu Zeit unterbrochen
  52 +werden sollen (z.B. damit der select in dem thread neu hinzugekommene
  53 + Verbindungen mit überwacht), es sei denn man setzt die threads in einen
  54 +asynchronous mode.
  55 +Außerdem nuss ich multiple threads für die socket verwaltung verwenden, da
  56 +windows select per default nur 64 sockets verwalten kann, was für einen server
  57 +geradezu lächerlich wenig ist, also benutze ich pro 64 sockets einen thread.
  58 +Im Moment suche ich nach einem Weg wie ich das Problem umgehen kann. Eine gute
  59 +Möglichkeit scheint zu sein, den socket an dem ich auf connections warte auch
  60 +in jedem select zu überwachen, dann sollte der select zurückkommen sobald eine
  61 +neue Verbindung hergestellt wird.
  62 +Dann muß nur noch sichergestellt sein das sich nur ein thread um die neu
  63 +ankommende Verbindung kümmert und das alle anderen solange warten bis der neue
  64 +socket in die zuständige socketliste eingetragen wurde. Das sollte aber mit
  65 +einer critical section kein Problem sein.
... ...
  1 +#!/bin/sh
  2 +# Script for cleaning all autogenerated files.
  3 +
  4 +test ! -f Makefile || make distclean
  5 +
  6 +# Brought in by autopoint.
  7 +rm -f ABOUT-NLS
  8 +mv m4/ax_create_stdint_h.m4 .
  9 +rm -f m4/*.m4
  10 +mv ax_create_stdint_h.m4 m4
  11 +rm -f src/po/Makefile.in.in
  12 +rm -f src/po/remove-potcdate.sin
  13 +rm -f test/po/Makefile.in.in
  14 +rm -f test/po/remove-potcdate.sin
  15 +
  16 +# Generated by aclocal.
  17 +rm -f aclocal.m4
  18 +
  19 +# Generated by autoconf.
  20 +rm -f configure
  21 +
  22 +# Generated by autoheader
  23 +rm -f config.h.in
  24 +
  25 +# Generated or brought in by automake.
  26 +rm -f Makefile.in
  27 +rm -f m4/Makefile.in
  28 +rm -f src/Makefile.in
  29 +rm -f test/Makefile.in
  30 +rm -f include/Makefile.in
  31 +rm -f INSTALL
  32 +rm -f COPYING
  33 +
  34 +# Generated by all in config
  35 +rm -rf config
  36 +
  37 +rm -rf autom4te.cache
  38 +
  39 +# Generated by testruns
  40 +find . -name exc_test.fil -exec rm -f {} \;
  41 +
  42 +# Generated by doxygen
  43 +rm -f doxy.wrn
  44 +rm -rf doc/full/*
  45 +rm -rf doc/usage/*
... ...
  1 +#!/bin/sh
  2 +# Script for regenerating all autogenerated files.
  3 +
  4 +autopoint -f # was: gettextize -f -c
  5 +cp po/Makefile.in.in src/po
  6 +cp po/remove-potcdate.sin src/po
  7 +cp po/Makefile.in.in test/po
  8 +cp po/remove-potcdate.sin test/po
  9 +rm -fR po
  10 +
  11 +aclocal -I m4
  12 +autoconf
  13 +autoheader
  14 +libtoolize -c -f
  15 +automake -a -c
... ...
  1 +AC_PREREQ(2.59)
  2 +AC_INIT(scot, 0.0.3, BUG-REPORT-ADDRESS)
  3 +AC_CONFIG_AUX_DIR([config])
  4 +AC_CONFIG_SRCDIR([src/cmdla.c])
  5 +AC_CONFIG_HEADER([config.h])
  6 +AM_INIT_AUTOMAKE
  7 +
  8 +AC_CANONICAL_HOST
  9 +
  10 +# Checks for programs.
  11 +AC_PROG_CC
  12 +AC_PROG_MAKE_SET
  13 +AC_LIBTOOL_WIN32_DLL
  14 +AC_PROG_LIBTOOL
  15 +
  16 +# Checks for header files.
  17 +AC_HEADER_STDC
  18 +AC_CHECK_HEADERS([getopt.h libintl.h locale.h stdlib.h string.h unistd.h wchar.h])
  19 +AX_CREATE_STDINT_H([include/scot/scot_int.h])
  20 +
  21 +
  22 +# Checks for libraries.
  23 +AM_GNU_GETTEXT([external])
  24 +AC_MSG_CHECKING([intl])
  25 +AC_MSG_RESULT([$LIBINTL])
  26 +AM_GNU_GETTEXT_VERSION(0.13.1)
  27 +localedir=`eval echo $datadir/locale`
  28 +AC_DEFINE_UNQUOTED(LOCALEDIR, "$localedir", [Name of gettext locale directory])
  29 +THREAD_LIB=
  30 +THREAD_CFLAGS=
  31 +AC_MSG_CHECKING([for Win32])
  32 +case "$host" in
  33 + *-*-mingw*)
  34 + win32="yes, use windows threads"
  35 + pthread="pthreadGC2"
  36 + SOCK_LIB="-lws2_32"
  37 + ;;
  38 + *)
  39 + win32="no"
  40 + pthread="pthread"
  41 + SOCK_LIB=""
  42 + ;;
  43 +esac
  44 +AC_MSG_RESULT([$win32])
  45 +
  46 +AC_CHECK_LIB($pthread,pthread_create,
  47 + THREAD_LIB=-l$pthread
  48 + THREAD_CFLAGS="-DUSE_PTHREAD -DREENTRANT"
  49 + thread="PTHREAD",
  50 + THREAD_CFLAGS="-DUSE_WTHREAD"
  51 + thread="WTHREAD",)
  52 +
  53 +AC_SUBST(SOCK_LIB)
  54 +AC_SUBST(THREAD_LIB)
  55 +AC_SUBST(THREAD_CFLAGS)
  56 +
  57 +AM_CONDITIONAL(USE_THREADS, test "x$thread" != "x")
  58 +AM_CONDITIONAL(PTHREAD, test "x$thread" == "xPTHREAD")
  59 +AM_CONDITIONAL(WTHREAD, test "x$thread" == "xWTHREAD")
  60 +AM_CONDITIONAL(WIN32, test "x$win32" != "xno")
  61 +
  62 +# Checks for typedefs, structures, and compiler characteristics.
  63 +AC_C_CONST
  64 +
  65 +# Checks for library functions.
  66 +AC_CHECK_FUNCS([memset setlocale])
  67 +
  68 +dnl We need to check if the right inotify version is accessible
  69 +use_inotify="yes"
  70 +AC_MSG_CHECKING([whether inotify is to be used for filemonitoring])
  71 +
  72 +if test "x$win32" == "xno"
  73 +then
  74 + AC_ARG_ENABLE(inotify,
  75 + [ --disable-inotify disable inotify in the ecore_file module],
  76 + [
  77 + if test "$enableval" == "yes"; then
  78 + AC_MSG_RESULT([yes])
  79 + else
  80 + AC_MSG_RESULT([no - but we need it])
  81 + use_inotify="no"
  82 + fi
  83 + ], [
  84 + AC_MSG_RESULT([yes])
  85 + ]
  86 + )
  87 +
  88 + dnl It's hard to find a good test on how to check the correct
  89 + dnl inotify version. They changed the headers a lot.
  90 + dnl in kernel 2.6.13 __NR_inotify_init was added to the defined syscalls
  91 + dnl in asm/unistd.h and IN_MOVE_SELF was added to linux/inotify.h
  92 + dnl so with this check you need a very new kernel and kernel-headers!
  93 + dnl On my gentoo, /usr/include/asm and /usr/include/linux are no symlinks
  94 + dnl into the current kernel tree....so i also try to find the includes
  95 + dnl under /usr/src/linux or under /usr/include/linux-`uname -r`
  96 + linux_rev=`uname -r`
  97 + INOTIFY_INCLUDES=
  98 + AC_MSG_CHECKING([for sufficient inotify includes])
  99 + if test "x$use_inotify" = "xyes"; then
  100 + AC_TRY_COMPILE(
  101 + [
  102 + #include <asm/unistd.h>
  103 + #include <linux/inotify.h>
  104 + ],
  105 + [ int a = __NR_inotify_init; int b = IN_MOVE_SELF; ],
  106 + [
  107 + AC_DEFINE(HAVE_INOTIFY, 1, [ File monitoring with Inotify ])
  108 + an_inc=/usr/include
  109 + ],
  110 + [
  111 + AC_TRY_COMPILE(
  112 + [
  113 + #include "/usr/src/linux/include/asm/unistd.h"
  114 + #include "/usr/src/linux/include/linux/inotify.h"
  115 + ],
  116 + [ int a = __NR_inotify_init; int b = IN_MOVE_SELF; ],
  117 + [
  118 + AC_DEFINE(HAVE_INOTIFY, 1, [ File monitoring with Inotify ])
  119 + AC_DEFINE(IN_KERNEL, 1, [ blablabla ])
  120 + INOTIFY_INCLUDES=-I/usr/src/linux/include
  121 + an_inc=/usr/src/linux/include
  122 + ],
  123 + [
  124 + AC_TRY_COMPILE(
  125 + [
  126 + #include </usr/src/linux-$linux_rev/include/asm/unistd.h>
  127 + #include </usr/src/linux-$linux_rev/include/linux/inotify.h>
  128 + ],
  129 + [ int a = __NR_inotify_init; int b = IN_MOVE_SELF; ],
  130 + [
  131 + AC_DEFINE(HAVE_INOTIFY, 1, [ File monitoring with Inotify ])
  132 + AC_DEFINE(IN_KERNEL_UNAME, 1, [ blablabla ])
  133 + INOTIFY_INCLUDES=-I/usr/src/linux-$linux_rev/include
  134 + an_inc=/usr/src/linux-$linux_rev/include
  135 + ],
  136 + [
  137 + use_inotify="no"
  138 + an_inc="not found"
  139 + ]
  140 + )
  141 + ]
  142 + )
  143 + ]
  144 + )
  145 + AC_MSG_RESULT([$an_inc])
  146 + test "x$an_inc" == "xnot found" && exit
  147 + else
  148 + AC_MSG_RESULT(["Not used"])
  149 + fi
  150 +
  151 + AC_SUBST(INOTIFY_INCLUDES)
  152 +else
  153 + use_inotify="no"
  154 + AC_MSG_RESULT([no])
  155 +fi
  156 +
  157 +AM_CONDITIONAL(USE_INOTIFY, test "x$use_inotify" != "xno")
  158 +
  159 +
  160 +AC_CONFIG_FILES([Makefile])
  161 +AC_CONFIG_FILES([src/Makefile])
  162 +AC_CONFIG_FILES([include/Makefile])
  163 +AC_CONFIG_FILES([test/Makefile])
  164 +AC_CONFIG_FILES([m4/Makefile])
  165 +AC_CONFIG_FILES([src/po/Makefile.in])
  166 +AC_CONFIG_FILES([test/po/Makefile.in])
  167 +
  168 +AC_OUTPUT
... ...
No preview for this file type
  1 +#include <stdio.h>
  2 +#include <scot/scot_int.h>
  3 +#include <scot/event.h>
  4 +#include <scot/thread.h>
  5 +
  6 +#define GEN_LOCAL
  7 +#include <scot/list.h>
  8 +#include <scot/queue.h>
  9 +#undef GEN_LOCAL
  10 +
  11 +struct scot_event_manager;
  12 +
  13 +struct scot_event_source
  14 +{
  15 + struct scot_event_manager * manager;
  16 + unsigned int group;
  17 + THREAD_T sthr;
  18 + scot_event_source_entry_fptr event_source_thread_entry;
  19 +
  20 + int (*event_done_cb) (struct scot_event *);
  21 +};
  22 +
  23 +/*
  24 + * das ist cool, mit folgender Struktur und der Tatsache das die registrierten
  25 + * callbacks in einer Instanz dieser Struktur und dann in einer liste
  26 + * gespeichert werden bedeutet, das ich mehrere callback zu einem event
  27 + * registrieren kann. Im moment würden diese dann in undefinierter
  28 + * Reihenfolge aufgerufen, sobald ein event auftaucht.
  29 + * Sobald der tree code fertig ist sollte man die callbacks in einem
  30 + * balanced b-tree speichern bei dem der key die event-nummer ist.
  31 + * Das würde die zugriffe auf die callbacks nochmal erheblich beschleunigen.
  32 + * Vorher könnte man sich überlegen callbacks sortiert einzufügen.
  33 + * (Warscheinlich würde das auch schon reichen, da callbacks normalerweise
  34 + * nur einmal zu beginn des Programms registriert werden und daher die
  35 + * insert-zeit nicht so relevant ist.)
  36 + */
  37 +struct scot_event_cb
  38 +{
  39 + uint32_t event;
  40 + int (*cb) (struct scot_event *); /* wenn ein cb 0 zurückliefert werden
  41 + keine weiteren registrierten
  42 + callbacks zu diesem event ausgeführt,
  43 + sonst so lange bis keine weiteren
  44 + events vorliegen. */
  45 +};
  46 +typedef struct scot_event_cb scot_event_cb_t;
  47 +GEN_LIST (scot_event_cb_t);
  48 +
  49 +struct scot_event_sink
  50 +{
  51 + struct scot_event_manager * manager;
  52 + unsigned int group;
  53 + uint32_t mask;
  54 +
  55 + list_scot_event_cb_t_node_t * cb_mappings;
  56 +};
  57 +
  58 +
  59 +typedef struct scot_event scot_event_t;
  60 +GEN_QUEUE (scot_event_t);
  61 +
  62 +
  63 +struct scot_event_manager
  64 +{
  65 + struct scot_event_source sources [32];
  66 + struct scot_event_sink sinks [32];
  67 +
  68 + queue_scot_event_node_t * queue;
  69 +};
  70 +
  71 +
  72 +/*
  73 + * Funktionen zum manager
  74 + */
  75 +struct scot_event_manager *
  76 +scot_event_manager_new (void);
  77 +
  78 +int
  79 +scot_event_manager_register_source (
  80 + struct scot_event_manager *,
  81 + struct scot_event_source *);
  82 +
  83 +int scot_event_manager_register_cb (
  84 + struct scot_event_manager *,
  85 + uint32_t event,
  86 + int (*cb) (struct scot_event *));
  87 +
  88 +/*
  89 + * Funktionen zur source
  90 + */
  91 +struct scot_event_source *
  92 +scot_event_source_init (
  93 + unsigned int group,
  94 + int (*event_done_cb) (struct scot_event *));
  95 +
  96 +int
  97 +scot_event_source_register (
  98 + struct scot_event_source *);
  99 +
  100 +/*
  101 + * Funktionen zur sink
  102 + */
... ...
  1 +nobase_include_HEADERS = scot/cmdla.h \
  2 + scot/list.h scot/list_impl.h scot/list_proto.h \
  3 + scot/list_man.h scot/list_mod.h scot/list_nav.h \
  4 + scot/list_type_proto.h scot/list_func_proto.h \
  5 + scot/stack.h scot/stack_impl.h scot/stack_proto.h \
  6 + scot/stack_type_proto.h scot/stack_func_proto.h \
  7 + scot/queue.h scot/queue_impl.h scot/queue_proto.h \
  8 + scot/queue_type_proto.h scot/queue_func_proto.h \
  9 + scot/exception.h scot/exception_t.h scot/excenv_t.h \
  10 + scot/thread.h scot/memory.h scot/dir.h scot/dir_common.h \
  11 + scot/scot_exceptions.h scot/scot_types.h \
  12 + scot/socket.h scot/socket_in.h \
  13 + scot/event.h scot/event_listener.h \
  14 + scot/fs_watcher.h \
  15 + scot/stream.h scot/stream_pool.h
  16 +
  17 +BUILT_SOURCES = scot/thread.h scot/memory.h scot/dir.h
  18 +CLEANFILES = scot/thread.h scot/memory.h scot/dir.h
  19 +
  20 +if PTHREAD
  21 +scot/thread.h: Makefile scot/posix/thread.h
  22 + cp scot/posix/thread.h scot/thread.h
  23 +else
  24 +scot/thread.h: Makefile scot/win32/thread.h
  25 + cp scot/win32/thread.h scot/thread.h
  26 +endif
  27 +
  28 +if WIN32
  29 +nobase_include_HEADERS += scot/stream_win.h
  30 +
  31 +scot/scot_types.h: Makefile scot/win32/scot_types.h
  32 + cp scot/win32/scot_types.h scot/scot_types.h
  33 +scot/memory.h: Makefile scot/win32/memory.h
  34 + cp scot/win32/memory.h scot/memory.h
  35 +scot/dir.h: Makefile scot/win32/dir.h
  36 + cp scot/win32/dir.h scot/dir.h
  37 +else
  38 +nobase_include_HEADERS += scot/socket_un.h scot/inotify.h
  39 +
  40 +scot/scot_types.h: Makefile scot/posix/scot_types.h
  41 + cp scot/posix/scot_types.h scot/scot_types.h
  42 +scot/memory.h: Makefile scot/posix/memory.h
  43 + cp scot/posix/memory.h scot/memory.h
  44 +scot/dir.h: Makefile scot/posix/dir.h
  45 + cp scot/posix/dir.h scot/dir.h
  46 +endif
  47 +
... ...
  1 +/*
  2 + * cmdla.h: Prototypes, defines, etc. for cmdla
  3 + *
  4 + * Copyright (C) 2006 Georg Steffers. All rights reserved.
  5 + *
  6 + * This software is licensed under the terms of the GNU Genral Public
  7 + * License (GPL). Please see gpl.txt for details or refer to
  8 + * http://www.gnu.org/licenses/gpl.html
  9 + *
  10 + * Author: Georg Steffers <georg@steffers.org>
  11 + *
  12 + * 01/14/2006: Georg Steffers - First implemented
  13 + * 01/15/2006: Georg Steffers - V0.1 ready. Modified this and that
  14 + * now long arguments are supported as
  15 + * well as arguments with am optional
  16 + * parameter.
  17 + * 01/23/2006: Georg Steffers - add support for gettext.
  18 + */
  19 +
  20 +#ifndef CMDLA_H
  21 +#define CMDLA_H
  22 +
  23 +/* Datatypes of given commandline values */
  24 +#define CMDLA_TYPE_STRING 0x00
  25 +#define CMDLA_TYPE_INT 0x01
  26 +#define CMDLA_TYPE_FLOAT 0x02
  27 +
  28 +/* Indicates wether an arg requires an parameter or not */
  29 +#define CMDLA_REQ_ARG 0x01
  30 +#define CMDLA_OPT_ARG 0x02
  31 +
  32 +#define CMDLAP_CBT_END { 0, NULL, 0, NULL, 0, NULL, NULL }
  33 +#define CMDLAS_CBT_END { 0, NULL, NULL, NULL, NULL }
  34 +
  35 +#define _GNU_SOURCE /* for getopt */
  36 +
  37 +#include <unistd.h>
  38 +#include <wchar.h>
  39 +#include <getopt.h>
  40 +
  41 +#include <scot_common.h>
  42 +
  43 +/*
  44 + * This struct holds all neccesary infomation for the default
  45 + * usage callback. It is filled within process_cmd_line and used
  46 + * with any usage function that did not specify explicitly different
  47 + * behaviour.
  48 + */
  49 +struct du_infot
  50 +{
  51 + const struct cmdlas_cbt *switches;
  52 + const struct cmdlap_cbt *arguments;
  53 + const char *about;
  54 + const char *copyright;
  55 + const char *usage_aa;
  56 + const char *program_name;
  57 +};
  58 +
  59 +
  60 +typedef int (*cmdlap_cb) (const char *, const int, void *);
  61 +typedef int (*cmdlas_cb) (void *);
  62 +
  63 +/*
  64 + * CoMmanDLine Argument Parameter CallBack Type.
  65 + * This holds the definition of an argument that takes a parameter.
  66 + */
  67 +struct cmdlap_cbt {
  68 + char carg; /* The single letter argument e.g. -a */
  69 + char *sarg; /* The string argument e.g. --arg */
  70 + int cmdla_argt; /* Datatype the arg take e.g. CMDLA_TYPE_INT */
  71 + cmdlap_cb cb; /* pointer to the callback funtion */
  72 + int cmdla_type; /* requires parameter? e.g. CMDLA_REQ_ARG */
  73 + void *var; /* this will be given to the callback */
  74 + const char *info; /* a short description for the help */
  75 +};
  76 +
  77 +/*
  78 + * CoMmanDLine Argument Switch CallBack Type.
  79 + * This holds the definition of an argument that is a switch.
  80 + */
  81 +struct cmdlas_cbt {
  82 + char carg; /* The single letter argument e.g. -a */
  83 + char *sarg; /* The string argument e.g. --arg */
  84 + cmdlas_cb cb; /* pointer to the callback funtion */
  85 + void *var; /* this will be given to the callback */
  86 + const char *info; /* a short description for the help */
  87 +};
  88 +
  89 +
  90 +/*
  91 + * The defaul usage method....this was previously static within
  92 + * cmdla but i realised that it is useful to make it callable
  93 + * within the calling code to do special usage in special cases
  94 + * and call this if no special case occured.
  95 + */
  96 +int default_usage_cb (void *);
  97 +
  98 +/*
  99 + * a default callback for struct cmdlap_cbt. It simply parses its first
  100 + * argument into its last according to the type specified by its sec. arg.
  101 + */
  102 +int get_cmdlap_cb (const char *, const int, void *);
  103 +
  104 +/*
  105 + * this does all the work.
  106 + * Arguments are: (argc, argv, a program description, a copyright string,
  107 + * additional text for the usage information,
  108 + * a list of arguments with parameter, a list of switches).
  109 + */
  110 +int process_cmd_line (
  111 + int, char *[], const char*, const char*, const char*,
  112 + const struct cmdlap_cbt *, const struct cmdlas_cbt *);
  113 +
  114 +int switch_cb (void *);
  115 +int inc_cb (void *);
  116 +
  117 +#endif /* CMDLA_H */
... ...
  1 +/*
  2 + * dir_common.h: definitions and prototypes common for all plattforms with
  3 + * dir.c
  4 + *
  5 + * Copyright (C) 2006 Georg Steffers
  6 + *
  7 + * Author: Georg Steffers [GST] <georg.steffers@aschendorff.de>
  8 + * Developer:
  9 + *
  10 + * Changes (for this file only):
  11 + * (2006-06-12) [GST] Started this changelog...well the program is
  12 + * ready since some weeks right now.
  13 + */
  14 +#ifndef DIR_COMMON_H
  15 +#define DIR_COMMON_H
  16 +
  17 +/* return values for get_dir_next */
  18 +#define GET_DIRENT_OK 0x00
  19 +#define NO_FILES_LEFT 0x01
  20 +#define GET_DIRENT_ERR 0x02
  21 +
  22 +/* flags for symlink following */
  23 +#define FOLLOW_SYM 0x00
  24 +#define DONT_FOLLOW_SYM 0x01
  25 +
  26 +#endif /* DIR_COMMON_H */
... ...
  1 +#ifndef SCOT_EVENT_H
  2 +#define SCOT_EVENT_H
  3 +
  4 +#include <stddef.h>
  5 +
  6 +#include <scot/scot_int.h>
  7 +#include <scot/scot_types.h>
  8 +
  9 +#define SCOT_EVENT_NO uint16_t
  10 +
  11 +/*
  12 + * basis event struktur. Ein Typ und die wirkliche größe.
  13 + */
  14 +struct scot_event
  15 +{
  16 + SCOT_EVENT_NO event;
  17 + uint32_t size; /* is used with serialization. If an event
  18 + was serialized and send over a datalink,
  19 + it is possible that not all data is read
  20 + at once. So i can first read
  21 + sizeof (struct scot_event) and then i
  22 + know exactly how much has to be read for
  23 + the whole event. */
  24 + uint32_t ed_size; /* This reflects the size of the extra_data
  25 + buffer...when serializing is done it is
  26 + neccessary to know where extra_data ends,
  27 + and as it could be any arbitrary data this
  28 + could not be guessed by the code. */
  29 + void * extra_data; /* maybe this should hold the object that
  30 + an callback function to this event belongs
  31 + to. */
  32 +};
  33 +
  34 +
  35 +struct scot_event * scot_event_new (struct scot_event *,
  36 + SCOT_EVENT_NO , void *, SIZE_T);
  37 +SIZE_T scot_event_serialize (struct scot_event *, char **);
  38 +struct scot_event * scot_event_deserialize (struct scot_event *, const char *);
  39 +void scot_event_free (struct scot_event *);
  40 +
  41 +/*
  42 + * event definitionen für stream pool events
  43 + * Die stream pool event gruppe hat nur eine erweiterte event struktur,
  44 + * es ist aber auch denkbar das eine event gruppe mehrere solche strukturen
  45 + * einschließt. (Alle events die ein stream pool erzeugt sind read
  46 + * write oder exception auf einem stream und fuer alle diese events
  47 + * reicht es den stream handle im event mitzugeben).
  48 + */
  49 +struct scot_stream_pool_event
  50 +{
  51 + struct scot_event event;
  52 + struct scot_stream * st;
  53 +};
  54 +
  55 +struct scot_stream_pool_event * scot_stream_pool_event_new (
  56 + struct scot_stream_pool_event *,
  57 + SCOT_EVENT_NO, void *, SIZE_T, struct scot_stream * );
  58 +
  59 +/*
  60 + * event definitionen für filesystem watcher events
  61 + */
  62 +struct scot_fs_watcher_event
  63 +{
  64 + struct scot_event event;
  65 + char * path;
  66 + char * name;
  67 + char * oldname; /* used by rename events */
  68 +};
  69 +
  70 +struct scot_fs_watcher_event * scot_fs_watcher_event_new (
  71 + struct scot_fs_watcher_event *,
  72 + SCOT_EVENT_NO, void *, SIZE_T,
  73 + const char *, const char *, const char *);
  74 +
  75 +#define GEN_SCOT_EVENT_NO (group, mask, no) ((group<<24)&(mask<<18)&no)
  76 +#define SCOT_EVENT_GEN_MASK(exp) 1<<(exp)
  77 +
  78 +#define SCOT_EVENT_CHK_GROUP(e, g) (((e)&((SCOT_EVENT_NO)(g)<<8)) == ((g)<<8))
  79 +
  80 +/* EG := EVENT_GROUP */
  81 +#define SCOT_EG_INTERNAL ((SCOT_EVENT_NO)0)
  82 +#define SCOT_EG_STREAM_POOL ((SCOT_EVENT_NO)1)
  83 +#define SCOT_EG_FS_WATCHER ((SCOT_EVENT_NO)2)
  84 +
  85 +#define SCOT_EVENT_STREAM_POOL_READ \
  86 + ((SCOT_EVENT_NO)(SCOT_EG_STREAM_POOL << 8) | 0)
  87 +#define SCOT_EVENT_STREAM_POOL_WRITE \
  88 + ((SCOT_EVENT_NO)(SCOT_EG_STREAM_POOL << 8) | 1)
  89 +#define SCOT_EVENT_STREAM_POOL_EXCEP \
  90 + ((SCOT_EVENT_NO)(SCOT_EG_STREAM_POOL << 8) | 2)
  91 +
  92 +#define SCOT_EVENT_FS_WATCHER_CREATE \
  93 + ((SCOT_EVENT_NO)(SCOT_EG_FS_WATCHER << 8) | 0)
  94 +#define SCOT_EVENT_FS_WATCHER_DELETE \
  95 + ((SCOT_EVENT_NO)(SCOT_EG_FS_WATCHER << 8) | 1)
  96 +#define SCOT_EVENT_FS_WATCHER_RENAME \
  97 + ((SCOT_EVENT_NO)(SCOT_EG_FS_WATCHER << 8) | 2)
  98 +#define SCOT_EVENT_FS_WATCHER_WRITTEN \
  99 + ((SCOT_EVENT_NO)(SCOT_EG_FS_WATCHER << 8) | 3)
  100 +#define SCOT_EVENT_FS_WATCHER_ATTRCHG \
  101 + ((SCOT_EVENT_NO)(SCOT_EG_FS_WATCHER << 8) | 4)
  102 +#define SCOT_EVENT_FS_WATCHER_SIZECHG \
  103 + ((SCOT_EVENT_NO)(SCOT_EG_FS_WATCHER << 8) | 5)
  104 +
  105 +
  106 +#endif /* SCOT_EVENT_H */
... ...
  1 +#ifndef _SCOT_EVENT_LISTENER_H
  2 +#define _SCOT_EVENT_LISTENER_H
  3 +
  4 +#include <limits.h>
  5 +
  6 +#include <scot/scot_int.h>
  7 +#include <scot/event.h>
  8 +#include <scot/thread.h>
  9 +
  10 +#include <scot/stack_type_proto.h>
  11 +
  12 +/* valid return codes for the callbacks */
  13 +#define SCOT_EVENT_END 0x00
  14 +#define SCOT_EVENT_CONT 0x01
  15 +#define SCOT_EVENT_CONT_DATA_DONE 0x02
  16 +
  17 +#define SCOT_EL_WAIT_THREAD_MAX INFINITE
  18 +
  19 +
  20 +typedef unsigned short (*scot_event_cb_fptr) (struct scot_event *);
  21 +
  22 +GEN_STACK_TYPE_PROTO (scot_event_cb_fptr);
  23 +
  24 +struct scot_event_listener
  25 +{
  26 + unsigned char group;
  27 +
  28 + stack_scot_event_cb_fptr_node_t * cb_mappings[UCHAR_MAX];
  29 + void * cb_extra_data[UCHAR_MAX];
  30 +
  31 + THREAD_T thread_handle;
  32 + THREAD_ID_T thread_id;
  33 + int thread_run_flg;
  34 +
  35 + scot_thread_entry_fptr el_entry_func;
  36 +};
  37 +typedef struct scot_event_listener scot_event_listener;
  38 +
  39 +void scot_event_listener_init (struct scot_event_listener *,
  40 + const unsigned char ,
  41 + const scot_thread_entry_fptr);
  42 +void scot_event_listener_fini (struct scot_event_listener *);
  43 +void scot_event_listener_start (struct scot_event_listener *);
  44 +void scot_event_listener_stop (struct scot_event_listener *);
  45 +int scot_event_listener_is_running (struct scot_event_listener *);
  46 +void scot_event_listener_register_cb (struct scot_event_listener *,
  47 + SCOT_EVENT_NO ,
  48 + scot_event_cb_fptr ,
  49 + void *);
  50 +void scot_event_listener_call_cb (struct scot_event_listener *,
  51 + struct scot_event *);
  52 +
  53 +#endif /* _SCOT_EVENT_LISTENER_H */
... ...
  1 +/**
  2 + * \file scot/excenv_t.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief The datatypes for exception environments.
  5 + *
  6 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  7 + *
  8 + * This program is free software; you can redistribute it and/or modify
  9 + * it under the terms of the GNU General Public License as published by
  10 + * the Free Software Foundation; either version 2 of the License, or
  11 + * (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21 + */
  22 +#ifndef STACK_EXCENV_T_H
  23 +#define STACK_EXCENV_T_H
  24 +
  25 +#include <setjmp.h>
  26 +
  27 +#include <scot/exception_t.h>
  28 +
  29 +struct excenv_t;
  30 +typedef struct excenv_t excenv_t;
  31 +
  32 +#ifndef USE_SCOT_STRUCT_EXCENV_T
  33 +struct excenv_t
  34 +{
  35 + const char _ [sizeof (struct {
  36 + jmp_buf env;
  37 + void *e_queue;
  38 + })];
  39 +};
  40 +#else
  41 +/**
  42 + * \internal
  43 + * \brief holds an exception environment.
  44 + */
  45 +struct excenv_t
  46 +{
  47 + jmp_buf env; /**< jump here on error. */
  48 + queue_exception_t_node_t *e_queue; /**< holds the exceptions. */
  49 +};
  50 +#endif
  51 +
  52 +#endif /* STACK_EXCENV_T_H */
... ...
  1 +/**
  2 + * \file scot/exception.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief The user interface to exception handling.
  5 + *
  6 + * This describes the macros TRY, CATCH, THROW and EXC.
  7 + *
  8 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  9 + *
  10 + * This program is free software; you can redistribute it and/or modify
  11 + * it under the terms of the GNU General Public License as published by
  12 + * the Free Software Foundation; either version 2 of the License, or
  13 + * (at your option) any later version.
  14 + *
  15 + * This program is distributed in the hope that it will be useful,
  16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18 + * GNU General Public License for more details.
  19 + *
  20 + * You should have received a copy of the GNU General Public License
  21 + * along with this program; if not, write to the Free Software
  22 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  23 + */
  24 +#ifndef EXCEPTION_H
  25 +#define EXCEPTION_H
  26 +
  27 +#include <setjmp.h>
  28 +
  29 +#include "excenv_t.h"
  30 +#include "exception_t.h"
  31 +#include <scot/thread.h>
  32 +
  33 +
  34 +#ifdef USE_THREADS
  35 +# define EXC_INIT threaded_exc_init
  36 +#else
  37 +# define EXC_INIT exc_init
  38 +#endif /* USE_THREADS */
  39 +
  40 +/**
  41 + * \pre None
  42 + * \return Nothing
  43 + * \post a current exception environment exists.
  44 + *
  45 + * \brief start exception handled code.
  46 + *
  47 + * This starts a block of exception handled code. This is done by
  48 + * creating a current exception environment.
  49 + */
  50 +#define TRY \
  51 + { \
  52 + excenv_new (EXC_INIT ()); \
  53 + if (setjmp (* excenv_jmp_buf (EXC_INIT ())) == 0)
  54 +
  55 +/**
  56 + * \param ee will hold the exception environment actually handled.
  57 + * \pre a current exception environment must exists.
  58 + * \return Nothing
  59 + * \post ee holds the current exception environment and it is removed
  60 + * from the stack of exception environments.
  61 + *
  62 + * \brief start exception handling.
  63 + *
  64 + * This starts a block of exception handling. This is done by
  65 + * retrieving the actual exception environment into \a ee.
  66 + */
  67 +#define CATCH(ee) \
  68 + ee = excenv_catch (EXC_INIT ()); \
  69 + } \
  70 + if (excenv_has_exception(ee) == 0) \
  71 + free_catched (ee); \
  72 + else
  73 +
  74 +/**
  75 + * \param e the exception to be thrown.
  76 + * \pre a current exception environment must exist.
  77 + * \return Nothing
  78 + * \post \a e is put into the current exception environment.
  79 + *
  80 + * \brief Throws an exception into the actual exception environment.
  81 + */
  82 +#define THROW(e) \
  83 + exc_throw (EXC_INIT (), (e))
  84 +
  85 +/**
  86 + * \brief this is just a wrapper around exc_new().
  87 + *
  88 + * This is just a wrapper around exc_new() that fills in automatically
  89 + * file and line.
  90 + */
  91 +#define EXC(lvl, errnum, err_msg) \
  92 + exc_new (lvl, __FILE__, __LINE__, errnum, err_msg)
  93 +
  94 +/**
  95 + * \brief a wrapper for exc_in_this_try()
  96 + */
  97 +#define EXC_IN_THIS_TRY(e) \
  98 + exc_in_this_try (e)
  99 +
  100 +void * exc_init ();
  101 +void * threaded_exc_init ();
  102 +
  103 +void excenv_new (void *);
  104 +jmp_buf * excenv_jmp_buf (void *);
  105 +void exc_throw (void *, const exception_t *);
  106 +excenv_t * excenv_catch (void *);
  107 +int excenv_has_exception (const excenv_t *);
  108 +
  109 +exception_t * exc_new (
  110 + const enum exclvl_t,
  111 + const char *,
  112 + const int,
  113 + const int,
  114 + const char *);
  115 +
  116 +exception_t * retrive_exception (const excenv_t *);
  117 +
  118 +void free_catched (excenv_t *);
  119 +void free_exception (exception_t *);
  120 +void thread_exc_end (THREAD_T);
  121 +void exc_end (void);
  122 +
  123 +void print_exception (exception_t *);
  124 +void print_all_exceptions (excenv_t *);
  125 +void forward_all_exceptions (excenv_t *);
  126 +
  127 +int exc_in_this_try (exception_t *);
  128 +enum exclvl_t exc_lvl_get (exception_t *);
  129 +char * exc_file_get (exception_t *);
  130 +int exc_line_get (exception_t *);
  131 +int exc_errnum_get (exception_t *);
  132 +char * exc_err_msg_get (exception_t *);
  133 +#endif /* EXCEPTION_H */
... ...
  1 +/**
  2 + * \file scot/exception_t.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief The datatypes for exceptions.
  5 + *
  6 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  7 + *
  8 + * This program is free software; you can redistribute it and/or modify
  9 + * it under the terms of the GNU General Public License as published by
  10 + * the Free Software Foundation; either version 2 of the License, or
  11 + * (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21 + */
  22 +#ifndef STACK_EXCEPTION_T_H
  23 +#define STACK_EXCEPTION_T_H
  24 +
  25 +/**
  26 + * \brief give the two states a speaking name.
  27 + *
  28 + * There are two exceptions possible EXC_ERRORS, that immediatly abort the
  29 + * current operation and EXC_WARNINGS, that will just be mentioned within
  30 + * the exception stack.
  31 + */
  32 +enum exclvl_t {EXC_WARNING, EXC_ERROR};
  33 +
  34 +struct exception_t;
  35 +typedef struct exception_t exception_t;
  36 +
  37 +#ifndef USE_SCOT_STRUCT_EXCEPTION_T
  38 +struct exception_t
  39 +{
  40 + const char _ [sizeof (struct {
  41 + int was_catched;
  42 + const enum exclvl_t lvl;
  43 + const char *file;
  44 + const int line;
  45 + const int errnum;
  46 + const char *err_msg;
  47 + })];
  48 +};
  49 +#else
  50 +/**
  51 + * \internal
  52 + * \brief holds an exception.
  53 + */
  54 +struct exception_t
  55 +{
  56 + int was_catched; /**< how often was it catched */
  57 + const enum exclvl_t lvl; /**< EXC_ERROR or EXC_WARNING */
  58 + const char *file; /**< file where it was created */
  59 + const int line; /**< line of that file */
  60 + const int errnum; /**< number of the error */
  61 + const char *err_msg; /**< message of the error */
  62 +};
  63 +
  64 +#include <scot/queue_type_proto.h>
  65 +GEN_QUEUE_TYPE_PROTO (exception_t);
  66 +#endif
  67 +
  68 +#endif /* STACK_EXCEPTION_T_H */
... ...
  1 +#ifndef SCOT_FS_WATCHER_H
  2 +#define SCOT_FS_WATCHER_H
  3 +
  4 +#include <scot/event_listener.h>
  5 +#include <scot/thread.h>
  6 +#include <scot/stream.h>
  7 +
  8 +#include <scot/list_type_proto.h>
  9 +
  10 +struct scot_fsw_info
  11 +{
  12 + int watch_d;
  13 + char * path;
  14 + uint32_t mask;
  15 + uint32_t got_events; /* also a mask, that shows, which events already
  16 + occured (will be 0 at init and after a callback was
  17 + called.) */
  18 + char * old_name; /* This is used within rename events. With inotify
  19 + a rename is build up from 2 inotify_events.
  20 + IN_MOVE_FROM and IN_MOVE_TO. The move from
  21 + event holds the old name. This old name is saved
  22 + here if an IN_MOVE_FORM occured. */
  23 +};
  24 +typedef struct scot_fsw_info scot_fsw_info;
  25 +GEN_LIST_TYPE_PROTO (scot_fsw_info);
  26 +
  27 +struct scot_fs_watcher
  28 +{
  29 + struct scot_event_listener el;
  30 + fd_set rfds;
  31 + struct scot_stream notify_d;
  32 +
  33 + list_scot_fsw_info_node_t * w_list;
  34 + THREAD_MUTEX_T mutex;
  35 +};
  36 +
  37 +
  38 +struct scot_fs_watcher * scot_fs_watcher_new (void);
  39 +void scot_fs_watcher_free (struct scot_fs_watcher *);
  40 +
  41 +void scot_fs_watcher_add (struct scot_fs_watcher *, const char *, uint32_t);
  42 +void scot_fs_watcher_remove (struct scot_fs_watcher *, const char *, uint32_t);
  43 +
  44 +int scot_fs_watcher_get_mask (struct scot_fs_watcher *, int);
  45 +void scot_fs_watcher_main_loop (struct scot_fs_watcher *);
  46 +
  47 +#endif /* SCOT_FS_WATCHER_H */
... ...
  1 +#ifndef INOTIFY_H
  2 +#define INOTIFY_H
  3 +
  4 +#include <sys/syscall.h>
  5 +#include <asm/unistd.h>
  6 +#include <sys/types.h>
  7 +#include <linux/inotify.h>
  8 +
  9 +#define IN_NEXT_EVENT(ev) \
  10 + (struct inotify_event *) \
  11 + ((char *)(ev) + sizeof (struct inotify_event) + (ev)->len)
  12 +
  13 +#define IN_NO_EVENT(ev) ((ev)->mask|IN_ALL_EVENTS) == IN_ALL_EVENTS
  14 +
  15 +
  16 +static inline int inotify_init (void)
  17 +{
  18 + return syscall (__NR_inotify_init);
  19 +}
  20 +
  21 +static inline int inotify_add_watch (int fd, const char *name, __u32 mask)
  22 +{
  23 + return syscall (__NR_inotify_add_watch, fd, name, mask);
  24 +}
  25 +
  26 +static inline int inotify_rm_watch (int fd, __u32 wd)
  27 +{
  28 + return syscall (__NR_inotify_rm_watch, fd, wd);
  29 +}
  30 +
  31 +#endif /* INOTIFY_H */
... ...
  1 +/**
  2 + * \file scot/list.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Macro which produce all prototypes and implementations
  5 + * for handling linked lists from Templates.
  6 + *
  7 + * This is the toplevel template file for typesafe lists. It is quite
  8 + * simple. It just defines one MACRO which in turn calls two other macros
  9 + * to generate all that is needed for listhandling of a list to a given type.
  10 + *
  11 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  12 + *
  13 + * This program is free software; you can redistribute it and/or modify
  14 + * it under the terms of the GNU General Public License as published by
  15 + * the Free Software Foundation; either version 2 of the License, or
  16 + * (at your option) any later version.
  17 + *
  18 + * This program is distributed in the hope that it will be useful,
  19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21 + * GNU General Public License for more details.
  22 + *
  23 + * You should have received a copy of the GNU General Public License
  24 + * along with this program; if not, write to the Free Software
  25 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  26 + */
  27 +#ifndef LIST_H
  28 +#define LIST_H
  29 +
  30 +#include <scot/list_proto.h>
  31 +#include <scot/list_impl.h>
  32 +
  33 +/**
  34 + * \param type the datatype that this list code should handle.
  35 + * \pre Type must be a single word typename. If one wants
  36 + * to use e.g. lists of structs one has to use typedef
  37 + * to create a single word type name like this:
  38 + * typedef struct mystruct_t mystruct_t;
  39 + * \return Nothing
  40 + * \post The complete framework of functions, types, globals
  41 + * prototypes and definitions to handle typesave
  42 + * lists for the given datatype are generated within the
  43 + * calling build file.
  44 + *
  45 + * \brief create complete framework to handle typesafe lists.
  46 + *
  47 + * This macro first colls GEN_LIST_PROTO() to create all prototypes
  48 + * neccesary for handling lists of the given \a type. And then it calls
  49 + * GEN_LIST_IMPL() to also create the neccesary definitions and
  50 + * implementations.\
  51 + * Normally this macro is only called if one only wants to have lists
  52 + * of the given type in a single c source file and nowhere else. Normally
  53 + * this is then used in conjunction with a previous define of GEN_LOCAL,
  54 + * that tells GEN_LIST() and the subsequent macros to generate the functions
  55 + * as static.\n
  56 + * If one wants to used lists of the given type in several places of the
  57 + * project one would normally call GEN_LIST_PROTO() in a h file and
  58 + * GEN_LIST_IMPL() in the corresponding c file (without GEN_LOCAL),
  59 + */
  60 +#define GEN_LIST(type) \
  61 + GEN_LIST_PROTO (type) \
  62 + GEN_LIST_IMPL (type)
  63 +
  64 +#endif /* LIST_H */
... ...
  1 +/**
  2 + * \file scot/list_func_proto.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Macro that produce function prototypes for handling
  5 + * linked lists.
  6 + *
  7 + * The macros here create all function prototypes to
  8 + * the implementations created by the macros in
  9 + * \link scot/list_impl.h scot/list_impl.h\endlink.
  10 + * These macros are normally not called directly within your code but
  11 + * through \link scot/list_proto.h::GEN_LIST_PROTO GEN_LIST_PROTO\endlink.
  12 + * This is because to use the interface declaration
  13 + * provided here one will also need the typedefs and datatype prototypes.
  14 + *
  15 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  16 + *
  17 + * This program is free software; you can redistribute it and/or modify
  18 + * it under the terms of the GNU General Public License as published by
  19 + * the Free Software Foundation; either version 2 of the License, or
  20 + * (at your option) any later version.
  21 + *
  22 + * This program is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with this program; if not, write to the Free Software
  29 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  30 + */
  31 +#ifndef LIST_FUNC_PROTO_H
  32 +#define LIST_FUNC_PROTO_H
  33 +
  34 +#ifdef GEN_LOCAL
  35 +# define STATIC static
  36 +#else
  37 +# define STATIC
  38 +#endif
  39 +
  40 +/**
  41 + * \param type the datatype that this list code should handle.
  42 + * \pre Type must be a single word typename. If one wants
  43 + * to use e.g. lists of structs one has to use typedef
  44 + * to create a single word type name like this:
  45 + * typedef struct mystruct_t mystruct_t;
  46 + * \return Nothing
  47 + * \post The function prototypes for manage lists of the given
  48 + * datatype are created.
  49 + *
  50 + * \brief Function prototypes for management.
  51 + *
  52 + * This creates the prototypes to the functions that are created by
  53 + * \link scot/list_man.h::GEN_LIST_MANAGEMENT GEN_LIST_MANAGEMENT\endlink
  54 + * in \link scot/list_man.h scot/list_man.h\endlink.
  55 + *
  56 + * Normally this is not called directly, but by
  57 + * \link scot/list_proto.h::GEN_LIST_PROTO GEN_LIST_PROTO()\endlink
  58 + * because this defined just a subset of all function prototypes neccesarry
  59 + * to handle typesafe lists.
  60 + */
  61 +#define GEN_LIST_MAN_PROTO(type) \
  62 + STATIC \
  63 + void \
  64 + list_ ## type ## _set_cmp ( \
  65 + list_ ## type ## _cmp_fptr); \
  66 + STATIC \
  67 + void \
  68 + list_ ## type ## _set_elem_free ( \
  69 + list_ ## type ## _elem_free_fptr); \
  70 + STATIC \
  71 + long \
  72 + list_ ## type ## _elem_free_is_set (void); \
  73 + STATIC \
  74 + list_ ## type ## _node_t * \
  75 + list_ ## type ## _new ( \
  76 + list_ ## type ## _node_t *); \
  77 + STATIC \
  78 + void \
  79 + list_ ## type ## _free ( \
  80 + list_ ## type ## _node_t *); \
  81 + STATIC \
  82 + int \
  83 + list_ ## type ## _count ( \
  84 + list_ ## type ## _node_t *); \
  85 + STATIC \
  86 + int \
  87 + list_ ## type ## _bol ( \
  88 + list_ ## type ## _node_t *, \
  89 + list_ ## type ## _node_t *); \
  90 + STATIC \
  91 + int \
  92 + list_ ## type ## _eol ( \
  93 + list_ ## type ## _node_t *anchor, \
  94 + list_ ## type ## _node_t *node);
  95 +
  96 +/**
  97 + * \param type the datatype that this list code should handle.
  98 + * \pre Type must be a single word typename. If one wants
  99 + * to use e.g. lists of structs one has to use typedef
  100 + * to create a single word type name like this:
  101 + * typedef struct mystruct_t mystruct_t;
  102 + * \return Nothing
  103 + * \post The function prototypes to navigate lists of the given
  104 + * datatype are created.
  105 + *
  106 + * \brief Function prototypes for navigation.
  107 + *
  108 + * This creates the prototypes to the functions that are created by
  109 + * \link scot/list_nav.h::GEN_LIST_NAVIGATION GEN_LIST_NAVIGATION\endlink
  110 + * in \link scot/list_nav.h scot/list_nav.h\endlink.
  111 + *
  112 + * Normally this is not called directly, but by
  113 + * \link scot/list_proto.h::GEN_LIST_PROTO GEN_LIST_PROTO()\endlink
  114 + * because this defined just a subset of all function prototypes neccesarry
  115 + * to handle typesafe lists.
  116 + */
  117 +#define GEN_LIST_NAV_PROTO(type) \
  118 + STATIC \
  119 + list_ ## type ## _node_t * \
  120 + list_ ## type ## _front ( \
  121 + list_ ## type ## _node_t *); \
  122 + STATIC \
  123 + list_ ## type ## _node_t * \
  124 + list_ ## type ## _last ( \
  125 + list_ ## type ## _node_t *); \
  126 + STATIC \
  127 + list_ ## type ## _node_t * \
  128 + list_ ## type ## _next ( \
  129 + list_ ## type ## _node_t *); \
  130 + STATIC \
  131 + list_ ## type ## _node_t * \
  132 + list_ ## type ## _prev ( \
  133 + list_ ## type ## _node_t *); \
  134 + STATIC \
  135 + list_ ## type ## _node_t * \
  136 + list_ ## type ## _find ( \
  137 + list_ ## type ## _node_t *, \
  138 + const type *); \
  139 + STATIC \
  140 + list_ ## type ## _node_t * \
  141 + list_ ## type ## _find_anchor ( \
  142 + list_ ## type ## _node_t *);
  143 +
  144 +/**
  145 + * \param type the datatype that this list code should handle.
  146 + * \pre Type must be a single word typename. If one wants
  147 + * to use e.g. lists of structs one has to use typedef
  148 + * to create a single word type name like this:
  149 + * typedef struct mystruct_t mystruct_t;
  150 + * \return Nothing
  151 + * \post The function prototypes to modify lists of the given
  152 + * datatype are created.
  153 + *
  154 + * \brief Function prototypes for modification.
  155 + *
  156 + * This creates the prototypes to the functions that are created by
  157 + * \link scot/list_mod.h::GEN_LIST_MODIFY GEN_LIST_MODIFY\endlink
  158 + * in \link scot/list_mod.h scot/list_mod.h\endlink.
  159 + *
  160 + * Normally this is not called directly, but by
  161 + * \link scot/list_proto.h::GEN_LIST_PROTO GEN_LIST_PROTO()\endlink
  162 + * because this defined just a subset of all function prototypes neccesarry
  163 + * to handle typesafe lists.
  164 + */
  165 +#define GEN_LIST_MOD_PROTO(type) \
  166 + STATIC \
  167 + type * \
  168 + list_ ## type ## _retrive ( \
  169 + list_ ## type ## _node_t *); \
  170 + STATIC \
  171 + void \
  172 + list_ ## type ## _set ( \
  173 + list_ ## type ## _node_t *, \
  174 + const type *); \
  175 + STATIC \
  176 + list_ ## type ## _node_t * \
  177 + list_ ## type ## _insert ( \
  178 + list_ ## type ## _node_t *, \
  179 + const type *); \
  180 + STATIC \
  181 + list_ ## type ## _node_t * \
  182 + list_ ## type ## _delete ( \
  183 + list_ ## type ## _node_t *); \
  184 + STATIC \
  185 + list_ ## type ## _node_t * \
  186 + list_ ## type ## _concat ( \
  187 + list_ ## type ## _node_t *, \
  188 + list_ ## type ## _node_t *);
  189 +
  190 +
  191 +/**
  192 + * \param type the datatype that this list code should handle.
  193 + * \pre Type must be a single word typename. If one wants
  194 + * to use e.g. lists of structs one has to use typedef
  195 + * to create a single word type name like this:
  196 + * typedef struct mystruct_t mystruct_t;
  197 + * \return Nothing
  198 + * \post All function prototypes for a lists of the given
  199 + * datatype are created.
  200 + *
  201 + * \brief Calls GEN_LIST_MAN_PROTO, GEN_LIST_NAV_PROTO and GEN_LIST_MOD_PROTO.
  202 + *
  203 + * This creates all the prototypes to the functions that are created by
  204 + * \link scot/list_impl.h::GEN_LIST_IMPL GEN_LIST_IMPL\endlink in
  205 + * \link scot/list_impl.h scot/list_impl.h\endlink.
  206 + * This provides one with the complete interface to the list of the given
  207 + * datatype.
  208 + */
  209 +#define GEN_LIST_FUNC_PROTO(type) \
  210 + GEN_LIST_MAN_PROTO (type); \
  211 + GEN_LIST_NAV_PROTO (type); \
  212 + GEN_LIST_MOD_PROTO (type);
  213 +
  214 +#endif /* LIST_FUNC_PROTO_H */
... ...
  1 +/**
  2 + * \file scot/list_impl.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Macro which creates functions for typesafe lists by templates.
  5 + *
  6 + * This combines the macro definitions in \link scot/list_man.h scot/list_man.h
  7 + * \endlink, \link scot/list_mod.h scot/list_mod.h \endlink and \link
  8 + * scot/list_nav.h scot/list_nav.h\endlink into one macro that is
  9 + * normally called within a c file that wants to use lists, as it provides
  10 + * you with all functions neccesary for list handling.\n
  11 + * Additionally the whole errorhandling code for lists is here. For that
  12 + * there are some function prototypes of functions implemented in
  13 + * \link list.c\endlink here. These functions do error output or will
  14 + * throw exceptions. Which function is called depends on if
  15 + * \link exception.c::USE_NO_EXCEPTIONS USE_NO_EXCEPTIONS\endlink is set at
  16 + * include time of this file, or not.
  17 + *
  18 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  19 + *
  20 + * This program is free software; you can redistribute it and/or modify
  21 + * it under the terms of the GNU General Public License as published by
  22 + * the Free Software Foundation; either version 2 of the License, or
  23 + * (at your option) any later version.
  24 + *
  25 + * This program is distributed in the hope that it will be useful,
  26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28 + * GNU General Public License for more details.
  29 + *
  30 + * You should have received a copy of the GNU General Public License
  31 + * along with this program; if not, write to the Free Software
  32 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  33 + */
  34 +#ifndef LIST_IMPL_H
  35 +#define LIST_IMPL_H
  36 +
  37 +
  38 +#include <scot/exception.h>
  39 +#include <scot/scot_types.h>
  40 +
  41 +/**
  42 + * \internal
  43 + * \param type the datatype that this queue code should handle.
  44 + * \param a a variable holding a pointer to queue_[type]_node_t.
  45 + *
  46 + * \pre Type must be a single word typename. If one wants
  47 + * to use e.g. lists of structs one has to use typedef
  48 + * to create a single word type name like this:
  49 + * typedef struct mystruct_t mystruct_t;
  50 + * a must be a valid pointer to a queue_[type]_node_t.
  51 + * \returns \a a cast to a pointer of list_[type]_node_t.
  52 + * \post None
  53 + *
  54 + * \brief Cast a pointer to list_[type]_node_t.
  55 + *
  56 + * FIXME: I should check better the validity of \a a.
  57 + */
  58 +#define LIST(type, a) (list_ ## type ## _node_t *) (a)
  59 +
  60 +void list_error_print (const char *, int, int);
  61 +void list_warning_print (const char *, int, int);
  62 +void list_error_throw (const char *, int, int);
  63 +void list_warning_throw (const char *, int, int);
  64 +void * list_malloc_print (SIZE_T, const char *, int);
  65 +void list_check_null_print (const void *, const char *, int);
  66 +void * list_malloc_throw (SIZE_T, const char *, int);
  67 +void list_check_null_throw (const void *, const char *, int);
  68 +
  69 +#ifdef USE_NO_EXCEPTION
  70 +# define LIST_ERROR(file, line, id) \
  71 + list_error_print ((file), (line), (id))
  72 +# define LIST_WARNING(file, line, id) \
  73 + list_warning_print ((file), (line), (id))
  74 +# define LIST_MALLOC(size, file, line) \
  75 + list_malloc_print ((size), (file), (line))
  76 +# define LIST_CHECK_NULL(val, file, line) \
  77 + list_check_null_print ((void *) (val), (file), (line))
  78 +# define LIST_EXC_START
  79 +# define LIST_EXC_END(file, line, id)
  80 +#else
  81 +/**
  82 + * \internal
  83 + * \param file filename of the file where the error occured.
  84 + * \param line line in the file where the error occured.
  85 + * \param id list error id.
  86 + *
  87 + * \brief print or thow an error
  88 + */
  89 +# define LIST_ERROR(file, line, id) \
  90 + list_error_throw ((file), (line), (id))
  91 +/**
  92 + * \internal
  93 + * \param file filename of the file where the error occured.
  94 + * \param line line in the file where the error occured.
  95 + * \param id list error id.
  96 + *
  97 + * \brief print or throw a warning
  98 + */
  99 +# define LIST_WARNING(file, line, id) \
  100 + list_warning_throw ((file), (line), (id))
  101 +/**
  102 + * \internal
  103 + * \param size the amount of memory that should be reserved.
  104 + * \param file filename of the file where this is called.
  105 + * \param line line in the file where this is called.
  106 + *
  107 + * \brief list malloc wrapper
  108 + *
  109 + * A malloc wrapper which either print an error or throw
  110 + * an exception.
  111 + */
  112 +# define LIST_MALLOC(size, file, line) \
  113 + list_malloc_throw ((size), (file), (line))
  114 +/**
  115 + * \internal
  116 + * \param val variable that should be check for NULL.
  117 + * \param file filename of the file where this is called.
  118 + * \param line line in the file where this is called.
  119 + *
  120 + * \brief this checks if val is null
  121 + */
  122 +# define LIST_CHECK_NULL(val, file, line) \
  123 + list_check_null_throw ((void *) (val), (file), (line))
  124 +/**
  125 + * \internal
  126 + * \brief start exception environment in generated list function.
  127 + */
  128 +# define LIST_EXC_START \
  129 + { \
  130 + excenv_t *ee; \
  131 + TRY {
  132 +/**
  133 + * \internal
  134 + * \brief end the exception environment of the generated list function.
  135 + *
  136 + * This ends the exception environment in the generated list
  137 + * function, that was started with LIST_EXC_START.
  138 + * Any exception that had occured will be forwarded in the upper
  139 + * exception environment and if exceptions had occured a new one
  140 + * will be thrown to the exception environment indicating that the
  141 + * function fails.
  142 + */
  143 +# define LIST_EXC_END(file, line, id) \
  144 + } \
  145 + CATCH (ee) \
  146 + { \
  147 + forward_all_exceptions (ee); \
  148 + list_error_throw ((file), (line), (id)); \
  149 + } \
  150 + }
  151 +#endif /* USE_NO_EXCEPTION */
  152 +
  153 +extern const char *list_err_msg[];
  154 +extern const char *list_wrn_msg[];
  155 +
  156 +struct list_node_t
  157 +{
  158 + const char _ [sizeof (struct {
  159 + const void *e;
  160 + const void *prev;
  161 + const void *next;
  162 + })];
  163 +};
  164 +
  165 +#ifdef GEN_LOCAL
  166 +/**
  167 + * \internal
  168 + * \brief make functions static or not dependig on if GEN_LOCAL was
  169 + * defined or not.
  170 + */
  171 +# define STATIC static
  172 +#else
  173 +# define STATIC
  174 +#endif
  175 +
  176 +#include "list_man.h"
  177 +#include "list_nav.h"
  178 +#include "list_mod.h"
  179 +
  180 +/**
  181 + * \param type the datatype that this list code should handle.
  182 + * \pre Type must be a single word typename. If one wants
  183 + * to use e.g. lists of structs one has to use typedef
  184 + * to create a single word type name like this:
  185 + * typedef struct mystruct_t mystruct_t;
  186 + * \return Nothing
  187 + * \post The functions, struct and globals to handle typesave
  188 + * lists for the given datatype are generated within the
  189 + * calling build file.
  190 + * FIXME: This seems not threadsafe to me, as the globals
  191 + * are used within all threads. Actually one could work
  192 + * around this because normally it is enough to set the
  193 + * comparison functions once and dont touch them anymore
  194 + * but it might be neccesary to compare elements within
  195 + * the list differently in different threads.
  196 + *
  197 + * \brief this creates all functions, structs and globals needed for a
  198 + * typesafe list of a given \a type.
  199 + *
  200 + * In detail the following is created by this macro:\n
  201 + * \li <b>struct list_[type]_node_t</b>: This is the structure a list
  202 + * is constructed of. A representation of a double linked list node with
  203 + * a pointer to the element it contains, a pointer to the next and a pointer
  204 + * to the previous element in the list. This list implementation uses a kind
  205 + * of a ringlist, that is the next pointer of the last node in the list
  206 + * and the prev pointer in the first element of the list points to the anchor.
  207 + * Thus in an empty list prev and next of the anchor both points to the
  208 + * anchor.
  209 + * \li <b>int list_[type]_default_cmp ()</b>: This is the default
  210 + * comparison function for lists. It simply compares the adresses of two
  211 + * elements. At list initialization list_[type]_compare() is set to this.
  212 + * \li <b>list_[type]_cmp_fptr list_[type]_compare</b>: This pointer
  213 + * to a function that compares list elements is used within the generated
  214 + * list functions.
  215 + * \li <b>list_[type]_elem_free_fptr list_[type]_elem_free</b>: This pointer
  216 + * , if set to non NULL, is used in list_[type]_delete() to free an
  217 + * element within a node before deleting the node. At initial time of
  218 + * the list code this is set to NULL, thus elements are not freed at all.
  219 + * (This is ok when stack variables are used, else one should at least
  220 + * set list_[type]_elem_free to free().)
  221 + * \li all functions defined in \link scot/list_man.h list_man.h\endlink,
  222 + * \link scot/list_mod.h list_mod.h\endlink and
  223 + * \link scot/list_nav.h list_nav.h\endlink.
  224 + */
  225 +#define GEN_LIST_IMPL(type) \
  226 +struct list_ ## type ## _node_t \
  227 +{ \
  228 + const type *e; \
  229 + struct list_ ## type ## _node_t *prev; \
  230 + struct list_ ## type ## _node_t *next; \
  231 +}; \
  232 + \
  233 +STATIC \
  234 +int list_ ## type ## _default_cmp ( \
  235 + const type * a, \
  236 + const type * b) \
  237 +{ \
  238 + return (a==b)?0:(a<b)?-1:1; \
  239 +} \
  240 + \
  241 +STATIC \
  242 +list_ ## type ## _cmp_fptr \
  243 +list_ ## type ## _compare = list_ ## type ## _default_cmp; \
  244 +STATIC \
  245 +list_ ## type ## _elem_free_fptr \
  246 +list_ ## type ## _elem_free = NULL; \
  247 + \
  248 +GEN_LIST_MANAGEMENT (type); \
  249 +GEN_LIST_NAVIGATION (type); \
  250 +GEN_LIST_MODIFY (type);
  251 +
  252 +#endif /* LIST_IMPL_H */
... ...
  1 +/**
  2 + * \file scot/list_man.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Templates of functions to manage typesafe lists.
  5 + *
  6 + * Here are macro definitions that create functions to manage typesafe
  7 + * lists. That is create new list, free list, check nodes a.s.f
  8 + *
  9 + * Normally the macros defined here will be never called directly but only
  10 + * via MACROS that group them in a sensefull way in scot/list_impl.h.\n
  11 + * \anchor onlyfunc_man
  12 + * \attention
  13 + * All documentation here does document the functions that are created by
  14 + * the macros, as the macros themself are pretty easy and all used the same.
  15 + * They are called with a type, that MUST be one word (use typedef if needed)
  16 + * and generates the function defined with their value.
  17 + *
  18 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  19 + *
  20 + * This program is free software; you can redistribute it and/or modify
  21 + * it under the terms of the GNU General Public License as published by
  22 + * the Free Software Foundation; either version 2 of the License, or
  23 + * (at your option) any later version.
  24 + *
  25 + * This program is distributed in the hope that it will be useful,
  26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28 + * GNU General Public License for more details.
  29 + *
  30 + * You should have received a copy of the GNU General Public License
  31 + * along with this program; if not, write to the Free Software
  32 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  33 + */
  34 +#ifndef LIST_MAN_H
  35 +#define LIST_MAN_H
  36 +
  37 +#include <stdlib.h>
  38 +#include <scot/list_impl.h>
  39 +#include <scot/memory.h> /* because we use functions from there */
  40 +
  41 +
  42 +/**
  43 + * \internal
  44 + * \param node a list_[type]_node_t* that should be checked for
  45 + * beeing an anchor.
  46 + * \param line the line where this MACRO is called.
  47 + * \pre a variable of type list_[type]_node_t* must exist.
  48 + * \return the code fragment
  49 + * \post None
  50 + *
  51 + * \brief check for anchor.
  52 + *
  53 + * This checks if the given \a node is an anchor. If not it calls
  54 + * LIST_ERROR, which either raises an exception if exceptions are user
  55 + * or otherwise prints out an error message to stderr and aborts the
  56 + * program.
  57 + */
  58 +#define MAN_NODE_NO_ANCHOR_ERROR(node, line) \
  59 + if ((node->e) != NULL) \
  60 + LIST_ERROR ("list_man.h", (line), NODE_NO_ANCHOR_ERR);
  61 +
  62 +/**
  63 + * \attention
  64 + * Only the generated function is explained here, for the reason look
  65 + * \ref onlyfunc_man "here".
  66 + *
  67 + * \param anchor a pointer that should contain the list anchor.
  68 + * \pre None
  69 + * \return NULL on error, but only if no exceptions are used.
  70 + * If exceptions are used an exception is thrown on error.
  71 + * On success a pointer to the newly created list_anchor
  72 + * will be returned.
  73 + * \retval NULL if an error occurs and no exceptions are used.
  74 + * \retval !=NULL the pointer to the newly created list anchor.
  75 + * \post enough memory on the heap.
  76 + *
  77 + * \brief template for list constructor.
  78 + *
  79 + * The function creates a new list anchor on the heap and returns it.
  80 + * This can be used with following list_[type]_*() functions.
  81 + * The memory reserved for this anchor must be freed by the context
  82 + * that uses this function if it did not need the list anymore.\n\n
  83 + */
  84 +#define GEN_LIST_NEW(type) \
  85 + STATIC \
  86 + list_ ## type ## _node_t * \
  87 + list_ ## type ## _new (list_ ## type ## _node_t *anchor) \
  88 + { \
  89 + LIST_EXC_START \
  90 + { \
  91 + anchor = (list_ ## type ## _node_t *) \
  92 + LIST_MALLOC (sizeof (list_ ## type ## _node_t), \
  93 + "list_man.h", 93); \
  94 + \
  95 + anchor->e = NULL; \
  96 + anchor->prev = anchor; \
  97 + anchor->next = anchor; \
  98 + } \
  99 + LIST_EXC_END ("list_man.h", 99, LIST_NEW_ERR); \
  100 + \
  101 + return anchor; \
  102 + }
  103 +
  104 +/**
  105 + * \attention
  106 + * Only the generated function is explained here, for the reason look
  107 + * \ref onlyfunc_man "here".
  108 + *
  109 + * \param anchor A pointer to the list anchor.
  110 + * \pre anchor must point to a valid list anchor previously
  111 + * assigned by list_[type]_new().
  112 + * \return Nothing
  113 + * \post The list is completely removed from the heap.
  114 + *
  115 + * \brief template for list destructor.
  116 + *
  117 + * The function frees a list given by its anchor. It uses list_[type]_delete()
  118 + * to delete every node one by one and finally it calls free on the anchor.
  119 + * list_[type]_delete does by default only delete the node and not the
  120 + * stored element. Read here to learn more.
  121 + */
  122 +#define GEN_LIST_FREE(type) \
  123 + STATIC \
  124 + void \
  125 + list_ ## type ## _free (list_ ## type ## _node_t *anchor) \
  126 + { \
  127 + list_ ## type ## _node_t *next; \
  128 + \
  129 + LIST_EXC_START \
  130 + { \
  131 + LIST_CHECK_NULL (anchor, "list_man.h", 48); \
  132 + MAN_NODE_NO_ANCHOR_ERROR (anchor, 49); \
  133 + \
  134 + next = list_ ## type ## _next (anchor); \
  135 + while (anchor != next) \
  136 + next = list_ ## type ## _delete (next); \
  137 + \
  138 + SCOT_MEM_FREE (anchor); \
  139 + } \
  140 + LIST_EXC_END ("list_man.h", 58, LIST_FREE_ERR); \
  141 + }
  142 +
  143 +/**
  144 + * \attention
  145 + * Only the generated function is explained here, for the reason look
  146 + * \ref onlyfunc_man "here".
  147 + *
  148 + * \param anchor A pointer to the list anchor.
  149 + * \param e A pointer to a variable of the \a type, the
  150 + * list was created for.
  151 + * \pre The \a anchor has to be not NULL and a valid
  152 + * anchor.\a e must not be NULL.
  153 + * \return The node that contains \a e.
  154 + * \post None
  155 + *
  156 + * \brief Find the node in the list that contains \a e.
  157 + */
  158 +#define GEN_LIST_COUNT(type) \
  159 + STATIC \
  160 + int \
  161 + list_ ## type ## _count (list_ ## type ## _node_t * anchor) \
  162 + { \
  163 + int ret = 0; \
  164 + \
  165 + LIST_EXC_START \
  166 + { \
  167 + list_ ## type ## _node_t *node; \
  168 + \
  169 + LIST_CHECK_NULL (anchor, "list_nav.h", 170); \
  170 + NAV_NODE_NO_ANCHOR_ERROR (anchor, 171); \
  171 + \
  172 + node = anchor; \
  173 + while (! list_ ## type ## _eol (anchor, node)) \
  174 + { \
  175 + node = node->next; \
  176 + \
  177 + if (node->e != NULL) \
  178 + ret ++; \
  179 + } \
  180 + } \
  181 + LIST_EXC_END ("list_man.h", 182, LIST_COUNT_ERR); \
  182 + \
  183 + return ret; \
  184 + }
  185 +
  186 +/**
  187 + * \attention
  188 + * Only the generated function is explained here, for the reason look
  189 + * \ref onlyfunc_man "here".
  190 + *
  191 + * \param anchor A pointer to the list anchor.
  192 + * \param node A pointer to a node in the list.
  193 + * \pre The \a anchor has to be not NULL and a valid
  194 + * anchor, the node has to be not NULL too.
  195 + * \return A boolean indicating if the first non-anchor
  196 + * node in the list is node. Tested by the address
  197 + * of the node, so it really must be the same
  198 + * address.
  199 + * \retval TRUE The node is the first node in the list.
  200 + * \retval FALSE The node is not the first node in the list.
  201 + * \post None
  202 + *
  203 + * \brief Checks if node is at the beginning of the list.
  204 + */
  205 +#define GEN_LIST_BOL(type) \
  206 + STATIC \
  207 + int \
  208 + list_ ## type ## _bol ( \
  209 + list_ ## type ## _node_t *anchor, \
  210 + list_ ## type ## _node_t *node) \
  211 + { \
  212 + LIST_EXC_START \
  213 + { \
  214 + LIST_CHECK_NULL (anchor, "list_man.h", 70); \
  215 + LIST_CHECK_NULL (node, "list_man.h", 71); \
  216 + MAN_NODE_NO_ANCHOR_ERROR (anchor, 72); \
  217 + } \
  218 + LIST_EXC_END ("list_man.h", 74, LIST_BOL_ERR); \
  219 + \
  220 + return anchor->next==node; \
  221 + }
  222 +
  223 +/**
  224 + * \attention
  225 + * Only the generated function is explained here, for the reason look
  226 + * \ref onlyfunc_man "here".
  227 + *
  228 + * \param anchor A pointer to the list anchor.
  229 + * \param node A pointer to a node in the list.
  230 + * \pre The \a anchor has to be not NULL and a valid
  231 + * anchor, the node has to be not NULL too.
  232 + * \return A boolean indicating if the last non-anchor
  233 + * node in the list is node. Tested by the address
  234 + * of the node, so it really must be the same
  235 + * address.
  236 + * \retval TRUE The node is the last node in the list.
  237 + * \retval FALSE The node is not the last node in the list.
  238 + * \post None
  239 + *
  240 + * \brief Checks if node is at the end of the list.
  241 + */
  242 +#define GEN_LIST_EOL(type) \
  243 + STATIC \
  244 + int \
  245 + list_ ## type ## _eol ( \
  246 + list_ ## type ## _node_t *anchor, \
  247 + list_ ## type ## _node_t *node) \
  248 + { \
  249 + LIST_EXC_START \
  250 + { \
  251 + LIST_CHECK_NULL (anchor, "list_man.h", 88); \
  252 + LIST_CHECK_NULL (node, "list_man.h", 89); \
  253 + MAN_NODE_NO_ANCHOR_ERROR (anchor, 90); \
  254 + } \
  255 + LIST_EXC_END ("list_man.h", 92, LIST_EOL_ERR); \
  256 + \
  257 + if (list_ ## type ## _isempty (anchor)) return -1; \
  258 + return node->next==anchor; \
  259 + }
  260 +
  261 +/**
  262 + * \attention
  263 + * Only the generated function is explained here, for the reason look
  264 + * \ref onlyfunc_man "here".
  265 + *
  266 + * \param anchor A pointer to the list anchor.
  267 + * \pre The \a anchor has to be not NULL and a valid
  268 + * anchor.
  269 + * \return A boolean indicating if the last non-anchor
  270 + * node in the list is node. Tested by the address
  271 + * of the node, so it really must be the same
  272 + * address.
  273 + * \retval TRUE The node is the last node in the list.
  274 + * \retval FALSE The node is not the last node in the list.
  275 + * \post None
  276 + *
  277 + * \brief Checks if node is at the end of the list.
  278 + */
  279 +#define GEN_LIST_ISEMPTY(type) \
  280 + STATIC \
  281 + int \
  282 + list_ ## type ## _isempty (list_ ## type ## _node_t *anchor) \
  283 + { \
  284 + LIST_EXC_START \
  285 + LIST_CHECK_NULL (anchor, "list_man.h", 103); \
  286 + LIST_EXC_END ("list_man.h", 104, LIST_ISEMPTY_ERR); \
  287 + \
  288 + return (anchor->prev==anchor && anchor->next==anchor); \
  289 + }
  290 +
  291 +/**
  292 + * \attention
  293 + * Only the generated function is explained here, for the reason look
  294 + * \ref onlyfunc_man "here".
  295 + *
  296 + * \param cmp A pointer to a function that compares two
  297 + * variables of \a type.
  298 + * \pre None
  299 + * \return Nothing
  300 + * \post None
  301 + *
  302 + * \brief Set the compare function to \a cmp.
  303 + *
  304 + * This sets the compare function used by some functions generated
  305 + * for a list of the \a type datatype. This compare function has
  306 + * to work similar to strcmp. It should return either <0, ==0 or >0
  307 + * depending on what comparator is lesser, greater or equal.
  308 + */
  309 +#define GEN_LIST_SET_CMP(type) \
  310 + STATIC \
  311 + void \
  312 + list_ ## type ## _set_cmp (list_ ## type ## _cmp_fptr cmp) \
  313 + { \
  314 + list_ ## type ## _compare = cmp; \
  315 + }
  316 +
  317 +/**
  318 + * \attention
  319 + * Only the generated function is explained here, for the reason look
  320 + * \ref onlyfunc_man "here".
  321 + *
  322 + * \param cmp A pointer to a function that compares two
  323 + * variables of \a type.
  324 + * \pre None
  325 + * \return Nothing
  326 + * \post None
  327 + *
  328 + * \brief Set the compare function to \a cmp.
  329 + *
  330 + * This sets the compare function used by some functions generated
  331 + * for a list of the \a type datatype. This compare function has
  332 + * to work similar to strcmp. It should return either <0, ==0 or >0
  333 + * depending on what comparator is lesser, greater or equal.
  334 + */
  335 +#define GEN_LIST_SET_ELEM_FREE(type) \
  336 + STATIC \
  337 + void \
  338 + list_ ## type ## _set_elem_free ( \
  339 + list_ ## type ## _elem_free_fptr efree) \
  340 + { \
  341 + list_ ## type ## _elem_free = efree; \
  342 + }
  343 +
  344 +
  345 +
  346 +#define GEN_LIST_ELEM_FREE_IS_SET(type) \
  347 + STATIC \
  348 + long \
  349 + list_ ## type ## _elem_free_is_set (void) \
  350 + { \
  351 + return (long) list_ ## type ## _elem_free; \
  352 + }
  353 +
  354 +
  355 +/**
  356 + * \param type the datatype that this list code should handle.
  357 + * \pre Type must be a single word typename. If one wants
  358 + * to use e.g. lists of structs one has to use typedef
  359 + * to create a single word type name like this:
  360 + * typedef struct mystruct_t mystruct_t;
  361 + * \return Nothing
  362 + * \post The functions for the given datatype that are described
  363 + * here are generated within the calling build file.
  364 + *
  365 + * \brief create functions neccesary to manage lists of the given \a type.
  366 + *
  367 + * Normally this is not called directly, but by GEN_LIST_IMPL() because this
  368 + * defined just a subset of all functions neccesarry to handle typesafe lists.
  369 + */
  370 +#define GEN_LIST_MANAGEMENT(type) \
  371 + GEN_LIST_SET_CMP (type); \
  372 + GEN_LIST_SET_ELEM_FREE (type); \
  373 + GEN_LIST_ELEM_FREE_IS_SET (type) \
  374 + GEN_LIST_NEW (type); \
  375 + GEN_LIST_FREE (type); \
  376 + GEN_LIST_COUNT (type); \
  377 + GEN_LIST_BOL (type); \
  378 + GEN_LIST_ISEMPTY (type); \
  379 + GEN_LIST_EOL (type);
  380 +
  381 +
  382 +#endif /* LIST_MAN_H */
... ...
  1 +/**
  2 + * \file scot/list_mod.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Templates of functions to modify typesafe lists.
  5 + *
  6 + * Here are macro definitions that create functions to modify typesafe
  7 + * lists. That is read, write, insert, delete a.s.f.
  8 + *
  9 + * Normally the macros defined here will be never called directly but only
  10 + * via MACROS that group them in a sensefull way in scot/list_impl.h.\n
  11 + * \anchor onlyfunc_mod
  12 + * \attention
  13 + * All documentation here does document the functions that are created by
  14 + * the macros, as the macros themself are pretty easy and all used the same.
  15 + * They are called with a type, that MUST be one word (use typedef if needed)
  16 + * and generates the function defined with their value.
  17 + *
  18 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  19 + *
  20 + * This program is free software; you can redistribute it and/or modify
  21 + * it under the terms of the GNU General Public License as published by
  22 + * the Free Software Foundation; either version 2 of the License, or
  23 + * (at your option) any later version.
  24 + *
  25 + * This program is distributed in the hope that it will be useful,
  26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28 + * GNU General Public License for more details.
  29 + *
  30 + * You should have received a copy of the GNU General Public License
  31 + * along with this program; if not, write to the Free Software
  32 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  33 + */
  34 +#ifndef LIST_MOD_H
  35 +#define LIST_MOD_H
  36 +
  37 +#include <stdlib.h>
  38 +#include <scot/list_impl.h>
  39 +#include <scot/memory.h> /* because we use functions from there */
  40 +
  41 +
  42 +/**
  43 + * \internal
  44 + * \param node a list_[type]_node_t* that should be checked for
  45 + * beeing an anchor.
  46 + * \param line the line where this MACRO is called.
  47 + * \pre a variable of type list_<type>_node_t* must exist.
  48 + * \return the code fragment
  49 + * \post None
  50 + *
  51 + * \brief check for anchor.
  52 + *
  53 + * This checks if the given \a node is an anchor. If not it calls
  54 + * LIST_ERROR, which either raises an exception if exceptions are user
  55 + * or otherwise prints out an error message to stderr and aborts the
  56 + * program.
  57 + */
  58 +#define MOD_NODE_NO_ANCHOR_ERROR(node, line) \
  59 + if ((node->e) != NULL) \
  60 + LIST_ERROR ("list_mod.h", (line), NODE_NO_ANCHOR_ERR);
  61 +
  62 +
  63 +/**
  64 + * \attention
  65 + * Only the generated function is explained here, for the reason look
  66 + * \ref onlyfunc_mod "here".
  67 + *
  68 + * \param node A pointer to a node in the list.
  69 + * \pre The \a node must be part of a correctly
  70 + * initialized list.
  71 + * \return The element saved in the node.
  72 + * \post None
  73 + *
  74 + * \brief Retrive element from node.
  75 + *
  76 + * This function retrieves the element from a node of a list.
  77 + */
  78 +#define GEN_LIST_RETRIVE(type) \
  79 + STATIC \
  80 + type * \
  81 + list_ ## type ## _retrive (list_ ## type ## _node_t *node) \
  82 + { \
  83 + LIST_EXC_START \
  84 + LIST_CHECK_NULL (node, "list_mod.h", 18); \
  85 + LIST_EXC_END ("list_mod.h", 19, LIST_RETR_ERR); \
  86 + \
  87 + return (type *) node->e; \
  88 + }
  89 +
  90 +/**
  91 + * \attention
  92 + * Only the generated function is explained here, for the reason look
  93 + * \ref onlyfunc_mod "here".
  94 + *
  95 + * \param node A pointer to a node in the list.
  96 + * \param e A pointer to a variable of the \a type, the
  97 + * list was created for.
  98 + * \pre The \a node must be part of a correctly
  99 + * initialized list. \a e must not be NULL.
  100 + * \return Nothing
  101 + * \post The element of \a node is \a e.
  102 + *
  103 + * \brief Set element od node.
  104 + *
  105 + * This function sets the element from a node of a list.
  106 + */
  107 +#define GEN_LIST_SET(type) \
  108 + STATIC \
  109 + void \
  110 + list_ ## type ## _set ( \
  111 + list_ ## type ## _node_t *node, \
  112 + const type *e) \
  113 + { \
  114 + LIST_EXC_START \
  115 + { \
  116 + LIST_CHECK_NULL (node, "list_mod.h", 33); \
  117 + LIST_CHECK_NULL (e, "list_mod.h", 34); \
  118 + } \
  119 + LIST_EXC_END ("list_mod.h", 36, LIST_SET_ERR); \
  120 + \
  121 + node->e = e; \
  122 + }
  123 +
  124 +/**
  125 + * \attention
  126 + * Only the generated function is explained here, for the reason look
  127 + * \ref onlyfunc_mod "here".
  128 + *
  129 + * \param node A pointer to a node in the list.
  130 + * \param e A pointer to a variable of the \a type, the
  131 + * list was created for.
  132 + * \pre The \a node must be part of a correctly
  133 + * initialized list.
  134 + * \a e must not be NULL.
  135 + * \return The node of the inserted element.
  136 + * \post List has one new node containing \a e.
  137 + *
  138 + * \brief Inserts a new node with element \a e into the list.
  139 + *
  140 + * This function creates a new list node and initializes it with
  141 + * \a e. Then this new node will be inserted behind \a node.
  142 + */
  143 +#define GEN_LIST_INSERT(type) \
  144 + STATIC \
  145 + list_ ## type ## _node_t * \
  146 + list_ ## type ## _insert ( \
  147 + list_ ## type ## _node_t *node, \
  148 + const type *e) \
  149 + { \
  150 + list_ ## type ## _node_t *ret; \
  151 + \
  152 + LIST_EXC_START \
  153 + { \
  154 + list_ ## type ## _node_t *new_node; \
  155 + \
  156 + LIST_CHECK_NULL (node, "list_mod.h", 54); \
  157 + LIST_CHECK_NULL (e, "list_mod.h", 55); \
  158 + \
  159 + new_node = (list_ ## type ## _node_t *) \
  160 + LIST_MALLOC (sizeof (list_ ## type ## _node_t), \
  161 + "list_mod.h", 58); \
  162 + \
  163 + new_node->e = e; \
  164 + new_node->prev = node; \
  165 + new_node->next = node->next; \
  166 + node->next->prev = new_node; \
  167 + node->next = new_node; \
  168 + \
  169 + ret = new_node; \
  170 + } \
  171 + LIST_EXC_END ("list_mod.h", 69, LIST_INSERT_ERR); \
  172 + \
  173 + return ret; \
  174 + }
  175 +
  176 +/**
  177 + * \attention
  178 + * Only the generated function is explained here, for the reason look
  179 + * \ref onlyfunc_mod "here".
  180 + *
  181 + * \param node A pointer to a node in the list.
  182 + * \pre The \a node must be part of a correctly
  183 + * initialized list.
  184 + * \return The next node behind the deleted one.
  185 + * \post The \a node is removed from the list and
  186 + * freed.
  187 + *
  188 + * \brief Deletes a new node with element \a e into the list.
  189 + *
  190 + * This function deletes a node from the list it is in. The node
  191 + * will be freed but by default NOT the element. Anyway, one can set
  192 + * a free function for elements of the list. This should free any
  193 + * resource the element has reserved.
  194 + * This function can be set with
  195 + * \link list_man.h::GEN_LIST_SET_ELEM_FREE
  196 + * list_[type]_set_elem_free ()\endlink
  197 + * and if set, is called by list_[type]_delete(). If such a function
  198 + * was set and one wants to reset to default behaviour (not to delete any
  199 + * element) one can pass NULL to \link list_man.h::GEN_LIST_SET_ELEM_FREE
  200 + * list_[type]_set_elem_free ()\endlink.
  201 + */
  202 +#define GEN_LIST_DELETE(type) \
  203 + STATIC \
  204 + list_ ## type ## _node_t * \
  205 + list_ ## type ## _delete (list_ ## type ## _node_t *node) \
  206 + { \
  207 + type *e; \
  208 + list_ ## type ## _node_t *prev, \
  209 + *next; \
  210 + \
  211 + LIST_EXC_START \
  212 + { \
  213 + if (list_ ## type ## _isempty (node)) \
  214 + LIST_WARNING ("list_mod.h", 86, DEL_ON_EMPTY_LIST_WRN); \
  215 + \
  216 + e = (type *) node->e; \
  217 + \
  218 + prev = node->prev; \
  219 + next = node->next; \
  220 + prev->next = next; \
  221 + next->prev = prev; \
  222 + \
  223 + if (list_ ## type ## _elem_free != NULL && e != NULL) \
  224 + list_ ## type ## _elem_free (e); \
  225 + \
  226 + SCOT_MEM_FREE (node); \
  227 + } \
  228 + LIST_EXC_END ("list_mod.h", 101, LIST_DELETE_ERR); \
  229 + \
  230 + return next; \
  231 + }
  232 +
  233 +/**
  234 + * \attention
  235 + * Only the generated function is explained here, for the reason look
  236 + * \ref onlyfunc_mod "here".
  237 + *
  238 + * \param anchor1 A pointer to the first list anchor.
  239 + * \param anchor2 A pointer to the second list anchor.
  240 + * \pre Both, \a anchor1 and \a anchor2 must be
  241 + * valid list_anchors.
  242 + * \return The anchor of the new concatenated list.
  243 + * \post A new list was created that contains both
  244 + * given lists. The anchor of at least one of the
  245 + * given lists is no longer valid and should no
  246 + * longer be used. In fact only the returned
  247 + * anchor is garantied to point to a valid list.
  248 + *
  249 + * \brief Concatenates two lists.
  250 + *
  251 + * This function joins the given two list to one. This will be done
  252 + * partly destructive...that is, at least one of the old anchors
  253 + * will be deleted.
  254 + */
  255 +#define GEN_LIST_CONCAT(type) \
  256 + STATIC \
  257 + list_ ## type ## _node_t * \
  258 + list_ ## type ## _concat ( \
  259 + list_ ## type ## _node_t *anchor1, \
  260 + list_ ## type ## _node_t *anchor2) \
  261 + { \
  262 + LIST_EXC_START \
  263 + { \
  264 + LIST_CHECK_NULL (anchor1, "list_mod.h", 115); \
  265 + MOD_NODE_NO_ANCHOR_ERROR (anchor1, 116); \
  266 + LIST_CHECK_NULL (anchor2, "list_mod.h", 117); \
  267 + MOD_NODE_NO_ANCHOR_ERROR (anchor2, 118); \
  268 + } \
  269 + LIST_EXC_END ("list_mod.h", 120, LIST_CONCAT_ERR); \
  270 + \
  271 + if (list_ ## type ## _isempty (anchor1)) \
  272 + return anchor2; \
  273 + \
  274 + if (list_ ## type ## _isempty (anchor2)) \
  275 + return anchor1; \
  276 + \
  277 + anchor2->next->prev = anchor1->prev; \
  278 + anchor2->prev->next = anchor1; \
  279 + anchor1->prev->next = anchor2->next; \
  280 + anchor1->prev = anchor2->prev; \
  281 + }
  282 +
  283 +
  284 +/**
  285 + * \param type the datatype that this list code should handle.
  286 + * \pre Type must be a single word typename. If one wants
  287 + * to use e.g. lists of structs one has to use typedef
  288 + * to create a single word type name like this:
  289 + * typedef struct mystruct_t mystruct_t;
  290 + * \return Nothing
  291 + * \post The functions for the given datatype that are described
  292 + * here are generated within the calling build file.
  293 + *
  294 + * \brief create functions neccesary to modify lists of the given \a type.
  295 + *
  296 + * Normally this is not called directly, but by GEN_LIST_IMPL() because this
  297 + * defines just a subset of all functions neccesarry to handle typesafe lists.
  298 + */
  299 +#define GEN_LIST_MODIFY(type) \
  300 + GEN_LIST_RETRIVE (type); \
  301 + GEN_LIST_SET (type); \
  302 + GEN_LIST_INSERT (type); \
  303 + GEN_LIST_DELETE (type); \
  304 + GEN_LIST_CONCAT (type);
  305 +
  306 +
  307 +
  308 +#endif /* LIST_MOD_H */
... ...
  1 +/**
  2 + * \file scot/list_nav.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Templates of functions to navigate within typesafe lists.
  5 + *
  6 + * Here are macro definitions that create functions to navigate within
  7 + * typesafe lists. That is get next node, get first node a.s.f
  8 + *
  9 + * Normally the macros defined here will be never called directly but only
  10 + * via MACROS that group them in a sensefull way in scot/list_impl.h.\n
  11 + * \anchor onlyfunc_nav
  12 + * \attention
  13 + * All documentation here does document the functions that are created by
  14 + * the macros, as the macros themself are pretty easy and all used the same.
  15 + * They are called with a type, that MUST be one word (use typedef if needed)
  16 + * and generates the function defined with their value.
  17 + *
  18 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  19 + *
  20 + * This program is free software; you can redistribute it and/or modify
  21 + * it under the terms of the GNU General Public License as published by
  22 + * the Free Software Foundation; either version 2 of the License, or
  23 + * (at your option) any later version.
  24 + *
  25 + * This program is distributed in the hope that it will be useful,
  26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28 + * GNU General Public License for more details.
  29 + *
  30 + * You should have received a copy of the GNU General Public License
  31 + * along with this program; if not, write to the Free Software
  32 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  33 + */
  34 +#ifndef LIST_NAV_H
  35 +#define LIST_NAV_H
  36 +
  37 +#include <stdlib.h>
  38 +#include <scot/list_impl.h>
  39 +
  40 +
  41 +
  42 +/**
  43 + * \internal
  44 + * \param node a list_[type]_node_t* that should be checked for
  45 + * beeing an anchor.
  46 + * \param line the line where this MACRO is called.
  47 + * \pre a variable of type list_[type]_node_t* must exist.
  48 + * \return the code fragment
  49 + * \post None
  50 + *
  51 + * \brief check for anchor.
  52 + *
  53 + * This checks if the given \a node is an anchor. If not it calls
  54 + * LIST_ERROR, which either raises an exception if exceptions are user
  55 + * or otherwise prints out an error message to stderr and aborts the
  56 + * program.
  57 + */
  58 +#define NAV_NODE_NO_ANCHOR_ERROR(node, line) \
  59 + if ((node->e) != NULL) \
  60 + LIST_ERROR ("list_nav.h", (line), NODE_NO_ANCHOR_ERR);
  61 +
  62 +
  63 +/**
  64 + * \attention
  65 + * Only the generated function is explained here, for the reason look
  66 + * \ref onlyfunc_man "here".
  67 + *
  68 + * \param anchor A pointer to the list anchor.
  69 + * \pre The \a anchor has to be not NULL and a valid
  70 + * anchor.
  71 + * \return The first node in the list, that is normally
  72 + * the anchor, thus this is pretty useless.
  73 + * \post None
  74 + *
  75 + * \brief Returns the first element in the list, that is the anchor...
  76 + * pathetic...
  77 + */
  78 +#define GEN_LIST_FRONT(type) \
  79 + STATIC \
  80 + list_ ## type ## _node_t * \
  81 + list_ ## type ## _front (list_ ## type ## _node_t *anchor) \
  82 + { \
  83 + LIST_EXC_START \
  84 + { \
  85 + LIST_CHECK_NULL (anchor, "list_nav.h", 20); \
  86 + NAV_NODE_NO_ANCHOR_ERROR (anchor, 21); \
  87 + } \
  88 + LIST_EXC_END ("list_nav.h", 23, LIST_FRONT_ERR); \
  89 + \
  90 + return anchor; \
  91 + }
  92 +
  93 +/**
  94 + * \attention
  95 + * Only the generated function is explained here, for the reason look
  96 + * \ref onlyfunc_man "here".
  97 + *
  98 + * \param anchor A pointer to the list anchor.
  99 + * \pre The \a anchor has to be not NULL and a valid
  100 + * anchor.
  101 + * \return The last node in the list.
  102 + * \post None
  103 + *
  104 + * \brief Get the last node in the list.
  105 + */
  106 +#define GEN_LIST_LAST(type) \
  107 + STATIC \
  108 + list_ ## type ## _node_t * \
  109 + list_ ## type ## _last (list_ ## type ## _node_t *anchor) \
  110 + { \
  111 + LIST_EXC_START \
  112 + { \
  113 + LIST_CHECK_NULL (anchor, "list_nav.h", 35); \
  114 + NAV_NODE_NO_ANCHOR_ERROR (anchor, 36); \
  115 + } \
  116 + LIST_EXC_END ("list_nav.h", 38, LIST_LAST_ERR); \
  117 + \
  118 + return anchor->prev; \
  119 + }
  120 +
  121 +/**
  122 + * \attention
  123 + * Only the generated function is explained here, for the reason look
  124 + * \ref onlyfunc_man "here".
  125 + *
  126 + * \param node A pointer to a node in the list.
  127 + * \pre The node has to be not NULL and should be in
  128 + * a linked list.
  129 + * \return The next node after the given node.
  130 + * \post None
  131 + *
  132 + * \brief Get the next node in the list.
  133 + */
  134 +#define GEN_LIST_NEXT(type) \
  135 + STATIC \
  136 + list_ ## type ## _node_t * \
  137 + list_ ## type ## _next (list_ ## type ## _node_t *node) \
  138 + { \
  139 + LIST_EXC_START \
  140 + LIST_CHECK_NULL (node, "list_nav.h", 49); \
  141 + LIST_EXC_END ("list_nav.h", 50, LIST_NEXT_ERR); \
  142 + \
  143 + return node->next; \
  144 + }
  145 +
  146 +/**
  147 + * \attention
  148 + * Only the generated function is explained here, for the reason look
  149 + * \ref onlyfunc_man "here".
  150 + *
  151 + * \param node A pointer to a node in the list.
  152 + * \pre The node has to be not NULL and should be in
  153 + * a linked list.
  154 + * \return The previous node after the given node.
  155 + * \post None
  156 + *
  157 + * \brief Get the previous node in the list.
  158 + */
  159 +#define GEN_LIST_PREV(type) \
  160 + STATIC \
  161 + list_ ## type ## _node_t * \
  162 + list_ ## type ## _prev (list_ ## type ## _node_t *node) \
  163 + { \
  164 + LIST_EXC_START \
  165 + LIST_CHECK_NULL (node, "list_nav.h", 61); \
  166 + LIST_EXC_END ("list_nav.h", 62, LIST_PREV_ERR); \
  167 + \
  168 + return node->prev; \
  169 + }
  170 +
  171 +/**
  172 + * \attention
  173 + * Only the generated function is explained here, for the reason look
  174 + * \ref onlyfunc_man "here".
  175 + *
  176 + * \param anchor A pointer to the list anchor.
  177 + * \param e A pointer to a variable of the \a type, the
  178 + * list was created for.
  179 + * \pre The \a anchor has to be not NULL and a valid
  180 + * anchor.\a e must not be NULL.
  181 + * \return The node that contains \a e.
  182 + * \post None
  183 + *
  184 + * \brief Find the node in the list that contains \a e.
  185 + */
  186 +#define GEN_LIST_FIND(type) \
  187 + STATIC \
  188 + list_ ## type ## _node_t * \
  189 + list_ ## type ## _find ( \
  190 + list_ ## type ## _node_t *anchor, \
  191 + const type *e) \
  192 + { \
  193 + list_ ## type ## _node_t *ret = NULL; \
  194 + \
  195 + LIST_EXC_START \
  196 + { \
  197 + list_ ## type ## _node_t *node; \
  198 + \
  199 + LIST_CHECK_NULL (anchor, "list_nav.h", 80); \
  200 + NAV_NODE_NO_ANCHOR_ERROR (anchor, 81); \
  201 + \
  202 + node = anchor; \
  203 + while (! list_ ## type ## _eol (anchor, node)) \
  204 + { \
  205 + node = node->next; \
  206 + \
  207 + if (node->e != NULL) \
  208 + if (list_ ## type ## _compare (e, node->e) == 0) \
  209 + ret = node; \
  210 + } \
  211 + } \
  212 + LIST_EXC_END ("list_nav.h", 93, LIST_FIND_ERR); \
  213 + \
  214 + return ret; \
  215 + }
  216 +
  217 +/**
  218 + * \attention
  219 + * Only the generated function is explained here, for the reason look
  220 + * \ref onlyfunc_man "here".
  221 + *
  222 + * \param node A pointer to a node in the list.
  223 + * \pre The node has to be not NULL and should be in
  224 + * a linked list.
  225 + * \return The anchor of the list, the \a node is in.
  226 + * \post None
  227 + *
  228 + * \brief Get the anchor of the list.
  229 + */
  230 +#define GEN_LIST_FIND_ANCHOR(type) \
  231 + STATIC \
  232 + list_ ## type ## _node_t * \
  233 + list_ ## type ## _find_anchor ( \
  234 + list_ ## type ## _node_t *entry) \
  235 + { \
  236 + list_ ## type ## _node_t *ret = NULL; \
  237 + \
  238 + LIST_EXC_START \
  239 + { \
  240 + list_ ## type ## _node_t *node; \
  241 + \
  242 + LIST_CHECK_NULL (entry, "list_nav.h", 110); \
  243 + \
  244 + node = entry; \
  245 + if (node->e == NULL) \
  246 + ret = node; \
  247 + \
  248 + while (! list_ ## type ## _eol (entry, node)) \
  249 + { \
  250 + node = node->next; \
  251 + \
  252 + if (node->e == NULL) \
  253 + ret = node; \
  254 + } \
  255 + \
  256 + if (ret == NULL) \
  257 + LIST_ERROR ("list_nav.h", 125, MALFORMED_LIST_ERR); \
  258 + } \
  259 + LIST_EXC_END ("list_nav.h", 127, LIST_FIND_ANCHOR_ERR); \
  260 + \
  261 + return NULL; \
  262 + }
  263 +
  264 +
  265 +/**
  266 + * \param type the datatype that this list code should handle.
  267 + * \pre Type must be a single word typename. If one wants
  268 + * to use e.g. lists of structs one has to use typedef
  269 + * to create a single word type name like this:
  270 + * typedef struct mystruct_t mystruct_t;
  271 + * \return Nothing
  272 + * \post The functions for the given datatype that are described
  273 + * here are generated within the calling build file.
  274 + *
  275 + * \brief create functions neccesary to modify lists of the given \a type.
  276 + *
  277 + * Normally this is not called directly, but by GEN_LIST_IMPL() because this
  278 + * defines just a subset of all functions neccesarry to handle typesafe lists.
  279 + */
  280 +#define GEN_LIST_NAVIGATION(type) \
  281 + GEN_LIST_FRONT (type); \
  282 + GEN_LIST_LAST (type); \
  283 + GEN_LIST_NEXT (type); \
  284 + GEN_LIST_PREV (type); \
  285 + GEN_LIST_FIND (type); \
  286 + GEN_LIST_FIND_ANCHOR (type);
  287 +
  288 +
  289 +
  290 +#endif /* LIST_NAV_H */
... ...
  1 +/**
  2 + * \file scot/list_proto.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief This generates all prototypes needed for typesafe lists.
  5 + *
  6 + * This combines the macro definitions in \link scot/list_type_proto.h
  7 + * scot/list_type_proto.h \endlink and \link scot/list_func_proto.h
  8 + * scot/list_func_proto.h \endlink.
  9 + * Additionally defines for all errornumbers that list will create can be
  10 + * found here.
  11 + * GEN_LIST_PROTO is normally called in a header file that describes a
  12 + * new Datatype and also wants lists of it.
  13 + * By doing this the complete interface to lists of that datatype is
  14 + * produced.
  15 + *
  16 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  17 + *
  18 + * This program is free software; you can redistribute it and/or modify
  19 + * it under the terms of the GNU General Public License as published by
  20 + * the Free Software Foundation; either version 2 of the License, or
  21 + * (at your option) any later version.
  22 + *
  23 + * This program is distributed in the hope that it will be useful,
  24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26 + * GNU General Public License for more details.
  27 + *
  28 + * You should have received a copy of the GNU General Public License
  29 + * along with this program; if not, write to the Free Software
  30 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  31 + */
  32 +#ifndef LIST_PROTO_H
  33 +#define LIST_PROTO_H
  34 +
  35 +#include <scot/list_type_proto.h>
  36 +#include <scot/list_func_proto.h>
  37 +
  38 +/** \brief errnum if list_[type]_new() failes*/
  39 +#define LIST_NEW_ERR 0x00
  40 +/** \brief errnum if list_[type]_free() failes*/
  41 +#define LIST_FREE_ERR 0x01
  42 +/** \brief errnum if list_[type]_bol() failes*/
  43 +#define LIST_BOL_ERR 0x02
  44 +/** \brief errnum if list_[type]_eol() failes*/
  45 +#define LIST_EOL_ERR 0x03
  46 +/** \brief errnum if list_[type]_isempty() failes*/
  47 +#define LIST_ISEMPTY_ERR 0x04
  48 +/** \brief errnum if list_[type]_front() failes*/
  49 +#define LIST_FRONT_ERR 0x05
  50 +/** \brief errnum if list_[type]_last() failes*/
  51 +#define LIST_LAST_ERR 0x06
  52 +/** \brief errnum if list_[type]_next() failes*/
  53 +#define LIST_NEXT_ERR 0x07
  54 +/** \brief errnum if list_[type]_prev() failes*/
  55 +#define LIST_PREV_ERR 0x08
  56 +/** \brief errnum if list_[type]_find() failes*/
  57 +#define LIST_FIND_ERR 0x09
  58 +/** \brief errnum if list_[type]_find_anchor() failes*/
  59 +#define LIST_FIND_ANCHOR_ERR 0x0A
  60 +/** \brief errnum if list_[type]_retrive() failes*/
  61 +#define LIST_RETR_ERR 0x0B
  62 +/** \brief errnum if list_[type]_set() failes*/
  63 +#define LIST_SET_ERR 0x0C
  64 +/** \brief errnum if list_[type]_insert() failes*/
  65 +#define LIST_INSERT_ERR 0x0D
  66 +/** \brief errnum if list_[type]_delete() failes*/
  67 +#define LIST_DELETE_ERR 0x0E
  68 +/** \brief errnum if list_[type]_concat() failes*/
  69 +#define LIST_CONCAT_ERR 0x0F
  70 +/** \brief errnum if list_[type]_count() failes*/
  71 +#define LIST_COUNT_ERR 0x10
  72 +
  73 +/** \brief errnum if node is no anchor*/
  74 +#define NODE_NO_ANCHOR_ERR 0x11
  75 +/** \brief errnum if list has no anchor*/
  76 +#define MALFORMED_LIST_ERR 0x12
  77 +
  78 +/** \brief warning if delete on empty list*/
  79 +#define DEL_ON_EMPTY_LIST_WRN 0x01
  80 +
  81 +
  82 +/**
  83 + * \param type the datatype that this list code should handle.
  84 + * \pre Type must be a single word typename. If one wants
  85 + * to use e.g. lists of structs one has to use typedef
  86 + * to create a single word type name like this:
  87 + * typedef struct mystruct_t mystruct_t;
  88 + * \return Nothing
  89 + * \post The typedefs, struct declaration and function prototypes
  90 + * for functions to lists for the given datatype are
  91 + * generated within the calling build file.
  92 + *
  93 + * \brief this creates all typdefs, declarations and prototypes needed for a
  94 + * typesafe list of a given \a type. This is normally calles within
  95 + * a header file.
  96 + */
  97 +#define GEN_LIST_PROTO(type) \
  98 + GEN_LIST_TYPE_PROTO (type) \
  99 + GEN_LIST_FUNC_PROTO (type)
  100 +
  101 +#endif /* LIST_PROTO_H */
... ...
  1 +/**
  2 + * \file scot/list_type_proto.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Macro that creates the datatype for handling linked lists.
  5 + *
  6 + * The macros here create all datatype prototypes typedefs declarations to
  7 + * the implementations created by the macros in
  8 + * \link scot/list_impl.h scot/list_impl.h\endlink.
  9 + * These macros are normally not called directly within your code but
  10 + * through \link scot/list_proto.h::GEN_LIST_PROTO GEN_LIST_PROTO\endlink.
  11 + * This is because normally one did not only
  12 + * want the datatypes but also the interface declaration to them.
  13 + *
  14 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  15 + *
  16 + * This program is free software; you can redistribute it and/or modify
  17 + * it under the terms of the GNU General Public License as published by
  18 + * the Free Software Foundation; either version 2 of the License, or
  19 + * (at your option) any later version.
  20 + *
  21 + * This program is distributed in the hope that it will be useful,
  22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24 + * GNU General Public License for more details.
  25 + *
  26 + * You should have received a copy of the GNU General Public License
  27 + * along with this program; if not, write to the Free Software
  28 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  29 + */
  30 +#ifndef LIST_TYPE_PROTO_H
  31 +#define LIST_TYPE_PROTO_H
  32 +
  33 +/**
  34 + * \param type the datatype that this list code should handle.
  35 + * \pre Type must be a single word typename. If one wants
  36 + * to use e.g. lists of structs one has to use typedef
  37 + * to create a single word type name like this:
  38 + * typedef struct mystruct_t mystruct_t;
  39 + * \return Nothing
  40 + * \post The datatype prototypes for lists of the given
  41 + * datatype are created.
  42 + *
  43 + * \brief Datatype prototypes to lists.
  44 + *
  45 + * This creates the prototypes of the datatypes needed to use the
  46 + * list interface.
  47 + *
  48 + * Normally this is not called directly, but by
  49 + * \link scot/list_proto.h::GEN_LIST_PROTO GEN_LIST_PROTO()\endlink
  50 + * because it is also neccesary to create the interface to this
  51 + * datatypes for working lists.
  52 + */
  53 +#define GEN_LIST_TYPE_PROTO(type) \
  54 + struct list_ ## type ## _node_t; \
  55 + typedef struct list_ ## type ## _node_t \
  56 + list_ ## type ## _node_t; \
  57 + \
  58 + typedef int (*list_ ## type ## _cmp_fptr) ( \
  59 + const type *, \
  60 + const type *); \
  61 + \
  62 + typedef void (*list_ ## type ## _elem_free_fptr) (type *);
  63 +
  64 +#endif /* LIST_TYPE_PROTO_H */
... ...
  1 +/*
  2 + * dir.h: as one might suggest here are definitions and prototypes for
  3 + * posix/dir.c
  4 + *
  5 + * Copyright (C) 2006 Georg Steffers
  6 + *
  7 + * Author: Georg Steffers [GST] <georg.steffers@aschendorff.de>
  8 + * Developer:
  9 + *
  10 + * Changes (for this file only):
  11 + * (2006-06-12) [GST] Started this changelog...well the program is
  12 + * ready since some weeks right now.
  13 + */
  14 +#ifndef DIR_H
  15 +#define DIR_H
  16 +
  17 +#include <sys/stat.h>
  18 +#include <dirent.h>
  19 +
  20 +#include <scot/dir_common.h>
  21 +#include <scot/event_listener.h>
  22 +
  23 +struct scot_dir
  24 +{
  25 + struct scot_event_listener el;
  26 +
  27 + DIR * handle;
  28 + const char * path;
  29 +
  30 + int notify_handle;
  31 +};
  32 +
  33 +/* abstraction for file information and an directory handle */
  34 +#define FILE_DATA struct dirent_stat
  35 +#define DIR_HANDLE DIR *
  36 +/* #define DIR_HANDLE struct scot_dir * */
  37 +
  38 +/* abstraction for checking if a file is a directory */
  39 +#define IS_DIRECTORY(file_data) (S_ISDIR ((file_data).stat.st_mode))
  40 +
  41 +/* abstraction for getting the filename of a directory entry. */
  42 +#define DIRENT_FNAME(file_data) ((file_data).file->d_name)
  43 +
  44 +/* !!!FIXME!!! is there any place where this is already defined in posix? */
  45 +#ifndef MAX_PATH
  46 +# define MAX_PATH 2000
  47 +#endif /* MAX_PATH */
  48 +
  49 +/* structure for all available information about the directory entry. */
  50 +struct dirent_stat
  51 +{
  52 + char path [MAX_PATH+1];
  53 + struct dirent * file;
  54 + struct stat stat;
  55 +};
  56 +
  57 +
  58 +/* the last parameter is posix specific. It defines if stat should
  59 + * follow symlinks or not. Under Windows it is ignored. */
  60 +DIR_HANDLE get_dir_first (const char *, FILE_DATA *, int);
  61 +int get_dir_next (DIR_HANDLE, const char *, FILE_DATA *, int);
  62 +
  63 +/*
  64 +DIR_HANDLE scot_dir_new (const char *);
  65 +void scot_dir_free (DIR_HANDLE);
  66 +
  67 +int get_dir_first (DIR_HANDLE, FILE_DATA *, int);
  68 +int get_dir_next (DIR_HANDLE, FILE_DATA *, int);
  69 +*/
  70 +
  71 +#endif /* DIR_H */
... ...
  1 +/***************************************************************************
  2 + * memory.h: Prototypes for default memory operations like memcpy and thus *
  3 + * on a win32 system nearly all CRT functions (CRT is the *
  4 + * windows C RunTime, that is the normal libC) aren't thread- *
  5 + * safe. As i build up tests this causes problems for example *
  6 + * with strcpy. So i decided to write wrapper that use non CRT *
  7 + * functions on Windows and normal libC ones on a posix system. *
  8 + * *
  9 + * Author: Georg Steffers <georg@steffers.org> *
  10 + * Date: 03/06/2006 *
  11 + ***************************************************************************/
  12 +#ifndef MEMORY_H
  13 +#define MEMORY_H
  14 +
  15 +#include <string.h>
  16 +#include <sys/types.h>
  17 +
  18 +#include <scot_common.h>
  19 +
  20 +#define SCOT_MEM_GET malloc
  21 +#define SCOT_MEM_FREE(p) if ((p)) {free((p)); (p)=NULL;}
  22 +#define SCOT_MEM_COPY memcpy
  23 +#define SCOT_MEM_MOVE memmove
  24 +#define SCOT_MEM_FILL memset
  25 +#define SCOT_MEM_ZERO(p,s) memset ((p), 0, (s))
  26 +#define SCOT_STR_LENGTH strlen
  27 +#define SCOT_STR_COPY strcpy
  28 +#define SCOT_STRN_COPY strncpy
  29 +#define SCOT_STR_CHAR strchr
  30 +#define SCOT_STRR_CHAR strrchr
  31 +
  32 +#endif /* MEMORY_H */
... ...
  1 +#ifndef SCOT_TYPES_H
  2 +#define SCOT_TYPES_H
  3 +
  4 +#include <sys/types.h>
  5 +
  6 +typedef ssize_t SSIZE_T;
  7 +typedef size_t SIZE_T;
  8 +
  9 +#endif /* SCOT_TYPES_H */
... ...
  1 +/*
  2 + * used for threadsafety within exception
  3 + * actually only pthread is supported
  4 + */
  5 +#ifndef THREAD_H
  6 +#define THREAD_H
  7 +
  8 +#include <stdio.h>
  9 +#include <pthread.h>
  10 +
  11 +#include <scot/scot_int.h>
  12 +
  13 +#ifndef INFINITE
  14 +# define INFINITE 0
  15 +#endif /* INFINITE */
  16 +
  17 +
  18 +#define JOIN_OK 0x00
  19 +#define JOIN_TIMEOUT 0x01
  20 +#define JOIN_ERROR 0x02
  21 +
  22 +/*
  23 + * i guess it is possible to write mutex code that uses cond
  24 + * elements to timeout on lock, but right now i have no clear
  25 + * idea of how to do this. The following thoughts i had:
  26 + * - create a struct that holds a pthread_mutex_t and a pthread_cond_t
  27 + * for every mutex.
  28 + * - lock mutexes only by calling pthread_cond_timedwait
  29 + * And here starts the problem...to do a cond_timedwait i need to ensure
  30 + * that the mutex is already locked...well and then a question i have not
  31 + * clearyfied, if a thread ends, will all locks on mutexes be removed?
  32 + * I guess so, but i did not test it. And an even more important question,
  33 + * is it possible to write cleanup-code that guarantees that a
  34 + * pthread_cond_signal is called for every mutex the thread holds...
  35 + * well, we will end up with the requirement that the programmer has to
  36 + * call a release mutex function before ending a thread and if the programmer
  37 + * forgets that the behaviour of out code is unspecified
  38 + * Right now i will not support timeouts on mutex-locks and to be consistent
  39 + * it is not supported on win32 either, also it would be much easier to
  40 + * implement there.
  41 + */
  42 +#define MUTEX_LOCK_OK 0x00
  43 +#define MUTEX_LOCK_ERROR 0x02
  44 +
  45 +#define THREAD_T pthread_t
  46 +#define THREAD_ID_T pthread_t
  47 +#define THREAD_ID pthread_self ()
  48 +#define SELF_THREAD pthread_self ()
  49 +#define THREAD_EQUAL pthread_equal
  50 +#define NEW_THREAD(th,f, a) thread_new ((th), (f), (a))
  51 +#define END_THREAD thread_end
  52 +#define DETACH_THREAD(thread) pthread_detach ((thread))
  53 +#define CANCEL_THREAD(thread) pthread_cancel ((thread))
  54 +#define EXIT_THREAD(retval) pthread_exit ((void *) (retval))
  55 +#define JOIN_THREAD thread_join
  56 +#define THREAD_CANCEL_ENABLE pthread_setcancelstate \
  57 + (PTHREAD_CANCEL_ENABLE, NULL)
  58 +#define THREAD_CANCEL_DISABLE pthread_setcancelstate \
  59 + (PTHREAD_CANCEL_DISABLE, NULL)
  60 +#define THREAD_CANCEL_ASYNC pthread_setcanceltype \
  61 + (PTHREAD_CANCEL_ASYNCHRONOUS, NULL)
  62 +#define THREAD_CANCEL_DEFER pthread_setcanceltype \
  63 + (PTHREAD_CANCEL_DEFERRED, NULL)
  64 +#define THREAD_TESTCANCEL pthread_testcancel ()
  65 +#define T_PROC_RET void *
  66 +
  67 +#define THREAD_MUTEX_T pthread_mutex_t
  68 +#define NEW_THREAD_MUTEX thread_mutex_new
  69 +#define FREE_THREAD_MUTEX pthread_mutex_destroy
  70 +#define LOCK_THREAD_MUTEX thread_mutex_lock
  71 +#define UNLOCK_THREAD_MUTEX pthread_mutex_unlock
  72 +
  73 +#define THREAD_COND_T pthread_cond_t
  74 +#define THREAD_COND_CS_T pthread_mutex_t
  75 +#define GET_THREAD_COND(c) (*(c) = PTHREAD_COND_INITIALIZER)
  76 +#define GET_THREAD_COND_CS(c) (*(c) = PTHREAD_MUTEX_INITIALIZER)
  77 +#define NEW_THREAD_COND thread_cond_new
  78 +#define NEW_THREAD_COND_CS thread_mutex_new
  79 +#define FREE_THREAD_COND pthread_cond_destroy
  80 +#define FREE_THREAD_COND_CS pthread_mutex_destroy
  81 +#define THREAD_COND_ENTER_CS(cs) pthread_mutex_lock ((cs))
  82 +#define THREAD_COND_LEAVE_CS(cs) pthread_mutex_unlock ((cs))
  83 +#define SIGNAL_THREAD_COND(cond) pthread_cond_signal ((cond))
  84 +#define BCAST_THREAD_COND(cond) pthread_cond_broadcast ((cond))
  85 +#define WAIT_THREAD_COND(cond, cs, t) thread_cond_wait ((cond), (cs), t)
  86 +
  87 +#define THREAD_ATEXIT_BEGIN pthread_cleanup_push
  88 +#define THREAD_ATEXIT_END pthread_cleanup_pop
  89 +
  90 +typedef T_PROC_RET (*scot_thread_entry_fptr) (void *);
  91 +
  92 +void thread_new (THREAD_T *, T_PROC_RET (*)(void *), void*);
  93 +int thread_join (THREAD_T, uint32_t);
  94 +void thread_end (THREAD_T, uint32_t);
  95 +void thread_mutex_new (THREAD_MUTEX_T *);
  96 +void thread_cond_new (THREAD_COND_T *);
  97 +int thread_mutex_lock (THREAD_MUTEX_T *);
  98 +
  99 +int thread_cond_wait (THREAD_COND_T *,
  100 + THREAD_COND_CS_T *, uint32_t);
  101 +
  102 +#endif /* THREAD_H */
... ...
  1 +/**
  2 + * \file scot/queue.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Macro which produce all prototypes and implementations for
  5 + * handling queues based on linked lists by Templates.
  6 + *
  7 + * This is the toplevel template file for queues based on typesafe lists.
  8 + * It is quite simple. It just defines one MACRO which in turn calls two
  9 + * other macros to generate all that is needed for queue-handling of a queue
  10 + * to a given type.
  11 + *
  12 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  13 + *
  14 + * This program is free software; you can redistribute it and/or modify
  15 + * it under the terms of the GNU General Public License as published by
  16 + * the Free Software Foundation; either version 2 of the License, or
  17 + * (at your option) any later version.
  18 + *
  19 + * This program is distributed in the hope that it will be useful,
  20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22 + * GNU General Public License for more details.
  23 + *
  24 + * You should have received a copy of the GNU General Public License
  25 + * along with this program; if not, write to the Free Software
  26 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  27 + */
  28 +#ifndef QUEUE_H
  29 +#define QUEUE_H
  30 +
  31 +#include <scot/queue_proto.h>
  32 +#include <scot/queue_impl.h>
  33 +
  34 +/**
  35 + * \param type the datatype that this list code should handle.
  36 + * \pre Type must be a single word typename. If one wants
  37 + * to use e.g. lists of structs one has to use typedef
  38 + * to create a single word type name like this:
  39 + * typedef struct mystruct_t mystruct_t;
  40 + * GEN_LIST(type) has to be called for the list functions,
  41 + * as queues depend on these.
  42 + * \return Nothing
  43 + * \post The complete framework of functions, types, globals
  44 + * prototypes and definitions to handle queues based on
  45 + * typesave
  46 + * lists for the given datatype are generated within the
  47 + * calling build file.
  48 + *
  49 + * \brief create complete framework to handle queues based on typesafe lists.
  50 + *
  51 + * This macro first colls GEN_QUEUE_PROTO() to create all prototypes
  52 + * neccesary for handling queues of the given \a type. And then it calls
  53 + * GEN_QUEUE_IMPL() to also create the neccesary definitions and
  54 + * implementations.\
  55 + * Normally this macro is only called if one only wants to have queues
  56 + * of the given type in a single c source file and nowhere else. Normally
  57 + * this is then used in conjunction with a previous define of GEN_LOCAL,
  58 + * that tells GEN_QUEUE() and the subsequent macros to generate the functions
  59 + * as static.\n
  60 + * If one wants to used queues of the given type in several places of the
  61 + * project one would normally call GEN_QUEUE_PROTO() in a h file and
  62 + * GEN_QUEUE_IMPL() in the c file that does the implementation of that
  63 + * h file (without GEN_LOCAL).
  64 + */
  65 +#define GEN_QUEUE(type) \
  66 + GEN_QUEUE_PROTO (type) \
  67 + GEN_QUEUE_IMPL (type)
  68 +
  69 +#endif /* QUEUE_H */
... ...
  1 +/**
  2 + * \file scot/queue_func_proto.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Macro that produces function prototypes for handling queues
  5 + * based on linked lists.
  6 + *
  7 + * The macros here create all function prototypes to
  8 + * the implementations created by the macros in
  9 + * \link scot/queue_impl.h scot/queue_impl.h\endlink.
  10 + * These macros are normally not called directly within your code but
  11 + * through \link scot/queue_proto.h::GEN_QUEUE_PROTO GEN_QUEUE_PROTO\endlink.
  12 + * This is because to use the interface declaration
  13 + * provided here one will also need the typedefs and datatype prototypes.
  14 + *
  15 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  16 + *
  17 + * This program is free software; you can redistribute it and/or modify
  18 + * it under the terms of the GNU General Public License as published by
  19 + * the Free Software Foundation; either version 2 of the License, or
  20 + * (at your option) any later version.
  21 + *
  22 + * This program is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with this program; if not, write to the Free Software
  29 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  30 + */
  31 +#ifndef QUEUE_FUNC_PROTO_H
  32 +#define QUEUE_FUNC_PROTO_H
  33 +
  34 +
  35 +#ifdef GEN_LOCAL
  36 +# define STATIC static
  37 +#else
  38 +# define STATIC
  39 +#endif
  40 +
  41 +
  42 +/**
  43 + * \param type the datatype that this list code should handle.
  44 + * \pre Type must be a single word typename. If one wants
  45 + * to use e.g. lists of structs one has to use typedef
  46 + * to create a single word type name like this:
  47 + * typedef struct mystruct_t mystruct_t;
  48 + * GEN_LIST_FUNC_PROTO should have bin called previously
  49 + * in one or the other way.
  50 + * \return Nothing
  51 + * \post All function prototypes for a queue of the given
  52 + * datatype are created.
  53 + *
  54 + * \brief This creates the prototypes to all queue functions
  55 + *
  56 + * This creates all the prototypes to the functions that are created by
  57 + * \link scot/queue_impl.h::GEN_QUEUE_IMPL GEN_QUEUE_IMPL\endlink in
  58 + * \link scot/queue_impl.h scot/queue_impl.h\endlink.
  59 + * This provides one with the complete interface to the queue of the given
  60 + * datatype.
  61 + */
  62 +#define GEN_QUEUE_FUNC_PROTO(type) \
  63 + STATIC \
  64 + queue_ ## type ## _node_t * \
  65 + queue_ ## type ## _new ( \
  66 + queue_ ## type ## _node_t *); \
  67 + \
  68 + STATIC \
  69 + void \
  70 + queue_ ## type ## _free ( \
  71 + queue_ ## type ## _node_t *); \
  72 + \
  73 + STATIC \
  74 + queue_ ## type ## _node_t * \
  75 + queue_ ## type ## _enqueue ( \
  76 + queue_ ## type ## _node_t *, \
  77 + const type *); \
  78 + \
  79 + STATIC \
  80 + type * \
  81 + queue_ ## type ## _dequeue ( \
  82 + queue_ ## type ## _node_t *); \
  83 + \
  84 + STATIC \
  85 + type * \
  86 + queue_ ## type ## _top ( \
  87 + queue_ ## type ## _node_t *);
  88 +
  89 +#endif /* QUEUE_FUNC_PROTO_H */
... ...
  1 +/**
  2 + * \file scot/queue_impl.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Templates of functions for handling queues based on typesafe lists.
  5 + *
  6 + * The Macros here generate the implementation for the interface to queues
  7 + * based on typesafe linked lists.
  8 + * \anchor onlyfunc_queue
  9 + * \attention
  10 + * All documentation here does document the functions that are created by
  11 + * the macros, as the macros themself are pretty easy and all used the same.
  12 + * They are called with a type, that MUST be one word (use typedef if needed)
  13 + * and generates the function defined with their value.
  14 + *
  15 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  16 + *
  17 + * This program is free software; you can redistribute it and/or modify
  18 + * it under the terms of the GNU General Public License as published by
  19 + * the Free Software Foundation; either version 2 of the License, or
  20 + * (at your option) any later version.
  21 + *
  22 + * This program is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with this program; if not, write to the Free Software
  29 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  30 + */
  31 +#ifndef QUEUE_IMPL_H
  32 +#define QUEUE_IMPL_H
  33 +
  34 +#include <scot/list.h>
  35 +
  36 +
  37 +/**
  38 + * \internal
  39 + * \param type the datatype that this queue code should handle.
  40 + * \param a a variable holding a pointer to list_[type]_node_t.
  41 + *
  42 + * \pre Type must be a single word typename. If one wants
  43 + * to use e.g. lists of structs one has to use typedef
  44 + * to create a single word type name like this:
  45 + * typedef struct mystruct_t mystruct_t;
  46 + * a must be a valid pointer to a list_[type]_node_t.
  47 + * \returns \a a cast to a pointer of queue_[type]_node_t.
  48 + * \post None
  49 + *
  50 + * \brief Cast a pointer to queue_[type]_node_t.
  51 + *
  52 + * FIXME: I should check better the validity of \a a.
  53 + */
  54 +#define QUEUE(type, a) (queue_ ## type ## _node_t *) (a)
  55 +
  56 +extern const char *queue_err_msg[];
  57 +
  58 +
  59 +#ifdef GEN_LOCAL
  60 +# define STATIC static
  61 +#else
  62 +# define STATIC
  63 +#endif
  64 +
  65 +
  66 +/**
  67 + * \attention
  68 + * Only the generated function is explained here, for the reason look
  69 + * \ref onlyfunc_queue "here".
  70 + *
  71 + * \param anchor a pointer that should contain the list anchor.
  72 + * \pre GEN_LIST_NEW(type) has to be called previously.
  73 + * \return NULL on error, but only if no exceptions are used.
  74 + * If exceptions are used an exception is thrown on error.
  75 + * On success a pointer to the newly created list_anchor
  76 + * will be returned.
  77 + * \retval NULL if an error occurs and no exceptions are used.
  78 + * \retval !=NULL the pointer to the newly created list anchor.
  79 + * \post enough memory on the heap.
  80 + *
  81 + * \brief template for queue constructor.
  82 + *
  83 + * this simply calls list_[type]_new(), that must be generated previously
  84 + * by a call of GEN_LIST_NEW(type).
  85 + */
  86 +#define GEN_QUEUE_NEW(type) \
  87 + STATIC \
  88 + queue_ ## type ## _node_t * \
  89 + queue_ ## type ## _new (queue_ ## type ## _node_t *anchor) \
  90 + { \
  91 + return anchor = QUEUE (type, \
  92 + list_ ## type ## _new (LIST (type, anchor))); \
  93 + }
  94 +
  95 +/**
  96 + * \attention
  97 + * Only the generated function is explained here, for the reason look
  98 + * \ref onlyfunc_queue "here".
  99 + *
  100 + * \param anchor a pointer that should contain the list anchor.
  101 + * \pre GEN_LIST_FREE(type) has to be called previously.
  102 + * \return Nothing
  103 + * \post The list is completely removed from the heap.
  104 + *
  105 + * \brief template for queue destructor.
  106 + *
  107 + * this simply calls list_[type]_free(), that must be generated previously
  108 + * by a call of GEN_LIST_FREE(type).
  109 + */
  110 +#define GEN_QUEUE_FREE(type) \
  111 + STATIC \
  112 + void \
  113 + queue_ ## type ## _free (queue_ ## type ## _node_t *anchor) \
  114 + { \
  115 + list_ ## type ## _free (LIST (type, anchor)); \
  116 + }
  117 +
  118 +/**
  119 + * \attention
  120 + * Only the generated function is explained here, for the reason look
  121 + * \ref onlyfunc_queue "here".
  122 + *
  123 + * \param anchor a pointer that should contain the list anchor.
  124 + * \param e A pointer to a variable of the \a type, the
  125 + * list was created for.
  126 + * \pre GEN_LIST_LAST(type) and GEN_LIST_INSERT(type)
  127 + * has to be called previously.
  128 + * \return The inserted element \a e.
  129 + * \post Element \a e is enqueued in the queue pointed by
  130 + * \a anchor.
  131 + *
  132 + * \brief template for a function that enqueues a value into a queue.
  133 + *
  134 + * To add a value into a queue meens to put it at the end of the queue.
  135 + * That is done by getting the last node of the list and insert a value
  136 + * behind it.
  137 + */
  138 +#define GEN_QUEUE_ENQUEUE(type) \
  139 + queue_ ## type ## _node_t * \
  140 + queue_ ## type ## _enqueue ( \
  141 + queue_ ## type ## _node_t *anchor, \
  142 + const type *e) \
  143 + { \
  144 + return QUEUE (type, list_ ## type ## _insert ( \
  145 + list_ ## type ## _last (LIST (type, anchor)), e)); \
  146 + }
  147 +
  148 +/**
  149 + * \attention
  150 + * Only the generated function is explained here, for the reason look
  151 + * \ref onlyfunc_queue "here".
  152 + *
  153 + * \param anchor a pointer that should contain the list anchor.
  154 + * \pre GEN_LIST_NEXT(type), GEN_LIST_RETRIVE(type)
  155 + * GEN_LIST_ISEMPTY(type) and GEN_LIST_DELETE(type)
  156 + * has to be called previously.
  157 + * \return The dequeued element.
  158 + * \post One Element is dequeued from the queue pointed to
  159 + * by \a anchor.
  160 + *
  161 + * \brief template for a function that dequeues a value from a queue.
  162 + *
  163 + * Dequeue means get and remove the first element from the queue.
  164 + * This is done here.
  165 + */
  166 +#define GEN_QUEUE_DEQUEUE(type) \
  167 + STATIC \
  168 + type * \
  169 + queue_ ## type ## _dequeue (queue_ ## type ## _node_t *anchor) \
  170 + { \
  171 + list_ ## type ## _node_t *next; \
  172 + const type *e; \
  173 + \
  174 + next = list_ ## type ## _next (LIST (type, anchor)); \
  175 + e = list_ ## type ## _retrive (next); \
  176 + \
  177 + if (! list_ ## type ## _isempty (next)) \
  178 + list_ ## type ## _delete (next); \
  179 + \
  180 + return (type *) e; \
  181 + }
  182 +
  183 +/**
  184 + * \attention
  185 + * Only the generated function is explained here, for the reason look
  186 + * \ref onlyfunc_queue "here".
  187 + *
  188 + * \param anchor a pointer that should contain the list anchor.
  189 + * \pre GEN_LIST_NEXT(type) and GEN_LIST_RETRIVE(type)
  190 + * has to be called previously.
  191 + * \return The next element in the queue.
  192 + * \post None
  193 + *
  194 + * \brief get next element in the queue without dequeueing it.
  195 + */
  196 +#define GEN_QUEUE_TOP(type) \
  197 + STATIC \
  198 + type * \
  199 + queue_ ## type ## _top ( \
  200 + queue_ ## type ## _node_t *anchor) \
  201 + { \
  202 + return list_ ## type ## _retrive ( \
  203 + list_ ## type ## _next (LIST (type, anchor))); \
  204 + }
  205 +
  206 +/**
  207 + * \param type the datatype that this list code should handle.
  208 + * \pre Type must be a single word typename. If one wants
  209 + * to use e.g. lists of structs one has to use typedef
  210 + * to create a single word type name like this:
  211 + * typedef struct mystruct_t mystruct_t;
  212 + * GEN_LIST_IMPL(type) should be called before this.
  213 + * \return Nothing
  214 + * \post The functions, struct and globals to handle queues
  215 + * based on typesave
  216 + * lists for the given datatype are generated within the
  217 + * calling build file.
  218 + *
  219 + * \brief this creates all functions, structs and globals needed for a
  220 + * queue based on typesafe list of a given \a type.
  221 + *
  222 + * In detail the following is created by this macro:\n
  223 + * \li <b>struct queue_[type]_node_t</b>: This is the structure a queue
  224 + * is constructed of. Practically this just contains an instance of a
  225 + * list_[type]_node_t, as queues are completely based on lists and does
  226 + * not add further information.
  227 + * \li all functions created by the macros defined within this file.
  228 + */
  229 +#define GEN_QUEUE_IMPL(type) \
  230 + struct queue_ ## type ## _node_t \
  231 + { \
  232 + struct list_ ## type ## _node_t list; \
  233 + }; \
  234 + \
  235 + GEN_QUEUE_NEW (type) \
  236 + GEN_QUEUE_FREE (type) \
  237 + GEN_QUEUE_ENQUEUE (type) \
  238 + GEN_QUEUE_DEQUEUE (type) \
  239 + GEN_QUEUE_TOP (type)
  240 +
  241 +#endif /* QUEUE_IMPL_H */
... ...
  1 +/**
  2 + * \file scot/queue_proto.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief This generates all prototypes needed for queues based on
  5 + * typesafe lists.
  6 + *
  7 + * This combines the macro definitions in \link scot/queue_type_proto.h
  8 + * scot/queue_type_proto.h \endlink and \link scot/queue_func_proto.h
  9 + * scot/queue_func_proto.h \endlink.
  10 + * Additionally defines for all errornumbers that queue will create can be
  11 + * found here.
  12 + * GEN_QUEUE_PROTO is normally called in a header file that describes a
  13 + * new Datatype and also wants lists of it.
  14 + * By doing this the complete interface to lists of that datatype is
  15 + * produced.
  16 + *
  17 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  18 + *
  19 + * This program is free software; you can redistribute it and/or modify
  20 + * it under the terms of the GNU General Public License as published by
  21 + * the Free Software Foundation; either version 2 of the License, or
  22 + * (at your option) any later version.
  23 + *
  24 + * This program is distributed in the hope that it will be useful,
  25 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27 + * GNU General Public License for more details.
  28 + *
  29 + * You should have received a copy of the GNU General Public License
  30 + * along with this program; if not, write to the Free Software
  31 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  32 + */
  33 +#ifndef QUEUE_PROTO_H
  34 +#define QUEUE_PROTO_H
  35 +
  36 +#include <scot/queue_type_proto.h>
  37 +#include <scot/queue_func_proto.h>
  38 +
  39 +/**
  40 + * \brief errnum if queue is empty
  41 + * \attention This is actually not use and will probably never be used
  42 + * in this form.
  43 + */
  44 +#define QUEUE_EMPTY 0
  45 +
  46 +
  47 +/**
  48 + * \param type the datatype that this list code should handle.
  49 + * \pre Type must be a single word typename. If one wants
  50 + * to use e.g. lists of structs one has to use typedef
  51 + * to create a single word type name like this:
  52 + * typedef struct mystruct_t mystruct_t;
  53 + * GEN_LIST_PROTO(type) should have been called previous
  54 + * to this call.
  55 + * \return Nothing
  56 + * \post The typedefs, struct declaration and function prototypes
  57 + * for functions to queues based on lists for the given
  58 + * datatype are generated within the calling build file.
  59 + *
  60 + * \brief this creates all typdefs, declarations and prototypes needed for a
  61 + * queue based on typesafe list of a given \a type.
  62 + * This is normally calles within a header file.
  63 + */
  64 +#define GEN_QUEUE_PROTO(type) \
  65 + GEN_QUEUE_TYPE_PROTO (type) \
  66 + GEN_QUEUE_FUNC_PROTO (type)
  67 +
  68 +#endif /* QUEUE_PROTO_H */
... ...
  1 +/**
  2 + * \file scot/queue_type_proto.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Macro that creates the datatype for handling queues based on
  5 + * linked lists.
  6 + *
  7 + * The macros here create all datatype prototypes and typedefs declarations to
  8 + * the implementations created by the macros in
  9 + * \link scot/queue_impl.h scot/queue_impl.h\endlink.
  10 + * These macros are normally not called directly within your code but
  11 + * through \link scot/queue_proto.h::GEN_QUEUE_PROTO GEN_QUEUE_PROTO\endlink.
  12 + * This is because normally one did not only
  13 + * want the datatypes but also the interface declaration to them.
  14 + *
  15 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  16 + *
  17 + * This program is free software; you can redistribute it and/or modify
  18 + * it under the terms of the GNU General Public License as published by
  19 + * the Free Software Foundation; either version 2 of the License, or
  20 + * (at your option) any later version.
  21 + *
  22 + * This program is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with this program; if not, write to the Free Software
  29 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  30 + */
  31 +#ifndef QUEUE_TYPE_PROTO_H
  32 +#define QUEUE_TYPE_PROTO_H
  33 +
  34 +/**
  35 + * \param type the datatype that this list code should handle.
  36 + * \pre Type must be a single word typename. If one wants
  37 + * to use e.g. lists of structs one has to use typedef
  38 + * to create a single word type name like this:
  39 + * typedef struct mystruct_t mystruct_t;
  40 + * GEN_LIST_TYPE_PROTO(type) should have been called
  41 + * previous to this.
  42 + * \return Nothing
  43 + * \post The datatype prototypes for queues based on lists
  44 + * of the given datatype are created.
  45 + *
  46 + * \brief Datatype prototypes to queues.
  47 + *
  48 + * This creates the prototypes of the datatypes needed to use the
  49 + * queue interface.
  50 + *
  51 + * Normally this is not called directly, but by
  52 + * \link scot/queue_proto.h::GEN_QUEUE_PROTO GEN_QUEUE_PROTO()\endlink
  53 + * because it is also neccesary to create the interface to this
  54 + * datatypes for working queues.
  55 + */
  56 +#define GEN_QUEUE_TYPE_PROTO(type) \
  57 + struct queue_ ## type ## _node_t; \
  58 + typedef struct queue_ ## type ## _node_t \
  59 + queue_ ## type ## _node_t;
  60 +
  61 +#endif /* QUEUE_TYPE_PROTO_H */
... ...
  1 +#ifndef SCOT_EXCEPTIONS_H
  2 +#define SCOT_EXCEPTIONS_H
  3 +
  4 +#include <stdlib.h>
  5 +
  6 +#include <scot/scot_types.h>
  7 +
  8 +
  9 +#define MALLOC_ERR 0x00
  10 +#define NULL_PTR_ERR 0x01
  11 +
  12 +extern const char *scot_err_msg[];
  13 +
  14 +void * exc_malloc (SIZE_T);
  15 +void * exc_malloc_fl (SIZE_T, const char *, int);
  16 +void check_null (const void *);
  17 +void check_null_fl (const void *, const char *, int);
  18 +
  19 +#endif /* SCOT_EXCEPTIONS_H */
... ...
  1 +#ifndef SCOT_SOCKET_H
  2 +#define SCOT_SOCKET_H
  3 +
  4 +#include <scot_common.h>
  5 +#include <scot/scot_types.h>
  6 +
  7 +#ifndef WIN32
  8 +# include <netdb.h>
  9 +# include <sys/socket.h>
  10 +# include <sys/un.h>
  11 +# include <arpa/inet.h>
  12 +# include <netinet/in.h>
  13 +# include <stdlib.h>
  14 +# include <errno.h>
  15 +
  16 +# define INVALID_SOCKET -1
  17 +# define SCOT_ERRNO errno
  18 +# define SCOT_H_ERRNO h_errno
  19 +# define SOCKET int
  20 +# define SCOT_SOCK_CLOSE close
  21 +#else
  22 +# include <winsock.h>
  23 +
  24 +# define SCOT_ERRNO WSAGetLastError()
  25 +# define SCOT_H_ERRNO WSAGetLastError()
  26 +# define SCOT_SOCK_CLOSE closesocket
  27 +#endif /* WIN32 */
  28 +
  29 +#include <scot/stream.h>
  30 +
  31 +/*
  32 + * prevent direct access to the structure
  33 + * from other methods then the ones that are made for this.
  34 + * Should especially encourage the use of getter and setter
  35 + * functions
  36 + */
  37 +#ifndef USE_STRUCT_SCOT_SOCKET
  38 +struct scot_socket
  39 +{
  40 + const char _ [sizeof (struct {
  41 + struct scot_stream socket;
  42 + struct sockaddr * sa;
  43 + SIZE_T addr_len;
  44 + })];
  45 +};
  46 +#else
  47 +struct scot_socket
  48 +{
  49 + struct scot_stream socket;
  50 + struct sockaddr * sa;
  51 + SIZE_T addr_len;
  52 +};
  53 +#endif /* USE_STRUCT_SCOT_SOCKET */
  54 +
  55 +/* socket errors */
  56 +#define SCOT_SOCKET_NEW_FAIL 0
  57 +#define SCOT_SOCKET_LISTEN_FAIL 1
  58 +#define SCOT_SOCKET_ACCEPT_FAIL 2
  59 +#define SCOT_SOCKET_CONNECT_FAIL 3
  60 +#define SCOT_SOCKET_NO_VALID_HOST 4
  61 +#define SCOT_SOCKET_AF_NOT_IMPLEMENTED 5
  62 +/* socket warnings */
  63 +#define SCOT_SOCKET_UN_FILE_EXISTS 0
  64 +extern const char * scot_socket_errmsg[];
  65 +extern const char * scot_socket_wrnmsg[];
  66 +
  67 +/*
  68 + * This function initializes scot sockets. This primary means it does
  69 + * nothing under a posix system an WSASartup on a Windows system.
  70 + */
  71 +void scot_socket_init (uint16_t, uint16_t);
  72 +/*
  73 + * This finalizes the scot sockets system. Again does noting on posix
  74 + * and WSACleanup on Windows.
  75 + */
  76 +void scot_socket_fini (void);
  77 +
  78 +void scot_socket_listen (const struct scot_socket*);
  79 +struct scot_socket * scot_socket_accept (const struct scot_socket*);
  80 +void scot_socket_connect (const struct scot_socket*,
  81 + const char *);
  82 +
  83 +void scot_socket_free (struct scot_socket*);
  84 +
  85 +#endif /* SCOT_SOCKET_H */
... ...
  1 +#ifndef SCOT_SOCKET_IN_H
  2 +#define SCOT_SOCKET_IN_H
  3 +
  4 +extern const char * scot_socket_errmsg[];
  5 +
  6 +
  7 +struct scot_socket * scot_socket_in_new (const char*, const char*);
  8 +struct scot_socket * scot_socket_in_accept (const struct scot_socket*);
  9 +void scot_socket_in_prep_con (const struct scot_socket *,
  10 + const char *);
  11 +
  12 +const char * scot_socket_in_get_host (struct scot_socket *);
  13 +const char * scot_socket_in_get_ddc (struct scot_socket *);
  14 +
  15 +#endif /* SCOT_SOCKET_IN_H */
... ...
  1 +#ifndef SCOT_SOCKET_UN_H
  2 +#define SCOT_SOCKET_UN_H
  3 +
  4 +extern const char * scot_socket_errmsg[];
  5 +
  6 +
  7 +struct scot_socket * scot_socket_un_new (const char*);
  8 +struct scot_socket * scot_socket_un_accept (const struct scot_socket*);
  9 +void scot_socket_un_prep_con (const struct scot_socket *,
  10 + const char *);
  11 +
  12 +const char * scot_socket_un_get_path (struct scot_socket*);
  13 +
  14 +#endif /* SCOT_SOCKET_UN_H */
... ...
  1 +/**
  2 + * \file scot/stack.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Macro which produce all prototypes and implementations for
  5 + * handling stacks based on linked lists by Templates.
  6 + *
  7 + * This is the toplevel template file for stacks based on typesafe lists.
  8 + * It is quite simple. It just defines one MACRO which in turn calls two
  9 + * other macros to generate all that is needed for queue-handling of a queue
  10 + * to a given type.
  11 + *
  12 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  13 + *
  14 + * This program is free software; you can redistribute it and/or modify
  15 + * it under the terms of the GNU General Public License as published by
  16 + * the Free Software Foundation; either version 2 of the License, or
  17 + * (at your option) any later version.
  18 + *
  19 + * This program is distributed in the hope that it will be useful,
  20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22 + * GNU General Public License for more details.
  23 + *
  24 + * You should have received a copy of the GNU General Public License
  25 + * along with this program; if not, write to the Free Software
  26 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  27 + */
  28 +#ifndef STACK_H
  29 +#define STACK_H
  30 +
  31 +#include <scot/stack_proto.h>
  32 +#include <scot/stack_impl.h>
  33 +
  34 +/**
  35 + * \param type the datatype that this list code should handle.
  36 + * \pre Type must be a single word typename. If one wants
  37 + * to use e.g. lists of structs one has to use typedef
  38 + * to create a single word type name like this:
  39 + * typedef struct mystruct_t mystruct_t;
  40 + * GEN_LIST(type) has to be called for the list functions,
  41 + * as queues depend on these.
  42 + * \return Nothing
  43 + * \post The complete framework of functions, types, globals
  44 + * prototypes and definitions to handle stacks based on
  45 + * typesafe
  46 + * lists for the given datatype are generated within the
  47 + * calling build file.
  48 + *
  49 + * \brief create complete framework to handle stacks based on typesafe lists.
  50 + *
  51 + * This macro first colls GEN_STACK_PROTO() to create all prototypes
  52 + * neccesary for handling stacks of the given \a type. And then it calls
  53 + * GEN_STACK_IMPL() to also create the neccesary definitions and
  54 + * implementations.\
  55 + * Normally this macro is only called if one only wants to have stacks
  56 + * of the given type in a single c source file and nowhere else. Normally
  57 + * this is then used in conjunction with a previous define of GEN_LOCAL,
  58 + * that tells GEN_STACK() and the subsequent macros to generate the functions
  59 + * as static.\n
  60 + * If one wants to used queues of the given type in several places of the
  61 + * project one would normally call GEN_STACK_PROTO() in a h file and
  62 + * GEN_STACK_IMPL() in the c file that does the implementation of that
  63 + * h file (without GEN_LOCAL).
  64 + */
  65 +#define GEN_STACK(type) \
  66 + GEN_STACK_PROTO (type) \
  67 + GEN_STACK_IMPL (type)
  68 +
  69 +#endif /* STACK_H */
... ...
  1 +/**
  2 + * \file scot/stack_func_proto.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Macro that produces function prototypes for handling stacks
  5 + * based on linked lists.
  6 + *
  7 + * The macros here create all function prototypes to
  8 + * the implementations created by the macros in
  9 + * \link scot/stack_impl.h scot/stack_impl.h\endlink.
  10 + * These macros are normally not called directly within your code but
  11 + * through \link scot/stack_proto.h::GEN_STACK_PROTO GEN_STACK_PROTO\endlink.
  12 + * This is because to use the interface declaration
  13 + * provided here one will also need the typedefs and datatype prototypes.
  14 + *
  15 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  16 + *
  17 + * This program is free software; you can redistribute it and/or modify
  18 + * it under the terms of the GNU General Public License as published by
  19 + * the Free Software Foundation; either version 2 of the License, or
  20 + * (at your option) any later version.
  21 + *
  22 + * This program is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with this program; if not, write to the Free Software
  29 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  30 + */
  31 +#ifndef STACK_FUNC_PROTO_H
  32 +#define STACK_FUNC_PROTO_H
  33 +
  34 +
  35 +#ifdef GEN_LOCAL
  36 +# define STATIC static
  37 +#else
  38 +# define STATIC
  39 +#endif
  40 +
  41 +
  42 +/**
  43 + * \param type the datatype that this list code should handle.
  44 + * \pre Type must be a single word typename. If one wants
  45 + * to use e.g. lists of structs one has to use typedef
  46 + * to create a single word type name like this:
  47 + * typedef struct mystruct_t mystruct_t;
  48 + * GEN_LIST_FUNC_PROTO should have bin called previously
  49 + * in one or the other way.
  50 + * \return Nothing
  51 + * \post All function prototypes for a stack of the given
  52 + * datatype are created.
  53 + *
  54 + * \brief This creates the prototypes to all stack functions
  55 + *
  56 + * This creates all the prototypes to the functions that are created by
  57 + * \link scot/stack_impl.h::GEN_STACK_IMPL GEN_STACK_IMPL\endlink in
  58 + * \link scot/stack_impl.h scot/stack_impl.h\endlink.
  59 + * This provides one with the complete interface to the stack of the given
  60 + * datatype.
  61 + */
  62 +#define GEN_STACK_FUNC_PROTO(type) \
  63 + STATIC \
  64 + stack_ ## type ## _node_t * \
  65 + stack_ ## type ## _new ( \
  66 + stack_ ## type ## _node_t *); \
  67 + \
  68 + STATIC \
  69 + void \
  70 + stack_ ## type ## _free ( \
  71 + stack_ ## type ## _node_t *); \
  72 + \
  73 + STATIC \
  74 + stack_ ## type ## _node_t * \
  75 + stack_ ## type ## _push ( \
  76 + stack_ ## type ## _node_t *, \
  77 + const type *); \
  78 + \
  79 + STATIC \
  80 + type * \
  81 + stack_ ## type ## _pop ( \
  82 + stack_ ## type ## _node_t *); \
  83 + \
  84 + STATIC \
  85 + type * \
  86 + stack_ ## type ## _top ( \
  87 + stack_ ## type ## _node_t *);
  88 +
  89 +#endif /* STACK_FUNC_PROTO_H */
... ...
  1 +/**
  2 + * \file scot/stack_impl.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Templates of functions for handling stacks based on typesafe lists.
  5 + *
  6 + * The Macros here generate the implementation for the interface to stacks
  7 + * based on typesafe linked lists.
  8 + * \anchor onlyfunc_stack
  9 + * \attention
  10 + * All documentation here does document the functions that are created by
  11 + * the macros, as the macros themself are pretty easy and all used the same.
  12 + * They are called with a type, that MUST be one word (use typedef if needed)
  13 + * and generates the function defined with their value.
  14 + *
  15 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  16 + *
  17 + * This program is free software; you can redistribute it and/or modify
  18 + * it under the terms of the GNU General Public License as published by
  19 + * the Free Software Foundation; either version 2 of the License, or
  20 + * (at your option) any later version.
  21 + *
  22 + * This program is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with this program; if not, write to the Free Software
  29 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  30 + */
  31 +#ifndef STACK_IMPL_H
  32 +#define STACK_IMPL_H
  33 +
  34 +#include <scot/list.h>
  35 +
  36 +
  37 +/**
  38 + * \internal
  39 + * \param type the datatype that this queue code should handle.
  40 + * \param a a variable holding a pointer to list_[type]_node_t.
  41 + *
  42 + * \pre Type must be a single word typename. If one wants
  43 + * to use e.g. lists of structs one has to use typedef
  44 + * to create a single word type name like this:
  45 + * typedef struct mystruct_t mystruct_t;
  46 + * a must be a valid pointer to a list_[type]_node_t.
  47 + * \returns \a a cast to a pointer of stack_[type]_node_t.
  48 + * \post None
  49 + *
  50 + * \brief Cast a pointer to stack_[type]_node_t.
  51 + *
  52 + * FIXME: I should check better the validity of \a a.
  53 + */
  54 +#define STACK(type, a) (stack_ ## type ## _node_t *) (a)
  55 +
  56 +extern const char *stack_err_msg[];
  57 +
  58 +
  59 +#ifdef GEN_LOCAL
  60 +# define STATIC static
  61 +#else
  62 +# define STATIC
  63 +#endif
  64 +
  65 +/**
  66 + * \attention
  67 + * Only the generated function is explained here, for the reason look
  68 + * \ref onlyfunc_stack "here".
  69 + *
  70 + * \param anchor a pointer that should contain the list anchor.
  71 + * \pre GEN_LIST_NEW(type) has to be called previously.
  72 + * \return NULL on error, but only if no exceptions are used.
  73 + * If exceptions are used an exception is thrown on error.
  74 + * On success a pointer to the newly created list_anchor
  75 + * will be returned.
  76 + * \retval NULL if an error occurs and no exceptions are used.
  77 + * \retval !=NULL the pointer to the newly created list anchor.
  78 + * \post enough memory on the heap.
  79 + *
  80 + * \brief template for stack constructor.
  81 + *
  82 + * this simply calls list_[type]_new(), that must be generated previously
  83 + * by a call of GEN_LIST_NEW(type).
  84 + */
  85 +#define GEN_STACK_NEW(type) \
  86 + STATIC \
  87 + stack_ ## type ## _node_t * \
  88 + stack_ ## type ## _new (stack_ ## type ## _node_t *anchor) \
  89 + { \
  90 + return anchor = STACK (type, \
  91 + list_ ## type ## _new (LIST (type, anchor))); \
  92 + }
  93 +
  94 +/**
  95 + * \attention
  96 + * Only the generated function is explained here, for the reason look
  97 + * \ref onlyfunc_stack "here".
  98 + *
  99 + * \param anchor a pointer that should contain the list anchor.
  100 + * \pre GEN_LIST_FREE(type) has to be called previously.
  101 + * \return Nothing
  102 + * \post The list is completely removed from the heap.
  103 + *
  104 + * \brief template for stack destructor.
  105 + *
  106 + * this simply calls list_[type]_free(), that must be generated previously
  107 + * by a call of GEN_LIST_FREE(type).
  108 + */
  109 +#define GEN_STACK_FREE(type) \
  110 + STATIC \
  111 + void \
  112 + stack_ ## type ## _free (stack_ ## type ## _node_t *anchor) \
  113 + { \
  114 + list_ ## type ## _free (LIST (type, anchor)); \
  115 + }
  116 +
  117 +/**
  118 + * \attention
  119 + * Only the generated function is explained here, for the reason look
  120 + * \ref onlyfunc_stack "here".
  121 + *
  122 + * \param anchor a pointer that should contain the list anchor.
  123 + * \param e A pointer to a variable of the \a type, the
  124 + * list was created for.
  125 + * \pre GEN_LIST_INSERT(type) has to be called previously.
  126 + * \return The pushed element \a e.
  127 + * \post Element \a e is pushed in the stack pointed by
  128 + * \a anchor.
  129 + *
  130 + * \brief template for a function that pushes a value into a stack.
  131 + *
  132 + * To add a value into a stack meens to put it at the beginning of the stack.
  133 + * That is simply a call to list_[type]_insert().
  134 + */
  135 +#define GEN_STACK_PUSH(type) \
  136 + STATIC \
  137 + stack_ ## type ## _node_t * \
  138 + stack_ ## type ## _push ( \
  139 + stack_ ## type ## _node_t *anchor, \
  140 + const type *e) \
  141 + { \
  142 + return STACK (type, list_ ## type ## _insert ( \
  143 + LIST (type, anchor), e)); \
  144 + }
  145 +
  146 +/**
  147 + * \attention
  148 + * Only the generated function is explained here, for the reason look
  149 + * \ref onlyfunc_stack "here".
  150 + *
  151 + * \param anchor a pointer that should contain the list anchor.
  152 + * \pre GEN_LIST_NEXT(type), GEN_LIST_RETRIVE(type)
  153 + * GEN_LIST_ISEMPTY(type) and GEN_LIST_DELETE(type)
  154 + * has to be called previously.
  155 + * \return The poped element.
  156 + * \post One Element is poped from the stack pointed to
  157 + * by \a anchor.
  158 + *
  159 + * \brief template for a function that pops a value from a stack.
  160 + *
  161 + * Pop means get and remove the first element from the stack.
  162 + * This is done here.
  163 + */
  164 +#define GEN_STACK_POP(type) \
  165 + STATIC \
  166 + type * \
  167 + stack_ ## type ## _pop (stack_ ## type ## _node_t *anchor) \
  168 + { \
  169 + list_ ## type ## _node_t *next; \
  170 + const type *e; \
  171 + \
  172 + next = list_ ## type ## _next (LIST (type, anchor)); \
  173 + e = list_ ## type ## _retrive (next); \
  174 + \
  175 + if (! list_ ## type ## _isempty (next)) \
  176 + list_ ## type ## _delete (next); \
  177 + \
  178 + return (type *) e; \
  179 + }
  180 +
  181 +/**
  182 + * \attention
  183 + * Only the generated function is explained here, for the reason look
  184 + * \ref onlyfunc_stack "here".
  185 + *
  186 + * \param anchor a pointer that should contain the list anchor.
  187 + * \pre GEN_LIST_NEXT(type) and GEN_LIST_RETRIVE(type)
  188 + * has to be called previously.
  189 + * \return The next element in the stack.
  190 + * \post None
  191 + *
  192 + * \brief get next element in the stack without poping it.
  193 + */
  194 +#define GEN_STACK_TOP(type) \
  195 + STATIC \
  196 + type * \
  197 + stack_ ## type ## _top ( \
  198 + stack_ ## type ## _node_t *anchor) \
  199 + { \
  200 + return list_ ## type ## _retrive ( \
  201 + list_ ## type ## _next (LIST (type, anchor))); \
  202 + }
  203 +
  204 +/**
  205 + * \param type the datatype that this list code should handle.
  206 + * \pre Type must be a single word typename. If one wants
  207 + * to use e.g. lists of structs one has to use typedef
  208 + * to create a single word type name like this:
  209 + * typedef struct mystruct_t mystruct_t;
  210 + * GEN_LIST_IMPL(type) should be called before this.
  211 + * \return Nothing
  212 + * \post The functions, struct and globals to handle stacks
  213 + * based on typesave
  214 + * lists for the given datatype are generated within the
  215 + * calling build file.
  216 + *
  217 + * \brief this creates all functions, structs and globals needed for a
  218 + * stack based on typesafe list of a given \a type.
  219 + *
  220 + * In detail the following is created by this macro:\n
  221 + * \li <b>struct stack_[type]_node_t</b>: This is the structure a stack
  222 + * is constructed of. Practically this just contains an instance of a
  223 + * list_[type]_node_t, as stacks are completely based on lists and does
  224 + * not add further information.
  225 + * \li all functions created by the macros defined within this file.
  226 + */
  227 +#define GEN_STACK_IMPL(type) \
  228 + struct stack_ ## type ## _node_t \
  229 + { \
  230 + struct list_node_t list; \
  231 + }; \
  232 + \
  233 + GEN_STACK_NEW (type) \
  234 + GEN_STACK_FREE (type) \
  235 + GEN_STACK_PUSH (type) \
  236 + GEN_STACK_POP (type) \
  237 + GEN_STACK_TOP (type)
  238 +
  239 +#endif /* STACK_IMPL_H */
... ...
  1 +/**
  2 + * \file scot/stack_proto.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief This generates all prototypes needed for stacks based on
  5 + * typesafe lists.
  6 + *
  7 + * This combines the macro definitions in \link scot/stack_type_proto.h
  8 + * scot/stack_type_proto.h \endlink and \link scot/stack_func_proto.h
  9 + * scot/stack_func_proto.h \endlink.
  10 + * Additionally defines for all errornumbers that stack will create can be
  11 + * found here.
  12 + * GEN_STACK_PROTO is normally called in a header file that describes a
  13 + * new Datatype and also wants lists of it.
  14 + * By doing this the complete interface to lists of that datatype is
  15 + * produced.
  16 + *
  17 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  18 + *
  19 + * This program is free software; you can redistribute it and/or modify
  20 + * it under the terms of the GNU General Public License as published by
  21 + * the Free Software Foundation; either version 2 of the License, or
  22 + * (at your option) any later version.
  23 + *
  24 + * This program is distributed in the hope that it will be useful,
  25 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27 + * GNU General Public License for more details.
  28 + *
  29 + * You should have received a copy of the GNU General Public License
  30 + * along with this program; if not, write to the Free Software
  31 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  32 + */
  33 +#ifndef STACK_PROTO_H
  34 +#define STACK_PROTO_H
  35 +
  36 +#include <scot/stack_type_proto.h>
  37 +#include <scot/stack_func_proto.h>
  38 +
  39 +/**
  40 + * \brief errnum if stack is empty
  41 + * \attention This is actually not use and will probably never be used
  42 + * in this form.
  43 + */
  44 +#define STACK_EMPTY 0
  45 +
  46 +
  47 +/**
  48 + * \param type the datatype that this list code should handle.
  49 + * \pre Type must be a single word typename. If one wants
  50 + * to use e.g. lists of structs one has to use typedef
  51 + * to create a single word type name like this:
  52 + * typedef struct mystruct_t mystruct_t;
  53 + * GEN_LIST_PROTO(type) should have been called previous
  54 + * to this call.
  55 + * \return Nothing
  56 + * \post The typedefs, struct declaration and function prototypes
  57 + * for functions to stacks based on lists for the given
  58 + * datatype are generated within the calling build file.
  59 + *
  60 + * \brief this creates all typdefs, declarations and prototypes needed for a
  61 + * stack based on typesafe list of a given \a type.
  62 + * This is normally calles within a header file.
  63 + */
  64 +#define GEN_STACK_PROTO(type) \
  65 + GEN_STACK_TYPE_PROTO (type) \
  66 + GEN_STACK_FUNC_PROTO (type)
  67 +
  68 +#endif /* STACK_PROTO_H */
... ...
  1 +/**
  2 + * \file scot/stack_type_proto.h
  3 + * \author Georg Steffers <georg@steffers.org>
  4 + * \brief Macro that creates the datatype for handling stacks based on
  5 + * linked lists.
  6 + *
  7 + * The macros here create all datatype prototypes and typedefs declarations to
  8 + * the implementations created by the macros in
  9 + * \link scot/stack_impl.h scot/stack_impl.h\endlink.
  10 + * These macros are normally not called directly within your code but
  11 + * through \link scot/stack_proto.h::GEN_STACK_PROTO GEN_STACK_PROTO\endlink.
  12 + * This is because normally one did not only
  13 + * want the datatypes but also the interface declaration to them.
  14 + *
  15 + * Copyright (C)2006 Georg Steffers <georg@steffers.org>
  16 + *
  17 + * This program is free software; you can redistribute it and/or modify
  18 + * it under the terms of the GNU General Public License as published by
  19 + * the Free Software Foundation; either version 2 of the License, or
  20 + * (at your option) any later version.
  21 + *
  22 + * This program is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with this program; if not, write to the Free Software
  29 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  30 + */
  31 +#ifndef STACK_TYPE_PROTO_H
  32 +#define STACK_TYPE_PROTO_H
  33 +
  34 +/**
  35 + * \param type the datatype that this list code should handle.
  36 + * \pre Type must be a single word typename. If one wants
  37 + * to use e.g. lists of structs one has to use typedef
  38 + * to create a single word type name like this:
  39 + * typedef struct mystruct_t mystruct_t;
  40 + * GEN_LIST_TYPE_PROTO(type) should have been called
  41 + * previous to this.
  42 + * \return Nothing
  43 + * \post The datatype prototypes for stacks based on lists
  44 + * of the given datatype are created.
  45 + *
  46 + * \brief Datatype prototypes to stacks.
  47 + *
  48 + * This creates the prototypes of the datatypes needed to use the
  49 + * stack interface.
  50 + *
  51 + * Normally this is not called directly, but by
  52 + * \link scot/stack_proto.h::GEN_STACK_PROTO GEN_STACK_PROTO()\endlink
  53 + * because it is also neccesary to create the interface to this
  54 + * datatypes for working stacks.
  55 + */
  56 +#define GEN_STACK_TYPE_PROTO(type) \
  57 + struct stack_ ## type ## _node_t; \
  58 + typedef struct stack_ ## type ## _node_t \
  59 + stack_ ## type ## _node_t; \
  60 +
  61 +#endif /* STACK_TYPE_PROTO_H */
... ...
  1 +/*
  2 + * Zunächst ein paar allgemeine Bemerkungen zu scot_stream:
  3 + *
  4 + * 1. scot-stream ist eine auf andere Klassen aufbauende Klasse. Es gibt
  5 + * kein scot_stream_new. Mann kann natürlich über malloc ein leeres
  6 + * stream-objekt anlegen, das macht für gewöhnlich aber keinen Sinn.
  7 + * Stattdessen gibt es in Klassen, die stream-io Endpunkte darstellen
  8 + * Funktionen der Form scot_<Klasse>_get_new_stream
  9 + * (z.B. scot_socket_get_new_stream). Diese Funktionen geben ein
  10 + * gültiges Stream Objekt zu einem Objekt der übergeordneten Klasse
  11 + * zurück. Das Objekt der übergeordnete Klasse muss sich alle auf diese
  12 + * Art angelegten Stream-Objekte merken.
  13 + * 2. Wenn ein Objekt der übergeordneten Klasse geschlossen wird, so werden
  14 + * auch alle Stream Objekte die von diesem erzeugt wurden freigegeben und
  15 + * auf NULL gesetzt. (Auf Sie währe eh keine Sinnvolle operation mehr
  16 + * möglich.)
  17 + * 3. Wird ein Stream-Objekt freigegeben, so bleibt das übergeordnete
  18 + * Objekt erhalten (und somit auch der handle geöffnet).
  19 + * 4. Ein close auf ein Stream Objekt schließt auch das übergeordnete
  20 + * Objekt und gibt es frei. Somit werden auch alle weiteren Stream
  21 + * Objekte geschlossen.
  22 + *
  23 + * !!!Zusammenfassend bleibt nochmal hervorzuheben das close gegenüber free
  24 + * die stärkere operation ist und zu einem free aller stream objekte und
  25 + * des übergeordneten Objekts führt.!!!
  26 + */
  27 +#ifndef SCOT_STREAM_H
  28 +#define SCOT_STREAM_H
  29 +
  30 +#include <scot/scot_int.h>
  31 +#include <scot/scot_types.h>
  32 +
  33 +#define SCOT_STREAM_BUF_SIZE 100
  34 +
  35 +/* scot stream types (scot_stream:s_type) . */
  36 +/* Die ersten bis zum --- Kommentar sind stream_pool fähig */
  37 +#define SCOT_STREAM_TYPE_SOCKET 0
  38 +#define SCOT_STREAM_TYPE_PIPE 1
  39 +#define SCOT_STREAM_TYPE_TERM 2
  40 +/* --- */
  41 +#define SCOT_STREAM_TYPE_FILE 3
  42 +#define SCOT_STREAM_TYPE_INOTIFY 4
  43 +
  44 +#ifdef WIN32
  45 +# include <Windows.h>
  46 +# include <scot/stream_win.h>
  47 +# define SCOT_FILE_READ win_file_read
  48 +#else
  49 +# define SCOT_FILE_READ read
  50 +#endif /* WIN32 */
  51 +
  52 +/* s must me a pointer to a stream...this is normally the case! */
  53 +#define SCOT_STREAM_TO_SOCKET(s) ((struct scot_socket *)(s))
  54 +#define SCOT_STREAM_TO_PIPE(s) ((struct scot_pipe *)(s))
  55 +#define SCOT_STREAM_TO_TERM(s) ((struct scot_term *)(s))
  56 +#define SCOT_STREAM_TO_FILE(s) ((struct scot_file *)(s))
  57 +#define SCOT_STREAM_TO_INOTIFY(s) ((struct scot_inotify *)(s))
  58 +
  59 +/*
  60 + * get the base object of the given stream with the correct type
  61 + * Those base types has to be specified here at the moment... maybe
  62 + * sometimes there will be some kind of registration method for
  63 + * base types
  64 + */
  65 +#define SCOT_STREAM_PROV(st) \
  66 + ((st)->s_type == SCOT_STREAM_TYPE_SOCKET)? SCOT_STREAM_TO_SOCKET((st)):\
  67 + ((st)->s_type == SCOT_STREAM_TYPE_PIPE)? SCOT_STREAM_TO_PIPE((st)):\
  68 + ((st)->s_type == SCOT_STREAM_TYPE_TERM)? SCOT_STREAM_TO_TERM((st)):\
  69 + ((st)->s_type == SCOT_STREAM_TYPE_FILE)? SCOT_STREAM_TO_FILE((st)):\
  70 + ((st)->s_type == SCOT_STREAM_TYPE_INOTIFY)?SCOT_STREAM_TO_INOTIFY((st)):(st)
  71 +
  72 +#define SCOT_STREAM_FREE(st) \
  73 + ((st)->s_type == SCOT_STREAM_TYPE_SOCKET)?\
  74 + scot_socket_free (SCOT_STREAM_TO_SOCKET (st)):\
  75 + ((st)->s_type == SCOT_STREAM_TYPE_PIPE)? scot_stream_free ((st)):\
  76 + ((st)->s_type == SCOT_STREAM_TYPE_TERM)? scot_stream_free ((st)):\
  77 + ((st)->s_type == SCOT_STREAM_TYPE_FILE)? scot_stream_free ((st)):\
  78 + ((st)->s_type == SCOT_STREAM_TYPE_INOTIFY)?scot_stream_free ((st)):\
  79 + scot_stream_free ((st))
  80 +
  81 +/*
  82 + * connections via ssl must be handled separately, because communication
  83 + * over them has some very distinc behaviour then with other streams.
  84 + * First, read and write are not done on a handle but on an ssl object.
  85 + * Next, ssl has an all or nothing approach. If a write could not send
  86 + * all data it sould be assumed as failed. This is neccessary for the
  87 + * encryption.
  88 + * Next, ssl is designed to sit on top of most stream types. Thus it
  89 + * is a separate object, that should be createable by a stream object.
  90 + */
  91 +
  92 +struct scot_stream
  93 +{
  94 +#ifndef WIN32
  95 + union
  96 + {
  97 + int32_t file;
  98 + int32_t sock;
  99 + } handle;
  100 +#else
  101 + union
  102 + {
  103 + HANDLE file;
  104 + SOCKET sock;
  105 + } handle;
  106 +#endif
  107 + char rbuf [SCOT_STREAM_BUF_SIZE];
  108 + char wbuf [SCOT_STREAM_BUF_SIZE];
  109 + uint32_t rbuf_idx;
  110 + uint32_t wbuf_idx;
  111 + int32_t s_type; /* an identifier of this stream (file, socket, pipe...) */
  112 + int16_t s_blk;
  113 +};
  114 +
  115 +int scot_stream_eof (struct scot_stream *);
  116 +SSIZE_T scot_stream_read (struct scot_stream *, char *, SIZE_T);
  117 +SSIZE_T scot_stream_write (struct scot_stream *, char *, SIZE_T);
  118 +void scot_stream_flush (struct scot_stream *);
  119 +
  120 +SSIZE_T scot_stream_read_pending (struct scot_stream *);
  121 +SSIZE_T scot_stream_write_pending (struct scot_stream *);
  122 +
  123 +int scot_stream_get_blocking (struct scot_stream *);
  124 +void scot_stream_set_block (struct scot_stream *);
  125 +void scot_stream_set_nonblock (struct scot_stream *);
  126 +
  127 +void scot_stream_close (struct scot_stream *);
  128 +int scot_stream_is_closed (struct scot_stream *);
  129 +
  130 +void scot_stream_free (struct scot_stream *);
  131 +
  132 +#endif /* SCOT_STREAM_H */
... ...
  1 +#ifndef SCOT_STREAM_POOL_H
  2 +#define SCOT_STREAM_POOL_H
  3 +
  4 +#include <sys/time.h>
  5 +#include <sys/types.h>
  6 +#include <unistd.h>
  7 +
  8 +#include <scot/event_listener.h>
  9 +#include <scot/stream.h>
  10 +#include <scot/thread.h>
  11 +#include <scot/stream_pool_fraction.h>
  12 +
  13 +#define GEN_LOCAL
  14 +# include <scot/list.h>
  15 +#undef GEN_LOCAL
  16 +
  17 +/*
  18 + * folgende masken dienen dazu zu bestimmen in welches fd_set
  19 + * (read, write, exception) ein filehandle eingetragen werden soll.
  20 + * D.h. für welche operation der select diesen handle überwachen soll.
  21 + */
  22 +#define SCOT_STREAM_POOL_FD_ADD_RMASK 0x1
  23 +#define SCOT_STREAM_POOL_FD_ADD_WMASK 0x2
  24 +#define SCOT_STREAM_POOL_FD_ADD_EMASK 0x4
  25 +
  26 +#define SCOT_STREAM_POOL_CLEANUP 0x00
  27 +#define SCOT_STREAM_POOL_RESTART_FRACTION 0x01
  28 +#define SCOT_STREAM_POOL_START_FRACTION 0x02
  29 +#define SCOT_STREAM_POOL_STOP_FRACTION 0x03
  30 +#define SCOT_STREAM_POOL_RESTART_ALL_FRAC 0x04
  31 +#define SCOT_STREAM_POOL_START_ALL_FRAC 0x05
  32 +#define SCOT_STREAM_POOL_STOP_ALL_FRAC 0x06
  33 +
  34 +#define SCOT_STREAM_POOL_KEEP_STREAMS 0x0
  35 +#define SCOT_STREAM_POOL_FREE_STREAMS 0x1
  36 +
  37 +
  38 +typedef struct scot_sp_fraction scot_sp_fraction;
  39 +GEN_LIST_TYPE_PROTO (scot_sp_fraction);
  40 +
  41 +struct scot_stream_pool
  42 +{
  43 + struct scot_event_listener el;
  44 +
  45 + uint16_t cmd;
  46 + void * cmd_arg;
  47 + THREAD_COND_T cmd_cond;
  48 + THREAD_COND_CS_T cmd_cs;
  49 +
  50 + list_scot_sp_fraction_node_t * pool;
  51 + THREAD_MUTEX_T mutex;
  52 +};
  53 +
  54 +
  55 +struct scot_stream_pool * scot_stream_pool_new (struct scot_stream_pool *);
  56 +void scot_stream_pool_free (struct scot_stream_pool *);
  57 +void scot_stream_pool_free_s (struct scot_stream_pool *,
  58 + int);
  59 +void scot_stream_pool_add (struct scot_stream_pool *,
  60 + struct scot_stream *,
  61 + int);
  62 +void scot_stream_pool_remove (struct scot_stream_pool *,
  63 + struct scot_stream *,
  64 + int);
  65 +int scot_stream_pool_get_rwe (struct scot_stream_pool *,
  66 + struct scot_stream *);
  67 +void scot_stream_pool_cmd (struct scot_stream_pool *,
  68 + uint16_t,
  69 + void *);
  70 +struct scot_stream * scot_sp_get_all_streams (struct scot_stream_pool *);
  71 +
  72 +#endif /* SCOT_STREAM_POOL_H */
... ...
  1 +#ifndef SCOT_STREAM_POOL_FRACTION_H
  2 +#define SCOT_STREAM_POOL_FRACTION_H
  3 +
  4 +#include <sys/time.h>
  5 +#include <sys/types.h>
  6 +#include <unistd.h>
  7 +
  8 +#include <scot/stream_pool.h>
  9 +#include <scot/event_listener.h>
  10 +#include <scot/scot_int.h>
  11 +#include <scot/stream.h>
  12 +#include <scot/thread.h>
  13 +
  14 +#define SCOT_MAX_FRACTION 64 /* Windows kann max. 64 Objekte pro thread
  15 + überwachen. */
  16 +
  17 +struct scot_sp_fraction
  18 +{
  19 + struct scot_event_listener * el;
  20 +
  21 + int stream_type; /* what streams to accept */
  22 +
  23 + THREAD_T thread_handle;
  24 + THREAD_ID_T thread_id;
  25 + int thread_run_flg;
  26 +
  27 + scot_thread_entry_fptr spf_entry_func;
  28 +
  29 + uint16_t s_count;
  30 + struct scot_stream * s_list [SCOT_MAX_FRACTION];
  31 + int free_s;
  32 +
  33 + /* for select */
  34 + fd_set rfds, wfds, efds;
  35 + int max_fd;
  36 +};
  37 +
  38 +extern scot_thread_entry_fptr scot_spf_thread_func[];
  39 +
  40 +struct scot_sp_fraction * scot_spf_new (struct scot_sp_fraction *,
  41 + struct scot_event_listener *,
  42 + int);
  43 +void scot_spf_free (struct scot_sp_fraction *);
  44 +void scot_spf_free_s (struct scot_sp_fraction *,
  45 + int);
  46 +void scot_spf_add (struct scot_sp_fraction *,
  47 + struct scot_stream *,
  48 + int);
  49 +void scot_spf_remove (struct scot_sp_fraction *,
  50 + struct scot_stream *,
  51 + int);
  52 +
  53 +#endif /* SCOT_STREAM_POOL_FRACTION_H */
... ...
  1 +#ifndef SCOT_STREAM_WIN_H
  2 +#define SCOT_STREAM_WIN_H
  3 +
  4 +#include <windows.h>
  5 +
  6 +SSIZE_T win_file_read (HANDLE, void *, SIZE_T);
  7 +
  8 +#endif /* SCOT_STREAM_WIN_H */
... ...
  1 +/*
  2 + * used for threadsafety within exception
  3 + * actually only pthread is supported
  4 + */
  5 +#ifndef THREAD_H
  6 +#define THREAD_H
  7 +
  8 +#include <stdio.h>
  9 +
  10 +#define JOIN_OK 0x00
  11 +#define JOIN_TIMEOUT 0x01
  12 +#define JOIN_ERROR 0x02
  13 +
  14 +/*
  15 + * i guess it is possible to write mutex code that uses cond
  16 + * elements to timeout on lock, but right now i have no clear
  17 + * idea of how to do this. The following thoughts i had:
  18 + * - create a struct that holds a pthread_mutex_t and a pthread_cond_t
  19 + * for every mutex.
  20 + * - lock mutexes only by calling pthread_cond_timedwait
  21 + * And here starts the problem...to do a cond_timedwait i need to ensure
  22 + * that the mutex is already locked...well and then a question i have not
  23 + * clearyfied, if a thread ends, will all locks on mutexes be removed?
  24 + * I guess so, but i did not test it. And an even more important question,
  25 + * is it possible to write cleanup-code that guarantees that a
  26 + * pthread_cond_signal is called for every mutex the thread holds...
  27 + * well, we will end up with the requirement that the programmer has to
  28 + * call a release mutex function before ending a thread and if the programmer
  29 + * forgets that the behaviour of out code is unspecified
  30 + * Right now i will not support timeouts on mutex-locks and to be consistent
  31 + * it is not supported on win32 either, also it would be much easier to
  32 + * implement there.
  33 + */
  34 +#define MUTEX_LOCK_OK 0x00
  35 +#define MUTEX_LOCK_ERROR 0x02
  36 +
  37 +#define THREAD_T int
  38 +#define THREAD_ID_T int
  39 +#define THREAD_ID 0
  40 +#define SELF_THREAD 0
  41 +#define NEW_THREAD perror ("No supported thread system used!\n")
  42 +#define CANCEL_THREAD(t) NEW_THREAD
  43 +#define EXIT_THREAD(r) NEW_THREAD
  44 +#define JOIN_THREAD(t,i) NEW_THREAD
  45 +#define THREAD_CANCEL_ENABLE NEW_THREAD
  46 +#define THREAD_CANCEL_DISABLE NEW_THREAD
  47 +#define THREAD_CANCEL_ASYNC NEW_THREAD
  48 +#define THREAD_CANCEL_DEFER NEW_THREAD
  49 +#define T_PROC_RET int
  50 +
  51 +#endif /* THREAD_H */
... ...
  1 +/*
  2 + * dir.h: as one might suggest here are definitions and prototypes for
  3 + * win32/dir.c
  4 + *
  5 + * Copyright (C) 2006 Georg Steffers
  6 + *
  7 + * Author: Georg Steffers [GST] <georg.steffers@aschendorff.de>
  8 + * Developer:
  9 + *
  10 + * Changes (for this file only):
  11 + * (2006-06-12) [GST] Started this changelog...well the program is
  12 + * ready since some weeks right now.
  13 + */
  14 +#ifndef DIR_H
  15 +#define DIR_H
  16 +
  17 +#include <windows.h>
  18 +
  19 +#include <scot/dir_common.h>
  20 +
  21 +/* abstraction for file information and an directory handle */
  22 +#define FILE_DATA struct dir_file
  23 +#define DIR_HANDLE HANDLE
  24 +
  25 +/* abstraction for checking if a file is a directory */
  26 +#define IS_DIRECTORY(file_data) \
  27 + ((file_data).file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  28 +
  29 +/* abstraction for getting the filename of a directory entry. */
  30 +#define DIRENT_FNAME(file_data) ((file_data).file.cFileName)
  31 +
  32 +/* structure for all available information about the directory entry. */
  33 +struct dir_file
  34 +{
  35 + char path [MAX_PATH+1];
  36 + WIN32_FIND_DATA file;
  37 +};
  38 +
  39 +/* the last in parameter is posix specific. It defines if stat should
  40 + * follow symlinks or not. Under Windows it is ignored. */
  41 +DIR_HANDLE get_dir_first (const char *, FILE_DATA *, int);
  42 +int get_dir_next (DIR_HANDLE, const char *, FILE_DATA *, int);
  43 +
  44 +#endif /* DIR_H */
... ...
  1 +/***************************************************************************
  2 + * memory.h: Prototypes for default memory operations like memcpy and thus *
  3 + * on a win32 system nearly all CRT functions (CRT is the *
  4 + * windows C RunTime, that is the normal libC) aren't thread- *
  5 + * safe. As i build up tests this causes problems for example *
  6 + * with strcpy. So i decided to write wrapper that use non CRT *
  7 + * functions on Windows and normal libC ones on a posix system. *
  8 + * *
  9 + * Author: Georg Steffers <georg@steffers.org> *
  10 + * Date: 03/06/2006 *
  11 + ***************************************************************************/
  12 +#ifndef MEMORY_H
  13 +#define MEMORY_H
  14 +
  15 +#include <windows.h>
  16 +#include <sys/types.h>
  17 +
  18 +#include <scot_common.h>
  19 +#include <scot/scot_types.h>
  20 +
  21 +#define SCOT_MEM_GET(s) HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, (s));
  22 +#define SCOT_MEM_FREE(p) \
  23 + if ((p)) {HeapFree(GetProcessHeap(), 0, (p)); (p)=NULL;}
  24 +#define SCOT_MEM_COPY(p,q,s) (CopyMemory ((p), (q), (s)), (p))
  25 +#define SCOT_MEM_MOVE(p,q,s) (MoveMemory ((p), (q), (s)), (p))
  26 +#define SCOT_MEM_FILL(p,v,s) (FillMemory ((p), (s), (v)), (p))
  27 +#define SCOT_MEM_ZERO ZeroMemory
  28 +#define SCOT_STR_LENGTH str_length
  29 +#define SCOT_STR_COPY str_copy
  30 +#define SCOT_STRN_COPY strn_copy
  31 +#define SCOT_STR_CHAR str_char
  32 +#define SCOT_STRR_CHAR strr_char
  33 +
  34 +SIZE_T str_length (const char *);
  35 +char * str_copy (char *, const char *);
  36 +char * strn_copy (char *, const char *, SIZE_T);
  37 +char * str_char (const char *, int);
  38 +char * strr_char (const char *, int);
  39 +
  40 +#endif /* MEMORY_H */
... ...
  1 +#ifndef SCOT_TYPES_H
  2 +#define SCOT_TYPES_H
  3 +
  4 +#include <Windows.h>
  5 +
  6 +#endif /* SCOT_TYPES_H */
... ...
  1 +/*
  2 + * used for threadsafety within exception
  3 + * actually only pthread is supported
  4 + */
  5 +#ifndef THREAD_H
  6 +#define THREAD_H
  7 +
  8 +#include <stdio.h>
  9 +#include <windows.h>
  10 +
  11 +
  12 +#define JOIN_OK 0x00
  13 +#define JOIN_TIMEOUT 0x01
  14 +#define JOIN_ERROR 0x02
  15 +
  16 +/*
  17 + * i guess it is possible to write mutex code that uses cond
  18 + * elements to timeout on lock, but right now i have no clear
  19 + * idea of how to do this. The following thoughts i had:
  20 + * - create a struct that holds a pthread_mutex_t and a pthread_cond_t
  21 + * for every mutex.
  22 + * - lock mutexes only by calling pthread_cond_timedwait
  23 + * And here starts the problem...to do a cond_timedwait i need to ensure
  24 + * that the mutex is already locked...well and then a question i have not
  25 + * clearyfied, if a thread ends, will all locks on mutexes be removed?
  26 + * I guess so, but i did not test it. And an even more important question,
  27 + * is it possible to write cleanup-code that guarantees that a
  28 + * pthread_cond_signal is called for every mutex the thread holds...
  29 + * well, we will end up with the requirement that the programmer has to
  30 + * call a release mutex function before ending a thread and if the programmer
  31 + * forgets that the behaviour of out code is unspecified
  32 + * Right now i will not support timeouts on mutex-locks and to be consistent
  33 + * it is not supported on win32 either, also it would be much easier to
  34 + * implement there.
  35 + */
  36 +#define MUTEX_LOCK_OK 0x00
  37 +#define MUTEX_LOCK_ERROR 0x02
  38 +
  39 +#define THREAD_T HANDLE
  40 +#define THREAD_ID_T DWORD
  41 +#define THREAD_ID GetCurrentThreadId ()
  42 +#define SELF_THREAD GetCurrentThread ()
  43 +#define NEW_THREAD thread_new
  44 +#define CANCEL_THREAD(thread) (! TerminateThread ((thread), -1))
  45 +#define EXIT_THREAD(retval) _endthreadex ((DWORD) (retval))
  46 +#define JOIN_THREAD thread_join
  47 +#define THREAD_CANCEL_ENABLE
  48 +#define THREAD_CANCEL_DISABLE
  49 +#define THREAD_CANCEL_ASYNC
  50 +#define THREAD_CANCEL_DEFER
  51 +#define T_PROC_RET DWORD WINAPI
  52 +
  53 +#define THREAD_MUTEX_T HANDLE
  54 +#define NEW_THREAD_MUTEX CreateMutex (NULL, FALSE, NULL)
  55 +#define LOCK_THREAD_MUTEX thread_mutex_lock
  56 +#define UNLOCK_THREAD_MUTEX(mutex) (! ReleaseMutex ((mutex)))
  57 +
  58 +#define THREAD_COND_T CONDITION_VARIABLE
  59 +#define THREAD_COND_CS_T CRITICAL_SECTION
  60 +#define GET_THREAD_COND(c)
  61 +#define GET_THREAD_COND_CS(c)
  62 +#define THREAD_COND_ENTER_CS(cs) EnterCriticalSection ((cs))
  63 +#define THREAD_COND_LEAVE_CS(cs) LeaveCriticalSection ((cs))
  64 +#define SIGNAL_THREAD_COND(cond) WakeConditionVariable ((cond))
  65 +#define BCAST_THREAD_COND(cond) WakeAllConditionVariable ((cond))
  66 +#define WAIT_THREAD_COND(cond, cs, t) \
  67 + SleepConditionVariableCS((cond), (cs), t)
  68 +
  69 +#define THREAD_ATEXIT_BEGIN
  70 +#define THREAD_ATEXIT_END
  71 +
  72 +typedef T_PROC_RET (*scot_thread_entry_fptr) (void *);
  73 +
  74 +THREAD_T thread_new (T_PROC_RET (*)(void *), void*);
  75 +int thread_join (THREAD_T, unsigned int);
  76 +THREAD_MUTEX_T thread_mutex_new (void);
  77 +int thread_mutex_lock (THREAD_MUTEX_T *);
  78 +
  79 +#endif /* THREAD_H */
... ...
  1 +/*
  2 + * scot_common.h: commen difinitions for scot.
  3 + * scot is a c obliging toolbox.
  4 + *
  5 + * Copyright (C) 2006 Georg Steffers. All rights reserved.
  6 + *
  7 + * This software is licensed under the terms of the GNU Genral Public
  8 + * License (GPL). Please see gpl.txt for details or refer to
  9 + * http://www.gnu.org/licenses/gpl.html
  10 + *
  11 + * Author: Georg Steffers <georg@steffers.org>
  12 + *
  13 + * 01/22/2006: Georg Steffers - introduced to give support for gettext
  14 + * to all code used in san.
  15 + * 01/24/2006: Georg Steffers - introduce some new macros:
  16 + * SANTEXTDOMAIN -> textdomain for messages
  17 + * given by libsan functions.
  18 + * LOCALDIR -> directory where to find that
  19 + * textdomain.
  20 + * D_(s) -> translates with the
  21 + * SANTEXTDOMAIN. This should be
  22 + * called for strings defined
  23 + * within san. But remember to
  24 + * call
  25 + * bindtextdomain (
  26 + * SANTEXTDOMAIN, LOCALEDIR);
  27 + * first.
  28 + */
  29 +#ifndef SCOT_COMMOM_H
  30 +#define SCOT_COMMON_H
  31 +
  32 +#include <locale.h>
  33 +#include <libintl.h>
  34 +#include <ctype.h>
  35 +#include <scot/scot_int.h>
  36 +
  37 +/* for PACKAGE and LOCALEDIR */
  38 +#ifdef HAVE_CONFIG_H
  39 +#include "../config.h"
  40 +#else
  41 +#define PACKAGE "scot"
  42 +#define LOCALEDIR "/usr/share/locale"
  43 +#endif /* HAVE_CONFIG_H */
  44 +
  45 +#define _(string) gettext(string) /* our mark for xgettext */
  46 +#define D_(s) dgettext(PACKAGE, s)
  47 + /* a mark dgettext calls */
  48 +#define N_(string) (string) /* noop mark for gettext */
  49 +
  50 +/* inline for C++, GCC, C99. For C89 these macros are empty. */
  51 +#if defined(__cplusplus)
  52 +# define STATIC_INLINE static inline
  53 +# define INLINE inline
  54 +scot/# define EXTERN_INLINE inline
  55 +#elif defined(__GNUC__)
  56 +# define STATIC_INLINE static __inline__
  57 +# define INLINE static __inline__
  58 +# define EXTERN_INLINE extern __inline__
  59 +#elif __STDC_VERSION__ >= 199901
  60 +# define STATIC_INLINE static inline
  61 +# define INLINE static inline
  62 +# define EXTERN_INLINE inline
  63 +#else /* C89 */
  64 +# define STATIC_INLINE static
  65 +# define INLINE static
  66 +# define EXTERN_INLINE
  67 +#endif /* inline definitions */
  68 +
  69 +#define SCOT_SOCKET_BACKLOG 5
  70 +
  71 +/*int scot_strisdigit (const char *);*/
  72 +#ifndef SCOT_STRISDIGIT
  73 +#define SCOT_STRISDIGIT scot_strisdigit
  74 +static
  75 +inline
  76 +int scot_strisdigit (const char * str)
  77 +{
  78 + while (*str)
  79 + if (!isdigit (*(str++))) return 0;
  80 + return 1;
  81 +}
  82 +#endif
  83 +
  84 +#ifndef UNIX_PATH_MAX
  85 +/*
  86 + * this should be done better....i got this val from linux/un.h but as
  87 + * this should be portable i should think about a more portable way to get
  88 + * this...maybe with configure....
  89 + */
  90 +#define UNIX_PATH_MAX 108
  91 +#endif /* UNIX_PATH_MAX */
  92 +
  93 +#define SCOT_UNX_PATH_TO_LONG 0
  94 +extern const char * scot_common_errmsg[];
  95 +
  96 +int base2exp (uint32_t);
  97 +
  98 +#endif /* SCOT_COMMON_H */
... ...
  1 +EXTRA_DIST = codeset.m4 gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 intmax.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 longdouble.m4 longlong.m4 nls.m4 po.m4 printf-posix.m4 progtest.m4 signed.m4 size_max.m4 stdint_h.m4 uintmax_t.m4 ulonglong.m4 wchar_t.m4 wint_t.m4 xsize.m4
... ...
Please register or login to post a comment