Пример #1
0
//-------------------------------------------------------------------
// PURPOSE:     Load parameters from paramset for script
// PARAMETERS:  fn - full path of script
//              paramset - num of loaded paramset (usually conf.script_param_set)
// RETURN:      1-succesfully applied, 0 - something was failed
//-------------------------------------------------------------------
int load_params_values(const char *fn, int paramset)
{
    // skip if internal script used
    if (fn == NULL || fn[0] == 0) return 0;
    // skip if 'default' parameters requested
    if (paramset == DEFAULT_PARAM_SET) return 0;
    
    if ((paramset < 0) || (paramset > 10)) paramset = 0;
    conf.script_param_set = paramset;
    make_param_filename( MAKE_PARAM_FILENAME, fn, paramset );

    char* buf = load_file(cfg_param_name, 0, 1);
    if (!buf)
        return 0;

    const char* ptr = buf;

    // Initial scan of saved paramset file
    // Ensure all saved params match defaults from script
    // If not assume saved file is invalid and don't load it
    //   may occur if script is changed, or file was saved by a different script with same name
    while (ptr[0]) 
    {
        ptr = skip_whitespace(ptr);
        if (ptr[0]=='@')
        {
            if (strncmp("@param", ptr, 6) == 0) 
            {
                if (!check_param(ptr+6))
                    return 0;
            }
        }
        ptr = skip_eol(ptr);
    }

    // All ok, reset and process file
    ptr = buf;

    while (ptr[0]) 
    {
        ptr = skip_whitespace(ptr);
        if (ptr[0]=='@')
        {
            // Already checked file, so only need to load the @default values
            // @param, @range & @values already set from script
            if (strncmp("@default", ptr, 8)==0)
            {
                process_default(ptr+8);
            }
        }
        ptr = skip_eol(ptr);
    }

    free(buf);

    return 1;
}
Пример #2
0
static inline void skip_preprocessor_dir( wxChar*& cur )
{
    do
    {
        skip_to_eol(cur);

        if ( *(cur-1) != _T('\\') )
            break;

        if ( cur < _gSrcEnd )
            skip_eol( cur );
        else
            break;

    } while(1);
}
Пример #3
0
static int
parse_config(gnc_t gnc, void *closure)
{
    int c;
    char *token;

    c = gnc(closure);
    if(c < 2)
        return -1;

    while(c >= 0) {
        c = skip_whitespace(c, gnc, closure);
        if(c == '\n' || c == '#') {
            c = skip_to_eol(c, gnc, closure);
            continue;
        }
        if(c < 0)
            break;
        c = getword(c, &token, gnc, closure);
        if(c < -1)
            return -1;

        if(strcmp(token, "mode") == 0) {
            char *mtoken;

            c = getword(c, &mtoken, gnc, closure);
            if(c < -1)
                return -1;

            if(strcmp(mtoken, "server") == 0) {
#ifndef NO_SERVER
                client_config = 0;
                if(!server_config)
                    server_config = calloc(1, sizeof(struct server_config));
                if(!server_config)
                    return -1;
#else
                return -1;
#endif
            } else if(strcmp(mtoken, "client") == 0) {
                if(server_config)
                    return -1;
                client_config = 1;
            } else if(strcmp(mtoken, "forwarder") == 0) {
                if(server_config)
                    return -1;
                client_config = 0;
            } else {
                return -1;
            }

            free(mtoken);

            c = skip_eol(c, gnc, closure);
            if(c < -1)
                return -1;
        } else if(strcmp(token, "lease-dir") == 0) {
            char *dir;

            if(!server_config)
                return -1;

            c = getstring(c, &dir, gnc, closure);
            if(c < -1)
                return -1;

            if(dir[0] != '/')
                return -1;

            server_config->lease_dir = dir;
            c = skip_eol(c, gnc, closure);
            if(c < -1)
                return -1;
        } else if(strcmp(token, "prefix") == 0) {
            char *ptoken;
            struct prefix_list *prefix;

            if(!server_config)
                return -1;

            c = getword(c, &ptoken, gnc, closure);
            if(c < -1)
                return -1;

            prefix = parse_prefix(ptoken, PREFIX);

            if(prefix == NULL || prefix->n != 1)
                return -1;

            if(prefix_list_v4(prefix)) {
                unsigned const char zeroes[4] = {0};
                unsigned mask, first, last;
                if(memcmp(server_config->lease_first, zeroes, 4) != 0)
                    return -1;
                mask = 0xFFFFFFFF << (128 - prefix->l[0].plen);
                first =
                    (prefix->l[0].p[12] << 24 |
                     prefix->l[0].p[13] << 16 |
                     prefix->l[0].p[14] << 8 |
                     prefix->l[0].p[15] ) & mask;
                last = first | (~ mask);
                first = htonl(first + 1);
                last = htonl(last - 1);
                memcpy(server_config->lease_first, &first, 4);
                memcpy(server_config->lease_last, &last, 4);
                free(prefix);
            } else {
                server_config->ipv6_prefix =
                    cat_prefix_list(server_config->ipv6_prefix,
                                    prefix);
            }
            free(ptoken);
            c = skip_eol(c, gnc, closure);
            if(c < -1)
                return -1;
        } else if(strcmp(token, "name-server") == 0 ||
                  strcmp(token, "ntp-server") == 0) {
            char *ptoken;
            struct prefix_list *prefix;

            if(!server_config)
                return -1;

            c = getword(c, &ptoken, gnc, closure);
            if(c < -1)
                return -1;

            prefix = parse_prefix(ptoken, ADDRESS);

            if(prefix == NULL)
                return -1;

            if(strcmp(token, "name-server") == 0)
                server_config->name_server =
                    cat_prefix_list(server_config->name_server,
                                    prefix);
            else
                server_config->ntp_server =
                    cat_prefix_list(server_config->ntp_server,
                                    prefix);
            free(ptoken);
        } else {
            return -1;
        }
        free(token);
    }
    return 1;
}
Пример #4
0
int split_patch(struct stream f, struct stream *f1, struct stream *f2)
{
	struct stream r1, r2;
	int chunks = 0;
	char *cp, *end;
	int state = 0;
	int acnt = 0, bcnt = 0;
	int a, b, c, d;
	int lineno = 0;
	char before[100], after[100];
	char func[100];

	f1->body = f2->body = NULL;

	r1.body = xmalloc(f.len);
	r2.body = xmalloc(f.len);
	r1.len = r2.len = 0;
	func[0] = 0;

	cp = f.body;
	end = f.body+f.len;
	while (cp < end) {
		/* state:
		 *   0   not in a patch
		 *   1   first half of context
		 *   2   second half of context
		 *   3   unified
		 */
		lineno++;
		switch (state) {
		case 0:
			if (sscanf(cp, "@@ -%99s +%99s @@%99[^\n]", before, after, func) >= 2) {
				int ok = 1;
				if (sscanf(before, "%d,%d", &a, &b) == 2)
					acnt = b;
				else if (sscanf(before, "%d", &a) == 1)
					acnt = 1;
				else
					ok = 0;

				if (sscanf(after, "%d,%d", &c, &d) == 2)
					bcnt = d;
				else if (sscanf(after, "%d", &c) == 1)
					bcnt = 1;
				else
					ok = 0;
				if (ok)
					state = 3;
				else
					state = 0;
			} else if (sscanf(cp, "*** %d,%d ****", &a, &b) == 2) {
				acnt = b-a+1;
				state = 1;
			} else if (sscanf(cp, "--- %d,%d ----", &c, &d) == 2) {
				bcnt = d-c+1;
				state = 2;
			} else
				sscanf(cp, "***************%99[^\n]", func);

			skip_eol(&cp, end);
			if (state == 1 || state == 3) {
				char *f;
				char buf[20];
				buf[0] = 0;
				chunks++;
				sprintf(buf+1, "%5d %5d %5d", chunks, a, acnt);
				memcpy(r1.body+r1.len, buf, 18);
				r1.len += 18;
				f = func;
				while (*f == ' ')
					f++;
				if (*f) {
					r1.body[r1.len++] = ' ';
					strcpy(r1.body + r1.len, f);
					r1.len += strlen(f);
				}
				r1.body[r1.len++] = '\n';
				r1.body[r1.len++] = '\0';
			}
			if (state == 2 || state == 3) {
				char buf[20];
				buf[0] = 0;
				sprintf(buf+1, "%5d %5d %5d\n", chunks, c, bcnt);
				memcpy(r2.body+r2.len, buf, 20);
				r2.len += 20;
			}
			if (state)
				func[0] = 0;
			break;
		case 1:
			if ((*cp == ' ' || *cp == '!' || *cp == '-' || *cp == '+')
			    && cp[1] == ' ') {
				cp += 2;
				copyline(&r1, &cp, end);
				acnt--;
				if (acnt == 0)
					state = 0;
			} else {
				fprintf(stderr, "%s: bad context patch at line %d\n",
					Cmd, lineno);
				return 0;
			}
			break;
		case 2:
			if ((*cp == ' ' || *cp == '!' || *cp == '-' || *cp == '+')
			    && cp[1] == ' ') {
				cp += 2;
				copyline(&r2, &cp, end);
				bcnt--;
				if (bcnt == 0)
					state = 0;
			} else {
				fprintf(stderr, "%s: bad context patch/2 at line %d\n",
					Cmd, lineno);
				return 0;
			}
			break;
		case 3:
			if (*cp == ' ') {
				char *cp2;
				cp++;
				cp2 = cp;
				copyline(&r1, &cp, end);
				copyline(&r2, &cp2, end);
				acnt--; bcnt--;
			} else if (*cp == '-') {
				cp++;
				copyline(&r1, &cp, end);
				acnt--;
			} else if (*cp == '+') {
				cp++;
				copyline(&r2, &cp, end);
				bcnt--;
			} else {
				fprintf(stderr, "%s: bad unified patch at line %d\n",
					Cmd, lineno);
				return 0;
			}
			if (acnt <= 0 && bcnt <= 0)
				state = 0;
			break;
		}
	}
	if (r1.len > f.len || r2.len > f.len)
		abort();
	*f1 = r1;
	*f2 = r2;
	return chunks;
}
Пример #5
0
/*
 * extract parts of a "diff3 -m" or "wiggle -m" output
 */
int split_merge(struct stream f, struct stream *f1, struct stream *f2, struct stream *f3)
{
	int state = 0;
	char *cp, *end;
	struct stream r1, r2, r3;
	f1->body = NULL;
	f2->body = NULL;

	r1.body = xmalloc(f.len);
	r2.body = xmalloc(f.len);
	r3.body = xmalloc(f.len);
	r1.len = r2.len = r3.len = 0;

	cp = f.body;
	end = f.body+f.len;
	while (cp < end) {
		/* state:
		 *  0 not in conflict
		 *  1 in file 1 of conflict
		 *  2 in file 2 of conflict
		 *  3 in file 3 of conflict
		 *  4 in file 2 but expecting 1/3 next
		 *  5 in file 1/3
		 */
		int len = end-cp;
		switch (state) {
		case 0:
			if (len >= 8 &&
			    strncmp(cp, "<<<<<<<", 7) == 0 &&
			    (cp[7] == ' ' || cp[7] == '\n')
				) {
				char *peek;
				state = 1;
				skip_eol(&cp, end);
				/* diff3 will do something a bit strange in
				 * the 1st and 3rd sections are the same.
				 * it reports
				 * <<<<<<<
				 * 2nd
				 * =======
				 * 1st and 3rd
				 * >>>>>>>
				 * Without a ||||||| at all.
				 * so to know if we are in '1' or '2', skip forward
				 * having a peek.
				 */
				peek = cp;
				while (peek < end) {
					if (end-peek >= 8 &&
					    (peek[7] == ' ' || peek[7] == '\n')) {
						if (strncmp(peek, "|||||||", 7) == 0 ||
						    strncmp(peek, ">>>>>>>", 7) == 0)
							break;
						else if (strncmp(peek, "=======", 7) == 0) {
							state = 4;
							break;
						}
					}
					skip_eol(&peek, end);
				}
			} else {
				char *cp2 = cp;
				copyline(&r1, &cp2, end);
				cp2 = cp;
				copyline(&r2, &cp2, end);
				copyline(&r3, &cp, end);
			}
			break;
		case 1:
			if (len >= 8 &&
			    strncmp(cp, "|||||||", 7) == 0 &&
			    (cp[7] == ' ' || cp[7] == '\n')
				) {
				state = 2;
				skip_eol(&cp, end);
			} else
				copyline(&r1, &cp, end);
			break;
		case 2:
			if (len >= 8 &&
			    strncmp(cp, "=======", 7) == 0 &&
			    (cp[7] == ' ' || cp[7] == '\n')
				) {
				state = 3;
				skip_eol(&cp, end);
			} else
				copyline(&r2, &cp, end);
			break;
		case 3:
			if (len >= 8 &&
			    strncmp(cp, ">>>>>>>", 7) == 0 &&
			    (cp[7] == ' ' || cp[7] == '\n')
				) {
				state = 0;
				skip_eol(&cp, end);
			} else
				copyline(&r3, &cp, end);
			break;
		case 4:
			if (len >= 8 &&
			    strncmp(cp, "=======", 7) == 0 &&
			    (cp[7] == ' ' || cp[7] == '\n')
				) {
				state = 5;
				skip_eol(&cp, end);
			} else
				copyline(&r2, &cp, end);
			break;
		case 5:
			if (len >= 8 &&
			    strncmp(cp, ">>>>>>>", 7) == 0 &&
			    (cp[7] == ' ' || cp[7] == '\n')
				) {
				state = 0;
				skip_eol(&cp, end);
			} else {
				char *t = cp;
				copyline(&r1, &t, end);
				copyline(&r3, &cp, end);
			}
			break;
		}
	}
	if (cp > end)
		abort();
	*f1 = r1;
	*f2 = r2;
	*f3 = r3;
	return state == 0;
}
Пример #6
0
static inline void skip_comments( char*& cur )
{
    ++cur; // skip '/' token

    if ( *cur != '/' && *cur != '*' ) return;

    // first, store position of the comment into the queue
    // (which further will be attached to the next context
    //  found)

    if ( cur-1 != _gLastSuppresedComment )
    {
        if ( _gCQSize == MAX_CQ_ENTRIES )
        {
            size_t i = MAX_CQ_ENTRIES-1;

            while( i != 0 )
            {
                _gCommentsQueue[i-1] = _gCommentsQueue[i];
                --i;
            }

            --_gCQSize ;
        }

        _gCommentsQueue[_gCQSize++] = cur-1;
    }

    // if signle-line comment, skip it now
    if ( *cur == '/' )
    {
        skip_to_eol( cur );
        skip_eol( cur );
        return;
    }

    size_t level = 1;

    // check for multiline comment (handle nested multiline comments!)

    int line_len = 0;

    ++cur;
    ++cur;
    do
    {
        // TBD:: check eof cond.

        // detect and remove vertical columns of '*''s

        while ( *cur != '/' && cur < _gSrcEnd )
        {
            switch (*cur)
            {
                case '*' :
                    {
                        if ( *(cur+1) != '/' )
                        {
                            if ( line_len == 1 )

                                *cur = ' ';
                        }

                        break;
                    }

                case 13 : line_len = 0; break;
                case 10 : { line_len = 0; ++_gLineNo; } break;

                default : ++line_len;
            }

            ++cur;
        }

        if ( cur >= _gSrcEnd  ) return;

        ++cur;

        if ( *(cur-2) == '*' )
        {
            --level;
            if ( level == 0 )
                break;
        }
        else
        if ( *cur == '*' )
        {
            ++cur;
            ++cur;

            ++level;
        }

    } while(1);
}
Пример #7
0
void CJSourceParser::AddMacroNode( wxChar*& cur )
{
    wxChar* start = cur;

    int lineNo = get_line_no();

    skip_preprocessor_dir( cur );

    int tmpLnNo;
    store_line_no( tmpLnNo );

    if ( !mMacrosOn ) return;

    spPreprocessorLine* pPL = new spPreprocessorLine();
    pPL->mSrcLineNo = lineNo;

    AttachComments( *pPL, cur );

    get_string_between( start, cur, &pPL->m_Line );

    ++start; // skip '#'
    get_next_token( start );

    pPL->mDefType = SP_PREP_DEF_OTHER;

    // if we found a definition or redefinition,
    // determine the type exactly and assign
    // a name to the context

    if ( *start == _T('d') )
    {
        if ( cmp_tokens_fast( start, _T("define"), 6 ) )
        {
            char* tok = start+6;

            get_next_token( tok );

            pPL->m_Name = get_token_str( tok );

            skip_token( tok );
            get_next_token( tok);


            if ( tok > cur )
                pPL->mDefType = SP_PREP_DEF_DEFINE_SYMBOL;
            else
                pPL->mDefType = SP_PREP_DEF_REDEFINE_SYMBOL;
        }
    }
    else if ( *start == _T('i') )
    {
        if ( cmp_tokens_fast( start, _T("include"), 7 ) )
        {
            pPL->mDefType = SP_PREP_DEF_INCLUDE_FILE;
        }
        else if ( *++start == _T('f') )
        {
            // either "#if" or "#ifdef"
            cur = start;
            skip_token( cur );
            get_next_token( cur );

            wxString condition = get_token_str( cur );

            // currently, everything except '0' is true
            if ( condition == _T("0") ) {
                // skip until the following else or enif
                while ( cur < _gSrcEnd ) {
                    skip_to_eol( cur );
                    skip_eol( cur );

                    get_next_token( cur );
                    if ( *cur++ == _T('#') && *cur == _T('e') )
                        break;
                }
            }

            // TODO parse the condition...
        }
    }
    else if ( cmp_tokens_fast( start, _T("else"), 4 ) )
    {
        // skip until "#endif"
        while ( cur < _gSrcEnd ) {
            skip_to_eol( cur );
            skip_eol( cur );

            get_next_token( cur );
            if ( *cur++ == _T('#') && cmp_tokens_fast( cur, "endif", 5 ) )
                break;
        }
    }

    mpCurCtx->AddMember( pPL );

    skip_to_eol( cur );
    skip_eol( cur );

    restore_line_no( tmpLnNo );

    clear_commets_queue();
}
Пример #8
0
/*
 * Name:    differ
 * Purpose: diff text pointers
 * Date:    October 31, 1992
 * Passed:  initial_rcol1:  beginning column to begin diff in window1
 *          initial_rcol2:  beginning column to begin diff in window2
 *          bottom:         line to display diagnostics
 * Notes:   a straight diff on text pointers is simple; however, diffing
 *            with leading spaces and tabs is kinda messy.  let's do the
 *            messy diff.
 */
int  differ( int initial_rcol1, int initial_rcol2, int bottom )
{
int  rcol1;             /* virtual real column on diff window 1 */
int  rcol2;             /* virtual real column on diff window 2 */
int  r1;                /* real real column rcol1 - needed for tabs */
int  r2;                /* real real column rcol2 - needed for tabs */
char c1;                /* character under r1 */
char c2;                /* character under r2 */
int  leading1;          /* adjustment for leading space in window 1 */
int  leading2;          /* adjustment for leading space in window 2 */
int  len1;              /* length of diff1 line */
int  len2;              /* length of diff2 line */
line_list_ptr node1;    /* scratch node in window 1 */
line_list_ptr node2;    /* scratch node in window 2 */
text_ptr diff1;         /* scratch text ptr in window 1 */
text_ptr diff2;         /* scratch text ptr in window 2 */
long rline1;            /* real line number of diff pointer 1 */
long rline2;            /* real line number of diff pointer 2 */
long bin_offset1;       /* binary offset of diff pointer 1 */
long bin_offset2;       /* binary offset of diff pointer 2 */
int  len;               /* line length variable */
register int tabs;      /* local variable for mode.inflate_tabs, T or F */
char line_buff[(MAX_COLS+1)*2];  /* buffer for char and attribute  */

   /*
    * initialize the text pointers and the initial column.  skip any
    *  initial blank lines.
    */
   rline1 = diff.rline1;
   rline2 = diff.rline2;
   node1 = diff.d1;
   node2 = diff.d2;
   bin_offset1 = diff.bin_offset1;
   bin_offset2 = diff.bin_offset2;
   tabs  = mode.inflate_tabs;
   if (diff.blank_lines) {
      while (node1->len != EOF  && is_line_blank( node1->line, node1->len )) {
         bin_offset1 += node1->len;
         node1 = node1->next;
         ++rline1;
         initial_rcol1 = 0;
      }
      while (node2->len != EOF  && is_line_blank( node2->line , node2->len)) {
         bin_offset2 += node2->len;
         node2 = node2->next;
         ++rline2;
         initial_rcol2 = 0;
      }
   }

   /*
    * if everything is everything, initialize the diff variables and diff.
    */
   if (node1->len != EOF  &&  node2->len != EOF) {
      diff1 = node1->line;
      diff2 = node2->line;
      rcol1 = initial_rcol1;
      rcol2 = initial_rcol2;
      len1  = node1->len;
      len2  = node2->len;

      assert( rcol1 >= 0 );
      assert( rcol1 < MAX_LINE_LENGTH );
      assert( rcol2 >= 0 );
      assert( rcol2 < MAX_LINE_LENGTH );
      assert( len1 >= 0 );
      assert( len1 < MAX_LINE_LENGTH );
      assert( len2 >= 0 );
      assert( len2 < MAX_LINE_LENGTH );

      /*
       * if cursors are past EOL, move them back to EOL.
       */
      len = find_end( diff1, len1 );
      if (rcol1 > len)
         rcol1 = len;
      len = find_end( diff2, len2 );
      if (rcol2 > len)
         rcol2 = len;

      /*
       * if skip leading space, make sure our cursors start on first non-space.
       */
      if (diff.leading) {
         leading1 = skip_leading_space( diff1, len1 );
         leading2 = skip_leading_space( diff2, len2 );
         if (tabs) {
            leading1 = detab_adjust_rcol( diff1, leading1 );
            leading2 = detab_adjust_rcol( diff2, leading2 );
         }
         if (rcol1 < leading1)
            rcol1 = leading1;
         if (rcol2 < leading2)
            rcol2 = leading2;
      }

      /*
       * we now have a valid rcol for the diff start, we may need to adjust
       *   for tabs, though.
       */
      assert( rcol1 >= 0 );
      assert( rcol1 < MAX_LINE_LENGTH );
      assert( rcol2 >= 0 );
      assert( rcol2 < MAX_LINE_LENGTH );

      r1 =  tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
      r2 =  tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;

      assert( r1 >= 0 );
      assert( r1 <= len1 );
      assert( r2 >= 0 );
      assert( r2 <= len2 );
      assert( r1 <= rcol1 );
      assert( r2 <= rcol2 );

      s_output( diff_message, g_display.mode_line, 67, g_display.diag_color );
      while (node1->len != EOF  &&  node2->len != EOF  &&
                         !g_status.control_break) {

         /*
          * look at each character in each diff window
          */
         c1 = (char)(r1 < len1 ? *(diff1 + r1)  : 0);
         c2 = (char)(r2 < len2 ? *(diff2 + r2)  : 0);

         /*
          *  tabs == space
          */
         if (tabs) {
            if (c1 == '\t')
               c1 = ' ';
            if (c2 == '\t')
               c2 = ' ';
         }

         /*
          * skip spaces, if needed
          */
         if (diff.all_space) {
            while (c1 == ' '  &&  r1 < len1) {
               ++rcol1;
               r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
               c1 =  (char)(r1 < len1  ?  *(diff1 + r1) :  0);
               if (c1 == '\t'  &&  tabs)
                  c1 = ' ';
            }
            while (c2 == ' '  &&  r2 < len2) {
               ++rcol2;
               r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;
               c2 =  (char)(r2 < len2  ? *(diff2 + r2) : 0);
               if (c2 == '\t'  &&  tabs)
                  c2 = ' ';
            }
         }

         /*
          * if one of the node pointers has come to EOL, move to next
          *   diff line.
          */
         if (diff.ignore_eol) {
            if (r1 >= len1) {
               node1 = skip_eol( node1, &r1, &rcol1, &rline1, &bin_offset1 );
               len1  = node1->len;
               if (len1 != EOF) {
                  diff1 = node1->line;
                  c1 =  (char)(r1 < len1  ?  *(diff1 + r1) : 0);
                  if (c1 == '\t'  &&  tabs)
                     c1 = ' ';
               }
            }
            if (r2 >= len2) {
               node2 = skip_eol( node2, &r2, &rcol2, &rline2, &bin_offset2 );
               len2  = node2->len;
               if (len2 != EOF) {
                  diff2 = node2->line;
                  c2 =  (char)(r2 < len2  ? *(diff2 + r2)  :  0);
                  if (c2 == '\t'  &&  tabs)
                     c2 = ' ';
               }
            }
         }

         /*
          * convert the characters to lower case, if needed.
          */
         if (mode.search_case == IGNORE) {
            c1 = (char)tolower( c1 );
            c2 = (char)tolower( c2 );
         }

         /*
          * diff each character in the diff lines until we reach EOL
          */
         while (r1 < len1  && r2 < len2) {
            if (c1 == c2) {
               if (diff.all_space) {
                  do {
                     ++rcol1;
                     r1 = tabs ? entab_adjust_rcol( diff1,len1,rcol1 ) : rcol1;
                     c1 =  (char)(r1 < len1  ?  *(diff1 + r1)  :  0);
                     if (c1 == '\t'  &&  tabs)
                        c1 = ' ';
                  } while (c1 == ' '  &&  r1 < len1);
                  do {
                     ++rcol2;
                     r2 = tabs ? entab_adjust_rcol( diff2,len2,rcol2 ) : rcol2;
                     c2 =  (char)(r2 < len2  ?  *(diff2 + r2)  :  0);
                     if (c2 == '\t'  &&  tabs)
                        c2 = ' ';
                  } while (c2 == ' '  &&  r2 < len2);
               } else {
                  ++rcol1;
                  ++rcol2;
                  r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
                  r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;
                  c1 =  (char)(r1 < len1  ?  *(diff1 + r1)  :  0);
                  c2 =  (char)(r2 < len2  ?  *(diff2 + r2)  :  0);
                  if (tabs) {
                     if (c1 == '\t')
                        c1 = ' ';
                     if (c2 == '\t')
                        c2 = ' ';
                  }
               }
               if (diff.ignore_eol) {
                  if (r1 >= len1) {
                     node1 = skip_eol(node1, &r1, &rcol1, &rline1,&bin_offset1);
                     len1  = node1->len;
                     if (len1 != EOF) {
                        diff1 = node1->line;
                        c1 =  (char)(r1 < len1  ?  *(diff1 + r1)  : 0);
                        if (c1 == '\t'  &&  tabs)
                           c1 = ' ';
                     }
                  }
                  if (r2 >= len2) {
                     node2 = skip_eol(node2, &r2, &rcol2, &rline2,&bin_offset2);
                     len2  = node2->len;
                     if (len2 != EOF) {
                        diff2 = node2->line;
                        c2 = (char)(r2 < len2  ? *(diff2 + r2)  :  0);
                        if (c2 == '\t'  &&  tabs)
                           c2 = ' ';
                     }
                  }
               }
               if (mode.search_case == IGNORE) {
                  c1 = (char)tolower( c1 );
                  c2 = (char)tolower( c2 );
               }
            } else {

               /*
                * when we show the diff, use rcol1 and rcol2, as
                *   find_adjust does not adjust rcol for tabs.
                */
               update_line( diff.w1 );
               diff.w1->bin_offset = bin_offset1;
               find_adjust( diff.w1, node1, rline1, rcol1 );
               check_virtual_col( diff.w1, rcol1, rcol1 );
               show_diff_window( diff.w1 );
               update_line( diff.w2 );
               diff.w2->bin_offset = bin_offset2;
               bin_offset_adjust( diff.w2, rline2 );
               find_adjust( diff.w2, node2, rline2, rcol2 );
               check_virtual_col( diff.w2, rcol2, rcol2 );
               show_diff_window( diff.w2 );
               s_output( diff_blank, g_display.mode_line, 67,
                         g_display.mode_color );
               return( OK );
            }
         }

         /*
          * if we haven't come to the end of a file buffer, check the last
          *   characters.  see if pointers are at EOL.
          */
         if (node1->len != EOF && node2->len != EOF) {
            if (rcol1 != len1  &&  rcol2 != len2) {
               update_line( diff.w1 );
               diff.w1->bin_offset = bin_offset1;
               find_adjust( diff.w1, node1, rline1, rcol1 );
               show_diff_window( diff.w1 );
               update_line( diff.w2 );
               diff.w2->bin_offset = bin_offset2;
               find_adjust( diff.w2, node2, rline2, rcol2 );
               show_diff_window( diff.w2 );
               s_output( diff_blank, g_display.mode_line, 67,
                         g_display.mode_color );
               return( OK );
            } else {
               node1 = skip_eol( node1, &r1, &rcol1, &rline1, &bin_offset1 );
               len1  = node1->len;
               diff1 = node1->line;
               node2 = skip_eol( node2, &r2, &rcol2, &rline2, &bin_offset2 );
               len2  = node2->len;
               diff2 = node2->line;
            }
         }

         assert( rcol1 >= 0 );
         assert( rcol1 < MAX_LINE_LENGTH );
         assert( rcol2 >= 0 );
         assert( rcol2 < MAX_LINE_LENGTH );
         assert( r1 >= 0 );
         assert( r1 < MAX_LINE_LENGTH );
         assert( r2 >= 0 );
         assert( r2 < MAX_LINE_LENGTH );
         assert( r1 <= rcol1 );
         assert( r2 <= rcol2 );
         if (node1->len == EOF)
            assert( len1 == EOF );
         else {
            assert( len1 >= 0 );
            assert( len1 < MAX_LINE_LENGTH );
         }
         if (node2->len == EOF)
            assert( len2 == EOF );
         else {
            assert( len2 >= 0 );
            assert( len2 < MAX_LINE_LENGTH );
         }
      }
      save_screen_line( 0, bottom, line_buff );
      set_prompt( diff_prompt4, bottom );
      getkey( );
      restore_screen_line( 0, bottom, line_buff );
      s_output( diff_blank, g_display.mode_line, 67, g_display.mode_color );
   }
   return( ERROR );
}
Пример #9
0
static void dodel(const char *username, const char *userhome,
	FILE *c, char *ctl,
	const char *extension, const char *sender, const char *receipient,
	const char *defaultext, const char *quota, const char *defaultmail,
	int recursion_level)
{
char	*ufromline;
char	*dtline;
char	*rpline;
time_t	t;
const char *curtime;

	time(&t);
	curtime=ctime(&t);
	if ((ufromline=malloc(strlen(curtime)+strlen(sender)+30))==0||
		(dtline=malloc(strlen(receipient)+
			sizeof("Delivered-To: "))) == 0 ||
		(rpline=malloc(strlen(sender) +
			sizeof("Return-Path: <>"))) == 0)
	{
		perror("malloc");
		exit(EX_TEMPFAIL);
	}

	if ( (!ctl || !*ctl) && recursion_level == 0)
	{
	const char *p= *defaultmail ? defaultmail:config_defaultdelivery();

		if ((ctl=malloc(strlen(p)+1)) == 0)
		{
			perror("malloc");
			exit(EX_TEMPFAIL);
		}
		strcpy(ctl, p);
	}

	sprintf(ufromline, "From %s %s", sender, curtime);

	{
	char *p;

		if ((p=strchr(ufromline, '\n')) != 0)
			*p=0;
	}

	strcat(strcpy(dtline, "Delivered-To: "), receipient);
	strcat(strcat(strcpy(rpline, "Return-Path: <"), sender), ">");

	while (*ctl)
	{
		if (*ctl == '#' || *ctl == '\n')
		{
			while (*ctl)
				if (*ctl++ == '\n')	break;
			continue;
		}

		/*
		** The fd hack is needed for BSD, whose C lib doesn't like
		** mixing stdio and unistd seek calls.
		*/

		if (*ctl == '.' || *ctl == '/')
		{
		const char *filename=ctl;
		int fd_hack=dup(fileno(stdin));
		FILE *fp_hack;

			if (fd_hack < 0 || lseek(fd_hack, 0L, SEEK_SET) < 0 ||
				(fp_hack=fdopen(fd_hack, "r")) == NULL)
			{
				perror("dup");
				exit(EX_TEMPFAIL);
			}

			while (*ctl)
			{
				if (*ctl == '/' && (ctl[1] == '\n' ||
					ctl[1] == 0))
					*ctl=0; /* Strip trailing / */
				if (*ctl == '\n')
				{
					*ctl++='\0';
					break;
				}
				++ctl;
			}

			if (savemessage(extension, sender, receipient,
				fp_hack, filename,
				ufromline,
				dtline,
				rpline, quota))
				exit(EX_TEMPFAIL);
			fclose(fp_hack);
			close(fd_hack);
			continue;
		}
		if (*ctl == '|')
		{
		const char *command=++ctl;
		int	rc;
		int fd_hack=dup(fileno(stdin));
		FILE *fp_hack;

			if (fd_hack < 0 || lseek(fd_hack, 0L, SEEK_SET) < 0 ||
				(fp_hack=fdopen(fd_hack, "r")) == NULL)
			{
				perror("dup");
				exit(EX_TEMPFAIL);
			}

			ctl=skip_eol(ctl, 0);
			while (*command == ' ' || *command == '\t')
				++command;

			rc=docommand(extension, sender, receipient, defaultext,
				fp_hack, username, userhome, command,
				dtline,
				rpline,
				ufromline,
				quota, defaultmail,
				recursion_level);
			if (rc)
				exit(rc);
			fclose(fp_hack);
			close(fd_hack);
			continue;
		}

		/* Forwarding instructions, parse RFC822 addresses */

		if (*ctl == '&' || *ctl == '!')	++ctl;	/* Legacy */
		{
			const char *addresses=ctl;
			struct rfc822t *tokens;
			struct rfc822a *addrlist;
			int n;

			ctl=skip_eol(ctl, 1);
			if ((tokens=rfc822t_alloc_new(addresses, NULL,
						      NULL)) == 0 ||
				(addrlist=rfc822a_alloc(tokens)) == 0)
			{
				perror("malloc");
				exit(EX_TEMPFAIL);
			}

			for (n=0; n<addrlist->naddrs; ++n)
			{
				char *p;

				if (addrlist->addrs[n].tokens == NULL)
					continue;

				p=rfc822_display_addr_tobuf(addrlist, n,
							    NULL);

				if (!p)
				{
					perror(addresses);
					exit(EX_TEMPFAIL);
				}

				printf("%s\n", p);
				free(p);
			}
			rfc822a_free(addrlist);
			rfc822t_free(tokens);
			fflush(stdout);
		}
	}
			
	free(rpline);
	free(dtline);
	free(ufromline);
}
Пример #10
0
//-------------------------------------------------------------------
// PURPOSE: Parse script (script_source_str) for @xxx
// PARAMETERS:  fn - full path of script
// RESULTS:  script_title
//           script_params
//           script_params_order
//           script_loaded_params, conf.script_vars
//-------------------------------------------------------------------
static void script_scan(const char *fn)
{
    register const char *ptr = script_source_str;
    register int i, j=0, n;
    char *c;

    if ( !ptr ) { ptr = lua_script_default; }     // sanity check

    // Build title

    c=strrchr(fn, '/');
    strncpy(script_title, (c)?c+1:fn, sizeof(script_title));
    script_title[sizeof(script_title)-1]=0;

    // Reset everything

    for (i=0; i<SCRIPT_NUM_PARAMS; ++i)
    {
        conf.script_vars[i] = 0;
        script_loaded_params[i] = 0;
        script_params[i][0]=0;
        script_param_order[i]=0;
        script_range_values[i] = 0;
        if (script_named_values[i]) free(script_named_values[i]);
        script_named_values[i] = 0;
        if (script_named_strings[i]) free(script_named_strings[i]);
        script_named_strings[i] = 0;
        script_named_counts[i] = 0;
    }

    // Fillup order, defaults

    while (ptr[0])
    {
        ptr = skip_whitespace(ptr);
        if (ptr[0]=='@') {
            if (strncmp("@title", ptr, 6)==0)
            {
                process_title(ptr+6);
            }
            else if (strncmp("@param", ptr, 6)==0)
            {
                n = process_param(ptr+6); // n=1 if '@param a' was processed, n=2 for 'b' ... n=26 for 'z'. n=0 if failed.
                if (n>0 && n<=SCRIPT_NUM_PARAMS)
                {
                  script_param_order[j]=n;
                  j++;
                }
            }
            else if (strncmp("@default", ptr, 8)==0)
            {
                process_default(ptr+8);
            }
            else if (strncmp("@range", ptr, 6)==0)
            {
                process_range(ptr+6);
            }
            else if (strncmp("@values", ptr, 7)==0)
            {
                process_values(ptr+7);
            }
        }
        ptr = skip_eol(ptr);
    }
}
Пример #11
0
void			GUI_Prefs_Read(const char *app_name)
{
	sPrefs.clear();
	string pref_dir;
	if (!GUI_GetPrefsDir(pref_dir)) return;
	pref_dir += DIR_STR;
    #if LIN
    pref_dir += ".";
    pref_dir +=  app_name;
    #else
	pref_dir += app_name;
    #endif
	pref_dir += ".prefs";
	MFMemFile* f = MemFile_Open(pref_dir.c_str());
	GUI_PrefSection_t * cur=NULL;
	if(f)
	{
		const char * p = MemFile_GetBegin(f);
		const char * e = MemFile_GetEnd(f);
		while(p<e)
		{
			skip_space(p,e);
			if(p<e && *p=='[')
			{
				++p;
				const char * cs = p;
				while(p<e && !is_eol(*p) && *p != ']')
					++p;
				string cur_name(cs,p);
				cur=&sPrefs[cur_name];
			}
			else if(p<e && *p != '\r' && *p != '\n')
			{
				const char * ks = p;
				while(p<e && !is_spc(*p) && !is_eol(*p) && *p != '=')
				{
					if (*p=='\\')	++p;
					if(p<e)			++p;
				}

				const char * ke = p;
				skip_space(p,e);
				if(p<e && *p=='=')
				{
					++p;
					skip_space(p,e);
					if(p<e)
					{
						const char * vs = p;
						while(p<e && !is_spc(*p) && !is_eol(*p) && *p != '=')
						{
							if (*p=='\\')	++p;
							if(p<e)			++p;
						}
						const char * ve = p;
						if(cur)
						{
							string key(ks,ke);
							string val(vs,ve);
							dequote(key);
							dequote(val);
							(*cur)[key] = val;
						}
					}
				}
			}
			skip_eol(p,e);
		}
		MemFile_Close(f);
	}

	#if DEBUG_PREFS
	for(GUI_Prefs_t::iterator s = sPrefs.begin(); s != sPrefs.end(); ++s)
	{
		printf("[%s]" CRLF, s->first.c_str());
		for(GUI_PrefSection_t::iterator p = s->second.begin(); p != s->second.end(); ++p)
			printf("'%s'='%s'" CRLF, p->first.c_str(), p->second.c_str());
	}
	#endif
}
Пример #12
0
//-------------------------------------------------------------------
// PURPOSE:     Load parameters from paramset for script
// PARAMETERS:  fn - full path of script
//              paramset - num of loaded paramset (usually conf.script_param_set)
// RETURN:      1-succesfully applied, 0 - something was failed
//-------------------------------------------------------------------
static int load_params_values()
{
    // skip if no script loaded
    if (conf.script_file[0] == 0) return 0;
    // skip if 'default' parameters requested
    if (conf.script_param_set == DEFAULT_PARAM_SET) return 0;
    
    if ((conf.script_param_set < 0) || (conf.script_param_set > 10))
        conf.script_param_set = 0;

    char *nm = make_param_filename(MAKE_PARAM_FILENAME_V2);

    char* buf = load_file(nm, 0, 1);
    if (buf == 0)
    {
        nm = make_param_filename(MAKE_PARAM_FILENAME);
        buf = load_file(nm, 0, 1);
        if (buf == 0)
            return 0;
    }

    const char* ptr = buf;
    int valid = 1;

    // Initial scan of saved paramset file
    // Ensure all saved params match defaults from script
    // If not assume saved file is invalid and don't load it
    //   may occur if script is changed, or file was saved by a different script with same name
    while (ptr[0] && valid)
    {
        ptr = skip_whitespace(ptr);
        if (ptr[0] == '@')
        {
            if (strncmp("@param", ptr, 6) == 0) 
            {
                if (!check_param(ptr+6))
                    valid = 0;
            }
        }
        else if (ptr[0] == '#')
        {
            if (!check_param(ptr+1))
                valid = 0;
        }
        ptr = skip_eol(ptr);
    }

    if (valid)
    {
        // All ok, reset and process file
        ptr = buf;

        while (ptr[0])
        {
            ptr = skip_whitespace(ptr);
            if (ptr[0]=='@')
            {
                // Already checked file, so only need to load the @default values
                // @param, @range & @values already set from script
                if (strncmp("@default", ptr, 8)==0)
                {
                    process_default(ptr+8, 0);
                }
            }
            else if (ptr[0] == '#')
            {
                process_default(ptr+1, 0);
            }
            ptr = skip_eol(ptr);
        }
    }

    free(buf);

    return valid;
}
Пример #13
0
//-------------------------------------------------------------------
// PURPOSE: Parse script (conf.script_file) for parameters and title
//-------------------------------------------------------------------
static void script_scan()
{
    // Reset everything
    sc_param *p = script_params;
    while (p)
    {
        if (p->name)       free(p->name);
        if (p->desc)       free(p->desc);
        if (p->options)    free(p->options);
        if (p->option_buf) free(p->option_buf);
        sc_param *l = p;
        p = p->next;
        free(l);
    }
    script_params = tail = 0;
    script_param_count = 0;

    parse_version(&script_version, "1.3.0.0", 0);
    script_has_version = 0;
    is_script_loaded = 0;

    // Load script file
    const char *buf=0;
    if (conf.script_file[0] != 0)
        buf = load_file_to_length(conf.script_file, 0, 1, 4096);    // Assumes parameters are in first 4K of script file

    // Check file loaded
    if (buf == 0)
    {
        strcpy(script_title, "NO SCRIPT");
        return;
    }

    // Build title from name (in case no title in script)
    const char *c = get_script_filename();
    strncpy(script_title, c, sizeof(script_title)-1);
    script_title[sizeof(script_title)-1]=0;

    // Fillup order, defaults
    const char *ptr = buf;
    while (ptr[0])
    {
        ptr = skip_whitespace(ptr);
        if (ptr[0] == '@')
        {
            if (strncmp("@title", ptr, 6)==0)
            {
                process_title(ptr+6);
            }
            else if (strncmp("@subtitle", ptr, 9)==0)
            {
                process_subtitle(ptr+9);
            }
            else if (strncmp("@param", ptr, 6)==0)
            {
                process_param(ptr+6);
            }
            else if (strncmp("@default", ptr, 8)==0)
            {
                process_default(ptr+8, 1);
            }
            else if (strncmp("@range", ptr, 6)==0)
            {
                process_range(ptr+6);
            }
            else if (strncmp("@values", ptr, 7)==0)
            {
                process_values(ptr+7);
            }
            else if (strncmp("@chdk_version", ptr, 13)==0)
            {
                ptr = skip_whitespace(ptr+13);
                parse_version(&script_version, ptr, 0);
                script_has_version = 1;
            }
        }
        else if (ptr[0] == '#')
        {
            process_single(ptr+1);
        }
        ptr = skip_eol(ptr);
    }

    free((void*)buf);
    is_script_loaded = 1;
}
/*
 * Lexical analyzer
 * Returns the next token from the source file
 */
void
get_token(void)
{
  int tp, base;
  char *cp;

  for(;;) {
    /*
     * skip spaces
     */
    while(tok_char != '\n' && isspace(tok_char))
      read_src_char();

    if(tok_char == EOF)	{
      token_type = TOK_EOF;
      token_string[0] = '\0';
      return;
    }

    if(tok_char != ';')
      break;

    /* comment */
    line_buf_ptr = NULL;
    tok_char = '\n';

  } /* for(;;) */

/*
 * character constant (integer)
 * (does not currently handle the quote character)
 */
  if(tok_char == '\'') {
    read_src_char();
    token_string[0] = tok_char;
    read_src_char();
    if(tok_char != '\'')
      goto invalid_token;
    read_src_char();
    token_string[1] = '\0';
    token_int_val = (long)((unsigned char)token_string[0]);
    token_type = TOK_INTCONST;
    return;
  }

  if(tok_char == '"') { /* string constant (include filename) */
    read_src_char();
    tp = 0;
    while(tp < TOKSIZE-1 && tok_char != '"' && tok_char != EOF)	{
      token_string[tp++] = tok_char;
      read_src_char();
    }
    if(tok_char != '\"' && !ifskip_mode)
      error(0, "String not terminated");
    token_string[tp] = '\0';
    read_src_char();
    token_type = TOK_STRCONST;
    return;
  }

/*
 * integer number
 */
  if(isdigit(tok_char)) {
    token_type = TOK_INTCONST;
    token_string[0] = tok_char;
    tp = 1;
    read_src_char();
    if(token_string[0] == '0') {
      if(tok_char == 'x' || tok_char == 'X') { /* hex number */
	token_string[tp++] = tok_char;
	read_src_char();
	while(tp < TOKSIZE-1 && isxdigit(tok_char)) {
	  token_string[tp++] = tok_char;
	  read_src_char();
	}
	token_string[tp] = '\0';
	token_int_val = strtoul(&token_string[2], NULL, 16);
	/* should put range check here */
	return;
      }
    }

    while(tp < TOKSIZE-2 && isxdigit(tok_char))	{
      token_string[tp++] = tok_char;
      read_src_char();
    }

    base = 10;
    switch(tok_char) {
      case 'H': /* hex */
      case 'h':
        base = 16; /* hex */
	token_string[tp++] = tok_char;
	read_src_char();
	break;

      case 'O': /* octal */
      case 'o':
	base = 8; /* octal */
	token_string[tp++] = tok_char;
	read_src_char();
	break;

      default:
	if(token_string[0] == '0' &&
	   (token_string[1] == 'b' || token_string[1] == 'B')) {
	  token_string[tp] = '\0';
	  token_int_val = strtoul(&token_string[2], &cp, 2);
	  if(cp != &token_string[tp] && !ifskip_mode)
	    error(0, "Invalid digit in a number");
	  /* should put range check here */
	  return;
	} else if(token_string[tp-1] == 'B' || token_string[tp-1] == 'b') {
	  base = 2;
	} else {
	  if(token_string[tp-1] != 'D' && token_string[tp-1] != 'd')
	    token_string[tp++] = '\0';
	}
	break;
    }

    token_string[tp] = '\0';
    token_int_val = strtoul(token_string, &cp, base);
    if(cp != &token_string[tp-1] && !ifskip_mode)
      error(0, "Invalid digit in a number");
    /* should put range check here */
    return;
  }

/*
 * Handle B'10010100' binary etc.
 */
  if((tok_char == 'b' || tok_char == 'B' ||
      tok_char == 'd' || tok_char == 'D' ||
      tok_char == 'h' || tok_char == 'H' ||
      tok_char == 'o' || tok_char == 'O') &&
     line_buf_ptr != NULL && *line_buf_ptr == '\'') {
    token_string[0] = tok_char;
    read_src_char();
    token_string[1] = tok_char;
    read_src_char();
    tp = 2;
    while(tp < TOKSIZE-1 && isxdigit(tok_char))	{
      token_string[tp++] = tok_char;
      read_src_char();
    }
    if(tok_char != '\'')
      goto invalid_token;
    token_string[tp++] = tok_char;
    read_src_char();
    token_string[tp] = '\0';

    switch(token_string[0]) {
      case 'b':
      case 'B':
        base = 2;
	break;

      case 'o':
      case 'O':
	base = 8;
	break;

      case 'h':
      case 'H':
	base = 16;
	break;

      case 'd':
      case 'D':
      default:
	base = 10;
	break;
    }

    token_int_val = strtoul(&token_string[2], &cp, base);
    if(cp != &token_string[tp-1] && !ifskip_mode)
      error(0, "Invalid digit in a number");
    /* should put range check here */
    token_type = TOK_INTCONST;
    return;
  }

/*
 * keyword or identifier
 */
  if(tok_char == '_' || tok_char == '.' || isalpha(tok_char)) {
    line_buf_off = (line_buf_ptr - &line_buffer[1]);

    token_string[0] = tok_char;
    tp = 1;
    read_src_char();

    if(token_string[0] == '.' &&
       tok_char != '_' && !isalnum(tok_char)) {
      token_string[1] = '\0';
      token_type = TOK_PERIOD;
      return;
    }

    while(tp < TOKSIZE-1 &&
	  (tok_char == '_' || tok_char == '.' || isalnum(tok_char))) {
      token_string[tp++] = tok_char;
      read_src_char();
    }
    token_string[tp] = '\0';

    token_type = FIRST_KW;
    cp = Keyword_Table;
    while(*cp) {
      if(strcasecmp(token_string, cp) == 0)
	return;
      while(*cp++)
	;
      token_type++;
    }
    token_type = TOK_IDENTIFIER;
    return;
  }

/*
 * non-numeric & non-alpha tokens
 */
  switch(tok_char) {
    case '\n':
    case '\0':
      token_type = TOK_NEWLINE;
      strcpy(token_string, "\\n");
      skip_eol();
      return;

    case '<':
      token_string[0] = tok_char;
      read_src_char();
      if(tok_char == '<') {
	token_string[1] = tok_char;
	token_string[2] = '\0';
	token_type = TOK_LSHIFT;
	read_src_char();
	return;
      }

      if(tok_char == '=') {
	token_string[1] = tok_char;
	token_string[2] = '\0';
	token_type = TOK_LESS_EQ;
	read_src_char();
	return;
      }

      if(tok_char == '>') {
	token_string[1] = tok_char;
	token_string[2] = '\0';
	token_type = TOK_NOT_EQ;
	read_src_char();
	return;
      }

      token_type = TOK_LESS;
      token_string[1] = '\0';
      return;

    case '>':
      token_string[0] = tok_char;
      read_src_char();
      if(tok_char == '>') {
	token_string[1] = tok_char;
	token_string[2] = '\0';
	token_type = TOK_RSHIFT;
	read_src_char();
	return;
      }

      if(tok_char == '=') {
	token_string[1] = tok_char;
	token_string[2] = '\0';
	token_type = TOK_GT_EQ;
	read_src_char();
	return;
      }

      token_string[1] = '\0';
      token_type = TOK_GREATER;
      return;

    case '!':
      token_string[0] = tok_char;
      read_src_char();
      if(tok_char != '=')
	goto invalid_token;
      token_string[1] = tok_char;
      token_string[2] = '\0';
      read_src_char();
      token_type = TOK_NOT_EQ;
      return;

    case '=':
      token_string[0] = tok_char;
      read_src_char();
      if(tok_char == '=') {
	token_string[1] = tok_char;
	read_src_char();
	token_string[2] = '\0';
	token_type = TOK_EQ;
	return;
      }

      if(tok_char == '<') {
	token_string[1] = tok_char;
	read_src_char();
	token_string[2] = '\0';
	token_type = TOK_LESS_EQ;
	return;
      }

      if(tok_char == '>') {
	token_string[1] = tok_char;
	read_src_char();
	token_string[2] = '\0';
	token_type = TOK_GT_EQ;
	return;
      }

      if(tok_char == '_' || tok_char == '.' ||
	 isalpha(tok_char)) { /* local symbol */
	line_buf_off = (line_buf_ptr - &line_buffer[2]);

	token_string[0] = tok_char;
	tp = 1;
	read_src_char();

	while(tp < TOKSIZE-1 &&
	      (tok_char == '_' || tok_char == '.' || isalnum(tok_char))) {
	  token_string[tp++] = tok_char;
	  read_src_char();
	}
	token_string[tp] = '\0';

	token_type = TOK_LOCAL_ID;
	return;
      }

      token_string[1] = '\0';
      token_type = TOK_EQUAL;
      return;

    case '$':
      read_src_char();
      if(!isxdigit(tok_char))
	{
	  token_string[0] = '$';
	  token_string[1] = '\0';
	  token_type = TOK_DOLLAR;
	  return;
	}

      tp = 0;
      do
	{
	  token_string[tp++] = tok_char;
	  read_src_char();
	} while(tp < TOKSIZE-1 && isxdigit(tok_char));

      token_string[tp] = '\0';
      token_int_val = strtoul(&token_string[1], NULL, 16);
      token_type = TOK_INTCONST;
      /* should put range check here */
      return;

    case '\\':
      token_type = TOK_BACKSLASH;
      break;

    case ',':
      token_type = TOK_COMMA;
      break;

    case '(':
      token_type = TOK_LEFTPAR;
      break;

    case ')':
      token_type = TOK_RIGHTPAR;
      break;

    case '+':
      token_type = TOK_PLUS;
      break;

    case '-':
      token_type = TOK_MINUS;
      break;

    case '&':
      token_type = TOK_BITAND;
      break;

    case '|':
      token_type = TOK_BITOR;
      break;

    case '^':
      token_type = TOK_BITXOR;
      break;

    case '~':
      token_type = TOK_BITNOT;
      break;

    case '*':
      token_type = TOK_ASTERISK;
      break;

    case '/':
      token_type = TOK_SLASH;
      break;

    case '%':
      token_type = TOK_PERCENT;
      break;

    case ':':
      token_type = TOK_COLON;
      break;

    case '[':
      token_type = TOK_LEFTBRAK;
      break;

    case ']':
      token_type = TOK_RIGHTBRAK;
      break;

    default:
      goto invalid_token;
  }

  token_string[0] = tok_char;
  token_string[1] = '\0';
  read_src_char();
  return;

invalid_token:
  if(!ifskip_mode)
    error(0, "Invalid token");
  token_string[0] = '\0';
  token_type = TOK_INVALID;
}