Back to index

texmacs  1.0.7.15
pst.c
Go to the documentation of this file.
00001 /*  $Header: /home/cvsroot/dvipdfmx/src/pst.c,v 1.6 2008/01/11 18:04:15 matthias Exp $
00002 
00003     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
00004 
00005     Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
00006     the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
00007 
00008     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014 
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU General Public License for more details.
00019 
00020     You should have received a copy of the GNU General Public License
00021     along with this program; if not, write to the Free Software
00022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00023 */
00024 
00025 #include <string.h>
00026 #include <ctype.h>
00027 
00028 #include "system.h"
00029 #include "mem.h"
00030 #include "error.h"
00031 #include "dpxutil.h"
00032 #include "pst_obj.h"
00033 #include "pst.h"
00034 
00035 
00036 #define TYPE_CHECK(o, t) do { \
00037                              if ((o) == NULL || pst_type_of((o)) != (t)) \
00038                                   ERROR("typecheck: object %p not of type %d.", (o), (t)); \
00039                              } while (0)
00040 
00041 static pst_obj *
00042 pst_parse_any (unsigned char **inbuf, unsigned char *inbufend)
00043 {
00044   unsigned char *data;
00045   unsigned char *cur = *inbuf;
00046   unsigned long  len;
00047 
00048   while (cur < inbufend && !PST_TOKEN_END(cur, inbufend))
00049     cur++;
00050 
00051   len = cur - (*inbuf);
00052   data = NEW(len+1, unsigned char);
00053   memcpy(data, *inbuf, len);
00054   data[len] = '\0';
00055 
00056   *inbuf = cur;
00057   return pst_new_obj(PST_TYPE_UNKNOWN, data);
00058 }
00059 
00060 static void
00061 skip_line (unsigned char **inbuf, unsigned char *inbufend)
00062 {
00063   while (*inbuf < inbufend && **inbuf != '\n' && **inbuf != '\r')
00064     (*inbuf)++;
00065   if (*inbuf < inbufend && **inbuf == '\r')
00066     (*inbuf)++;
00067   if (*inbuf < inbufend && **inbuf == '\n')
00068     (*inbuf)++;
00069 }
00070 
00071 static void
00072 skip_comments (unsigned char **inbuf, unsigned char *inbufend)
00073 {
00074   while (*inbuf < inbufend && **inbuf == '%') {
00075     skip_line(inbuf, inbufend);
00076     skip_white_spaces(inbuf, inbufend);
00077   }
00078 }
00079 
00080 #if 0
00081 static pst_obj *
00082 pst_parse_comment (unsigned char **inbuf, unsigned char *inbufend)
00083 {
00084   unsigned char *data;
00085   unsigned char *cur = *inbuf;
00086   unsigned long  len;
00087 
00088   if (*cur != '%')
00089     return NULL;
00090   
00091   while (cur < inbufend && *cur != '\n' && *cur != '\r')
00092     cur++;
00093   len = cur - (*inbuf);
00094   data = NEW(len+1, unsigned char);
00095   memcpy(data, *inbuf, len);
00096   data[len] = '\0';
00097      
00098   *inbuf = cur;
00099   return pst_new_obj(PST_TYPE_UNKNOWN, data);
00100 }
00101 #endif
00102 
00103 /* NOTE: the input buffer must be null-terminated, i.e., *inbufend == 0 */
00104 pst_obj *
00105 pst_get_token (unsigned char **inbuf, unsigned char *inbufend)
00106 {
00107   pst_obj *obj = NULL;
00108   unsigned char c;
00109 
00110   ASSERT(*inbuf <= inbufend && !*inbufend);
00111 
00112   skip_white_spaces(inbuf, inbufend);
00113   skip_comments(inbuf, inbufend);
00114   if (*inbuf >= inbufend)
00115     return NULL;
00116   c = **inbuf;
00117   switch (c) {
00118 #if 0
00119   case '%':
00120     obj = pst_parse_comment(inbuf, inbufend);
00121     break;
00122 #endif
00123   case '/':
00124     obj = pst_parse_name(inbuf, inbufend);
00125     break;
00126   case '[': case '{': /* This is wrong */
00127     obj = pst_new_mark();
00128     (*inbuf)++;
00129     break;
00130   case '<':
00131     if (*inbuf + 1 >= inbufend)
00132       return NULL;
00133     c = *(*inbuf+1);
00134     if (c == '<') {
00135       obj = pst_new_mark();
00136       *inbuf += 2;
00137     } else if (isxdigit(c))
00138       obj = pst_parse_string(inbuf, inbufend);
00139     else if (c == '~') /* ASCII85 */
00140       obj = pst_parse_string(inbuf, inbufend);
00141     break;
00142   case '(':
00143     obj = pst_parse_string(inbuf, inbufend);
00144     break;
00145   case '>':
00146     if (*inbuf + 1 >= inbufend || *(*inbuf+1) != '>') {
00147       ERROR("Unexpected end of ASCII hex string marker.");
00148     } else  {
00149       char *mark;
00150 
00151       mark = NEW(3, char);
00152       mark[0] = '>'; mark[1] = '>'; mark[2] = '\0';
00153       obj = pst_new_obj(PST_TYPE_UNKNOWN, mark);
00154       (*inbuf) += 2;
00155     }
00156     break;
00157   case ']': case '}': 
00158     {
00159       char *mark;
00160 
00161       mark = NEW(2, char);
00162       mark[0] = c; mark[1] = '\0';
00163       obj = pst_new_obj(PST_TYPE_UNKNOWN, mark);
00164       (*inbuf)++;
00165     }
00166     break;
00167   default:
00168     if (c == 't' || c == 'f')
00169       obj = pst_parse_boolean(inbuf, inbufend);
00170     else if (c == 'n')
00171       obj = pst_parse_null(inbuf, inbufend);
00172     else if (c == '+' || c == '-' || isdigit(c) || c == '.')
00173       obj = pst_parse_number(inbuf, inbufend);
00174     break;
00175   }
00176 
00177   if (!obj) {
00178     obj = pst_parse_any(inbuf, inbufend);
00179   }
00180 
00181   return obj;
00182 }