Adding upstream version 1.0.2.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-04-22 17:57:53 +02:00
parent a04160a00d
commit 36fe29e3d5
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
464 changed files with 372850 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -0,0 +1,8 @@
/*!\file
* \return Bei Erfolg liefert die Funktion true (1) zurück, sonst false (0).
*
* \see
* - ppl7::CWString::Set(const char *text, int size=-1);
*
*
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1,182 @@
<doxygenlayout version="1.0">
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title="Einleitung"/>
<tab type="modules" visible="yes" title=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespaces" visible="yes" title=""/>
<tab type="namespacemembers" visible="yes" title=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classes" visible="yes" title=""/>
<tab type="classindex" visible="no" title=""/>
<tab type="hierarchy" visible="yes" title=""/>
<tab type="classmembers" visible="yes" title=""/>
</tab>
<tab type="files" visible="no" title="">
<tab type="files" visible="yes" title=""/>
<tab type="globals" visible="yes" title=""/>
</tab>
<tab type="dirs" visible="no" title=""/>
<tab type="examples" visible="yes" title=""/>
<tab type="pages" visible="yes" title=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<allmemberslink visible="yes"/>
<memberdecl>
<membergroups visible="yes"/>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<typedefs title=""/>
<enums title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<detaileddescription title=""/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<membergroups visible="yes"/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdecl>
<memberdef>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<detaileddescription title=""/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<dirs visible="yes" title=""/>
<nestedgroups visible="yes" title=""/>
<files visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdecl>
<memberdef>
<pagedocs/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

255
src/pplib/docs/credits.dox Normal file
View file

@ -0,0 +1,255 @@
/*!\page pplPageCredits Credits
Die PPL-Library verwendet fremden Code, der zum Teil in der Library intergiert ist,
zum Teil wird dagegen gelinkt. Sämtlicher integrierter Code sowie alle zwingend
erforderlichen Libraries stehen unter einer BSD oder BSD ähnlichen Lizenz.
- \ref pplPageCredits_Integrated
- \ref pplPageCredits_Linked
- \ref pplPageCredits_Linked_Required
- \ref pplPageCredits_Linked_Optional
\section pplPageCredits_Integrated Integrierter Code
- <b>MD5-Hashberechnung</b>\n
Copyright RSA Data Security, Inc. MD5 Message-Digest Algorithm)
\code
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
\endcode
- <b>Zufallszahlengenerator</b>\n
Copyright (c) 1983, 1993 The Regents of the University of California
\code
Copyright (c) 1983, 1993
The Regents of the University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
\endcode
- <b>CRC32-Berechnung</b>\n
Quelle unbekannt
- <b>GIF-Reader</b>\n
Copyright 1990, 1991, 1993 by David Koblas
\code
+-------------------------------------------------------------------+
| Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) |
| Permission to use, copy, modify, and distribute this software |
| and its documentation for any purpose and without fee is hereby |
| granted, provided that the above copyright notice appear in all |
| copies and that both that copyright notice and this permission |
| notice appear in supporting documentation. This software is |
| provided "as is" without express or implied warranty. |
+-------------------------------------------------------------------+
\endcode
\section pplPageCredits_Linked Verlinkte Libraries
\subsection pplPageCredits_Linked_Required Zwingend erforderliche Libraries
Die nachfolgenden Libraries sind zwingend erforderlich, um die PPL-Library kompilieren zu können.
Das configure-Script prüft diese und bricht ab, wenn sie nicht vorhanden sind.
- <b>PCRE</b> (http://www.pcre.org/)\n
Copyright (c) 1997-2008 University of Cambridge All rights reserved.
\code
PCRE LICENCE
------------
PCRE is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Release 7 of PCRE is distributed under the terms of the "BSD" licence, as
specified below. The documentation for PCRE, supplied in the "doc"
directory, is distributed under the same terms as the software itself.
The basic library functions are written in C and are freestanding. Also
included in the distribution is a set of C++ wrapper functions.
THE BASIC LIBRARY FUNCTIONS
---------------------------
Written by: Philip Hazel
Email local part: ph10
Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
Copyright (c) 1997-2008 University of Cambridge
All rights reserved.
THE C++ WRAPPER FUNCTIONS
-------------------------
Contributed by: Google Inc.
Copyright (c) 2007-2008, Google Inc.
All rights reserved.
THE "BSD" LICENCE
-----------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the name of Google
Inc. nor the names of their contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
End
\endcode
- <b>Zlib</b> (http://www.zlib.net/)\n
Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
\code
zlib.h -- interface of the 'zlib' general purpose compression library
version 1.2.3, July 18th, 2005
Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly jloup@gzip.org
Mark Adler madler@alumni.caltech.edu
\endcode
- <b>Bzip2</b> (http://www.bzip.org/)\n
Copyright (C) 1996-2007 Julian R Seward
\code
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2007 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, jseward@bzip.org
bzip2/libbzip2 version 1.0.5 of 10 December 2007
\endcode
\subsection pplPageCredits_Linked_Optional Optionale Libraries
Die Nachfolgenden Libraries können optional mit der PPL-Library verwendet werden.
Bei Verwendung dieser Libraries müssen die gegebenenfalls abweichenden Lizenzbestimmungen
berücksichtigt werden.
- MySQL (http://www.mysql.org/)
- FreeTDS (http://www.freetds.org/)
- Sybase (http://www.sybase.com/)
- PNG (http://www.libpng.org/pub/png/)
- JPEG (http://www.ijg.org/)
- SDL (http://www.libsdl.org/)
- FreeType2 (http://www.freetype.org/)
- Iconv (http://www.gnu.org/software/libiconv/)
- MCrypt (http://mcrypt.sourceforge.net/)
- Lame (http://lame.sourceforge.net/)
- LibMad (http://mad.sourceforge.net/)
- Curl (http://curl.haxx.se/)
- OpenSSL (http://www.openssl.org/)
- LDNS (http://www.nlnetlabs.nl/projects/ldns/)
*/

View file

@ -0,0 +1,35 @@
/*!\defgroup PPLGroupDatabases Datenbanken
\brief Datenbank-Klassen
\desc
Die nachfolgenden Klassen und Funktionen können verwendet werden, um auf verschiedene Datenbanken
zuzugreifen. Die Funktionen und Klassen befinden sich im Namespace \ref ppl7::db.
\par Verwendung:
Um Queries auf einer Datenbank auszuführen, muss zunächst eine Verbindung hergestellt werden. Im einfachsten
Fall wird dazu eine Instanz der gewünschten Datenbank erstellt (z.B. ppl7::db::MySQL) und deren
Connect-Funktion aufgerufen, oder die Funktion ppl7::db::Connect aufgerufen, die als Ergebnis einen
Pointer auf ein ppl7::db::Database-Objekt zurückliefert.
\par
Anschließend können mit der ppl7::db::Exec oder ppl7::db::Query-Funktion des Objekts SQL-Queries ausgeführt werden, wobei
Exec nur ein "Erfolgreich" zurückliefert, aber keine Daten, und Query ein ppl7::db::ResultSet-Objekt zurückliefert,
aus dem das Ergebnis des Queries ausgelesen werden kann.
\par
Falls man sehr viele Datenbank-Verbindungen parallel benötigt, können zur Verwaltung auch
Datenbank-Pools verwendet werden. Hiervon gibt es 2 Stück: <ol>
<li>ppl7::db::Pool zur Verwaltung von beliebig vielen Verbindungen zu einer einzelnen Datenbank</li>
<li>ppl7::db::PoolEx zur Verwaltung von beliebig vielen Verbindungen zu verschiedenen Datenbanken</li>
</ol>
*/
/*!\namespace ppl7::db
\ingroup PPLGroupDatabases
\brief Namensraum der Datenbank-Funktionen und Klassen
\desc
In diesem Namensraum befinden sich Funktionen und Klassen zur Verwendung von Datenbanken.
Weitere Informationen sind \ref PPLGroupDatabases "hier zu finden".
*/

View file

@ -0,0 +1,40 @@
/*! \defgroup PPLGroupDataTypes Datentypen
* \section DatenTypIntegers Integers
PPL7 verwendet in vielen Fällen spezielle Datentypen, um sicherzustellen, dass
diese auf allen Platformen gleich groß sind. Diese sind:
<table>
<tr><th>Datentyp</th><th>Beschreibung</th></tr>
<tr><td>ppluint8</td><td>Vorzeichenloser 8-Bit Wert</td></tr>
<tr><td>ppluint16</td><td>Vorzeichenloser 16-Bit Wert</td></tr>
<tr><td>ppluint32</td><td>Vorzeichenloser 32-Bit Wert</td></tr>
<tr><td>ppluint64</td><td>Vorzeichenloser 64-Bit Wert</td></tr>
<tr><td>ppluint8</td><td>8-Bit Wert mit Vorzeichen</td></tr>
<tr><td>ppluint16</td><td>16-Bit Wert mit Vorzeichen</td></tr>
<tr><td>ppluint32</td><td>32-Bit Wert mit Vorzeichen</td></tr>
<tr><td>ppluint64</td><td>64-Bit Wert mit Vorzeichen</td></tr>
</table>
\section DatenTypOther Andere Datenstrukturen
\li \link ppl7::Variant Variant:\endlink Basisklasse für die nachfolgenden Datenstrukturen \n
\li \link ppl7::String String-Klasse \endlink \n
Die String-Klasse ppl7::String wird zum Verwalten von beliebig großen Strings verwendet
\li \link ppl7::Array Einfache Arrays mit Strings\endlink \n
Die Klasse ppl7::Array wird für einfache zweidimensionale Array verwendet, wobei der
Schlüssel eine laufende Nummer ist und der Wert ein String.
\li \link ppl7::AssocArray Komplexe Assoziative Arrays \endlink \n
Die Klasse ppl7::AssocArray wird für komplexe mehrdimensionale Arrays verwendet, wobei
der Schlüssel ein String oder eine Nummer sein kann. Der Wert kann alle hier aufgeführten Datentypen
beinhalten.
\li \link ppl7::ByteArray Ein Datentyp zum Speichern von binären Daten \endlink \n
Die Klasse ppl7::ByteArray wird zum Speichern von Binären Daten verwendet.
\li \link ppl7::ByteArrayPtr Ein Datentyp zum Speichern von Pointern \endlink \n
Die Klasse ppl7::ByteArrayPtr wird zum Speichern von Pointern auf beliebige Speicherbereiche
verwendet. Sie dient als Basisklasse für ppl7::ByteArray.
*/

View file

@ -0,0 +1,32 @@
#include <ppl7.h>
class MyClass : public ppl7::Thread
{
public:
virtual void threadMain();
};
void MyClass::threadMain()
{
printf ("Client-Thread wurde gestartet.\n");
while (1) {
if(threadShouldStop()) break; // Soll der Thread gestoppt werden?
ppl7::MSleep(100); // 100 Millisekunden warten
}
printf ("Client-Thread wurde beendet.\n");
}
int main(int argc, char **argv)
{
MyClass Job;
printf ("Der Haupthread startet einen Client-Thread...\n");
Job.threadStart();
printf ("Der Haupthread wartet nun 5 Sekunden...\n");
ppl7::SSleep(5);
printf ("Der Haupthread signalisiert dem Client-Thread, dass er sich beenden soll...\n");
Job.threadSignalStop();
printf ("Der Haupthread wartet, bis der Client-Thread beendet ist...\n");
Job.threadStop();
printf ("Der Client-Thread wurde erfolgreich gestoppt.\n");
return 0;
}

View file

@ -0,0 +1,69 @@
#include <ppl7.h>
#include <ppl7-audio.h>
int main(int argc, char **argv)
{
ppl7::Icecast ice; // Icecast-Objekt anlegen
ppl7::File file;
// Version der libshout ausgeben
printf ("libshout-Version: %s\n",(const char*)ice.version());
// Zu streamende MP3-Datei öffnen
if (!file.Open("/musik/powerplay/Ausgaben/Powerplay 152.mp3")) {
ppl6::PrintError();
return 1;
}
// Buffer für Audio-Daten reservieren
char *buffer=(char*)malloc(8192);
if (!buffer) {
printf("Kein Speicher!\n");
return 1;
}
// Exceptions abfangen
try {
// Stream-Format auf MP3 setzen
ice.setFormatMP3();
// Verbindungsparameter definieren
ice.setConnection("icecast.pfp.de",8000,"icesource");
// Mount-Punkt festlegen
ice.setMount("/live");
// Stream-Informationen setzen
ice.setGenre("Trance House Techno Electro");
ice.setName("Patrick F.'s Powerplay");
ice.setUrl("http://powerplay.pfp.de/");
ice.setDescription("Trance, House, Techno, Electro, mixed by Patrick Fedick");
// Verbindung zum Server aufbauen
ice.connect();
// Name des aktuellen Titels als Metainformation senden
ice.setTitle("Powerplay Ausgabe 152");
printf ("Beginne Stream\n");
size_t bytes;
// Quelldatei Schrittweise einlesen
while ((bytes=file.Fread(buffer,1,8192))) {
// Mit Server synchronisieren
ice.sync();
// Daten senden
ice.send(buffer,bytes);
}
printf ("Stream beendet\n");
} catch (ppl6::Exception& e) {
// Ursache der Exception ausgeben
printf ("Exception aufgetreten: %s\n",e.what());
free(buffer);
return 1;
}
free(buffer);
return 0;
}

View file

@ -0,0 +1,384 @@
int DB_Example1() {
ppl6::CAssocArray param;
param.Set("type","mysql");
param.Set("host","db.pfp.de");
param.Set("port","3306");
param.Set("user","patrick");
param.Set("password","xxxxxxx");
param.Set("dbname","test");
ppl6::db::Database *db=ppl6::db::Connect(param);
if (!db) {
ppl6::PrintError();
return 0;
}
} // EOF
int DB_Example2() {
ppl6::db::MySQL db;
db.SetParam("host","db.pfp.de");
db.SetParam("port","3306");
db.SetParam("user","patrick");
db.SetParam("password","xxxxxxx");
db.SetParam("dbname","test");
if (!db.Connect()) {
ppl6::PrintError();
return 0;
}
} // EOF
int DB_Example3() {
ppl6::CAssocArray param;
param.Set("host","db.pfp.de");
param.Set("port","3306");
param.Set("user","patrick");
param.Set("password","xxxxxxx");
param.Set("dbname","test");
ppl6::db::MySQL db;
if (!db.Connect(param)) {
ppl6::PrintError();
return 0;
}
} // EOF
int DB_Example4() {
ppl6::CAssocArray param;
param.Set("host","db.pfp.de");
param.Set("port","3306");
param.Set("user","patrick");
param.Set("password","xxxxxxx");
param.Set("dbname","test");
ppl6::db::MySQL db;
if (!db.ConnectCreate(param)) {
ppl6::PrintError();
return 0;
}
} // EOF
int DB_MySQL_Example1() {
// Verbindungsparameter festlegen
ppl6::CAssocArray param;
param.Set("host","db.pfp.de");
param.Set("port","3306");
param.Set("user","patrick");
param.Set("password","xxxxxxx");
param.Set("dbname","test");
// Datenbank-Klasse anlegen
ppl6::db::MySQL db;
// Verbindung aufbauen
if (!db.Connect(param)) {
ppl6::PrintError();
return 0;
}
// Query abschicken
ppl6::db::Result *res=db.Query("select * from user oder by nachname, vorname");
if (!res) { // Fehler abfangen
ppl6::PrintError();
} else {
printf ("Es wurden %i Datensätze gefunden\n",res->Rows());
// Result wieder freigeben
delete res;
}
// Die Verbindung wird durch den Destruktor der Klasse automatisch
// ordnungsgemäß getrennt
} // EOF
int DB_Sybase_Example1() {
// Verbindungsparameter festlegen
ppl6::CAssocArray param;
param.Set("host","db.pfp.de");
param.Set("port","4711");
param.Set("user","patrick");
param.Set("password","xxxxxxx");
param.Set("dbname","test");
// Datenbank-Klasse anlegen
ppl6::db::Sybase db;
// Verbindung aufbauen
if (!db.Connect(param)) {
ppl6::PrintError();
return 0;
}
// Query abschicken
ppl6::db::Result *res=db.Query("select * from user oder by nachname, vorname");
if (!res) { // Fehler abfangen
ppl6::PrintError();
} else {
printf ("Es wurden %i Datensätze gefunden\n",res->Rows());
// Result wieder freigeben
delete res;
}
// Die Verbindung wird durch den Destruktor der Klasse automatisch
// ordnungsgemäß getrennt
} // EOF
int DB_Sybase_Example2() {
// Verbindungsparameter festlegen
ppl6::CAssocArray param;
param.Set("host","db.pfp.de");
param.Set("port","4711");
param.Set("user","patrick");
param.Set("password","xxxxxxx");
param.Set("dbname","test");
// Datenbank-Klasse anlegen
ppl6::db::Sybase db;
// Verbindung aufbauen
if (!db.Connect(param)) {
ppl6::PrintError();
return 0;
}
// Query abschicken
ppl6::db::Result *res=db.Query("select * from user oder by nachname, vorname");
if (!res) { // Fehler abfangen
ppl6::PrintError();
} else {
pplint64 rows=0;
ppl6::CAssocArray row;
// Durch das Ergebnis durchiterieren
while (res->FetchArray(row)) {
// Felder der aktuellen Ergebnis-Zeile befinden sich nun im Array "row" und
// können verarbeitet werden
printf ("%s %s\n",row["nachname"],row["vorname"]);
rows++;
}
delete res;
}
// Die Verbindung wird durch den Destruktor der Klasse automatisch
// ordnungsgemäß getrennt
} // EOF
int DB_Postgres_Example1() {
// Verbindungsparameter festlegen
ppl6::CAssocArray param;
param.Set("host","db.pfp.de");
param.Set("port","5432");
param.Set("user","patrick");
param.Set("password","xxxxxxx");
param.Set("dbname","test");
// Datenbank-Klasse anlegen
ppl6::db::Postgres db;
// Verbindung aufbauen
if (!db.Connect(param)) {
ppl6::PrintError();
return 0;
}
// Query abschicken
ppl6::db::Result *res=db.Query("select * from user oder by nachname, vorname");
if (!res) { // Fehler abfangen
ppl6::PrintError();
} else {
printf ("Es wurden %i Datensätze gefunden\n",res->Rows());
// Result wieder freigeben
delete res;
}
// Die Verbindung wird durch den Destruktor der Klasse automatisch
// ordnungsgemäß getrennt
} // EOF
int DB_Result_Example1() {
// Zunächst erstellen wir eine Verbindung zu einer MySQL-Datenbank
ppl6::CAssocArray param;
param.Set("host","db.pfp.de");
param.Set("port","3306");
param.Set("user","patrick");
param.Set("password","xxxxxxx");
param.Set("dbname","test");
ppl6::db::MySQL db;
// Verbindung zur Datenbank aufbauen
if (!db.Connect(param)) {
ppl6::PrintError();
return 0;
}
// Select abschicken
ppl6::db::Result *res=db.Query("select * from user order by name");
if (!res) {
ppl6::PrintError();
return 0;
}
printf ("Es wurden %lli Datensätze gefunden:\n",res->Rows());
ppl6::CAssocArray row;
// Wir verwenden Result::FetchArray, um durch das Ergebnis zu traversieren
while ((res->FetchArray(row))) {
printf ("Name: %s, Email: %s\n",row["name"],row["email"]);
}
delete res; // Ergebnis löschen, Speicher freigeben
db.Disconnect();
} // EOF
int DB_Save_Example1(ppl6::db::Database *db) {
// Die Funktion geht davon aus, dass "db" eine gültige Datenbank-Verbindung
// enthält.
ppl6::CAssocArray Data;
Data.Set("vorname","Patrick");
Data.Set("nachname","Fedick");
Data.Set("email","xxx@xxxx.xx");
return db->Save("update","user",Data,"where userid=1");
} // EOF
int DB_Pool_Example1() {
// Connect-Parameter festlegen
ppl6::CAssocArray param;
param.Set("type","sybase");
param.Set("host","database.example.com");
param.Set("port","1234");
param.Set("user","demo");
param.Set("password","demo");
param.Set("dbname","test");
// Pool erzeugen
ppl6::db::Pool Pool;
// Pool mit den Connect-Parametern initialisieren
if (!Pool.SetConnectParams(param)) {
ppl6::PrintError();
return;
}
// Verbindung aus dem Pool holen
ppl6::db::Database *db=Pool.Get();
if (!db) {
ppl6::PrintError();
return;
}
// Verbindung verwenden
...
// Verbindung an den Pool zurückgeben
if (!Pool.Release(db)) {
ppl6::PrintError();
return;
}
} // EOF
int DB_PoolEx_Example1() {
// Pool erzeugen
ppl6::db::PoolEx Pool;
// Connect-Parameter für die erste Datenbank festlegen
ppl6::CAssocArray param1;
param.Set("type","sybase");
param.Set("host","database.example.com");
param.Set("port","1234");
param.Set("user","demo");
param.Set("password","demo");
param.Set("dbname","test");
// Pool mit den Connect-Parametern anlegen
// Die Datenbank bekommt die ID 1 und den Namen "Hauptdatenbank"
if (!Pool.CreatePool(1,"Hauptdatenbank",param)) {
ppl6::PrintError();
return;
}
// Connect-Parameter für die zweite Datenbank festlegen
ppl6::CAssocArray param1;
param.Set("type","mysql");
param.Set("host","mysql.example.com");
param.Set("port","4711");
param.Set("user","demo");
param.Set("password","demo");
param.Set("dbname","test");
// Pool mit den Connect-Parametern anlegen.
// Die Datenbank bekommt die ID 2 und den Namen "MySQL_1"
if (!Pool.CreatePool(2,"DB2",param)) {
ppl6::PrintError();
return;
}
// Verbindung zur ersten Datenbank anhand des Namens holen
ppl6::db::Database *db=Pool.Get("Hauptdatenbank");
if (!db) {
ppl6::PrintError();
return;
}
// Verbindung verwenden
...
// Verbindung an den Pool zurückgeben
if (!Pool.Release(db)) {
ppl6::PrintError();
return;
}
// Verbindung zur zweiten Datenbank anhand der ID holen
ppl6::db::Database *db=Pool.Get(2);
if (!db) {
ppl6::PrintError();
return;
}
// Verbindung verwenden
...
// Verbindung an den Pool zurückgeben
if (!Pool.Release(db)) {
ppl6::PrintError();
return;
}
} // EOF
ppl6::db::Result *DB_GenericResult_Example1(const CString &Query) {
int num_fields; // Nimmt die Anzahl Felder im Result auf
// Datenbank-spezifische Code, der das Query ausführt
// ...
// Result-Objekt erstellen
ppl6::db::GenericResult *res=new GenericResult;
if (!res) { // Out of Memory anfangen
SetError(2);
return NULL;
}
// Anzahl Felder im Result übergeben
res->SetNumFields(num_fields);
for (int i=0;i<num_fields;i++) {
const char *field_name = xxxxx; // Name des Feldes
Result::Type field_type = xxxxx; // Datentyp
// Namen und Feldtypen übergeben
res->SetFieldName(i, field_name, field_type);
}
// Ergebniszeilen übergeben
for (pplint64 r=0;r<num_rows;r++) {
// Neue Zeile
res->NewRow();
// Felder durchgehen
for (int i=0;i<num_fields;i++) {
void *value = xxxx; // Pointer auf den Inhalt des Feldes
int len_value = xxxx; // Anzahl Bytes des Feldes
res->StoreField(i,value,len_value);
}
}
// Betroffene Zeilen übergeben
res->SetAffectedRows(num_rows);
// Index aufbauen
res->BuildIndex();
// fertig
return (ppl6::db::Result *)res;
} // EOF

View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<VisualStudioToolFile
Name="Nasm"
Version="8.00"
>
<Rules>
<CustomBuildRule
Name="NASM"
DisplayName="Nasm Assembler"
CommandLine="nasm -f win32 [AllOptions] [AdditionalOptions] [Inputs]"
Outputs="[$ObjectFileName]"
FileExtensions="*.asm"
ExecutionDescription="Assembling $(InputFileName)"
ShowOnlyRuleProperties="false"
>
<Properties>
<StringProperty
Name="Defines"
DisplayName="Definitions"
Category="Pre-Defined Symbols"
Description="Specify pre-defined symbols (&apos;symbol&apos; or &apos;symbol = value&apos;) "
Switch="-D [value]"
Delimited="true"
Inheritable="true"
/>
<StringProperty
Name="IncludePaths"
DisplayName="Include Paths"
Category="Configuration"
Description="Set the paths for any additional include files"
Switch="-I &quot;[value]&quot;"
Delimited="true"
Inheritable="true"
/>
<StringProperty
Name="UnDefines"
DisplayName="Remove Definitions"
Category="Pre-Defined Symbols"
Description="Remove pre-defined symbols "
Switch="-U [value]"
Delimited="true"
Inheritable="true"
/>
<StringProperty
Name="ObjectFileName"
DisplayName="Object File Name"
Category="Output"
Description="Select the output file name"
Switch="-o &quot;[value]&quot;"
DefaultValue="&quot;$(IntDir)\$(InputName).obj&quot;"
/>
<StringProperty
Name="ListFileName"
DisplayName="List File Name"
Category="Output"
Description="Select an output listing by setting its file name"
Switch="-l &quot;[value]&quot;"
/>
<StringProperty
Name="PreIncludeFile"
DisplayName="Pre Include File"
Category="Configuration"
Description="Select a pre-included file by setting its name"
Switch="-P &quot;[value]&quot;"
/>
<BooleanProperty
Name="Debug"
DisplayName="Debug Information"
Category="Output"
Description="Generate debugging information"
Switch="-g "
/>
</Properties>
</CustomBuildRule>
</Rules>
</VisualStudioToolFile>

View file

@ -0,0 +1,95 @@
dnl AX_PATH_LIB_PPL7([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
AC_DEFUN([AX_PATH_LIB_PPL7],[dnl
AC_ARG_WITH([libppl7],
[ --with-libppl7[[=PATH]] Prefix where PPL7-Library is installed],
[ppl7_prefix="$withval"],
[ppl7_prefix="no"])
#if test "$ppl7_prefix" != "no"
#then
if test "$ppl7_prefix" = "no"
then
AC_PATH_PROG(ppl7config,ppl7-config)
elif test "$ppl7_prefix" != "yes"
then
ppl7config="$ppl7_prefix/bin/ppl7-config"
else
AC_PATH_PROG(ppl7config,ppl7-config)
fi
AC_MSG_CHECKING([for lib ppl7])
if test [ -z "$ppl7config" ]
then
AC_MSG_RESULT(no)
AC_MSG_ERROR([ppl7 library (libppl7) and/or headers not found])
ifelse([$3], , :, [$3])
else
AC_MSG_RESULT(yes)
min_ppl_version=ifelse([$1], ,6.0.0,[$1])
AC_MSG_CHECKING(for ppl7 version >= $min_ppl_version)
ppl_version=`${ppl7config} --version`
ppl_config_major_version=`echo $ppl_version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
ppl_config_minor_version=`echo $ppl_version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
ppl_config_micro_version=`echo $ppl_version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
ppl_config_version=`expr $ppl_config_major_version \* 10000 + $ppl_config_minor_version \* 100 + $ppl_config_micro_version`
ppl_req_major_version=`echo $min_ppl_version | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
ppl_req_minor_version=`echo $min_ppl_version | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
ppl_req_micro_version=`echo $min_ppl_version | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
ppl_req_version=`expr $ppl_req_major_version \* 10000 + $ppl_req_minor_version \* 100 + $ppl_req_micro_version`
if test $ppl_config_version -lt $ppl_req_version
then
AC_MSG_RESULT([no, have $ppl_version])
ifelse([$3], , :, [$3])
else
AC_MSG_RESULT([yes (version $ppl_version) ])
#AC_MSG_CHECKING(ppl7 debug libraries)
LIBPPL7_DEBUG_LIBS=`${ppl7config} --libs debug`
#AC_MSG_RESULT($LIBPPL7_DEBUG_LIBS)
#AC_MSG_CHECKING(ppl7 release libraries)
LIBPPL7_RELEASE_LIBS=`${ppl7config} --libs release`
LIBPPL7_RELEASE_ARCHIVE=`${ppl7config} --archive release`
LIBPPL7_DEBUG_ARCHIVE=`${ppl7config} --archive debug`
#AC_MSG_RESULT($LIBPPL7_RELEASE_LIBS)
#AC_MSG_CHECKING(ppl7 includes)
LIBPPL7_CFLAGS=`${ppl7config} --cflags`
LIBPPL7=`${ppl7config} --ppllib release`
LIBPPL7_DEBUG=`${ppl7config} --ppllib debug`
#AC_MSG_RESULT($LIBPPL7_CFLAGS)
ifelse([$2], , :, [$2])
fi
fi
#else
# AC_MSG_RESULT(not configured)
# AC_MSG_ERROR([ppl7 library is required])
#fi
])
dnl AX_PPL7_FEATURE([FEATURE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
AC_DEFUN([AX_PPL7_FEATURE],[dnl
AC_MSG_CHECKING([for ppl7-feature: $1])
if test -z "${ppl_features}"
then
ppl_features=`${ppl7config} --features`
fi
echo ${ppl_features}| tr " " "\n" | grep -i "^$1" > /dev/null 2>&1
if test $? -eq 0
then
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi
])

View file

@ -0,0 +1,12 @@
/*!\page Dateiformate
- \subpage PFPFileVersion1
- \subpage PFPFileVersion2
- \subpage PFPFileVersion3
- \subpage PFPFont5Format
- \subpage PFPFont6Format
- \subpage PPLResVersion6
- \subpage PPLSocketMessage
- \subpage PFPSpriteTexture1
*/

View file

@ -0,0 +1,72 @@
/*!
\page PFPFileVersion1 Format PFP-Files Version 1
Ein PFP-File in der Version 1 beginnt immer mit einem 30-Byte großen Header, gefolgt
von individuellen Nutzdaten
Alle Größenangaben mit 2 oder mehr Byte sind im Little Endian-Format!
\par Header
Der Header einer Version 1 Datei sieht so aus:
\code
Byte 0: String "PFS-File" 8 Bytes
Byte 8: Hauptversion (1) 1 Byte
Byte 9: Unterversion (0) 1 Byte
Byte 10: File-ID ("DRV") 3 Bytes
Byte 13: Zeiger auf Name und Autor 2 Bytes
Byte 15: Erstelldatum 4 Bytes
Byte 19: Erstellzeit 3 Bytes
Byte 22: Datum letzte Änderung 4 Bytes
Byte 26: Zeit letzte Änderung 3 Bytes
Byte 29: Komprimierungsverfahren (0) 1 Byte
\endcode
Beschreibung:
<ul>
<li><b>File-ID</b>\n
Diese 3 Bytes enthalten einen eindeutigen String, der Aufschluß über den Inhalt der
Datei gibt. Dies kann z.B. "FNT", "PIC", "DRV", usw. sein.</li>
<li><b>Haupt- und Unterversion</b>\n
Diese beiden Bytes enthalten die Version für die jewwilige File-ID.</li>
<li><b>Zeiger auf Name</b>\n
Enthält die Datei einen Namensstring, wird hier ein 2-Byte-Pointer darauf
gespeichert. Der Namensstring muß daher innerhalb der ersten 64 KByte der Datei
stehen. In der Regel steht der Name direkt im Anschluss an den Header. Der
String muss mit einem 0-Byte terminiert sein.</li>
<li><b>Zeiger auf Autor</b>\n
Wie beim Namensstring. Der Autor steht in der Regel direkt nach Header und Name,
und muß ebenfalls mit einem 0-Byte terminiert sein.</li>
<li><b>Erstelldatum</b>\n
Ein 4-Byte-Wert der das Datum der Erstellung der Datei im Format "yyyymmdd" enthält.
Eine Datei, die am 1. November 2007 erstellt wurde, enthält also den Wert 20071101.</li>
<li><b>Erstellzeit</b>\n
Dieser 3-Byte-Wert enthält die Uhrzeit der Erstellung, gerechnet in Sekunden seit
Mitternacht. In Kombination mit dem Erstelldatum erhält man so einen Sekundengenauen
Zeitpunkt der Erstellung. Der Wert errechnet sich folgendermassen:
\code
Sekunden + Minuten * 60 + Stunden * 3600
\endcode
</li>
<li><b>Datum letzte Änderung</b>\n
Ein 4-Byte-Wert der das Datum der letzten Änderung im Format "yyyymmdd" enthält.</li>
<li><b>Zeit letzte Änderung</b>\n
Dieser 3-Byte-Wert enthält die Uhrzeit der letzten Änderung, gerechnet in Sekunden seit
Mitternacht.</li>
<li><b>Komprimierung</b>\n
Dieser Wert ist leider nicht genau definiert. Einizig der Wert "0" bedeutet "unkomprimiert".
</li>
</ul>
\par Name und Autor
Im Anschluss an den Header folgen nun optional Name und Autor der Datei, sofern die
Zeiger in Byte 16 und 18 dafür gesetzt wurden. Beide Angaben müssen mit einem
0-Byte terminiert werden.
\par Nutzdaten
Danach folgen die Nutzdaten. Deren Aufbau ist durch das PFP-Format Version 1 nicht
vorgegeben.
*/

View file

@ -0,0 +1,86 @@
/*!
\page PFPFileVersion2 Format PFP-Files Version 2
Ein PFP-File in der Version 2 beginnt immer mit einem Header, gefolgt
von individuellen Nutzdaten
Alle Größenangaben mit 2 oder mehr Byte sind im Little Endian-Format!
\par Header
Der Header einer Version 2 Datei sieht so aus:
\code
Byte 0: String "PFP-File" 8 Bytes
Byte 8: PFP-File-Version (2) 1 Byte
Byte 9: Länge des PFP-Header (40) 1 Byte
Byte 10: File-ID ("xxxx") 4 Bytes
Byte 14: Unterversion (x) 1 Byte
Byte 15: Hauptversion (x) 1 Byte
Byte 16: Zeiger auf Name 2 Byte
Byte 18: Zeiger auf Autor 2 Byte
Byte 20: Erstelldatum 4 Byte
Byte 24: Erstellzeit in Sekunden 4 Byte
Byte 28: Datum letzte Änderung 4 Byte
Byte 32: Zeit letzte Änderung in Sekunden 4 Byte
Byte 36: Komprimierung 2 Byte
Byte 38: unbenutzt 2 Byte
\endcode
Beschreibung:
<ul>
<li><b>Länge des PFP-Header</b>\n
Der Header ist in der Regel 38 (ältere Formate) oder 40 (neuere Formate) Byte lang</li>
<li><b>File-ID</b>\n
Diese 4 Byte enthalten einen eindeutigen String, der Aufschluß über den Inhalt der
Datei gibt. Dies kann z.B. "FONT", "PICT", "LANG", usw. sein.</li>
<li><b>Haupt- und Unterversuin</b>\n
Diese beiden Bytes enthalten die Version für die jewwilige File-ID.</li>
<li><b>Zeiger auf Name</b>\n
Enthält die Datei einen Namensstring, wird hier ein 2-Byte-Pointer darauf
gespeichert. Der Namensstring muß daher innerhalb der ersten 64 KByte der Datei
stehen. In der Regel steht der Name direkt im Anschluss an den Header. Der
String muss mit einem 0-Byte terminiert sein.</li>
<li><b>Zeiger auf Autor</b>\n
Wie beim Namensstring. Der Autor steht in der Regel direkt nach Header und Name,
und muß ebenfalls mit einem 0-Byte terminiert sein.</li>
<li><b>Erstelldatum</b>\n
Ein 4-Byte-Wert der das Datum der Erstellung der Datei im Format "yyyymmdd" enthält.
Eine Datei, die am 1. November 2007 erstellt wurde, enthält also den Wert 20071101.</li>
<li><b>Erstellzeit</b>\n
Dieser 4-Byte-Wert enthält die Uhrzeit der Erstellung, gerechnet in Sekunden seit
Mitternacht. In Kombination mit dem Erstelldatum erhält man so einen Sekundengenauen
Zeitpunkt der Erstellung. Der Wert errechnet sich folgendermassen:
\code
Sekunden + Minuten * 60 + Stunden * 3600
\endcode
</li>
<li><b>Datum letzte Änderung</b>\n
Ein 4-Byte-Wert der das Datum der letzten Änderung im Format "yyyymmdd" enthält.</li>
<li><b>Zeit letzte Änderung</b>\n
Dieser 4-Byte-Wert enthält die Uhrzeit der letzten Änderung, gerechnet in Sekunden seit
Mitternacht.</li>
<li><b>Komprimierung</b>\n
Dieser Wert ist leider nicht genau definiert. Einizig der Wert "0" bedeutet "unkomprimiert".
</li>
</ul>
\par Name und Autor
Im Anschluss an den Header folgen nun optional Name und Autor der Datei, sofern die
Zeiger in Byte 16 und 18 dafür gesetzt wurden. Beide Angaben müssen mit einem
0-Byte terminiert werden.
\par Nutzdaten
Danach folgen die Nutzdaten. Deren Aufbau ist durch das PFP-Format Version 2 nicht
vorgegeben.
\par Nutzung
Zum Lesen und schreiben eines PFP-Headers gibt es folgende Funktionen:
- ppl6::PFPSTRUCT - Struktur zum Bearbeiten eines Headers
- ppl6::WritePFPHeader - Header schreiben
- ppl6::SavePFPHeader - Header lesen
- ppl6::PresetPFPHeader - Header-Struktur mit Defaultdaten fülllen
- ppl6::is_pfp - Prüfen, ob sich an der Speicherstelle ein PFP-Header befindet
- ppl6::ident - Allround-Funktion zum identifizieren einer Datei
*/

View file

@ -0,0 +1,113 @@
/*!
\page PFPFileVersion3 Format PFP-Files Version 3
Ein PFP-File in der Version 3 ist in mehrere aufeinanderfolgende Abschnitte aufgeteilt:
- 24 Byte langer Header
- optionaler 8-Byte langer Komprimierungsheader
- Chunks
Alle 4-Byte Größenangaben sind im LittleEndian-Format!
\par Header
Der Header einer Version 3 Datei sieht so aus:
\code
Byte 0: String "PFP-File" 8 Bytes
Byte 8: PFP-File-Version (3) 1 Byte
Byte 9: Länge des PFP-Header (24) 1 Byte
Byte 10: File-ID, 4 Byte-String 4 Byte
Byte 14: Unterversion 1 Byte
Byte 15: Hauptversion 1 Byte
Byte 16: Komprimierung 1 Byte
0=unkomprimiert
1=Zlib
2=Bzip2
Byte 17: reserviert 3 Byte
Byte 20: Timestamp der Erstellung (UTC) 4 Byte
\endcode
Im Anschluss an den Header folgen die Nutzdaten. Sofern keine Komprimierung
verwendet wurde, geht es sofort mit dem ersten Chunk los. Ist die Datei
komprimiert folgt erst der Komprimierungsheader:
\par Komprimierungsheader
\code
Byte 0: Größe der Nutzdaten unkomprimiert in Byte 4 Byte
Byte 4: Größe der Nutzdaten komprimiert in Byte 4 Byte
\endcode
\par Chunks
In einem PFP-File können beliebig viele Chunks vorkommen. Ein Chunk besteht immer aus einem
4-Byte langen Namen, gefolgt von einem 4-Byte Integer, der die Größe des Chunks einschließlich
des Headers angibt, gefolgt von den Nutzdaten. Abgesehen von den unten aufgeführten vordefinierten
Chunks, können beliebig viele Chunks mit gleichem Namen vorhanden sein.
Ein Chunk muss nicht zwingend Nutzdaten enthalten.
\code
Byte 0: Chunkname, 4 Byte-String in Grossbuchstaben 4 Byte
Byte 4: Größe des Chunks einschließlich 8-Byte Header 4 Byte
Byte 8: Nutzdaten des Chunks
\endcode
\par Vordefinierte Chunks
Die nachfolgenden Chunks sind vordefiniert, aber optional
<ul>
<li>\b Author
\code
Byte 0: AUTH
Byte 4: Länge des nachfolgenden Strings
Byte 8: Name des Authors mit schließendem 0-Byte
\endcode
Der Name des Authors kann mit der Funktion PFPFile::SetAuthor gesetzt werden.
</li>
<li>\b Name
\code
Byte 0: NAME
Byte 4: Länge des nachfolgenden Strings
Byte 8: Name der Datei oder Beschreibung des Inhalts mit schließendem 0-Byte
\endcode
Der Name des Files kann mit der Funktion PFPFile::SetName gesetzt werden.
</li>
<li>\b Description
\code
Byte 0: DESC
Byte 4: Länge des nachfolgenden Strings
Byte 8: Nähere Beschreibung mit schließendem 0-Byte
\endcode
Die Description kann mit der Funktion PFPFile::SetDescription gesetzt werden.
</li>
<li>\b Copyright
\code
Byte 0: COPY
Byte 4: Länge des nachfolgenden Strings
Byte 8: Copyright-String mit schließendem 0-Byte
\endcode
Der Copyright-String kann mit der Funktion PFPFile::SetCopyright gesetzt werden.
</li>
</ul>
\par End of File
Dieser Chunk ist immer der letzte in der Datei und kennzeichnet das
Ende der Nutzdaten.
\code
Byte 0: ENDF
Byte 4: 0
\endcode
\par Nutzung
Um das Lesen und Schreiben solcher Dateien zu vereinfachen, kann die Klasse PFPFile in
Kombination mit PFPChunk verwendet werden.
*/

View file

@ -0,0 +1,43 @@
/*!
\page PPLResVersion6 Format PPL-Resource Version 6
Das Format eines PPL-Resource Files ist mehr oder weniger der Vorläufer
der Version 3 des \ref PFPFileVersion3 "PFP-File-Formats". Es hat einen eigenen
vereinfachten Header (kein PFP-Header), gefolgt von beliebigen Chunks mit Nutzdaten.
Alle Pointer und Größenangaben mit 2 oder mehr Byte sind in Little Endian
gespeichert.
\par Header
Der Header ist 9 Byte lang und hat folgenden Aufbau:
\code
Byte 0-5: String "PPLRES" 6 Byte
Byte 6: 0-Byte 1 Byte
Byte 7: Major Version (6) 1 Byte
Byte 8: Minor Version (0) 1 Byte
Byte 9: Start der Chunks
\endcode
Danach beginnen bereits die Chunks.
\par Chunks
\code
Byte 0: Size of Chunk incl. Header 4 Byte
Byte 4: ID of Resource 2 Byte
Byte 6: Size of data uncompressed 4 Byte
Byte 10: Size of data compressed 4 Byte
Byte 14: Compression-Type (0=none, 1=zlib, 2=bzip2) 1 Byte
Byte 15: Offset of Data from Chunk-Start 1 Byte
Byte 16: Name of Resource with 0-Byte n Byte
Byte n: Data
\endcode
Nach dem letzten Chunk muss ein 4-Byte großer 0-Wert geschrieben werden, der
das Ende der Datei markiert.
\par Erstellen von Resourcen
TODO
\par Einlesen von Resourcen
Zum Einlesen von Resourcen-Dateien gibt es die Klasse ppl6::CResource.
*/

View file

@ -0,0 +1,53 @@
/*!
\page PPLSocketMessage Format PPL Socket-Message
Mit der Klasse ppl6::CpplSocketMessage und den Funktionen CpplSocket::Write und
CpplSocket::WaitForMessage lassen sich bequem Nachrichten per TCP austauschen.
Jedes Nachrichtenpaket besteht dabei aus einem Header und den Nutzdaten.
\par Aufbau des Headers Version 1
Version 1 besteht aus einem 20 Byte langem Header mit folgendem Aufbau:
\code
Byte 0: "V" (1 Byte)
Byte 1: Version=1 (1 Byte)
Byte 2: CommandId (2 Byte)
Byte 4: Id (4 Byte)
Byte 8: Bytes Nutzdaten (4 Byte)
Byte 12: Flags (1 Byte)
Bit 0: Zlib-Kompression
Bit 1: Client supports Zlib
Bit 2: Client supports MsgChannel
Byte 13: Datatype, PPL_ARRAY, usw. (1 Byte)
Byte 14: Zufallszahl (2 Byte)
Byte 16: CRC-Summe über den Header (4 Byte)
\endcode
Die CRC-Summe wird über die ersten 16 Byte des Headers gebildet
(siehe ppl6::crc32). Alle mehrbyteigen Werte müssen in Network-Byte-Order
(Big Endian) angegeben werden.
\par Aufbau des Headers Version 2
Der Version 2-Header ist 4 Byte länger, die eine zusätzliche CRC-Summe
über die Nutzdaten enthalten.
\code
Byte 0: "V" (1 Byte)
Byte 1: Version=2 (1 Byte)
Byte 2: CommandId (2 Byte)
Byte 4: Id (4 Byte)
Byte 8: Bytes Nutzdaten (4 Byte)
Byte 12: Flags (1 Byte)
Bit 0: Zlib-Kompression
Bit 1: Client supports Zlib
Bit 2: Client supports MsgChannel
Byte 13: Datatype, PPL_ARRAY, usw. (1 Byte)
Byte 14: Zufallszahl (2 Byte)
Byte 16: CRC-Summe über die Nutzdaten (4 Byte)
Byte 20: CRC-Summe über den Header (4 Byte)
\endcode
Die CRC-Summe des Headers wird über die ersten 20 Byte des Headers gebildet
(siehe ppl6::crc32). Alle mehrbyteigen Werte müssen in Network-Byte-Order
(Big Endian) angegeben werden.
*/

73
src/pplib/docs/groups.dox Normal file
View file

@ -0,0 +1,73 @@
/*!\defgroup PPLGroupInternet Internet
\brief Internet-Klassen und Funktionen
Internet-Klassen und Funktionen
*/
/*!\defgroup PPLGroupGrafik Grafik
\brief Grafik-Klassen und Funktionen
\desc
Die nachfolgenden Klassen dienen zum Erstellen und Verwalten von Bitmap-Grafiken.
*/
/*!\defgroup PPLGroupSound Sound
\brief Sound-Klassen und Funktionen
*/
/*!\defgroup PPLGroupToolkit Toolkit
\ingroup PPLGroupGrafik
\brief Toolkit zum Erstellen von Dialogen und Eingabemasken
*/
/*!\defgroup PPLGroupMath Mathematische Funktionen und Klassen
\brief Mathematische Funktionen und Klassen
*/
/*!\defgroup PPLGroupDateTime Datums- und Zeit-Funktionen
\brief Datums- und Zeit-Funktionen
*/
/*!\defgroup PPLGroupFileIO Dateien und Verzeichnise
\brief Funktionen und Klassen zur Verarbeitung von Dateien und Verzeichnissen
*/
/*!\defgroup PPLGroupStrings String-Verarbeitung
\brief Funktionen und Klassen zur Verarbeitung von Strings
*/
/*!\defgroup PPLGroupMemory Speicherverwaltung
\brief Funktionen und Klassen zur Verwalten des Speichers
*/
/*!\defgroup PPL7_CRYPT Verschlüsselung und Hashes
\brief Verschlüsselung und Hashes
\header \#include <ppl7-crypto.h>
\descr
Auf dieser Seite sind Klassen und Funktion zu finden, mit denen Daten nach verschiedenen
kryptographischen Algorithmen verschlüsselt und entschlüsselt werden können, sowie
Klassen und Funktionen zum Berechnen von Hash-Werten oder Prüfsummen nach verschiedenen
Algorithmen.
\par
Die Funktionen der Klasse ppl7::MCrypt basieren auf der Bibliothek
<a href="http://mcrypt.sourceforge.net/">libmcrypt</a> und sind daher nur
verfügbar, wenn diese beim Kompilieren der PPL-Library eingebunden wurden.
Die Klasse ppl7::Digest setzt auf <a href="http://www.openssl.org/">OpenSSL</a> auf
und ist daher nur verfügbar, wenn diese beim Kompilieren der PPL-Library eingebunden wurde.
*/
/*!\defgroup PPL7_COMPRESSION Datenkomprimierung
\brief Komprimierung von Daten
\descr
Mit den nachfolgenden Klassen und Funktionen können Daten komprimiert und entkomprimiert werden:
*/

33
src/pplib/docs/gtest.dox Normal file
View file

@ -0,0 +1,33 @@
/*!\page unittests Unit Tests
PPL7 comes with a bunch of unit tests, which are used in continious and nightly builds.
\section Install Google test framework
PPL7 uses the Google test framework version 1.6.0. You can download the framework here:
http://code.google.com/p/googletest/downloads/detail?name=gtest-1.6.0.zip
Unpack the file somewhere:
\code
cd
wget "http://code.google.com/p/googletest/downloads/detail?name=gtest-1.6.0.zip"
cd /usr/local
unzip ~/gtest-1.6.0.zip
cd gtest-1.6.0
configure --prefix=/usr/local/gtest-1.6.0
\endcode
\section Prepare and start unit tests
You must specify the installation path of google test during configure of ppl7. So if you unpacked the
framework in /usr/local/gtest-1.6.0, you would call
\code
./configure --enable-gtest=/usr/local/gtest-1.6.0 ...
\endcode
After ppl7 is build, you can call "make test" to run the testsuite.
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

View file

@ -0,0 +1,35 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>PPLib - Dokumentation, Version $projectnumber</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript">
$(document).ready(initResizable);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
<link href="ppl7style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Erzeugt von Doxygen 1.7.3 -->
<script type="text/javascript"><!--
var searchBox = new SearchBox("searchBox", "search",false,'Suchen');
--></script>
<div id="top">
<table style="margin: 0px; padding: 0px; width: 100%; border-bottom: 1px solid #243352;
background-image: url('header-bg.png'); background-color: #000000; background-repeat: repeat-x;">
<tr><td align="left" width="48">
<img align="left" src="ppl7-icon-48x48.png" alt="PPL7-Icon">
</td><td align="left" width="100%" valign="bottom" style="font-weight: 700; font-size: 180%; color: #ffffff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.9);">
Patrick's Programming Library Version $projectnumber - Dokumentation
</td></tr>
</table>

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -0,0 +1,234 @@
/*!\page Installation Download und Installation
\section inst1 Download
Die aktuelle Version und Dokumentation der Library ist hier zu finden:
http://www.pfp.de/ppl
Die Sourcen sind dort im Format ".tar.bz2" zu finden. Unter Unix kann dieses Archiv mit tar
oder gtar ausgepackt werden (<code>tar -xjf ppl*.tar.bz2</code>), unter Windows eignet sich
zum Beispiel <a href="http://http://www.7-zip.org/">7-Zip</a>.
\section inst1a Git
Der Quellcode der Library wird bei <a href="https://github.com/pfedick/pplib">GitHub</a>
gehostet und kann wie nachfolgend beschrieben aus dem Repository ausgecheckt werden.
\code
git clone https://github.com/pfedick/pplib.git ppl7
\endcode
\section inst2 Installation unter UNIX
Die Library wird mit einem configure-script ausgeliefert, in dem alle optionalen
Features ausgewählt werden können. Um eine Basisversion zu erhalten reicht oftmals ein
einfaches configure ohne Parameter aus:
\code
./configure
make
make install
\endcode
Für das "make install" sind ggfs. Root-Rechte erforderlich.
Das Configure untersucht das System und setzt entsprechende Defines für den
Compiler. Optionale Features werden zum Teil automatisch eingebunden, wenn
sie gefunden werden.
Wird eine Library nicht gefunden oder nicht automatisch eingebunden, kann über
Parameter beim Aufruf des configure-Scripts nachgeholfen werden. Beispiel:
\code
./configure --with-mysql=/usr/local/mysql
\endcode
Soll eine bestimmte Library explizit nicht eingebunden werden, kann man dies mit
"--without-xxx" festlegen, wobei xxx für den Namen der Library steht:
\code
./configure --without-mysql
\endcode
Alle weiteren Details sind im configure zu finden, wenn man es mit "./configure --help"
aufruft.
\subsection inst2compiler Compiler auswählen
Sofern nichts angegeben wird, wird der Defaultcompiler verwendet, in der Regel gcc bzw. g++. Sind mehrere Compiler
vorhanden, kann durch setzen der Umgebungsvariablen CC und CXX vor Aufruf von "configure" bestimmt werden,
welcher Compiler verwendet werden soll.
\subsubsection inst2compiler_gcc47 Beispiel 1: gcc Version 5
Unter FreeBSD kann man verschiedene Versionen über die Ports-Collection installieren. Die installierten
Binaries bekommen dann die Version im Dateinamen angehangen, z.B. "5". Das gcc-Binary heisst somit "gcc5",
bzw. "g++5":
\code
export CC=gcc5
export CXX=g++5
./configure ...
\endcode
\subsubsection inst2compiler_clang Beispiel 2: clang Version 6
\code
export CC=clang60
export CXX=clang++60
./configure ...
\endcode
\subsection inst2ubuntu1804 Installation unter Ubuntu 18.04 LTS
Wenn man alle Features der Library nutzen will, muß man folgende Pakete installieren:
\code
sudo apt install -y gcc g++ nasm googletest \
zlib1g-dev libbz2-dev libssl-dev libpcre3-dev \
libmcrypt-dev libgtest-dev libcurl4-openssl-dev libldns-dev \
libbind-dev libmysqlclient-dev libpq-dev libsqlite3-dev \
libpng-dev libjpeg-dev libtiff-dev libsdl2-dev libfreetype6-dev \
libmad0-dev libmp3lame-dev libmpg123-dev \
libogg-dev libshout3-dev libmicrohttpd-dev libidn11-dev
\endcode
Ist alles installiert, kann man das configure mit folgenden Parametern aufrufen:
\code
export CFLAGS="-no-pie "
./configure --prefix=$HOME \
--with-lame --with-pcre=/usr --with-x --with-openssl=/usr \
--with-mysql --with-libiconv-prefix --with-nasm \
--with-gcrypt=auto --with-ogg=/usr \
--with-postgresql --with-sqlite3 \
--with-libmicrohttpd=/usr/local \
--with-jpeg --with-libpng=$PREFIX --with-libtiff \
--with-libtiff=/usr --with-mpg123 \
--with-libidn --with-libldns=/usr
\endcode
\subsection inst2debian Installation unter Debian / Ubuntu (Veraltet)
Wenn man alle Features der Library nutzen will, muß man folgende Pakete installieren:
\code
# Kern-Funktionalität
sudo apt-get install zlib1g-dev libbz2-dev libssl-dev libpcre3-dev nasm
# Kryptografie
sudo apt-get instal libssl-dev libmcrypt-dev
# Internet
sudo apt-get install libcurl4-openssl-dev libldns-dev
# Datenbanken
sudo apt-get install libmysqlclient-dev libpq-dev freetds-dev
# Grafik
sudo apt-get install libpng12-dev libjpeg62-dev libsdl1.2-dev libfreetype6-dev libmad0-dev
# Sound
sudo apt-get install libmp3lame-dev libmad0-dev libmpg123-dev libogg-dev libshout3-dev
\endcode
Ist alles installiert, kann man das configure mit folgenden Parametern aufrufen:
\code
export CFLAGS="-no-pie "
echo "configuring for generic Linux"
./configure --prefix=$PREFIX \
--with-lame --with-pcre --with-x --with-openssl \
--with-mysql --with-libiconv-prefix --with-nasm \
--with-ogg \
--with-postgresql \
--with-libmicrohttpd \
--with-jpeg --with-libpng --with-libtiff \
--with-libtiff --with-mpg123 \
--with-libidn \
--enable-gtest=/usr/local/googletest-release-1.7.0
\endcode
\subsection inst2freebsd Installation unter FreeBSD
\code
export PREFIX=/usr/local
export CFLAGS="-I/usr/local/include"
export LDFLAGS="-L/usr/local/lib"
export CPPFLAGS=-I/usr/local/include
export CC=clang$CLANG_VERSION
export CXX=clang++$CLANG_VERSION
./configure --prefix=$PREFIX \
--with-lame=/usr/local --with-mpg123=/usr/local \
--with-pcre=/usr/local --with-x --with-openssl=/usr --with-mysql \
--with-libiconv-prefix=/usr/local --with-nasm \
--with-jpeg --with-libpng --with-libtiff=/usr/local \
--with-postgresql \
--with-libidn=/usr/local \
--with-ogg=/usr/local \
--with-libmicrohttpd=/usr/local \
--enable-gtest=/usr/local
\endcode
\section inst3 Installation unter Windows
\subsection inst3mingw Installation mit MinGW32/64
Für fast alle unterstützten Module gibt es fertige Pakete, die mit "pacman" installiert werden können.
Einzig für mcrypt gibt es keine Pakete.
\subsubsection inst3mingw_pacman Pakete installieren
Um alle Features nutzen zu können, müssen folgende Pakete installiert werden:
\code
pacman -S mingw-w64-x86_64-SDL2 mingw-w64-x86_64-bzip2 mingw-w64-x86_64-curl mingw-w64-x86_64-freetype \
mingw-w64-x86_64-gtest mingw-w64-x86_64-iconv mingw-w64-x86_64-lame mingw-w64-x86_64-ldns \
mingw-w64-x86_64-libiconv mingw-w64-x86_64-libidn mingw-w64-x86_64-libjpeg-turbo \
mingw-w64-x86_64-libmad mingw-w64-x86_64-libpng mingw-w64-x86_64-libogg mingw-w64-x86_64-libtiff \
mingw-w64-x86_64-mpg123 mingw-w64-x86_64-nasm mingw-w64-x86_64-openssl mingw-w64-x86_64-pcre \
mingw-w64-x86_64-sqlite3 mingw-w64-x86_64-zlib
\endcode
\subsubsection inst3mingw_mcrypt MCrypt installieren
Im folgenden wird angenommen, dass wir die 64-Bit-Version von MCrypt erstellen und unter /usr/local installieren wollen:
\code
export VERSION=2.5.8
export PREFIX=/usr/local
export MINGW=/mingw64
export PATH=$MINGW/bin:$PATH
rm -rf libmcrypt-$VERSION.tar.gz
wget -O libmcrypt-$VERSION.tar.gz "http://sourceforge.net/projects/mcrypt/files/Libmcrypt/$VERSION/libmcrypt-$VERSION.tar.gz/download"
rm -rf libmcrypt-$VERSION
tar -xzf libmcrypt-$VERSION.tar.gz
cd libmcrypt-$VERSION
grep -v "\-no\-undefined" configure > configure2
rm config.sub
automake -a
./configure2 --prefix=$PREFIX --enable-static --disable-shared
make
make install
\endcode
\subsubsection inst3mingw_ppl7
\code
export MINGW=/mingw64
export PATH=$MINGW/bin:$PATH
export CPPFLAGS="-I/usr/local/include"
export LDLAGS="-L/usr/local/lib"
export CFLAGS="-I/usr/local/include"
./configure --prefix=/usr/local \
--with-pcre=$MINGW --with-bzip2=$MINGW --with-zlib=$MINGW \
--with-nasm=$MINGW/bin --with-libiconv-prefix=$MINGW \
--with-lame=$MINGW --with-mpg123=$MINGW --disable-freetypetest --with-ft-prefix=$MINGW \
--with-libtiff=$MINGW --with-jpeg=$MINGW \
--with-libjpegturbo=$MINGW --with-libpng=$MINGW \
--with-libmcrypt-prefix=/usr/local \
--with-openssl=$MINGW --with-libcurl=$MINGW \
--with-libldns=$MINGW --with-libidn=$MINGW \
--with-sdl-prefix=$MINGW \
--without-postgresql --without-mysql \
--enable-gtest=/usr/local/gtest-1.7.0 \
\endcode
\subsection inst3vstudio Installation mit Visual Studio
Visual Studio wird zur Zeit nicht unterstützt.
*/

153
src/pplib/docs/main.dox Normal file
View file

@ -0,0 +1,153 @@
/*!\mainpage PPLib-Dokumentation
\image html resource/ppl7-icon-256x256.png
\section Einleitung
PPL steht für "Patrick's Programming Library" und ist eine Sammlung nützlicher
Funktionen und Klassen für C++-Anwendungen, geschrieben von Patrick Fedick <patrick@pfp.de>.
Sie beinhaltet Funktionen aus verschiedenen Bereichen, wie
- Datei- und Verzeichniss-Zugriff
- Strings, Arrays, Listen, Trees
- Multithreading
- Sockets (TCP, UDP)
- Verschlüsselung
- Internet
- Datenbanken
- Zeit, Datum und mathematische Funktionen
- Grafik
- Sound
- Speicherverwaltung
Die erste Version erschien bereits im Jahr 1997 und bestand fast vollständig
aus Assembler-Code für Windows. Seitdem wurde die Library mehrfach umstrukturiert und erweitert
und besteht nun zum größten Teil aus plattform-unabhängigem C und C++-Code. Unterstützt werden
folgende Systeme:
- Linux (getestet unter CentOS 6/7, Ubuntu 16.04, 18.04 in der 64-Bit-Version)
- FreeBSD (Version 10.x und 11.x in 64-Bit)
- Windows 7/10 (mit MinGW in 32- und 64-Bit)
Als Compiler wird gcc ab Version 4.4 benötigt oder clang ab Version 3.
Seit Version 6.2.0 steht die PPL-Library unter einer Open Source BSD-Lizenz und darf somit fast
uneingeschränkt auch in kommerziellen oder "closed source" Programmen verwendet werden. Die
genauen Lizenzbestimmungen sind \ref pplPageLicense "hier" zu finden.
\section Inhalt
- \subpage Installation
- \subpage ppl7_usage "Verwendung"
- \subpage PPLGroupDataTypes "Die speziellen Datentypen von PPLib"
- \subpage ppl7 "PPL7 Namespace"
- <a class="el" href="classes.html">Die Klassen</a>
- <a class="el" href="modules.html">Übersicht der Module</a>
- \subpage PPL7_Features
- \subpage Errors
- \subpage PPLGroupThreads
- \subpage PPLGroupMemory
- \subpage PPLGroupMath
- \subpage PPLGroupDateTime
- \subpage PPLGroupStrings
- \subpage PPLGroupFileIO
- \subpage PPLGroupGrafik
- \subpage PPLGroupToolkit
- \subpage PPLGroupSound
- \subpage PPLGroupInternet
- \subpage PPLGroupDatabases
- \subpage PPL7_CRYPT
- \subpage PPL7_COMPRESSION
- Sonstiges
- \subpage unittests
- \subpage Dateiformate
- \subpage formatstring
- \subpage todo
- \subpage deprecated
- \subpage PPLHistory
- \subpage pplPageCredits
- \subpage pplPageLicense
\image html resource/ppl7-icon-48x48.png
*/
/*!\page pplPageLicense Copyright
PPL7 steht unter der "2-Klausel BSD Lizenz". BSD-Lizenz bezeichnet eine Gruppe von Lizenzen aus
dem Open-Source-Bereich. Der Urtyp der Lizenz stammt von der University of California,
Berkeley, worauf das Akronym BSD hinweist: Berkeley Software Distribution.
Software unter BSD-Lizenz darf frei verwendet werden. Es ist erlaubt, sie zu kopieren,
zu verändern und zu verbreiten. Einzige Bedingung ist, dass der Copyright-Vermerk des
ursprünglichen Programms nicht entfernt werden darf. Somit eignet sich unter einer BSD-Lizenz
stehende Software auch als Vorlage für kommerzielle (teilproprietäre) Produkte, wie es
beispielsweise bei „JunOS“ der Fall ist, dem Router-Betriebssystem der Firma Juniper Networks.
Dieses Lizenzmodell unterscheidet sich von der GNU General Public License (GPL) darin,
dass es kein Copyleft enthält: Ein Programmierer, der ein unter einer BSD-Lizenz
veröffentlichtes Programm verändert und dann verbreitet, ist nicht verpflichtet,
den Quellcode seines veränderten Programms mitzuveröffentlichen. Er ist aber verpflichtet,
das Ergebnis seiner Änderungen wiederum unter der BSD-Lizenz zu veröffentlichen.
(Quelle: http://de.wikipedia.org/wiki/BSD-Lizenz)
Der Wortlaut der Lizenz lautet folgendermassen:
\include LICENSE.TXT
Übersetzung:
\code
Copyright (c) 2013, Patrick Fedick <patrick@pfp.de>
All rights reserved.
Weiterverbreitung und Verwendung in nichtkompilierter oder kompilierter Form,
mit oder ohne Veränderung, sind unter den folgenden Bedingungen zulässig:
* * Weiterverbreitete nichtkompilierte Exemplare müssen das obige Copyright,
die Liste der Bedingungen und den folgenden Haftungsausschluss im Quelltext
enthalten.
* * Weder der Name des Copyright-Inhabers noch die Namen der Beitragsleistenden
dürfen zum Kennzeichnen oder Bewerben von Produkten, die von dieser
Software abgeleitet wurden, ohne spezielle vorherige schriftliche
Genehmigung verwendet werden.
DIESE SOFTWARE WIRD VOM COPYRIGHT INHABER UND DEN BEITRAGSLEISTENDEN OHNE
JEGLICHE SPEZIELLE ODER IMPLIZIERTE GARANTIEN ZUR VERFÜGUNG GESTELLT, DIE
UNTER ANDEREM EINSCHLIESSEN: DIE IMPLIZIERTE GARANTIE DER VERWENDBARKEIT DER
SOFTWARE FÜR EINEN BESTIMMTEN ZWECK. AUF KEINEN FALL SIND DER COPYRIGHT
INHABER ODER DIE BEITRAGSLEISTENDEN FÜR IRGENDWELCHE DIREKTEN, INDIREKTEN,
ZUFÄLLIGEN, SPEZIELLEN, BEISPIELHAFTEN ODER FOLGENDEN SCHÄDEN (UNTER ANDEREM
VERSCHAFFEN VON ERSATZGÜTERN ODER -DIENSTLEISTUNGEN; EINSCHRÄNKUNG DER
NUTZUNGSFÄHIGKEIT; VERLUST VON NUTZUNGSFÄHIGKEIT; DATEN; PROFIT ODER
GESCHÄFTSUNTERBRECHUNG), WIE AUCH IMMER VERURSACHT UND UNTER WELCHER
VERPFLICHTUNG AUCH IMMER, OB IN VERTRAG, STRIKTER VERPFLICHTUNG ODER
UNERLAUBTE HANDLUNG (INKLUSIVE FAHRLÄSSIGKEIT) VERANTWORTLICH, AUF WELCHE
WEG SIE AUCH IMMER DURCH DIE BENUTZUNG DIESER SOFTWARE ENTSTANDEN SIND,
SOGAR, WENN SIE AUF DIE MÖGLICHKEIT EINES SOLCHEN SCHADENS HINGEWIESEN
WORDEN SIND.
\endcode
(Quelle der Übersetzung: http://de.wikipedia.org/wiki/BSD-Lizenz)
*/
/*!
\namespace ppl7
\brief Der Namensraum der PPLib-Library
ppl7 ist der Namensraum für alle in der PPLib-Library Version 7 enthaltenen Funktionen und Klassen.
*/
/*!\namespace ppl7::grafix
\ingroup PPLGroupGrafik
\brief Namensraum der Grafik-Funktionen
Im Namespace ppl7::grafix sind alle Grafikfunktionen der Library enthalten.
*/
/*!\namespace ppl7::tk
\ingroup PPLGroupGrafik
\brief Namensraum des Grafik-Toolkits
In diesem Namespace sind die Klassen des Toolkits enthalten, mit denen eine Benutzeroberfläche
erstellt werden kann.
*/

View file

@ -0,0 +1,13 @@
/*!\file
\note
Diese Funktion ist nur verfügbar, wenn PPL mit dem Configure-Flag --with-pcre konfiguriert
und kompiliert wurde.
\note
Falls kein UTF-8 angegeben wird, das System auf dem das Programm läuft aber UTF-8
in LC_CTYPE konfiguriert hat, wird automatisch UTF-8 verwendet.
\note
Falls UTF-8 verwendet wird, der zu vergleichende String aber ungültiges UTF-8 enthält,
macht die Funktion ein Fallback auf Singlebyte-Zeichen.
*/

View file

@ -0,0 +1,3 @@
body, table, div, p, dl {
font-family: Liberation Sans, Bitstream Vera Sans, Arial, sans-serif, Helvetica;
}

View file

@ -0,0 +1,52 @@
/*!\file
\arg \c i caseless\n
If this bit is set, letters in the pattern match both upper and lower case letters.
It is equivalent to Perl's /i option, and it can be changed within a pattern by a
(?i) option setting. In UTF-8 mode, PCRE always understands the concept of case for
characters whose values are less than 128, so caseless matching is always possible.
For characters with higher values, the concept of case is supported if PCRE is compiled
with Unicode property support, but not otherwise. If you want to use caseless matching
for characters 128 and above, you must ensure that PCRE is compiled with Unicode property
support as well as with UTF-8 support.
\arg \c m multiline\n
By default, PCRE treats the subject string as consisting of a single line of characters
(even if it actually contains newlines). The "start of line" metacharacter (^) matches
only at the start of the string, while the "end of line" metacharacter ($) matches only
at the end of the string, or before a terminating newline. This is the same as Perl.
When "m" it is set, the "start of line" and "end of line" constructs match immediately
following or immediately before any newline in the subject string, respectively, as well
as at the very start and end. This is equivalent to Perl's /m option, and it can be
changed within a pattern by a (?m) option setting. If there are no "\n" characters in a
subject string, or no occurrences of ^ or $ in a pattern, setting "m" has no effect.
\arg \c x extended\n
If this is set, whitespace data characters in the pattern are totally ignored except when
escaped or inside a character class. Whitespace does not include the VT character (code 11).
In addition, characters between an unescaped # outside a character class and the next
newline character, inclusive, are also ignored.
\arg \c s dotall\n
If this bit is set, a dot metacharater in the pattern matches all characters, including
newlines. Without it, newlines are excluded. This option is equivalent to Perl's /s option,
and it can be changed within a pattern by a (?s) option setting. A negative class such as
[^a] always matches a newline character, independent of the setting of this option.
\arg \c 8 UTF8\n
This option causes PregMatch to regard both the pattern and the subject as strings of
UTF-8 characters instead of single-byte character strings. However, it is available only
when PCRE is built to include UTF-8 support. If not, the use of this option provokes an
error. Details of how this option changes the behaviour of PCRE are given in the section
on UTF-8 support in the main pcre page.
\arg \c a anchored\n
If this bit is set, the pattern is forced to be "anchored", that is, it is constrained
to match only at the first matching point in the string that is being searched (the
"subject string"). This effect can also be achieved by appropriate constructs in the
pattern itself, which is the only way to do it in Perl.
\arg \c u ungreedy\n
This option inverts the "greediness" of the quantifiers so that they are not greedy by
default, but become greedy if followed by "?". It is not compatible with Perl. It can also
be set by a (?U) option setting within the pattern.
*/

View file

239
src/pplib/docs/sprintf.dox Normal file
View file

@ -0,0 +1,239 @@
/*!\page formatstring Formatierungsstring
Viele Funktionen verwenden einen Formatierungsstring gefolgt von einer variablen Anzahl Parametern.
Das nachfolgende Kapitel beschreibt, welche Zeichen und Flags im Formatstring verwendet werden können.
\section formatstring_format Format des Formatstrings
Der Formatstring ist eine Zeichenkette, die, so vorhanden, in ihrem initialen Shift-Zustand
beginnt und endet. Der Formatstring setzt sich zusammen aus Null oder mehr Anweisun-
gen: normale Zeichen (nicht \%), welche unverändert zum Ausgabekanal kopiert werden; und
Umwandlungsspezifikationen, welche jeweils null oder mehr Argumente fordern. Jede
Umwandlungsspezifikation wird durch das Zeichen \% eingeleitet und endet mit einem
Umwandlungsspezifikator. Dazwischen können (in dieser Ordung) null oder mehr Flags, eine
optionale minimale Feldbreite, eine optionale Genauigkeit und ein optionaler Längenmodifikator.
Die Argumente müssen (nach type promotion) genau zu den Umwandlungsspezifikatoren passen.
Standardmäßig werden die Argumente in der Reihenfolge benutzt, in der sie angegeben sind,
wobei jeder * und jeder Umwandlungsspezifikator das nächste Argument abfragt (und es ist
ein Fehler, wenn nicht ausreichend Argumente gegeben sind). Man kann auch explizit
angeben, welches Argument genommen wird, an jeder Stelle wo ein ein Argument erforderlich
ist, indem man \%m$ anstelle von * schreibt, wobei die Dezimalzahl m die Position des
gewünschten Arguments in der Argumentenliste angibt, beginnend mit 1. Damit sind
printf("\%*d", width, num);
und
printf("\%2$*1$d", width, num);
äquivalent. Der zweite Stil erlaubt wiederholte Referenzen auf das gleiche Argument. Der
C99-Standard schließt den Stil mit $ nicht mit ein, er stammt aus der Single Unix Specification.
Wenn der Stil, der $ benutzt, eingesetzt wird, muss er durchgehend für alle
Umwandlungen, die ein Argument nehmen, und alle Breiten- und Genauigkeitsargumente verwendet
werden, darf aber mit \%\%, das kein Argument konsumiert, vermischt werden. Es darf
keine Lücken in der Zahl der Argumente, die mit $ spezifiziert werden, geben; zum
Beispiel muss, wenn Argument 1 und 3 auftreten, auch Argument 2 irgendwo im Formatstring
erwähnt werden.
Für einige numerische Umwandlungen wird ein Radixzeichen ("Dezimalkomma") oder ein
Tausender-Gruppierungszeichen verwendet. Des tatsächlich benutzte Zeichen hängt vom
LC_NUMERIC-Teil der Locale ab. Die POSIX-Locale benutzt . als Radixzeichen und hat kein
Gruppierungszeichen. Damit resultiert
printf("\%.2f", 1234567.89);
in 1234567.89 in der POSIX-Locale, in 1234567,89 in der Locale nl_NL und in
1.234.567,89 in der Locale da_DK.
\section formatstring_zeichen Die Zeichen für die Flags
Das Zeichen \% wird von null oder mehr der folgenden Flags gefolgt:
\arg \c \# gibt an, dass der Wert in eine alternative Form gewandelt werden soll. Bei der
Umwandlung o wird das erste Zeichen der Ausgabe eine Null (indem 0 vorangestellt
wird, wenn der Wert nicht schon Null war). Bei den Umwandlungen x und X wird einem
Ergebnis ungleich Null der String 0x (oder 0X bei X) vorangestellt. Bei den
Umwandlungen a, A, e, E, f, F, g und G enthält das Ergebnis immer einen
Dezimaltrennzeichen, auch wenn ihm keine Ziffern folgen. (Normalerweise tritt ein
Dezimaltrennzeichen nur in Ergebnissen auf, wenn ihm eine Ziffer folgt.) Bei den
Umwandlungen g und G werden nachfolgende Nullen nicht aus dem Ergebnis entfernt,
wie sie es normalerweise würden. Für andere Umwandlungen ist das Ergebis
undefiniert.
\arg \c 0 Auffüllen mit Nullen. Bei den Umwandlungen d, i, o, u, x, X, a, A, e, E, f, F, g
und G wird der umgewandelte Wert links mit Nullen, nicht mit Leerzeichen
aufgefüllt. Werden sowohl 0 als auch - angegeben, so wird 0 ignoriert. Wenn eine
Genauigkeit bei einer numerischen Umwandlung (d, i, o, u, x und X), angegeben ist,
wird das Flag 0 ignoriert. Für andere Umwandlungen ist das Ergebis undefiniert.
\arg \c - Linksbündige Ausgabe des umgewandelten Wertes an der Feldgrenze gesetzt wird.
(Standard ist rechtsbündige Ausrichtung.) Außer bei der Umwandlung n wird der
umgewandelte Wert rechts mit Leerzeichen aufgefüllt statt links mit Leerzeichen oder
Nullen. Ein - übersteuert ein 0 falls beide angegeben sind.
\arg \c (ein Leerzeichen) gibt an, dass ein Leerzeichen vor einer positiven Zahl bleiben
soll, die durch einen Vorzeichenwechsel entstanden ist.
\arg \c + gibt an, dass vor alle durch Vorzeichenwechel entstandenen Zahlen das Vorzeichen
(+ oder -) gesetzt wird. Standardmäßig wird ein Vorzeichen nur für negative
Zahlen verwendet. Ein + übersteuert ein Leerzeichen, falls beide angegeben sind.
Die obigen fünf Flags werden vom C-Standard definiert. Die SUSv2 spezifiziert ein weiteres
Flag.
\arg \c ´ Für dezimalen Umwandlungen (i, d, u, f, F, g, G) gibt an, dass die Ausgabe bei
einem numerischen Argument guppiert werden soll, wenn die lokale Spracherweiterung
dieses angibt. Beachte, dass viele Versionen vom gcc diese Option nicht parsen
kann und stattdessen eine Warnung ausgeben. SUSv2 schließt \%F nicht mit ein.
glibc 2.2 fügt ein weiteres Flag hinzu.
\arg \c I Für dezimale Ganzzahlumwandlungen (i, d, u) benutzt die Ausgabe die alternativen
Ausgabeziffern der Locale, wenn es solche gibt (zum Beispiel arabische Ziffern).
Allerdings schließt die Bibliothek keine Locale-Definitionen mit ein, die outdigits
definieren.
\section formatstring_feldbreite Die Feldbreite
Eine optionale Dezimalzahl, die die minimale Feldbreite angibt. Wenn der umgewandelte
Wert weniger Zeichen als die Feldbreite hat, wird er links mit Leerzeichen aufgefüllt
(oder rechts, wenn das Flag für Linksbündigkeit gesetzt ist). Statt einer Dezimalzahl kann
auch * oder *m$ (für eine Dezimalzahl m) angegeben werden, um zu spezifizieren, dass
die Feldbreite im nächsten (oder m-ten) Argument gegeben ist, welches den Type int haben
muss. Eine negative Feldbreite wird als Flag - gefolgt von einer positiven Breite
interpretiert. In keinem Fall resultiert eine nichtexistierende oder kleine Feldbreite im
Abschneiden eines Feldes; ist das Ergebnis einer Umwandlung breiter als die Feldbreite, so
wird das Feld erweitert, um das Ergebnis aufzunehmen.
\section formatstring_genauigkeit Die Genauigkeit
Eine optionale Genauigkeit in der Form eines Punkts (.) gefolgt von einer optionalen
Zahl. Statt einer Dezimalzahl kann auch * oder *m$ (für eine Dezimalzahl m) angegeben
werden, um zu spezifizieren, dass die Genauigkeit im nächsten (oder m-ten) Argument
gegeben ist, welches den Type int haben muss. Wenn die Zahl weggelassen wird oder es eine
negative Zahle ist, wird eine Genauigkeit von Null angenommen. Dies gibt die minimale
Anzahl der Ziffern an, die bei den Umwandlungen d, i, o, u, x und X erscheinen, bzw. die
Anzahl der Ziffern nach dem Dezimaltrennzeichen bei a, A, e, E, f und F , die maximale
Anzahl von signifikanten Ziffern bei g und G , oder die maximale Anzahl von auszugebenden
Zeichen eines Strings bei s und S.
\section formatstring_laengenmodifikator Der Längenmodifikator
Im folgenden steht "Ganzzahlumwandlung" für d, i, o, u, x oder X.
\arg \c hh Eine folgende Ganzzahlumwandlung entspricht einem Argument vom Typ signed char oder
unsigned char, oder eine folgende n-Umwandlung entspricht einem Zeiger auf ein
signed-char-Argument.
\arg \c h Eine folgende Ganzzahlumwandlung entspricht einem Argument vom Typ short int oder
unsigned short int, oder eine folgende n-Umwandlung entspricht einem Zeiger auf ein
short-int-Argument.
\arg \c l Eine folgende Ganzzahlumwandlung entspricht einem Argument vom Typ long int oder
unsigned long int, oder eine folgende n-Umwandlung entspricht einem Zeiger auf ein
long-int-Argument, oder eine folgende c-Umwandlung entspricht einem Zeiger auf ein
wchar_t-Argument,
\arg \c ll Eine folgende Ganzzahlumwandlung entspricht einem Argument vom Typ long long int
oder unsigned long long int, oder eine folgende n-Umwandlung entspricht einem
Zeiger auf ein long-long-int-Argument.
\arg \c L Eine folgende a-, A-, e-, E-, f-, F-, g- oder G-Umwandlung entspricht einem long
double-Argument. (C99 erlaubt \%LF, aber SUSv2 nicht.)
\arg \c q (quad. Nur BSD 4.4 und Linux libc5. Nicht benutzen.) Dies ist ein Synonym für ll.
\arg \c j Eine folgende Ganzzahlumwandlung entspricht einem Argument vom Typ intmax_t oder
uintmax_t.
\arg \c z Eine folgende Ganzzahlumwandlung entspricht einem Argument vom Typ size_t oder
ssize_t. (Linux libc5 hat Z in dieser Bedeutung. Nicht benutzen.)
\arg \c t Eine folgende Ganzzahlumwandlung entspricht einem Argument vom Typ ptrdiff_t.
SUSv2 kennt nur die Längenmodifikatoren h (in hd, hi, ho, hx, hX, hn) und l (in ld, li,
lo, lx, lX, ln, lc, ls) und L (in Le, LE, Lf, Lg, LG).
\section formatstring_umwandlungsspezifikator Der Umwandlungsspezifikator
Ein Zeichen, das den Typ der anzuwendenden Umwandlung angibt. Die Umwandlungsspezifika-
toren und ihre Bedeutung sind:
\arg \c d,i Das Argument int (oder eine entsprechende Variante) wird umgewandelt in eine
vorzeichenbehaftete Dezimalzahl. Die Genauigkeit, sofern vorhanden, gibt die minimale
Anzahl vor Ziffern an, die auftreten muss; wenn der umgewandelte Wert weniger Ziffern
benötigt, wird er links mit Nullen aufgefüllt. Die voreingestellte Genauigkeit
ist 1. Wird 0 mit einer expliziten Genauigkeit 0 gedruckt, so ist die Ausgabe leer.
\arg \c o,u,x,X
Das unsigned-int-Argument wird in eine vorzeichenlose Oktal- (o), Dezimal- (u),
oder Hexadezimalzahl (x und X) umgewandelt. Die Buchstaben abcdef werden für
Umwandlungen x benutzt; die Buchstaben ABCDEF für Umwandlungen X. Die Genauigkeit,
sofern vorhanden, gibt die minimale Anzahl vor Ziffern an, die auftreten muss; wenn
der umgewandelte Wert weniger Ziffern benötigt, wird er links mit Nullen
aufgefüllt. Die voreingestellte Genauigkeit ist 1. Wird 0 mit einer expliziten
Genauigkeit 0 gedruckt, so ist die Ausgabe leer.
\arg \c e,E Das Argument double wird gerundet und in das Format [-]d.ddde±dd umgewandelt, wobei
eine Ziffer vor dem Dezimaltrennzeichen erscheint und die Anzahl der Ziffern dahinter
der Genauigkeit entspricht; wenn die Genauigkeit fehlt, wird sie als 6 angenommen;
wenn die Genauigkeit Null ist, erscheint kein Dezimaltrennzeichen. Eine
Umwandlung E benutzt den Buchstaben E (in Gegensatz zu e), um den Exponenten
einzuleiten. Der Exponent enthält immer mindestens zwei Ziffern; wenn der Wert
Null ist, ist der Exponent 00.
\arg \c f,F Das Argument double wird gerundet und umgewandelt in dezimale Notation im Format
[-]ddd.ddd, wobei die Anzahl der Ziffern hinter dem Dezimaltrennzeichen der
Genauigkeit entspricht. Wenn die Genauigkeit fehlt, wird sie als 6 angenommen;
wenn die Genauigkeit Null ist, erscheint kein Dezimaltrennzeichen. Wenn ein
Dezimaltrennzeichen erscheint, befindet sich mindestens eine Ziffer davor.
(SUSv2 kennt F nicht und sagt, dass Zeichenkettenrepräsentationen für Unendlich und NaN
(Not a Number - keine Zahl) vorhanden sein können. Der C99-Standard spezifiziert [-]inf
oder [-]infinity für Unendlich, und eine Zeichenkette beginnend mit nan für NaN im
Falle von f, und [-]INF oder [-]INFINITY oder NAN im Falle von F.)
\arg \c g , G Das Argument double wird umgewandelt in das Format f oder e (oder F oder E für die
Umwandlung G). Die Genauigkeit gibt die Anzahl der signifikanten Stellen an. Wenn
die Genauigkeit fehlt, werden 6 Ziffern zurückgegeben; wenn die Genauigkeit Null
ist, wird sie als 1 angenommen. Form e wird benutzt, wenn der Exponent kleiner als
-4 oder größer als oder gleich der Genauigkeit ist. Nachfolgende Nullen im
Bruchteil werden entfernt; ein Dezimaltrennzeichen erscheint nur, wenn es von mindestens
einer Ziffer gefolgt wird.
\arg \c a,A (C99; nicht in SUSv2) Für die Umwandlung a wird das double-Argument in hexadezimale
Notation gebracht (unter Benutzung der Buchstaben abcdef) in der Form
[-]0xh.hhhhp±d; für A sind dagegen der Präfix 0X, die Buchstaben ABCDEF und das
Exponententrennzeichen P. Vor dem Dezimaltrennzeichen ist eine hexadezimale Ziffer,
die Anzahl der Stellen dahinter entspricht der Genauigkeit. Die standardmäßige
Genauigkeit genügt für eine exakte Repräsentation des Wertes, wenn eine exakte
Repräsentation zur Basis 2 existiert und ist sonstigenfalls groß genug, um Werte
vom Typ double zu unterscheiden. Die Ziffer vor dem Dezimaltrennzeichen ist
unspezifiziert für nichtnormalisierte Zahlen, und nicht Null, aber ansonsten
unspezifiziert, für normalisierte Zahlen.
\arg \c c Wenn kein Modifikator l vorhanden ist, wird das Argument int umgewandelt in einen
unsigned char und das resultierende Zeichen ausgegeben. Wenn ein l vorhanden ist,
wird das wint_t-Argument (breites Zeichen) mit einem Ruf der Funktion wcrtomb zu
einer Multibyte-Folge umgewandelt, mit der Konvertierung beginnend im initialen
Zustand, und die resultierende Multibyte-Zeichenkette wird ausgegeben.
\arg \c s Wenn kein Modifikator l vorhanden ist, wird das Argument const char * erwartet als
ein Zeiger auf ein Array vom Typ Character (Zeiger auf einen String). Zeichen aus
diesem Array werden bis zu (aber nicht einschliesslich) des terminierenden NUL-
Zeichens ausgegeben; wenn eine Genauigkeit angegeben ist, werden nicht mehr Zeichen
als die angegebene Anzahl ausgegeben. Wenn eine Genauigkeit angegeben ist braucht
kein Null-Zeichen vorhanden zu sein; wenn die Genauigkeit nicht angegeben ist oder
größer als die Array-Größe ist, muss das Array ein beendendes Zeichen NUL enthalten.
Wenn ein l vorhanden ist, wird das const-wchar_t-*-Argument als ein Zeiger
auf ein Array von breiten Zeichen erwartet. Breite Zeichen aus dem Array werden zu
Multibyte-Zeichen umgewandelt (jedes mit einem Ruf von wcrtomb, beginnend im initialen
Zustand vor dem ersten breiten Zeichen), bis zu und einschließlich des terminierenden
breiten NUL-Zeichens. Wenn eine Genauigkeit angegeben ist, werden
nicht mehr Bytes als die angegebene Anzahl ausgegeben, aber es werden keine partiellen
Multibyte-Zeichen ausgegeben. Man beachte, dass die Genauigkeit die Anzahl
der Bytes, nicht der breiten Zeichen oder Bildschirmpositionen angibt. Das Array
muss ein terminierendes breites NUL-Zeichen enthalten, wenn nicht eine Genauigkeit
gegeben ist, die so klein ist, dass die Zahl der geschriebenen Bytes sie
übersteigt, bevor das Ende des Arrays erreicht ist.
\arg \c p Das Zeiger-Argument void * wird hexadezimal ausgegeben (wie bei \%\#x oder \%\#lx).
\arg \c n Die Anzahl der bis hierhin ausgegebenen Zeichen wird in dem Integer gespeichert,
der durch das Zeiger-Argument int * (bzw. Äquivalent) gegeben ist. Kein Argument
wird umgewandelt.
\arg \c \% Ein \% wird ausgegeben. Kein Argument wird umgewandelt. Die komplette
Umwandlungsspezifikation ist \%\%.
*/

103
src/pplib/docs/strftime.dox Normal file
View file

@ -0,0 +1,103 @@
/*!\file strftime.dox
Normale Zeichen im Format werden ohne Konvertierung kopiert. Konvertierungsanweisungen werden durch »\%« charakterisiert. Folgende Anweisungen stehen
zur Verfügung:
\arg \c \%a Der abgekürzte Wochentag abhängig von der momentanen Locale.
\arg \c \%A Der gesamte Wochentag abhängig von der momentanen Locale.
\arg \c \%b Der abgekürzte Monatsname abhängig von der momentanen Locale.
\arg \c \%B Der volle Monatsname abhängig von der momentanen Locale.
\arg \c \%c Das bevorzugte Datums- und Uhrzeit-Repräsentation laut Einstellungen der momentanen Locale.
\arg \c \%C Das Jahrhundert als zweistellige Zahl.
\arg \c \%d Der Tag im Monat als Dezimalzahl (01 - 31).
\arg \c \%D Äquivalent zu \%m/\%d/\%y. (US-amerikanisches Format. In anderen Ländern ist \%d/\%m/\%y durchaus üblich . In internationalem Kontext ist dieses Format daher
mehrdeutig und sollte nicht verwendet werden.) (SU)
\arg \c \%e Wie \%d, der Tag im Monat als Dezimalzahl, aber eine führende Null ist durch ein Leerzeichen ersetzt. (SU)
\arg \c \%E Modifikator: Alternatives Format benutzen, s.u. (SU)
\arg \c \%g Wie \%G, aber ohne das Jahrhundert, also mit zweistelligem Jahr (00-99). (TZ)
\arg \c \%G Das Jahr laut ISO 8601 mit dem Jahrhundert als Dezimalzahl. Das vierstellige Jahr, das zu ISO-Wochennummer (siehe \%V) passt. Es hat dasselbe Format und
denselben Wert wie \%y, nur dass, wenn die ISO-Wochennummer zum vorhergehenden oder nächsten Jahr gehört, dieses Jahr stattdessen benutzt wird. (TZ)
\arg \c \%h Äquivalent zu \%b. (SU)
\arg \c \%H Die Stunde im 24h-Format als Ganzzahl (00 - 23).
\arg \c \%I Die Stunde im 12h-Format als Ganzzahl (01 - 12).
\arg \c \%j Der Tag im Jahr als Ganzzahl (001 - 366).
\arg \c \%k Die Stunde im 24h-Format als Ganzzahl (0 - 23); einzelne Ziffern haben ein vorangestelltes Leerzeichen. (Siehe \%H.) (TZ)
\arg \c \%l Die Stunde im 12h-Format als Ganzzahl (0 - 12); einzelne Ziffern haben ein vorangestelltes Leerzeichen. (Siehe \%I.) (TZ)
\arg \c \%m Der Monat als Ganzzahl (01 - 12).
\arg \c \%M Die Minute als Ganzzahl (00 - 59).
\arg \c \%n Ein Zeilenvorschub. (SU)
\arg \c \%O Modifikator: Alternatives Format benutzen, s.u. (SU)
\arg \c \%p Entweder »AM« oder »PM«, je nach der übergebenen Uhrzeit, oder die zugehörigen Zeichenketten in der momentanen Locale. Mittag erhält »PM«, Mitternacht »AM«.
\arg \c \%P Wie \%p, aber in Kleinbuchstaben. (GNU)
\arg \c \%r Zeit in AM/PM-Notation; in der POSIX-Locale ist das äquivalent zu »\%I:\%M:\%S \%p«. (SU)
\arg \c \%R Zeit in 24h-Notation (\%H:\%M). (SU) Für eine Version mit Sekunden siehe \%T.
\arg \c \%s Die Zahl der Sekunden seit der Epoche, also seit 1970-01-01 00:00:00 UTC. (TZ)
\arg \c \%S Die Sekunde als Ganzzahl (00 - 61).
\arg \c \%t Ein Tabulatorzeichen. (SU)
\arg \c \%T Zeit in 24h-Notation (\%H:\%M:\%S). (SU)
\arg \c \%u Der Tag der Woche als Zahl von 1 bis 7, mit Montag als 1. Siehe auch \%w. (SU)
\arg \c \%U Die Wochennummer des aktuellen Jahres als Ganzzahl von 00 bis 53, beginnend mit dem ersten Sonntag als erster Tag der ersten Woche. Siehe auch \%V und \%W.
\arg \c \%V Die Wochennummer nach ISO 8601:1988 als Dezimalzahl von 01 bis 53, wobei Woche 1 die erste Woche ist, die wenigstens 4 Tage im laufenden Jahr hat, mit Montag
als dem ersten Tag der Woche. Siehe auch \%U und \%W. (SU)
\arg \c \%w Der Tag der Woche als Zahl von 0 bis 6, mit Sonntag als 0. Siehe auch \%u.
\arg \c \%W Die Wochennummer des aktuellen Jahres als Ganzzahl von 00 bis 53, beginnend mit dem ersten Montag als erster Tag der ersten Woche.
\arg \c \%x Die bevorzugte Datums-Repräsentation ohne die Zeit in der momentanen Locale.
\arg \c \%X Die bevorzugte Uhrzeit-Repräsentation ohne das Datum in der momentanen Locale.
\arg \c \%y Das Jahr als Ganzzahl ohne das Jahrhundert (00 - 99).
\arg \c \%Y Das Jahr als Ganzzahl mit dem Jahrhundert.
\arg \c \%z Die Zeitzone als Stundendifferenz zu GMT. Benötigt, um RFC822-konforme Datumsangaben zu erhalten (mit »\%a, \%d \%b \%Y \%H:\%M:\%S \%z«). (GNU)
\arg \c \%Z Die Zeitzone oder der Name oder die Abkürzung.
\arg \c \%+ Datum und Zeit im Format von date(1). (TZ)
\arg \c \%\% Das Zeichen »\%«.
Einige Konvertierungsanweisungen können durch vorangestelltes E oder O modifiziert werden, um anzufordern, dass ein alternatives Format benutzt werden soll.
Existiert das alternative Format in der momentanen Locale nicht, ist das Verhalten so, als ob es keine Modifikation gibt. (SU)
Die Single Unix Specification erwähnt \%Ec, \%EC, \%Ex, \%EX, \%Ry, \%EY, \%Od, \%Oe, \%OH, \%OI, \%Om, \%OM, \%OS, \%Ou, \%OU, \%OV, \%Ow, \%OW, \%Oy, wobei der Effekt von O ist,
alternative numerische Symbole zu benutzen (etwa römische Zahlen), und der von E, eine Locale-abhängige alternative Repräsentation zu wählen.
*/

View file

@ -0,0 +1,111 @@
/*! \struct ppl7::tagTime
*
* Siehe ppl7::PPLTIME
*
*/
/*!\struct ppl7::PPLTIME
* \ingroup PPLGroupDateTime
*
* In dieser Struktur wird ein Datum in seine einzelnen Bestandteile zerlegt, wie Jahr, Monat, Tag,
* Stunden, Minuten und Sekunden.
*
* \code
typedef struct tagTime {
ppluint64 epoch;
int year;
int month;
int day;
int hour;
int min;
int sec;
int day_of_week;
int day_of_year;
int summertime;
int gmt_offset;
int have_gmt_offset;
} PPLTIME;
\endcode
*
*/
/*!\struct ppl7::RECT ppl7.h "ppl7.h"
\ingroup PPLGroupDataTypes
\brief Struktur, die ein Rechteck definiert
\desc
Der Typ "RECT" definiert die Koordinaten eines Rechtecks. Die Variablen
\p RECT.left und \p RECT.top definieren dabei die linke obere Ecke, die Variablen
\p RECT.right und \p RECT.bottom die rechte untere Ecke. Dabei ist zu beachten, dass \p right und
\p bottom jeweils außerhalb des Rechtecks liegen (also um 1 erhöht). Das hat den Vorteil,
dass man Höhe und Breite einfach durch Subtraktion errechnen kann.
Ist ein Rechteck 600 Pixel breit, 200 Pixel hoch, und beginnt bei den Koordinaten 100/20, haben die
Variablen in RECT folgende Werte:
\code
RECT r;
r.left=100;
r.top=20;
r.right=700;
r.bottom=220;
int width=r.right-r.left;
int height=r.bottom-r.top;
\endcode
Sie wird hauptsächlich innerhalb der Garfik-Bibliothek verwendet, um die Koordinaten von
Fenstern, Surfaces, Rechtecken, Clippings und Texturen zu speichern, oder um rechteckige
Formen zu zeichnen oder zu Kopieren (z.B. ppl7::grafix::Blt).
\remarks
Windows verwendet den Datentyp "long" für die einzelnen Elemente. Dieser ist unter Windows 32 Bit breit,
sowohl in einer 32-Bit als auch in einer 64-Bit Umgebung. Unter Unix ist "long" aber in einer 64-Bit-Umgebung
auch 64 Bit breit. Daher verwendet die PPL-Library als Datentyp "int", der auf beiden Systemen 32-Bit breit
ist.
*/
/*!\var ppl7::RECT::left
\brief Spezifiziert die X-Koordinate der oberen linken Ecke des Rechtecks
*/
/*!\var ppl7::RECT::top
\brief Spezifiziert die Y-Koordinate der oberen linken Ecke des Rechtecks
*/
/*!\var ppl7::RECT::right
\brief Spezifiziert die X-Koordinate der unteren rechten Ecke des Rechtecks
Per Definition sind die Koordinaten für die rechte und untere Ecke des Rechtecks
exklusiv, das heisst sie liegen nicht innerhalb des Rechtecks, sondern um einen Pixel
außerhalb.
*/
/*!\var ppl7::RECT::bottom
\brief Spezifiziert die Y-Koordinate der unteren rechten Ecke des Rechtecks
Per Definition sind die Koordinaten für die rechte und untere Ecke des Rechtecks
exklusiv, das heisst sie liegen nicht innerhalb des Rechtecks, sondern um einen Pixel
außerhalb.
*/
/*!\struct ppl7::POINT ppl7.h "ppl7.h"
\ingroup PPLGroupDataTypes
\brief Koordinaten eines einzelnen Punktes
\desc
Diese Struktur definiert die X- und Y-Koordinaten eines einzelnen Punktes innerhalb einer
2-Dimensionalen Fläche.
*/
/*!\var ppl7::POINT::x
\brief Die X-Koordinate des Punktes
*/
/*!\var ppl7::POINT::y
\brief Die Y-Koordinate des Punktes
*/

104
src/pplib/docs/threads.dox Normal file
View file

@ -0,0 +1,104 @@
/*!
\defgroup PPLGroupThreads Threads
Ein Thread ist ein sequentieller Abarbeitungslauf eines Prozesses und teilt sich mit den anderen
vorhandenen Threads (multithreading) des zugehörigen Prozesses eine Reihe von Betriebsmitteln,
nämlich das Codesegment, das Datensegment und die verwendeten Dateideskriptoren. Allerdings bewahrt
jeder Thread seinen eigenen Befehlszähler und seinen eigenen Stack. Durch die gemeinsame Nutzung des
Speicherbereichs kann es natürlich auch zu Konflikten kommen. Diese müssen durch den Einsatz von
Synchronisationsmechanismen (\ref PPLGroupThreadsMutex) aufgelöst werden.
\see http://de.wikipedia.org/wiki/Thread_%28Informatik%29
\defgroup PPLGroupThreadsMutex Mutex
\ingroup PPLGroupThreads
\brief Mutexes stellen ein Low-Level-Interface für die Synchronisation von Threads dar. Mit ihnen
kann verhindert werden, dass mehrere Threads versuchen gleichzeitig auf die gleichen Daten
zuzugreifen.
Das (oder der) Mutex (Abk. für engl. Mutual Exclusion, „wechselseitiger Ausschluss“) bezeichnet Verfahren,
mit denen verhindert wird, dass nebenläufige Prozesse bzw. Threads gleichzeitig auf Daten zugreifen und
so unter Umständen inkonsistente Zustände herbeiführen. Dieses Konzept ist von zentraler Bedeutung sowohl
für Systeme, deren Software in Threads abläuft, als auch für konkurrierend ablaufende Prozesse im
Allgemeinen, beispielsweise quasigleichzeitige Zugriffe auf ein Datenbanksystem aus mehreren
unabhängigen Clients. Das Konzept wird auch als Prozess- oder Thread-Synchronisation bezeichnet.
In vielen Programmiersprachen heißen auch die für die Synchronisation benötigten Objekte Mutexe.
\see http://de.wikipedia.org/wiki/Mutex
\defgroup PPLGroupThreadsPriority Thread-Prioritäten
\ingroup PPLGroupThreads
\brief Ein Thread kann verschiedene Prioritäten haben, die bestimmen, wieviel Rechenzeit ihm
zugesprochen wird.
\section ThreadsPriority_Class Klassen
Ein Thread kann in eine von 4 Grundklassen eingeordnet werden, die bestimmen, mit welcher Priorität
er ausgeführt werden soll:
\li THREAD_CLASS::IDLE
\li THREAD_CLASS::NORMAL (der Default)
\li THREAD_CLASS::HIGH
\li THREAD_CLASS::REALTIME
Zur Zeit wird dieses Feature noch nicht verwendet!
\section ThreadsPriority_Priority Priorität
Zusätzlich kann noch ein Feintuning vorgenommen werden, bei dem die Priorität des Threads
festgelegt wird:
\li THREAD_PRIORITY::LOWEST\n
Der Thread hat die niedrigste Priorität
\li THREAD_PRIORITY::BELOW_NORMAL\n
Der Thread hat eine etwas niedrigere Priorität wie normal
\li THREAD_PRIORITY::NORMAL\n
Der Thread hat normale Priorität
\li THREAD_PRIORITY::ABOVE_NORMAL:\n
Der Thread hat eine etwas höhere Priorität wie normal
\li THREAD_PRIORITY::HIGHEST\n
Der Thread hat die höchste Priorität
Mit folgenden Funktionen kann die Priorität eines Threads gelesen oder verändert werden:
\defgroup PPLGroupThreadsStacksize Thread-Stackgröße
\ingroup PPLGroupThreads
\brief Die Größe des Stacks verändern
Die Größe des Stacks wird vom Betriebssystem vorgegeben und sollte in den meisten Fällen
ausreichen. Manchmal ist er allerdings für die vorgesehene Anwendung zu klein (sehr viele
Rekursive Aufrufe) oder zu groß. Daher ist es möglich vor dem Starten des Threads die Größe
des Stacks zu verändern.
\defgroup PPLGroupThreadsStarten Threads starten
\ingroup PPLGroupThreads
\brief Zeigt, wie ein Thread gestartet wird
Um einen Thread zu starten, sind mehrere Schritte erforderlich.
\li Zuerst muß der Anwender eine eigene Klasse erstellen und diese von ppl6::CThread ableiten
\li Die Klasse des Anwenders muß eine Funktion "ThreadMain" enthalten, die den auszuführenden
Code enthält.
\li Diese muß in regelmäßigen Abständen die Funktion CThread::ThreadShouldStop aufrufen, um
zu prüfen, ob der Thread sich beenden soll.
\li Der Thread selbst wird dann von Hauptprogramm aus über die Funktion CThread::ThreadStart()
gestartet.
Beispiel:
\include CThread_ThreadMain.cpp
\defgroup PPLGroupThreadsCThreadPool Threads in einem Pool verwalten
\ingroup PPLGroupThreads
\brief Threads in einem Pool verwalten.
Wenn man mit mehreren Threads arbeitet, kann es sinnvoll sein diese zu gruppieren und in einem
Pool zusammenzufassen. Der Pool hat den Vorteil, dass alle Threads mit nur einem einzigen Befehl
gestoppt oder gelöscht werden können.
*/

View file

@ -0,0 +1,161 @@
/*!\page ppl7_usage PPL7 verwenden
\section ppl7_usage_code Programmcode
Innerhalb des Programmcodes ist darauf zu achten, dass die notwendigen Header-Dateien
eingebunden werden. Die Basisfunktionalität ist in der Datei "ppl7.h" zu finden. Diese
sollte daher immer eingebunden werden:
\code
#include <ppl7.h>
\endcode
Wird von weiteren Features gebrauch gemacht, können folgende weitere Include-Dateien
benötigt werden:
\code
#include <ppl7-grafix.h>
#include <ppl7-sound.h>
#include <ppl7-tk.h>
\endcode
Damit die Include-Dateien gefunden werden, sollte der Compiler mit der Ausgabe
von "ppl7-config --cflags" gestartet werden, und der Linker mit "ppl7-config --libs".
Da alle Funktionen der Library im Namespace "ppl7" zu finden sind, muss dies bei
der Verwendung berücksichtigt werden. Dazu gibt es zwei Möglichkeiten:
\li 1. Globale Verwendung der Funktionen\n
Dazu fügt man am Anfang des Programmcodes folgenden Code ein:
\code
using namespace ppl7;
\endcode
Danach sind alle Funktionen sofort mit ihrem Namen aufrufbar.
\li 2. Gezielte Verwendung der Funktionen\n
Dazu wird bei Aufruf einer Funktion aus der Library jeweils der Namespace
"ppl7::" vorangestellt. Beispiel:
\code
ppl7::SendMail Mail;
ppl7::String d;
ppl7::MkISO8601Date(&d); // Datum im String speichern
Mail.setHeader("To","patrick@pfp.de");
Mail.setHeader("From","patrick@pfp.de");
Mail.setHeader("Subject","Testmail %s",(char*)d);
Mail.message.set("Dies ist eine Testmail");
Mail.setServer("mail.pfp.de:smtp");
if (!Mail.send()) {
ppl6::PrintError();
return 0;
}
printf ("ok\n");
\endcode
\section ppl7_usage_makefile Makefile
Das folgende Beispiel soll als Template für ein Makefile dienen. Wichtig sind die
beiden Zeilen "CFLAGS" und "LIB", in denen das Tool "ppl6-config" aufgerufen wird.
Das Keywort "debug" sagt dem Programm, dass die Debug-Version der Library
verwendet werden soll. Für eine Release-Version sollte aus Performancegründen
das Keywort "release" verwendet werden oder ganz weggelassen werden. Außerdem
empfiehlt es sich die Kompiler Optimierungen zu aktivieren, indem man bei den
CFLAGS "-O2" oder "-O3" hinzufügt.
\code
CC = gcc
EXTRA_CFLAGS =
INCLUDE = -I. -I../include
CFLAGS = -ggdb -Wall $(INCLUDE) $(EXTRA_CFLAGS) `ppl7-config --cflags debug`
LIB = `ppl7-config --libs debug` -lstdc++
PROGRAM = ppltestprog
OBJECTS=compile/main.o
$(PROGRAM): compile Makefile $(OBJECTS)
$(CC) $(CFLAGS) -o $(PROGRAM) $(OBJECTS) $(LIB)
-chmod 755 $(PROGRAM)
all: $(PROGRAM)
clean:
-rm -f compile $(PROGRAM) *.log debug.txt *.core
install: $(PROGRAM)
cp $(PROGRAM) /usr/local/bin
compile:
-mkdir compile
compile/main.o: main.cpp testprog.h Makefile
$(CC) $(CFLAGS) -o compile/main.o -c main.cpp
\endcode
\section ppl7_usage_autoconf Verwendung von "autoconf"
Soll \b autoconf zur Erkennung der PPL-Library verwendet werden, kann folgendes m4-Makro
verwendet werden:
<b>ppl7.m4</b>
\include ppl7.m4
Das Makro kann beispielsweise so im Configure-Script verwendet werden:
\code
sinclude(autoconf/ppl7.m4)
report_have_ppl7="no"
AX_PATH_LIB_PPL7([7.0.0],
AC_DEFINE(HAVE_LIBPPL7, 1, [ Define if you have ppl7. ])
report_have_ppl7="yes"
AC_SUBST(LIBPPL7_CFLAGS)
AC_SUBST(LIBPPL7)
AC_SUBST(LIBPPL7_DEBUG)
AC_SUBST(LIBPPL7_DEBUG_LIBS)
AC_SUBST(LIBPPL7_RELEASE_LIBS)
,
AC_MSG_ERROR(no suitable ppl7 available)
)
\endcode
Es gibt noch ein weiteres Macro, um das vorhandensein eines bestimmten Features
abzufragen. Dieses würde im configure nach dem obrigen Aufruf so eingebunden:
\code
AX_PPL7_FEATURE([zlib],ppl_has_zlib="yes",ppl_has_zlib="no")
AX_PPL7_FEATURE([bzip2],ppl_has_bzip2="yes",ppl_has_bzip2="no")
...
\endcode
Denkbar wäre auch:
\code
AX_PPL7_FEATURE([zlib],,AC_MSG_ERROR(a required feature is missing))
\endcode
Das Makefile aus dem Beispiel oben würde dann so aussehen:
\code
CC = gcc
EXTRA_CFLAGS =
INCLUDE = -I. -I../include
CFLAGS = -ggdb -Wall $(INCLUDE) $(EXTRA_CFLAGS) @LIBPPL7_CFLAGS@
LIB = @LIBPPL7_RELEASE_LIBS@ -lstdc++
PROGRAM = ppltestprog
OBJECTS=compile/main.o
$(PROGRAM): compile Makefile $(OBJECTS)
$(CC) $(CFLAGS) -o $(PROGRAM) $(OBJECTS) $(LIB)
-chmod 755 $(PROGRAM)
all: $(PROGRAM)
clean:
-rm -f compile $(PROGRAM) *.log debug.txt *.core
install: $(PROGRAM)
cp $(PROGRAM) /usr/local/bin
compile:
-mkdir compile
compile/main.o: main.cpp testprog.h Makefile
$(CC) $(CFLAGS) -o compile/main.o -c main.cpp
\endcode
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB