EnglischFranzösischSpanisch

Server ausführen | Ubuntu > | Fedora > |


OnWorks-Favicon

gvpr - Online in der Cloud

Führen Sie gvpr im kostenlosen OnWorks-Hosting-Provider über Ubuntu Online, Fedora Online, Windows-Online-Emulator oder MAC OS-Online-Emulator aus

Dies ist der Befehl gvpr, der im kostenlosen OnWorks-Hosting-Provider über eine unserer zahlreichen kostenlosen Online-Workstations wie Ubuntu Online, Fedora Online, Windows-Online-Emulator oder MAC OS-Online-Emulator ausgeführt werden kann

PROGRAMM:

NAME


gvpr - Sprache zum Scannen und Verarbeiten von Diagrammmustern

ZUSAMMENFASSUNG


gvpr [-icnqV?] [ -o Outfile ] [ -a args ] [ 'prog' | -f Profil ] [ Dateien ]

BESCHREIBUNG


gvpr (Vorher bekannt als gpr) ist ein von inspirierter Graph-Stream-Editor awk. Es kopiert Eingaben
Graphen zu seiner Ausgabe, möglicherweise ihre Struktur und Attribute transformieren, neue erstellen
Grafiken oder das Drucken beliebiger Informationen. Das Graphenmodell ist das von
libcgraph(3). Insbesondere, gvpr liest und schreibt Graphen in der Punktsprache.

Grundsätzlich gilt, gvpr durchläuft jeden Eingabegraphen, bezeichnet mit $G, jeden Knoten und jede Kante besuchen,
Abgleichen mit den Prädikatsaktionsregeln, die im Eingabeprogramm bereitgestellt werden. Die Regeln sind
der Reihe nach ausgewertet. Für jedes Prädikat, das als wahr ausgewertet wird, ist die entsprechende Aktion
durchgeführt. Während der Durchquerung wird der aktuell besuchte Knoten oder die aktuell besuchte Kante mit bezeichnet $.

Für jeden Eingabegraphen gibt es einen Ziel-Untergraph, bezeichnet mit $T, zunächst leer und gebraucht
um ausgewählte Entitäten zu akkumulieren, und einen Ausgabegraphen, $O, zur Endbearbeitung verwendet und dann
Ausgabe geschrieben. Standardmäßig ist das Ausgabediagramm das Zieldiagramm. Die Ausgabegrafik
kann im Programm oder eingeschränkt auch auf der Kommandozeile eingestellt werden.

OPTIONAL


Die folgenden Optionen werden unterstützt:

-a args
Die Zeichenfolge args wird in durch Leerzeichen getrennte Tokens aufgeteilt, mit dem Individuum
Token, die als Strings in der verfügbar sind gvpr Programm als ARGV[0],...,ARGV[ARGC-1].
Leerzeichen in Teilzeichenfolgen in einfachen oder doppelten Anführungszeichen oder vor a
Backslash, werden als Trennzeichen ignoriert. Im Allgemeinen wird ein umgekehrter Schrägstrich deaktiviert
jede besondere Bedeutung des folgenden Zeichens. Beachten Sie, dass die Tokens abgeleitet von
mehrere -a Flags werden verkettet.

-c Verwenden Sie das Quelldiagramm als Ausgabediagramm.

-i Leiten Sie die knoteninduzierte Untergraphenerweiterung des Ausgabegraphen im Kontext von
seinen Wurzelgraphen.

-o Outfile
Bewirkt, dass der Ausgabestream in die angegebene Datei geschrieben wird; Standardmäßig ist die Ausgabe
geschrieben stdout.

-f Profil
Verwenden Sie den Inhalt der angegebenen Datei als das Programm, das für die Eingabe ausgeführt werden soll. Wenn
Profil einen Schrägstrich enthält, wird der Name als Pfadname der Datei verwendet.
Andernfalls gvpr verwendet die in der Umgebungsvariablen angegebenen Verzeichnisse
GVPRPATH um die Datei zu suchen. Wenn -f ist nicht gegeben, gvpr verwendet die erste nicht‐
Optionsargument als Programm.

-q Schaltet Warnmeldungen aus.

-n Deaktiviert das Vorauslesen von Grafiken. Standardmäßig ist die Variable $NG wird auf den nächsten Graphen gesetzt
verarbeitet werden. Dies erfordert ein Lesen des nächsten Graphen vor der Verarbeitung der
aktueller Graph, der blockieren kann, wenn der nächste Graph nur als Reaktion auf . erzeugt wird
einige Aktionen bezüglich der Verarbeitung des aktuellen Graphen.

-V Veranlasst das Programm, Versionsinformationen zu drucken und zu beenden.

-? Veranlasst das Programm, Nutzungsinformationen zu drucken und zu beenden.

OPERANDEN


Der folgende Operand wird unterstützt:

Dateien Namen von Dateien, die 1 oder mehrere Grafiken in der Punktsprache enthalten. Wenn nein -f Option
gegeben ist, wird der Vorname aus der Liste entfernt und als Eingabeprogramm verwendet.
Wenn die Dateiliste leer ist, Standard werden verwendet.

PROGRAMME


A gvpr Programm besteht aus einer Liste von Prädikat‐Aktionsklauseln, die eine der folgenden Formen haben:

START { Aktion }

BEG_G { Aktion }

N [ Prädikat ] { Aktion }

E [ Prädikat ] { Aktion }

END_G { Aktion }

ENDE { Aktion }

Ein Programm kann höchstens eines von jedem der START, END_G und ENDE Klauseln. Dort kann
eine beliebige Anzahl von sein BEG_G, N und E Aussagen, die erste auf Graphen angewendet, die zweite auf
Knoten, die dritte zu Kanten. Diese sind in Blöcke unterteilt, ein Block bestehend aus einem
optional BEG_G Aussage und so N und E Aussagen bis zum nächsten BEG_G Aussage, wenn
beliebig. Die Top‐Level‐Semantik von a gvpr Programm sind:

Bewerten START Klausel, falls vorhanden.
Für jeden Eingabegraphen G {
Für jeden Block {
Kleidungsset G als aktueller Graph und aktuelles Objekt.
Bewerten BEG_G Klausel, falls vorhanden.
Für jeden Knoten und jede Kante in G {
Legen Sie den Knoten oder die Kante als aktuelles Objekt fest.
Bewerten N or E Klauseln, ggf.
}
}
Kleidungsset G als aktuelles Objekt.
Bewerten END_G Klausel, falls vorhanden.
}
Bewerten ENDE Klausel, falls vorhanden.

Die Aktionen der START, BEG_G, END_G und ENDE Klauseln werden ausgeführt, wenn die Klauseln
bewertet. Für N or E Klauseln können entweder das Prädikat oder die Aktion weggelassen werden. Wenn da
kein Prädikat mit einer Aktion ist, wird die Aktion an jedem Knoten oder jeder Kante ausgeführt, da
angemessen. Wenn es keine Aktion gibt und das Prädikat als wahr ausgewertet wird, wird das zugehörige
Knoten oder Kante wird dem Zielgraphen hinzugefügt.

Die Blöcke werden in der Reihenfolge ihres Auftretens ausgewertet. Innerhalb eines Blocks wird die N Klauseln
(E Klauseln) werden in der Reihenfolge ausgewertet, in der sie auftreten. Beachten Sie jedoch,
dass innerhalb eines Blocks N or E Klauseln können in Abhängigkeit von der Durchlaufreihenfolge verschachtelt sein.

Prädikate und Aktionen sind Abfolgen von Anweisungen im C-Dialekt, die von der . unterstützt werden
ausdr(3) Bibliothek. Der einzige Unterschied zwischen Prädikaten und Aktionen besteht darin, dass erstere
muss einen Typ haben, der entweder als wahr oder falsch interpretiert werden kann. Hier das übliche C
Es wird eine Konvention befolgt, in der ein Wert ungleich Null als wahr angesehen wird. Dies würde beinhalten
nichtleere Zeichenfolgen und nichtleere Verweise auf Knoten, Kanten usw. Wenn jedoch eine Zeichenfolge
in eine ganze Zahl umgewandelt werden, wird dieser Wert verwendet.

Neben den üblichen C-Basistypen (ungültig, int, verkohlen, schweben, lange, ohne Vorzeichen und doppelt),
gvpr bietet Schnur als Synonym für char *, und die graphbasierten Typen Knoten_t, Kante_t,
graph_t und obj_tdem „Vermischten Geschmack“. Seine obj_t Typ kann als Supertyp der anderen 3 Beton angesehen werden
Typen; der richtige Basistyp wird dynamisch gepflegt. Neben diesen Basistypen sind die
nur andere unterstützte Typausdrücke sind (assoziative) Arrays.

Konstanten folgen der C-Syntax, aber Strings können mit beiden in Anführungszeichen gesetzt werden "..." or '...'. gvpr
akzeptiert C++-Kommentare sowie Kommentare vom Typ cpp. Für letzteres, wenn eine Zeile mit beginnt
ein '#'-Zeichen, der Rest der Zeile wird ignoriert.

Eine Anweisung kann eine Deklaration einer Funktion, einer Variablen oder eines Arrays oder einer ausführbaren Datei sein
Erklärung. Für Deklarationen gibt es einen einzigen Geltungsbereich. Array-Deklarationen haben die Form:

tippe Feld [ type0 ]

woher type0 es ist optional. Wenn es angegeben wird, erzwingt der Parser, dass alle Arrays
Indizes haben den angegebenen Typ. Wenn es nicht mitgeliefert wird, können Objekte aller Art
als Indizes verwendet. Wie in C müssen Variablen und Arrays deklariert werden. Insbesondere ein
nicht deklarierte Variable wird als Name eines Attributs eines Knotens, einer Kante oder . interpretiert
Grafik, je nach Kontext.

Ausführbare Anweisungen können eine der folgenden sein:

{ [ Aussage realisieren kannst... ] }
Ausdruck // häufig jung = Ausdruck
wenn ( Ausdruck ) Aussage [ sonst Aussage ]
zum( Ausdruck ; Ausdruck ; Ausdruck ) Aussage
zum( Feld [ jung ]) Aussage
für ( Feld [ jung ]) Aussage
während( Ausdruck ) Aussage
Schalter ( Ausdruck ) Häuser Aussagen
brechen [ Ausdruck ]
fortsetzen [ Ausdruck ]
Rückkehr [ Ausdruck ]
Elemente in Klammern sind optional.

In der zweiten Form des für Aussage und die fürr Anweisung, die Variable jung eingestellt ist
jeder Wert, der als Index im angegebenen Array verwendet wird, und dann das zugehörige Aussage is
bewertet. Bei numerischen und String-Indizes werden die Indizes aufsteigend zurückgegeben
(abnehmende) numerische oder lexikographische Reihenfolge für für (fürr, bzw). Dies kann verwendet werden
zum Sortieren.

Funktionsdefinitionen können nur im START Klausel.

Ausdrücke umfassen die üblichen C-Ausdrücke. Stringvergleiche mit == und != behandeln die
rechte Operand als Muster zum Zweck des Abgleichs mit regulären Ausdrücken. Muster
unsere Website benutzen, ksh(1) Datei-Match-Muster-Syntax. (Für einfache String-Gleichheit verwenden Sie die strcmp
Funktion.

gvpr versucht, einen Ausdruck je nach Bedarf als Zeichenfolge oder numerischen Wert zu verwenden. Beide
C-ähnliche Umwandlungen und Funktionsschablonen führen dazu, dass, wenn möglich, Konvertierungen durchgeführt werden.

Ausdrücke grafischer Art (d. h., graph_t, Knoten_t, Kante_t, obj_t) kann gefolgt werden von a
Feldbezug in Form von .Name. Der resultierende Wert ist der Wert des Attributs
namens Name des angegebenen Objekts. Darüber hinaus kann in bestimmten Zusammenhängen eine nicht deklarierte,
unmodifizierter Bezeichner wird als Attributname angesehen. Insbesondere solche Identifikatoren
bezeichnen Attribute des aktuellen Knotens bzw. der aktuellen Kante in N und E Klauseln und die
aktuelle Grafik in BEG_G und END_G Klauseln.

Wie üblich im libcgraph(3) Modell, Attribute sind String-Werte. In Ergänzung, gvpr
unterstützt bestimmte Pseudoattribute von Graphobjekten, die nicht unbedingt Zeichenfolgenwerte haben. Diese
spiegeln intrinsische Eigenschaften der Graphobjekte wider und können nicht vom Benutzer eingestellt werden.

ganzer : Knoten_t
der Kopf einer Kante.

Schwanz : Knoten_t
das Ende einer Kante.

Name : Schnur
der Name einer Kante, eines Knotens oder eines Graphen. Der Name einer Kante hat die Form "<tail‐
Name>[]", wo ist "->"Oder"--" es hängt davon ab
ob der Graph gerichtet ist oder nicht. Das Halterungsteil [] erscheint nur, wenn die
edge hat einen nicht trivialen Schlüssel.

ingrad : int
der Ingrad eines Knotens.

außergrad : int
der Outgrad eines Knotens.

Grad : int
der Grad eines Knotens.

Wurzel : graph_t
der Wurzelgraph eines Objekts. Die Wurzel eines Wurzelgraphen ist sich selbst.

Elternteil : graph_t
der Elterngraph eines Untergraphen. Der Elternteil eines Wurzelgraphen ist NULL

n_kanten : int
die Anzahl der Kanten im Graphen

n_knoten : int
die Anzahl der Knoten im Graphen

gerichtet : int
wahr (nicht null), wenn der Graph gerichtet ist

streng : int
wahr (nicht null), wenn der Graph streng ist

EINGEBAUT FUNKTIONEN


Die folgenden Funktionen sind integriert in gvpr. Diese Funktionen, die Verweise auf den Graphen zurückgeben
Objekte kehren zurück NULL im Fehlerfall.

Graphs und Subgraph
Graph(s : Schnur, t : Schnur): graph_t
erstellt einen Graphen mit dem Namen s und dessen Typ durch die Zeichenfolge angegeben wird t.
Groß-/Kleinschreibung ignorieren, die Zeichen U, D, S, N die Interpretation ungerichtet haben,
gerichtet, streng und nicht streng. Wenn t ist leer, ein gerichteter, nicht‐
strenger Graph wird erzeugt.

unterg(g : graph_t, s : Schnur): graph_t
erstellt einen Untergraphen in der Grafik g mit name s. Wenn der Teilgraph bereits existiert, ist er
ist zurückgekommen.

isSubg(g : graph_t, s : Schnur): graph_t
gibt den Untergraphen im Graphen zurück g mit name s, falls vorhanden, oder NULL Andernfalls.

fstsubg(g : graph_t): graph_t
gibt den ersten Untergraphen im Graphen zurück gbezeichnet, oder NULL wenn keine vorhanden ist.

nxtsubg(sg : graph_t): graph_t
gibt den nächsten Untergraphen nach zurück sgbezeichnet, oder NULL.

isDirect(g : graph_t): int
gibt true zurück, wenn und nur wenn g gerichtet ist.

istStreng(g : graph_t): int
gibt true zurück, wenn und nur wenn g ist streng.

nKnoten(g : graph_t): int
gibt die Anzahl der Knoten in . zurück g.

nKanten(g : graph_t): int
gibt die Anzahl der Kanten in . zurück g.

Nodes
Knoten(sg : graph_t, s : Schnur): Knoten_t
erstellt einen Knoten im Graphen g des Namens s. Wenn ein solcher Knoten bereits existiert, wird er zurückgegeben.

Unterknoten(sg : graph_t, n : Knoten_t): Knoten_t
fügt den Knoten ein n in den Untergraph g. Gibt den Knoten zurück.

fstnode(g : graph_t): Knoten_t
gibt den ersten Knoten im Graphen zurück gbezeichnet, oder NULL wenn keine vorhanden ist.

nxtnode(n : Knoten_t): Knoten_t
gibt den nächsten Knoten zurück nach n im Wurzelgraphen, oder NULL.

nxtnode_sg(sg : graph_t, n : Knoten_t): Knoten_t
gibt den nächsten Knoten zurück nach n in sgbezeichnet, oder NULL.

istKnoten(sg : graph_t, s : Schnur): Knoten_t
sucht nach einem Knoten im (Unter-)Graphen sg des Namens s. Wenn ein solcher Knoten existiert, wird er zurückgegeben.
Andernfalls NULL wird zurückgegeben.

isSubnode(sg : graph_t, n : Knoten_t): int
gibt einen Wert ungleich null zurück, wenn Knoten n ist in (Unter-)Grafik sg, oder sonst null.

GradOf(sg : graph_t, n : Knoten_t): int
gibt den Ingrad von node . zurück n in (Unter-)Grafik sg.

ausgradOf(sg : graph_t, n : Knoten_t): int
gibt den Außengrad von Knoten zurück n in (Unter-)Grafik sg.

Grad von(sg : graph_t, n : Knoten_t): int
gibt den Knotengrad zurück n in (Unter-)Grafik sg.

Edges
Rand(t : Knoten_t, h : Knoten_t, s : Schnur): Kante_t
erzeugt eine Kante mit Schwanzknoten t, Kopfknoten h und Name s im Wurzeldiagramm. Wenn die
Graph ungerichtet ist, ist die Unterscheidung zwischen Kopf- und Schwanzknoten unwichtig.
Wenn eine solche Kante bereits existiert, wird sie zurückgegeben.

edge_sg(sg : graph_t, t : Knoten_t, h : Knoten_t, s : Schnur): Kante_t
erzeugt eine Kante mit Schwanzknoten t, Kopfknoten h und Name s in (Unter-)Grafik sg (und alles
Elterndiagramme). Wenn der Graph ungerichtet ist, ist die Unterscheidung zwischen Kopf und Schwanz
Knoten ist unwichtig. Wenn eine solche Kante bereits existiert, wird sie zurückgegeben.

Unterkante(g : graph_t, e : Kante_t): Kante_t
fügt die Kante ein e in den Untergraph g. Gibt die Kante zurück.

isEdge(t : Knoten_t, h : Knoten_t, s : Schnur): Kante_t
sucht nach einer Kante mit Schwanzknoten t, Kopfknoten h und Name s. Wenn der Graph ist
ungerichtet ist die Unterscheidung zwischen Kopf- und Schwanzknoten unwichtig. Wenn so ein
Kante existiert, wird sie zurückgegeben. Ansonsten, NULL wird zurückgegeben.

isEdge_sg(sg : graph_t, t : Knoten_t, h : Knoten_t, s : Schnur): Kante_t
sucht nach einer Kante mit Schwanzknoten t, Kopfknoten h und Name s in (Unter-)Grafik sg. Wenn der
Graph ungerichtet ist, ist die Unterscheidung zwischen Kopf- und Schwanzknoten unwichtig.
Wenn eine solche Kante existiert, wird sie zurückgegeben. Ansonsten, NULL wird zurückgegeben.

isSubedge(g : graph_t, e : Kante_t): int
gibt einen Wert ungleich null zurück, wenn edge e ist in (Unter-)Grafik sg, oder sonst null.

fstaus(n : Knoten_t): Kante_t
gibt die erste Außenkante von node . zurück n im Wurzeldiagramm.

fstout_sg(sg : graph_t, n : Knoten_t): Kante_t
gibt die erste Außenkante von node . zurück n in (Unter-)Grafik sg.

nxtout(e : Kante_t): Kante_t
gibt die nächste Außenkante zurück nach e im Wurzeldiagramm.

nxtout_sg(sg : graph_t, e : Kante_t): Kante_t
gibt die nächste Außenkante zurück nach e im Diagramm sg.

fstin(n : Knoten_t): Kante_t
gibt die erste Kante von node . zurück n im Wurzeldiagramm.

fstin_sg(sg : graph_t, n : Knoten_t): Kante_t
gibt die erste Kante von node . zurück n im Diagramm sg.

nxtin(e : Kante_t): Kante_t
gibt die nächste Kante zurück nach e im Wurzeldiagramm.

nxtin_sg(sg : graph_t, e : Kante_t): Kante_t
gibt die nächste Kante zurück nach e im Diagramm sg.

fstege(n : Knoten_t): Kante_t
gibt die erste Kante von Knoten zurück n im Wurzeldiagramm.

fsedge_sg(sg : graph_t, n : Knoten_t): Kante_t
gibt die erste Kante von Knoten zurück n im Diagramm sg.

nxedge(e : Kante_t, Knoten_t): Kante_t
gibt die nächste Kante nach . zurück e im Wurzeldiagramm.

nxtedge_sg(sg : graph_t, e : Kante_t, Knoten_t): Kante_t
gibt die nächste Kante nach . zurück e in der Grafik sg.

opp(e : Kante_t, Knoten_t): Knoten_t
gibt den Knoten am Rand zurück e Nicht gleichzusetzen mit n. Gibt NULL zurück, wenn n ist kein Knoten von
e. Dies kann bei der Verwendung nützlich sein fstege und nxedge die Nachbarn von aufzählen
n.

Graph I / O
schreiben(g : graph_t): ungültig
Drucke g im Punktformat auf den Ausgabestrom.

schreibenG(g : graph_t, Fanname : Schnur): ungültig
Drucke g im Punktformat in die Datei Fanname.

fwriteG(g : graph_t, fd : int): ungültig
Drucke g im Punktformat auf den offenen Stream, der durch die ganze Zahl gekennzeichnet ist fd.

lesenG(Fanname : Schnur): graph_t
gibt einen aus der Datei gelesenen Graphen zurück Fanname. Die Grafik sollte im Punktformat vorliegen. Wenn nein
Grafik kann gelesen werden, NULL wird zurückgegeben.

freadG(fd : int): graph_t
gibt den nächsten aus dem offenen Stream gelesenen Graphen zurück fd. Kehrt zurück NULL am Ende der Datei.

Graph Sonstiges
löschen(g : graph_t, x : obj_t): ungültig
löscht Objekt x aus der Grafik g. Wenn g is NULL, verwendet die Funktion den Wurzelgraphen von
x. Wenn x ein Graph oder Untergraph ist, ist er geschlossen, es sei denn x ist gesperrt.

ist in(g : graph_t, x : obj_t): int
gibt wahr zurück, wenn x ist im Untergraph g.

KlonG(g : graph_t, s : Schnur): graph_t
erstellt einen Klon von Graph g mit dem Namen von s. Wenn s ist "", hat der erstellte Graph die
gleicher Name wie g.

klonen(g : graph_t, x : obj_t): obj_t
erstellt einen Klon des Objekts x im Diagramm g. Insbesondere hat das neue Objekt die gleichen
Name/Wert-Attribute und Struktur wie das ursprüngliche Objekt. Wenn ein Objekt mit dem
gleicher Schlüssel wie x existiert bereits, seine Attribute werden von denen von . überlagert x und dem
Objekt zurückgegeben wird. Wenn eine Kante geklont wird, werden beide Endpunkte implizit geklont.
Wenn ein Graph geklont wird, werden alle Knoten, Kanten und Untergraphen implizit geklont. Wenn x
ist eine Grafik, g könnte sein NULL, in diesem Fall ist das geklonte Objekt eine neue Wurzel
Graph. In diesem Fall entspricht der Aufruf KlonG(x,"").

Kopieren(g : graph_t, x : obj_t): obj_t
erstellt eine Kopie des Objekts x im Diagramm g, wobei das neue Objekt denselben Namen/Wert hat
Attribute wie das ursprüngliche Objekt. Wenn ein Objekt mit dem gleichen Schlüssel wie x bereits
existiert, seine Attribute werden überlagert von denen von x und das Objekt wird zurückgegeben. Notiz
dass dies eine flache Kopie ist. Wenn x ist ein Graph, keiner seiner Knoten, Kanten oder Teilgraphen
werden in das neue Diagramm kopiert. Wenn x eine Kante ist, werden die Endpunkte erzeugt, wenn
notwendig, aber sie werden nicht geklont. Wenn x ist eine Grafik, g könnte sein NULLin welchem ​​Fall
Das geklonte Objekt wird ein neues Stammdiagramm sein.

KopieA(src : obj_t, tgt : obj_t): int
kopiert die Attribute des Objekts src zu widersprechen tgt, überschreiben alle Attributwerte
tgt anfangs haben kann.

induzieren(g : graph_t): ungültig
erweitert g zu seiner knoteninduzierten Teilgraphenerweiterung in seinem Wurzelgraphen.

hatAttr(src : obj_t, Name : Schnur): int
gibt einen Wert ungleich null zurück, wenn Objekt src hat ein Attribut, dessen Name ist Name. Es gibt 0 zurück
Andernfalls.

istAttr(g : graph_t, Art : Schnur, Name : Schnur): int
gibt einen Wert ungleich null zurück, wenn ein Attribut Name wurde definiert in g für Objekte der
gegeben Art. Für Knoten, Kanten und Graphen gilt: Art sollte "N", "E" und "G" sein,
bzw. Andernfalls wird 0 zurückgegeben.

alter(src : obj_t, Name : Schnur): Schnur
gibt den Wert von Attribut zurück Name im Objekt src. Dies ist für diese Fälle nützlich
wann Name Konflikte mit einem der Schlüsselwörter wie "head" oder "root". Wenn die
Attribut wurde im Graphen nicht deklariert, die Funktion initialisiert es mit
ein Standardwert von "". Um dies zu vermeiden, sollte man die hatAttr or istAttr Funktion
um zu prüfen, ob das Attribut vorhanden ist.

Vermögenswert(src : obj_t, Name : Schnur, Wert : Schnur): int
setzt den Wert des Attributs Name im Objekt src zu Wert. Gibt bei Erfolg 0 zurück,
ungleich Null bei Fehler. Sehen alter zu teilen.

getDflt(g : graph_t, Art : Schnur, Name : Schnur): Schnur
gibt den Standardwert des Attributs zurück Name in Objekten in g des Gegebenen Art. For
Knoten, Kanten und Graphen, Art sollte "N", "E" bzw. "G" sein. Wenn die
Attribut wurde im Graphen nicht deklariert, die Funktion initialisiert es mit
ein Standardwert von "". Um dies zu vermeiden, sollte man die istAttr Funktion zu überprüfen
dass das Attribut existiert.

setDflt(g : graph_t, Art : Schnur, Name : Schnur, Wert : Schnur): int
setzt den Standardwert des Attributs Name zu Wert in Objekten in g des Gegebenen
Art. Für Knoten, Kanten und Graphen gilt: Art sollte "N", "E" bzw. "G" sein.
Gibt bei Erfolg 0 zurück, bei Fehler ungleich Null. Sehen getDflt zu teilen.

fstAttr(g : graph_t, Art : Schnur): Schnur
gibt den Namen des ersten Attributs von Objekten in . zurück g des Gegebenen Art. For
Knoten, Kanten und Graphen, Art sollte "N", "E" bzw. "G" sein. Wenn da
keine Attribute sind, wird der String "" zurückgegeben.

nxtAttr(g : graph_t, Art : Schnur, Name : Schnur): Schnur
gibt den Namen des nächsten Attributs von Objekten in zurück g des Gegebenen Art nach dem
Attribut Name. Das Argument Name muss der Name eines vorhandenen Attributs sein; es
ist normalerweise der Rückgabewert eines vorherigen Aufrufs von fstAttr or nxtAttr. For
Knoten, Kanten und Graphen, Art sollte "N", "E" bzw. "G" sein. Wenn da
Sind keine Attribute mehr vorhanden, wird der String "" zurückgegeben.

compOf(g : graph_t, n : Knoten_t): graph_t
gibt die Zusammenhangskomponente des Graphen zurück g enthaltender Knoten n, als Untergraph von
g. Der Untergraph enthält nur die Knoten. Kann man gebrauchen induzieren um die Kanten hinzuzufügen. Der
Funktion schlägt fehl und kehrt zurück NULL if n ist nicht in g. Die Konnektivität basiert auf dem
zugrunde liegender ungerichteter Graph von g.

So'ne Art(obj : obj_t): Schnur
gibt einen Hinweis auf den Typ von . zurück obj. Für Knoten, Kanten und Graphen liefert es
"N", "E" bzw. "G".

sperren(g : graph_t, v : int): int
implementiert Graph-Locking für Root-Graphen. Wenn die ganze Zahl v positiv ist, ist der Graph
so einstellen, dass zukünftige Anrufe an löschen keine sofortige Wirkung haben. Wenn v ist null, die
Grafik ist freigeschaltet. Wenn ein Aufruf zum Löschen des Diagramms erfolgte, während es war
gesperrt, der Graph ist geschlossen. Wenn v negativ ist, wird nichts unternommen. In allen Fällen ist die
vorheriger Sperrwert wird zurückgegeben.

Streicher
sprintf(fmt : Schnur, realisieren kannst...): Schnur
gibt den String zurück, der sich aus der Formatierung der Werte der Ausdrücke ergibt
auftretend nach fmt nach dem printf(3) Format fmt

gsub(str : Schnur, Klaps : Schnur): Schnur

gsub(str : Schnur, Klaps : Schnur, erwidern : Schnur): Schnur
Rückgabe str mit allen übereinstimmenden Teilzeichenfolgen Klaps gelöscht oder ersetzt durch erwidern,
beziehungsweise.

unten(str : Schnur, Klaps : Schnur): Schnur

unten(str : Schnur, Klaps : Schnur, erwidern : Schnur): Schnur
Rückgabe str mit der ganz linken Teilzeichenfolge übereinstimmend Klaps gelöscht oder ersetzt durch erwidern,
bzw. Am Anfang und Ende dürfen die Zeichen '^' und '$' verwendet werden,
bzw. von Klaps um das Muster am Anfang oder Ende von zu verankern str.

substr(str : Schnur, idx : int): Schnur

substr(str : Schnur, idx : int, len : int): Schnur
gibt die Teilzeichenfolge von zurück str ab Position idx bis zum Ende der Zeichenfolge oder
von Länge len, bzw. Die Indizierung beginnt bei 0. Wenn idx ist negativ oder idx is
größer als die Länge von str, tritt ein schwerwiegender Fehler auf. Ebenso im zweiten
Fall, wenn len ist negativ oder idx + len ist größer als die Länge von str, ein tödlicher
Fehler auftritt.

strcmp(s1 : Schnur, s2 : Schnur): int
bietet die Standard-C-Funktion strcmp(3).

Länge(s : Schnur): int
gibt die Länge des Strings zurück s.

Index(s : Schnur, t : Schnur): int

rindex(s : Schnur, t : Schnur): int
gibt den Index des Zeichens in string zurück s wo die ganz linke (ganz rechts) Kopie
von Schnur t gefunden werden kann, oder -1 wenn t ist kein Teilstring von s.

Spiel(s : Schnur, p : Schnur): int
gibt den Index des Zeichens in string zurück s wo die am weitesten links stehende Übereinstimmung des Musters
p gefunden werden kann, oder -1 wenn kein Teilstring von s Streichhölzer p.

TOUPPER(s : Schnur): Schnur
gibt eine Version von . zurück s wobei die alphabetischen Zeichen in Großbuchstaben umgewandelt werden.

tolower(s : Schnur): Schnur
gibt eine Version von . zurück s wobei die alphabetischen Zeichen in Kleinbuchstaben umgewandelt werden.

Kanon(s : Schnur): Schnur
gibt eine Version von . zurück s geeignet, um als Bezeichner in einer Punktdatei verwendet zu werden.

html(g : graph_t, s : Schnur): Schnur
gibt eine ``magische'' Version von . zurück s als HTML-String. Dies wird normalerweise verwendet, um
Anfügen eines HTML-ähnlichen Labels an ein Diagrammobjekt. Beachten Sie, dass die zurückgegebene Zeichenfolge in lebt
g. Insbesondere wird es freigegeben, wenn g geschlossen ist und als HTML-String fungieren soll,
es muss mit einem Objekt von verwendet werden g. Beachten Sie außerdem, dass die spitze Klammer
Zitate sollten nicht Teil von . sein s. Diese werden hinzugefügt, wenn g ist in konkretem DOT . geschrieben
Format.

ishtml(s : Schnur): int
gibt einen Wert ungleich Null zurück, wenn und nur wenn s ist ein HTML-String.

xOf(s : Schnur): Schnur
gibt die Zeichenfolge "x" wenn s hat die Form "x,y", wo beide x und y sind numerisch.

yOf(s : Schnur): Schnur
gibt die Zeichenfolge "y" wenn s hat die Form "x,y", wo beide x und y sind numerisch.

llOf(s : Schnur): Schnur
gibt die Zeichenfolge "llx,lly" wenn s hat die Form "llx,lly,Urx,Ury", wo alle llx,
lly, Urxund Ury sind numerisch.

urOf(s)
urOf(s : Schnur): Schnur gibt die Zeichenfolge "Urx,Ury" wenn s hat die Form
"llx,lly,Urx,Ury", wo alle llx, lly, Urxund Ury sind numerisch.

sscanf(s : Schnur, fmt : Schnur, realisieren kannst...): int
scannt die Zeichenfolge s, Extrahieren von Werten nach sscanf(3) Format fmtdem „Vermischten Geschmack“. Seine
Werte werden in den folgenden Adressen gespeichert fmt, Adressen mit der Form &v,
woher v ist eine deklarierte Variable des richtigen Typs. Gibt die Anzahl der Elemente zurück
erfolgreich gescannt.

gespalten(s : Schnur, arr : Feld, sep : Schnur): int

gespalten(s : Schnur, arr : Feld): int

Token(s : Schnur, arr : Feld, sep : Schnur): int

Token(s : Schnur, arr : Feld): int
The gespalten Funktion bricht die Zeichenfolge s in Felder, während die Token Funktion
zerlegt die Zeichenfolge in Token. Ein Feld besteht aus allen Nicht-Trennzeichen
zwischen zwei Trennzeichen oder dem Anfang oder Ende der Zeichenfolge. Also, a
Feld kann die leere Zeichenfolge sein. Ein Token ist ein maximaler, nicht leerer Teilstring nicht
ein Trennzeichen enthalten. Die Trennzeichen sind die im
sep Streit. Wenn sep nicht angegeben ist, ist der Standardwert " \t\n". Der
Funktionen geben die Anzahl der Felder oder Token zurück.

Die Felder und Token werden im Argumentarray gespeichert. Das Array muss sein Schnur-
bewertet und, wenn ein Indextyp angegeben ist, muss dieser sein int. Die Einträge sind indiziert
durch aufeinanderfolgende ganze Zahlen, beginnend bei 0. Alle bereits im Array gespeicherten Werte werden
entweder überschrieben werden oder nach der Rückkehr der Funktion noch vorhanden sein.

I / O
drucken(realisieren kannst...): ungültig
drucken( ausdr, realisieren kannst... ) druckt eine String-Darstellung jedes Arguments der Reihe nach auf
stdout, gefolgt von einem Zeilenumbruch.

printf(fmt : Schnur, realisieren kannst...): int

printf(fd : int, fmt : Schnur, realisieren kannst...): int
gibt die Zeichenfolge aus, die sich aus der Formatierung der Werte der folgenden Ausdrücke ergibt
fmt nach dem printf(3) Format fmt. Gibt bei Erfolg 0 zurück. Standardmäßig ist es
druckt auf stdout. Wenn die optionale ganze Zahl fd gegeben ist, wird die Ausgabe auf die geschrieben
offener Stream verbunden mit fd.

scanf(fmt : Schnur, realisieren kannst...): int

scanf(fd : int, fmt : Schnur, realisieren kannst...): int
scannt Werte aus einem Eingabestrom gemäß der scanf(3) Format fmtdem „Vermischten Geschmack“. Seine
Werte werden in den folgenden Adressen gespeichert fmt, Adressen mit der Form &v,
woher v ist eine deklarierte Variable des richtigen Typs. Standardmäßig liest es von
Standard. Wenn die optionale ganze Zahl fd gegeben ist, wird die Eingabe aus dem offenen Stream gelesen
zugeordneten fd. Gibt die Anzahl der erfolgreich gescannten Elemente zurück.

öffnenF(s : Schnur, t : Schnur): int
öffnet die Datei s als I/O-Stream. Das String-Argument t gibt an, wie die Datei ist
geöffnet. Die Argumente sind die gleichen wie bei der C-Funktion öffnen(3). Es kehrt ein . zurück
Ganzzahl, die den Stream angibt, oder -1 im Fehlerfall.

Streams 0, 1 und 2 sind wie gewohnt bereits geöffnet als Standard, stdoutund stderr,
bzw. Seit gvpr darf verwenden Standard Um die Eingabegrafiken zu lesen, sollte der Benutzer
Vermeiden Sie die Verwendung dieses Streams.

schließenF(fd : int): int
schließt den offenen Stream, der durch die ganze Zahl bezeichnet wird fd. Streams 0, 1 und 2 können nicht sein
abgeschlossen. Gibt bei Erfolg 0 zurück.

lesenL(fd : int): Schnur
gibt die nächste aus dem Eingabestrom gelesene Zeile zurück fd. Es gibt die leere Zeichenfolge "" zurück
am Ende der Datei. Beachten Sie, dass das Newline-Zeichen in der zurückgegebenen Zeichenfolge verbleibt.

Mathe
exp(d : doppelt): doppelt
gibt e an die zurück dte Macht.

Log(d : doppelt): doppelt
gibt den natürlichen Logarithmus von . zurück d.

sqrt(d : doppelt): doppelt
gibt die Quadratwurzel des Doppelten zurück d.

pow(d : doppelt, x : doppelt): doppelt
Rückgabe d erhoben zum xte Macht.

cos(d : doppelt): doppelt
gibt den Kosinus von zurück d.

Sünde(d : doppelt): doppelt
gibt den Sinus von zurück d.

atan2(y : doppelt, x : doppelt): doppelt
gibt den Arkustangens von zurück y / x im Bereich -pi bis pi.

MIN(y : doppelt, x : doppelt): doppelt
gibt das Minimum von zurück y und x.

MAX(y : doppelt, x : doppelt): doppelt
gibt das Maximum von zurück y und x.

Assoziativ Arrays
# arr : int
gibt die Anzahl der Elemente im Array zurück arr.

idx in arr : int
gibt 1 zurück, wenn ein Wert für den Index gesetzt wurde idx im Array arr. Es gibt 0 zurück
Andernfalls.

ungesetzt(v : Feld, idx): int
entfernt das von . indizierte Element idx. Es gibt 1 zurück, wenn das Element existierte, andernfalls 0.

ungesetzt(v : Feld): ungültig
initialisiert das Array neu.

Sonstiges
verlassen(v : int): ungültig
Ursachen gvpr mit dem Exit-Code verlassen v.

System(cmd : Schnur): int
bietet die Standard-C-Funktion System(3). Es führt aus cmd in der Shell des Benutzers
Umgebung und gibt den Exit-Status der Shell zurück.

alle(): doppelt
gibt ein pseudozufälliges Double zwischen 0 und 1 zurück.

Sand(): int

Sand(v : int): int
setzt einen Seed für den Zufallszahlengenerator. Das optionale Argument gibt den Startwert an;
wenn es weggelassen wird, wird die aktuelle Zeit verwendet. Der vorherige Seed-Wert wird zurückgegeben.
Sand sollte vor allen Anrufen angerufen werden alle.

Farbex(Farbe : Schnur, fmt : Schnur): Schnur
übersetzt eine Farbe von einem Format in ein anderes. Der Farbe Argument sollte eine Farbe sein
in einer der anerkannten Zeichenfolgendarstellungen. Der fmt Wert sollte einer von . sein
„RGB“, „RGBA“, „HSV“ oder „HSVA“. Im Fehlerfall wird eine leere Zeichenfolge zurückgegeben.

EINGEBAUT VARIABLEN


gvpr stellt bestimmte spezielle, eingebaute Variablen bereit, deren Werte automatisch von . gesetzt werden
gvpr je nach Kontext. Sofern nicht anders angegeben, kann der Benutzer ihre Werte nicht ändern.

$ : obj_t
bezeichnet das aktuelle Objekt (Knoten, Kante, Graph) je nach Kontext. Es ist nicht
verfügbar in START or ENDE Klauseln.

$F : Schnur
ist der Name der aktuellen Eingabedatei.

$G : graph_t
bezeichnet den aktuell verarbeiteten Graphen. Es ist nicht verfügbar in START or ENDE
Klauseln.

$NG : graph_t
bezeichnet den nächsten zu verarbeitenden Graphen. Wenn $NG ist NULL, der aktuelle Graph $G ist
letzte Grafik. Beachten Sie, dass, wenn die Eingabe von stdin kommt, der letzte Graph nicht sein kann
ermittelt, bis das Eingangsrohr geschlossen ist. Es ist nicht verfügbar in START or ENDE
Klauseln, oder wenn die -n Flagge verwendet wird.

$O : graph_t
bezeichnet den Ausgabegraphen. Vor dem Durchqueren des Graphen wird es auf das Ziel initialisiert
Graph. Nach der Durchquerung und alle END_G Aktionen, wenn es sich auf einen nicht leeren Graphen bezieht,
dieser Graph wird auf den Ausgabestream gedruckt. Es ist nur gültig in N, E und END_G
Klauseln. Der Ausgabegraph kann vom Benutzer eingestellt werden.

$T : graph_t
bezeichnet den aktuellen Zielgraphen. Es ist ein Untergraph von $G und ist nur erhältlich in
N, E und END_G Klauseln.

$tgtname : Schnur
bezeichnet den Namen des Zielgraphen. Standardmäßig ist es eingestellt auf "gvpr_result". Wenn
mehrfach verwendet während der Ausführung von gvpr, der Name wird mit einem angehängt
ganze Zahl. Diese Variable kann vom Benutzer eingestellt werden.

$tvroot : Knoten_t
bezeichnet den Startknoten für eine (gerichtete oder ungerichtete) Tiefe‐zuerst oder Breite‐
erste Traversierung des Graphen (vgl. $tvtyp unter). Der Standardwert ist NULL für
jedes Eingabediagramm. Nach der Traversierung an der gegebenen Wurzel, wenn der Wert von $tvroot
geändert hat, beginnt ein neuer Durchlauf mit dem neuen Wert von $tvroot. Auch einstellen
$tvnächster Siehe unten.

$tvnächster : Knoten_t
bezeichnet den nächsten Startknoten für eine (gerichtete oder ungerichtete) Tiefe zuerst oder
Breitendurchquerung des Graphen (vgl. $tvtyp unter). Wenn eine Durchquerung beendet ist
und dem $tvroot wurde nicht zurückgesetzt, aber die $tvnächster wurde eingestellt, aber nicht verwendet, dies
Knoten wird als nächste Auswahl für verwendet $tvroot. Der Standardwert ist NULL für
jedes Eingabediagramm.

$tvege : Kante_t
Bei BFS- und DFS-Traversalen wird dies auf die Kante gesetzt, die verwendet wird, um den Strom zu erreichen
Knoten oder Kante. Am Anfang einer Durchquerung oder bei anderen Durchquerungstypen wird der
Wert ist NULL.

$tvtyp : tvtype_t
zeigt an, wie gvpr durchläuft einen Graphen. Es kann nur einen der konstanten Werte annehmen
mit dem Prävix "TV_", das unten beschrieben wird. TV_flat ist die Vorgabe.

In der zugrunde liegenden Graphenbibliothek cgraph(3), Kanten in ungerichteten Graphen sind gegeben an
willkürliche Richtung. Dies wird für Durchquerungen verwendet, wie z TV_fwderforderlich
gerichtete Kanten.

Argc : int
bezeichnet die Anzahl der Argumente, die durch die -a args Kommandozeilenargument.

ARGV : Schnur Feld
bezeichnet das Array von Argumenten, das durch die -a args Kommandozeilenargument. Der
iDas Argument ist gegeben durch ARGV[i].

EINGEBAUT Konstanten


Es gibt mehrere symbolische Konstanten, die durch . definiert sind gvpr.

NULL : obj_t
eine Null-Objektreferenz, die 0 entspricht.

TV_flat : tvtype_t
eine einfache, flache Durchquerung, bei der Graphobjekte in scheinbar willkürlicher Reihenfolge besucht werden.

TV_ne : tvtype_t
eine Durchquerung, die zuerst alle Knoten besucht, dann alle Kanten.

TV_de : tvtype_t
eine Durchquerung, die zuerst alle Kanten und dann alle Knoten besucht.

TV_dfs : tvtype_t
TV_postdfs : tvtype_t
TV_prepostdfs : tvtype_t
eine Durchquerung des Graphen unter Verwendung einer Tiefensuche auf dem zugrunde liegenden ungerichteten
Graph. Um die Durchquerung zu machen, gvpr überprüft den Wert von $tvroot. Wenn das die hat
gleicher Wert, den er vorher hatte (beim Start wird der vorherige Wert initialisiert
zu NULL.) gvpr sucht einfach nach einem nicht besuchten Knoten und durchquert seinen verbundenen
Komponente. Andererseits, wenn $tvroot geändert hat, wird seine verbundene Komponente
besichtigt werden, vorausgesetzt, es wurde noch nicht besucht oder, wenn $tvroot is NULL, die
die Überfahrt wird gestoppt. Beachten Sie, dass mit TV_dfs und $tvroot, es ist möglich zu erstellen
eine Endlosschleife.

Standardmäßig erfolgt die Durchquerung in Vorbestellung. Das heißt, ein Knoten wird vorher besucht
alle seine unbesuchten Kanten. Für TV_postdfs, alle unbesuchten Kanten eines Knotens sind
vor dem Knoten besucht. Für TV_prepostdfs, ein Knoten wird zweimal besucht, bevor und
nach all seinen unbesuchten Kanten.

TV_fwd : tvtype_t
TV_postfwd : tvtype_t
TV_prepostfwd : tvtype_t
Eine Durchquerung des Graphen unter Verwendung einer Tiefensuche nur auf dem folgenden Graphen
Vorwärtsbögen. Die Wahl der Wurzeln für die Traversierung ist die gleiche wie für beschrieben
TV_dfs Oben. Die unterschiedliche Besuchsreihenfolge von TV_fwd, TV_postfwd
und TV_prepostfwd sind die gleichen wie bei den analogen Durchläufen
TV_dfs, TV_postdfs und TV_prepostdfs.

TV_rev : tvtype_t
TV_postrev : tvtype_t
TV_prepostrev : tvtype_t
Eine Durchquerung des Graphen unter Verwendung einer Tiefensuche nur auf dem folgenden Graphen
umgekehrte Bögen. Die Wahl der Wurzeln für die Traversierung ist die gleiche wie für beschrieben
TV_dfs Oben. Die unterschiedliche Besuchsreihenfolge von TV_rev, TV_postrev
und TV_prepostrev sind die gleichen wie bei den analogen Durchläufen
TV_dfs, TV_postdfs und TV_prepostdfs.

TV_bfs : tvtype_t
Eine Traversierung des Graphen mit einer Breitensuche auf dem Graphen ohne Berücksichtigung der Kante
Richtungen. Siehe den Artikel auf TV_dfs oben für die Rolle von $tvroot.

Beispiele:


gvpr -i 'N[color=="blau"]' Datei.gv

Erzeuge den knoteninduzierten Teilgraphen aller Knoten mit der Farbe Blau.

gvpr -c 'N[color=="blue"]{color = "rot"}' Datei.gv

Machen Sie alle blauen Knoten rot.

START { int n, e; int tot_n = 0; int tot_e = 0; }
BEG_G {
n = nKnoten($G);
e = nKanten($G);
printf ("%D Knoten %d Kanten %s\n", n, e, $G.name);
tot_n += n;
tot_e += e;
}
ENDE { printf ("%D Knoten %d Kanten insgesamt\n", tot_n, tot_e) }

Version des Programms gc.

gvpr -c ""

Gleichwertig nop.

BEG_G { graph_t g = Graph ("verschmelzen", "S"); }
E {
Knoten_t h = Klon(g,$.head);
Knoten_t t = Klon(g,$.tail);
Kante_t e = Kante(t,h,"");
e.Gewicht = e.Gewicht + 1;
}
END_G { $O = g; }

Erzeugt eine strenge Version des Eingabegraphen, wobei das Gewichtungsattribut einer Kante
gibt an, wie viele Kanten aus dem Eingabegraphen die Kante darstellt.

START {node_t n; int Grad[]}
E{Grad[Kopf]++; Grad[Schwanz]++; }
END_G {
für (Grad[n]) {
printf ("grad[%s] = %d\n", n.name, Grad[n]);
}
}

Berechnet die Grade von Knoten mit Kanten.

START {
int i, Einzug;
int gesehen[Zeichenfolge];
ungültig prInd (int cnt) {
für (i = 0; i < cnt; ich++) printf (" ");
}
}
BEG_G {

$tvtyp = TV_prepostfwd;
$tvroot = Knoten($,ARGV[0]);
}
N {
if (gesehen[$.name]) Einzug--;
sonst {
prInd(einrücken);
drucken ($.name);
gesehen[$.name] = 1;
einrücken++;
}
}

Druckt die Tiefendurchquerung des Graphen, beginnend mit dem Knoten, dessen Name ist
ARGV[0], als eingerückte Liste.

UMGEBUNG


GVPRPATH
Durch Doppelpunkte getrennte Liste von Verzeichnissen, die durchsucht werden sollen, um die durch . angegebene Datei zu finden
die Option -f. gvpr hat eine eingebaute Standardliste. Wenn GVPRPATH ist nicht definiert, die
Standardliste wird verwendet. Wenn GVPRPATH beginnt mit Doppelpunkt, die Liste wird gebildet durch
anhängen GVPRPATH in die Standardliste. Wenn GVPRPATH endet mit Doppelpunkt, die Liste ist
gebildet durch Anhängen der Standardliste an GVPRPATH. Andernfalls, GVPRPATH wird verwendet für
Die Liste.

Ersetzen Sie auf Windows-Systemen im vorherigen Absatz ``Doppelpunkt'' durch ``Semikolon''.

Verwenden Sie gvpr online mit den onworks.net-Diensten


Ad


Ad