Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

wserror.c

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /*
00058  *
00059  * wserror.c
00060  *
00061  * Author: Markku Rossi <mtr@iki.fi>
00062  *
00063  * Copyright (c) 1999-2000 WAPIT OY LTD.
00064  *       All rights reserved.
00065  *
00066  * Error and information reporting functions.
00067  *
00068  */
00069 
00070 #include "wsint.h"
00071 
00072 /********************* High-level functions *****************************/
00073 
00074 void ws_info(WsCompilerPtr compiler, char *message, ...)
00075 {
00076     va_list ap;
00077 
00078     if (!compiler->params.verbose)
00079         return;
00080 
00081     ws_puts(WS_STDOUT, "wsc: ");
00082 
00083     va_start(ap, message);
00084     ws_vfprintf(WS_STDOUT, message, ap);
00085     va_end(ap);
00086 
00087     ws_puts(WS_STDOUT, WS_LINE_TERMINATOR);
00088 }
00089 
00090 
00091 void ws_fatal(char *fmt, ...)
00092 {
00093     va_list ap;
00094 
00095     fprintf(stderr, "wsc: fatal: ");
00096 
00097     va_start(ap, fmt);
00098     vfprintf(stderr, fmt, ap);
00099     va_end(ap);
00100 
00101     fprintf(stderr, "\n");
00102 
00103     abort();
00104 }
00105 
00106 
00107 void ws_error_memory(WsCompilerPtr compiler)
00108 {
00109     gw_assert(compiler->magic == COMPILER_MAGIC);
00110 
00111     if (compiler->errors & WS_ERROR_B_MEMORY)
00112         /* We have already reported this error. */
00113         return;
00114 
00115     compiler->errors |= WS_ERROR_B_MEMORY;
00116     ws_puts(WS_STDERR, "wsc: error: out of memory" WS_LINE_TERMINATOR);
00117 }
00118 
00119 
00120 void ws_error_syntax(WsCompilerPtr compiler, WsUInt32 line)
00121 {
00122     gw_assert(compiler->magic == COMPILER_MAGIC);
00123 
00124     if (compiler->errors & WS_ERROR_B_MEMORY)
00125         /* It makes no sense to report syntax errors when we have run out
00126            of memory.  This information is not too valid. */ 
00127         return;
00128 
00129     if (line == 0)
00130         line = compiler->linenum;
00131 
00132     if (compiler->last_syntax_error_line == line)
00133         /* It makes no sense to report multiple syntax errors from the
00134            same line. */ 
00135         return;
00136 
00137     compiler->last_syntax_error_line = line;
00138     compiler->errors |= WS_ERROR_B_SYNTAX;
00139 
00140     ws_fprintf(WS_STDERR, "%s:%u: syntax error" WS_LINE_TERMINATOR,
00141                compiler->input_name, line);
00142 }
00143 
00144 
00145 void ws_src_error(WsCompilerPtr compiler, WsUInt32 line, char *message, ...)
00146 {
00147     va_list ap;
00148 
00149     gw_assert(compiler->magic == COMPILER_MAGIC);
00150 
00151     if (line == 0)
00152         line = compiler->linenum;
00153 
00154     compiler->errors |= WS_ERROR_B_SEMANTIC;
00155 
00156     ws_fprintf(WS_STDERR, "%s:%u: ", compiler->input_name, line);
00157 
00158     va_start(ap, message);
00159     ws_vfprintf(WS_STDERR, message, ap);
00160     va_end(ap);
00161 
00162     ws_puts(WS_STDERR, WS_LINE_TERMINATOR);
00163 
00164     compiler->num_errors++;
00165 }
00166 
00167 
00168 void ws_src_warning(WsCompilerPtr compiler, WsUInt32 line, char *message, ...)
00169 {
00170     va_list ap;
00171 
00172     gw_assert(compiler->magic == COMPILER_MAGIC);
00173 
00174     if (line == 0)
00175         line = compiler->linenum;
00176 
00177     ws_fprintf(WS_STDERR, "%s:%u: warning: ", compiler->input_name, line);
00178 
00179     va_start(ap, message);
00180     ws_vfprintf(WS_STDERR, message, ap);
00181     va_end(ap);
00182 
00183     ws_puts(WS_STDERR, WS_LINE_TERMINATOR);
00184 
00185     compiler->num_errors++;
00186 }
00187 
00188 /********************* Low-level functions ******************************/
00189 
00190 void ws_fprintf(WsIOProc io, void *context, const char *fmt, ...)
00191 {
00192     va_list ap;
00193 
00194     va_start(ap, fmt);
00195     ws_vfprintf(io, context, fmt, ap);
00196     va_end(ap);
00197 }
00198 
00199 
00200 void ws_vfprintf(WsIOProc io, void *context, const char *fmt, va_list ap)
00201 {
00202     int start, i;
00203 
00204     for (start = 0, i = 0; fmt[i]; i++)
00205         if (fmt[i] == '%' && fmt[i + 1]) {
00206             char buf[256];
00207             char *cp;
00208             int ival;
00209             unsigned int uival;
00210             int padder = ' ';
00211             int left = 0;
00212             unsigned int width = 0;
00213 
00214             if (fmt[i + 1] == '%') {
00215                 /* An escaped `%'.  Print leading data including the `%'
00216                           character. */
00217                 i++;
00218                 (*io)(fmt + start, i - start, context);
00219                 start = i + 1;
00220                 continue;
00221             }
00222 
00223             /* An escape sequence. */
00224 
00225             /* Print leading data if any. */
00226             if (i > start)
00227                 (*io)(fmt + start, i - start, context);
00228 
00229             /* We support a minor sub-set of the printf()'s formatting
00230                       capabilities.  Let's see what we got. */
00231             i++;
00232 
00233             /* Alignment? */
00234             if (fmt[i] == '-') {
00235                 left = 1;
00236                 i++;
00237             }
00238 
00239             /* Padding? */
00240             if (fmt[i] == '0') {
00241                 padder = '0';
00242                 i++;
00243             }
00244 
00245             /* Width? */
00246             while ('0' <= fmt[i] && fmt[i] <= '9') {
00247                 width *= 10;
00248                 width += fmt[i++] - '0';
00249             }
00250 
00251             /* Check the format. */
00252             cp = buf;
00253             switch (fmt[i]) {
00254             case 'c':       /* character */
00255                 ival = (int) va_arg(ap, int);
00256 
00257                 snprintf(buf, sizeof(buf), "%c", (char) ival);
00258                 cp = buf;
00259                 break;
00260 
00261             case 's':       /* string */
00262                 cp = va_arg(ap, char *);
00263                 break;
00264 
00265             case 'd':       /* integer */
00266                 ival = va_arg(ap, int);
00267 
00268                 snprintf(buf, sizeof(buf), "%d", ival);
00269                 cp = buf;
00270                 break;
00271 
00272             case 'u':       /* unsigned integer */
00273                 uival = va_arg(ap, unsigned int);
00274 
00275                 snprintf(buf, sizeof(buf), "%u", uival);
00276                 cp = buf;
00277                 break;
00278 
00279             case 'x':       /* unsigned integer in hexadecimal format */
00280                 uival = va_arg(ap, unsigned int);
00281 
00282                 snprintf(buf, sizeof(buf), "%x", uival);
00283                 cp = buf;
00284                 break;
00285 
00286             default:
00287                 ws_fatal("ws_vfprintf(): format %%%c not implemented", fmt[i]);
00288                 break;
00289             }
00290 
00291             if (left)
00292                 /* Output the value left-justified. */
00293                 (*io)(cp, strlen(cp), context);
00294 
00295             /* Need padding? */
00296             if (width > strlen(cp)) {
00297                 /* Yes we need. */
00298                 int amount = width - strlen(cp);
00299 
00300                 while (amount-- > 0)
00301                     ws_fputc(padder, io, context);
00302             }
00303 
00304             if (!left)
00305                 /* Output the value right-justified. */
00306                 (*io)(cp, strlen(cp), context);
00307 
00308             /* Process more. */
00309             start = i + 1;
00310         }
00311 
00312     /* Print trailing data if any. */
00313     if (i > start)
00314         (*io)(fmt + start, i - start, context);
00315 }
00316 
00317 
00318 void ws_puts(WsIOProc io, void *context, const char *str)
00319 {
00320     (*io)(str, strlen(str), context);
00321 }
00322 
00323 
00324 void ws_fputc(int ch, WsIOProc io, void *context)
00325 {
00326     char c = (char) ch;
00327 
00328     (*io)(&c, 1, context);
00329 }
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.