1/*
2   +----------------------------------------------------------------------+
3   | Zend Engine                                                          |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 2.00 of the Zend license,     |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.zend.com/license/2_00.txt.                                |
11   | If you did not receive a copy of the Zend license and are unable to  |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@zend.com so we can mail you a copy immediately.              |
14   +----------------------------------------------------------------------+
15   | Authors: Andi Gutmans <andi@zend.com>                                |
16   |          Zeev Suraski <zeev@zend.com>                                |
17   +----------------------------------------------------------------------+
18*/
19
20/* $Id$ */
21
22/* This indenter doesn't really work, it's here for no particular reason. */
23
24
25#include "zend.h"
26#include <zend_language_parser.h>
27#include "zend_compile.h"
28#include "zend_indent.h"
29
30#define zendtext LANG_SCNG(yy_text)
31#define zendleng LANG_SCNG(yy_leng)
32
33
34static void handle_whitespace(int *emit_whitespace)
35{
36    unsigned char c;
37    int i;
38
39    for (c=0; c<128; c++) {
40        if (emit_whitespace[c]>0) {
41            for (i=0; i<emit_whitespace[c]; i++) {
42                zend_write((char *) &c, 1);
43            }
44        }
45    }
46    memset(emit_whitespace, 0, sizeof(int)*256);
47}
48
49
50ZEND_API void zend_indent()
51{
52    zval token;
53    int token_type;
54    int in_string=0;
55    int nest_level=0;
56    int emit_whitespace[256];
57    int i;
58    TSRMLS_FETCH();
59
60    memset(emit_whitespace, 0, sizeof(int)*256);
61
62    /* highlight stuff coming back from zendlex() */
63    token.type = 0;
64    while ((token_type=lex_scan(&token TSRMLS_CC))) {
65        switch (token_type) {
66            case T_INLINE_HTML:
67                zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
68                break;
69            case T_WHITESPACE: {
70                    token.type = 0;
71                    /* eat whitespace, emit newlines */
72                    for (i=0; i<LANG_SCNG(yy_leng); i++) {
73                        emit_whitespace[(unsigned char) LANG_SCNG(yy_text)[i]]++;
74                    }
75                    continue;
76                }
77                break;
78            case '"':
79                in_string = !in_string;
80                /* break missing intentionally */
81            default:
82                if (token.type==0) {
83                    /* keyword */
84                    switch (token_type) {
85                        case ',':
86                            ZEND_PUTS(", ");
87                            goto dflt_printout;
88                            break;
89                        case '{':
90                            nest_level++;
91                            if (emit_whitespace['\n']>0) {
92                                ZEND_PUTS(" {\n");
93                                memset(emit_whitespace, 0, sizeof(int)*256);
94                            } else {
95                                ZEND_PUTS("{");
96                            }
97                            break;
98                        case '}':
99                            nest_level--;
100                            if (emit_whitespace['\n']==0) {
101                                ZEND_PUTS("\n");
102                            }
103                            for (i=0; i<nest_level; i++) {
104                                ZEND_PUTS("    ");
105                            }
106                            goto dflt_printout;
107                            break;
108dflt_printout:
109                        default:
110                            if (emit_whitespace['\n']>0) {
111                                for (i=0; i<emit_whitespace['\n']; i++) {
112                                    ZEND_PUTS("\n");
113                                }
114                                memset(emit_whitespace, 0, sizeof(int)*256);
115                                for (i=0; i<nest_level; i++) {
116                                    ZEND_PUTS("    ");
117                                }
118                            } else {
119                                handle_whitespace(emit_whitespace);
120                            }
121                            zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
122                            break;
123                    }
124                } else {
125                    handle_whitespace(emit_whitespace);
126                    if (in_string) {
127                        zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
128                        /* a part of a string */
129                    } else {
130                        zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
131                    }
132                }
133                break;
134        }
135        if (token.type == IS_STRING) {
136            switch (token_type) {
137            case T_OPEN_TAG:
138            case T_CLOSE_TAG:
139            case T_WHITESPACE:
140                break;
141            default:
142                efree(token.value.str.val);
143                break;
144            }
145        }
146        token.type = 0;
147    }
148}
149
150/*
151 * Local variables:
152 * tab-width: 4
153 * c-basic-offset: 4
154 * indent-tabs-mode: t
155 * End:
156 */
157