1/*
2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "NFA.h"
28
29#if ENABLE(CONTENT_EXTENSIONS)
30
31#include <wtf/ASCIICType.h>
32#include <wtf/DataLog.h>
33
34namespace WebCore {
35
36namespace ContentExtensions {
37
38#if CONTENT_EXTENSIONS_STATE_MACHINE_DEBUGGING
39void NFA::debugPrintDot() const
40{
41 dataLogF("digraph NFA_Transitions {\n");
42 dataLogF(" rankdir=LR;\n");
43 dataLogF(" node [shape=circle];\n");
44 dataLogF(" {\n");
45
46 for (unsigned i = 0; i < nodes.size(); ++i) {
47 dataLogF(" %d [label=<Node %d", i, i);
48
49 const auto& node = nodes[i];
50
51 if (node.actionStart != node.actionEnd) {
52 dataLogF("<BR/>(Final: ");
53 bool isFirst = true;
54 for (unsigned actionIndex = node.actionStart; actionIndex < node.actionEnd; ++actionIndex) {
55 if (!isFirst)
56 dataLogF(", ");
57 dataLogF("%" PRIu64, actions[actionIndex]);
58 isFirst = false;
59 }
60 dataLogF(")");
61 }
62 dataLogF(">]");
63
64 if (node.actionStart != node.actionEnd)
65 dataLogF(" [shape=doublecircle]");
66 dataLogF(";\n");
67 }
68 dataLogF(" }\n");
69
70 dataLogF(" {\n");
71 for (unsigned i = 0; i < nodes.size(); ++i) {
72 const auto& node = nodes[i];
73
74 HashMap<uint32_t, Vector<uint32_t>, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> transitionsPerTarget;
75
76 for (uint32_t transitionIndex = node.rangesStart; transitionIndex < node.rangesEnd; ++transitionIndex) {
77 const ImmutableCharRange& range = transitions[transitionIndex];
78 for (uint32_t targetIndex = range.targetStart; targetIndex < range.targetEnd; ++targetIndex) {
79 uint32_t target = targets[targetIndex];
80 auto addResult = transitionsPerTarget.add(target, Vector<uint32_t>());
81 addResult.iterator->value.append(transitionIndex);
82 }
83 }
84
85 for (const auto& slot : transitionsPerTarget) {
86 dataLogF(" %d -> %d [label=\"", i, slot.key);
87
88 bool isFirst = true;
89 for (uint32_t rangeIndex : slot.value) {
90 if (!isFirst)
91 dataLogF(", ");
92 else
93 isFirst = false;
94
95 const ImmutableCharRange& range = transitions[rangeIndex];
96 if (range.first == range.last) {
97 if (isASCIIPrintable(range.first))
98 dataLogF("%c", range.first);
99 else
100 dataLogF("%d", range.first);
101 } else {
102 if (isASCIIPrintable(range.first) && isASCIIPrintable(range.last))
103 dataLogF("%c-%c", range.first, range.last);
104 else
105 dataLogF("%d-%d", range.first, range.last);
106 }
107 }
108 dataLogF("\"]\n");
109 }
110
111 for (uint32_t epsilonTargetIndex = node.epsilonTransitionTargetsStart; epsilonTargetIndex < node.epsilonTransitionTargetsEnd; ++epsilonTargetIndex) {
112 uint32_t target = epsilonTransitionsTargets[epsilonTargetIndex];
113 dataLogF(" %d -> %d [label=\"ɛ\"]\n", i, target);
114 }
115 }
116
117 dataLogF(" }\n");
118 dataLogF("}\n");
119}
120#endif
121
122} // namespace ContentExtensions
123
124} // namespace WebCore
125
126#endif // ENABLE(CONTENT_EXTENSIONS)
127