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