Showing
57 changed files
with
4813 additions
and
0 deletions
Too many changes to show.
To preserve performance only 57 of 57+ files are displayed.
AUTHORS
0 → 100644
ChangeLog
0 → 100644
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. | ... | ... |
Makefile.am
0 → 100644
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 | ... | ... |
NEWS
0 → 100644
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. | ... | ... |
README
0 → 100644
autoclean.sh
0 → 100755
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/* | ... | ... |
autogen.sh
0 → 100755
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 | ... | ... |
configure.ac
0 → 100644
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 | ... | ... |
design/scot-event-subsystem.dia
0 → 100644
No preview for this file type
event_new.c
0 → 100644
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 | + */ | ... | ... |
include/Makefile.am
0 → 100644
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 | + | ... | ... |
include/scot/cmdla.h
0 → 100644
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 */ | ... | ... |
include/scot/dir_common.h
0 → 100644
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 */ | ... | ... |
include/scot/event.h
0 → 100644
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 */ | ... | ... |
include/scot/event_listener.h
0 → 100644
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 */ | ... | ... |
include/scot/excenv_t.h
0 → 100644
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 */ | ... | ... |
include/scot/exception.h
0 → 100644
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 */ | ... | ... |
include/scot/exception_t.h
0 → 100644
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 */ | ... | ... |
include/scot/fs_watcher.h
0 → 100644
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 */ | ... | ... |
include/scot/inotify.h
0 → 100644
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 */ | ... | ... |
include/scot/list.h
0 → 100644
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 */ | ... | ... |
include/scot/list_func_proto.h
0 → 100644
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 */ | ... | ... |
include/scot/list_impl.h
0 → 100644
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 */ | ... | ... |
include/scot/list_man.h
0 → 100644
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 */ | ... | ... |
include/scot/list_mod.h
0 → 100644
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 */ | ... | ... |
include/scot/list_nav.h
0 → 100644
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 */ | ... | ... |
include/scot/list_proto.h
0 → 100644
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 */ | ... | ... |
include/scot/list_type_proto.h
0 → 100644
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 */ | ... | ... |
include/scot/posix/dir.h
0 → 100644
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 */ | ... | ... |
include/scot/posix/memory.h
0 → 100644
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 */ | ... | ... |
include/scot/posix/scot_types.h
0 → 100644
include/scot/posix/thread.h
0 → 100644
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 */ | ... | ... |
include/scot/queue.h
0 → 100644
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 */ | ... | ... |
include/scot/queue_func_proto.h
0 → 100644
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 */ | ... | ... |
include/scot/queue_impl.h
0 → 100644
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 */ | ... | ... |
include/scot/queue_proto.h
0 → 100644
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 */ | ... | ... |
include/scot/queue_type_proto.h
0 → 100644
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 */ | ... | ... |
include/scot/scot_exceptions.h
0 → 100644
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 */ | ... | ... |
include/scot/socket.h
0 → 100644
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 */ | ... | ... |
include/scot/socket_in.h
0 → 100644
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 */ | ... | ... |
include/scot/socket_un.h
0 → 100644
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 */ | ... | ... |
include/scot/stack.h
0 → 100644
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 */ | ... | ... |
include/scot/stack_func_proto.h
0 → 100644
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 */ | ... | ... |
include/scot/stack_impl.h
0 → 100644
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 */ | ... | ... |
include/scot/stack_proto.h
0 → 100644
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 */ | ... | ... |
include/scot/stack_type_proto.h
0 → 100644
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 */ | ... | ... |
include/scot/stream.h
0 → 100644
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 */ | ... | ... |
include/scot/stream_pool.h
0 → 100644
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 */ | ... | ... |
include/scot/stream_pool_fraction.h
0 → 100644
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 */ | ... | ... |
include/scot/stream_win.h
0 → 100644
include/scot/thread_none.h
0 → 100644
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 */ | ... | ... |
include/scot/win32/dir.h
0 → 100644
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 */ | ... | ... |
include/scot/win32/memory.h
0 → 100644
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 */ | ... | ... |
include/scot/win32/scot_types.h
0 → 100644
include/scot/win32/thread.h
0 → 100644
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 */ | ... | ... |
include/scot_common.h
0 → 100644
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 */ | ... | ... |
m4/Makefile.am
0 → 100644
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