📄 ws.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * 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. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 KANNEL GROUP OR ITS 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * * ws.c * * Author: Markku Rossi <mtr@iki.fi> * * Copyright (c) 1999-2000 WAPIT OY LTD. * All rights reserved. * * Public entry points to the WMLScript compiler and the main compile * function. * */#include "wsint.h"#include "ws.h"#include "wsstree.h"#include "wsasm.h"/********************* Types and definitions ****************************/#define WS_CHECK_COMPILE_ERROR() \ do { \ if (compiler->errors != 0) { \ if (compiler->errors & WS_ERROR_B_MEMORY) \ result = WS_ERROR_OUT_OF_MEMORY; \ else if (compiler->errors & WS_ERROR_B_SYNTAX) \ result = WS_ERROR_SYNTAX; \ else if (compiler->errors & WS_ERROR_B_SEMANTIC) \ result = WS_ERROR_SEMANTIC; \ else \ /* This shouldn't happen. */ \ result = WS_ERROR; \ goto out; \ } \ } while (0);/********************* Static variables *********************************//* Human readable names for the result codes. */static struct{ WsResult code; char *description;} result_codes[] = { { WS_OK, "success" }, { WS_ERROR_OUT_OF_MEMORY, "out of memory" }, { WS_ERROR_SYNTAX, "syntax error" }, { WS_ERROR_SEMANTIC, "compile error" }, { WS_ERROR_IO, "IO error" }, { WS_ERROR, "error" }, { 0, NULL },};/********************* Prototypes for static functions ******************//* Compile the input stream `input' with the compiler `compiler' and return the byte-code in `output_return' and its length in `output_len_return'. The function returns a WsResult error code describing the success of the compilation. */static WsResult compile_stream(WsCompilerPtr compiler, const char *input_name, WsStream *input, unsigned char **output_return, size_t *output_len_return);/* The default I/O function to send the output to stdout and stderr. The argument `context' must be a `FILE *' file to which the output is written. */static void std_io(const char *data, size_t len, void *context);/* A comparison function for functions entries when sorting them by their usage counts. The function is stable maintaining their original order if their usage counts are equal. */static int sort_functions_cmp(const void *a, const void *b);/********************* Global functions *********************************/WsCompilerPtr ws_create(WsCompilerParams *params){ WsCompilerPtr compiler = ws_calloc(1, sizeof(*compiler)); if (compiler == NULL) return NULL; /* Store user params if specified. */ if (params) compiler->params = *params; /* Basic initialization. */ compiler->magic = COMPILER_MAGIC; if (compiler->params.stdout_cb == NULL) { compiler->params.stdout_cb = std_io; compiler->params.stdout_cb_context = stdout; } if (compiler->params.stderr_cb == NULL) { compiler->params.stderr_cb = std_io; compiler->params.stderr_cb_context = stderr; } return compiler;}void ws_destroy(WsCompilerPtr compiler){ if (compiler == NULL) return; ws_free(compiler);#if WS_MEM_DEBUG if (ws_has_leaks()) ws_dump_blocks();#endif /* WS_MEM_DEBUG */}WsResult ws_compile_file(WsCompilerPtr compiler, const char *input_name, FILE *input, FILE *output){ WsResult result; WsStream *stream; unsigned char *bc; size_t bc_len; /* Initialize the input stream. */ stream = ws_stream_new_file(input, WS_FALSE, WS_FALSE); if (stream == NULL) return WS_ERROR_OUT_OF_MEMORY; result = compile_stream(compiler, input_name, stream, &bc, &bc_len); ws_stream_close(stream); if (result == WS_OK) { /* Store the result to the file. */ if (fwrite(bc, 1, bc_len, output) != bc_len) result = WS_ERROR_IO; ws_bc_data_free(bc); } return result;}WsResult ws_compile_data(WsCompilerPtr compiler, const char *input_name, const unsigned char *input, size_t input_len, unsigned char **output_return, size_t *output_len_return){ WsResult result; WsStream *stream; /* Initialize the input stream. */ stream = ws_stream_new_data_input(input, input_len); if (stream == NULL) return WS_ERROR_OUT_OF_MEMORY; result = compile_stream(compiler, input_name, stream, output_return, output_len_return); ws_stream_close(stream); return result;}void ws_free_byte_code(unsigned char *byte_code){ ws_bc_data_free(byte_code);}const char *ws_result_to_string(WsResult result){ int i; for (i = 0; result_codes[i].description; i++) { if (result_codes[i].code == result) return result_codes[i].description; } return "unknown result code";}/********************* Lexer's memory handling helpers ******************/WsBool ws_lexer_register_block(WsCompiler *compiler, void *ptr){ void **n; if (ptr == NULL) return WS_TRUE; n = ws_realloc(compiler->lexer_active_list, ((compiler->lexer_active_list_size + 1) * sizeof(void *))); if (n == NULL) return WS_FALSE; compiler->lexer_active_list = n; compiler->lexer_active_list[compiler->lexer_active_list_size++] = ptr; return WS_TRUE;}WsBool ws_lexer_register_utf8(WsCompiler *compiler, WsUtf8String *string){ if (!ws_lexer_register_block(compiler, string)) return WS_FALSE; if (!ws_lexer_register_block(compiler, string->data)) { compiler->lexer_active_list_size--; return WS_FALSE; } return WS_TRUE;}void ws_lexer_free_block(WsCompiler *compiler, void *ptr){ int i; if (ptr == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -