示例#1
0
double rnum(double range)
{
   double r;
   double rmax = ( (1<<31) - 1);

   r=random();
   errlog1(5,"random returns: %g",r);
   r=r * (BSIZE/rmax) + 1;
   errlog1(5,"rnum returns: %g",r);
   return(r);
}
示例#2
0
int 
parseaf(char *buf)
{
   double baro, dewpt_in, dewpt_out;

   if (!sumcheck(buf, SIZEAF)) {
      errlog(8, "Checksum failure for AF block.");
      return (-1);
   }
   baro = DDtoint(buf[3]) + (DDtoint(buf[4]) * 100.0) + (xDtoint(buf[5]) * 10000.0);
   baro /= 10;

   dewpt_in = DDtoint(buf[7]);
   dewpt_out = DDtoint(buf[18]);

   correct(dewpt_in, current_cal.dp_in_mul, current_cal.dp_in_offs);
   correct(dewpt_out, current_cal.dp_out_mul, current_cal.dp_out_offs);
   correct(baro, current_cal.barometer_mul, current_cal.barometer_offs);

   update(current_obs.dp_in, dewpt_in, DEWIN);
   update(current_obs.dp_out, dewpt_out, DEWOUT);
   update(current_obs.barometer, baro, BARO);


   errlog1(9, "Barometer: %g mb", baro);
   errlog2(9, "Indoor dewpoint: %gC, Outdoor dewpoint: %gC", dewpt_in, dewpt_out);

}
示例#3
0
int 
parsecf(char *buf)
{
   double gust, avg, chill, hum_out;
   double avg_dir, gust_dir;

   if (!sumcheck(buf, SIZECF)) {
      errlog(9, "Checksum failure for CF block.");
      return (-1);
   }
   gust = ((xDtoint(buf[2]) * 100) + DDtoint(buf[1])) / 10;
   gust_dir = (Dxtoint(buf[2])) + (DDtoint(buf[3]) * 10);

   avg = ((xDtoint(buf[5]) * 100) + DDtoint(buf[4])) / 10;
   avg_dir = (Dxtoint(buf[5])) + (DDtoint(buf[6]) * 10);

   chill = DDtoint(buf[16]);
   if (buf[21] & 0x20) {
      chill = -1.0 * chill;
   }

#if 0
   pthread_mutex_lock(&current_obs_lock);
   if (((chill - current_obs.temp_out) > 0.5) && (avg > 0 || gust > 0)) {
      chill = -1.0 * chill;
   }
   pthread_mutex_unlock(&current_obs_lock);
#endif

   correct(chill, current_cal.chill_mul, current_cal.chill_offs);
   correct(gust, current_cal.gust_spd_mul, current_cal.gust_spd_offs);

   correct(gust_dir, current_cal.gust_dir_mul, current_cal.gust_dir_offs);
   correct(avg_dir, current_cal.wavg_dir_mul, current_cal.wavg_dir_offs);

   gust_dir = (gust_dir < 0) ? 360 + ((int) gust_dir % 360) : (int) gust_dir % 360;

   correct(avg, current_cal.wavg_spd_mul, current_cal.wavg_spd_offs);
   avg_dir = (avg_dir < 0) ? 360 + ((int) avg_dir % 360) : (int) avg_dir % 360;


   update(current_obs.gust, gust, GUST);
   update(current_obs.wavg, avg, WAVG);
   update(current_obs.gust_dir, gust_dir, GUSTDIR);
   update(current_obs.wavg_dir, avg_dir, WAVGDIR);
   update(current_obs.chill, chill, WCHILL);

   errlog2(9, "Wind gust %g m/s, direction: %g", gust, gust_dir);
   errlog2(9, "Wind avg  %g m/s, direction: %g", avg, avg_dir);
   errlog1(9, "Wind chill %g C", chill);
}
示例#4
0
main(int argc, char **argv)
{
   pthread_attr_t sched_attr;
   int maxprio, minprio;
   int go = 1;
   struct sched_param fifo_param;
   struct sigaction ignoreChildDeath =
   {NULL, 0, (SA_NOCLDSTOP | SA_RESTART), NULL};
   struct sigaction hupAction =
   {hupcatch, 0, SA_RESTART, NULL};
   struct sigaction termAction =
   {termcatch, 0, SA_RESTART, NULL};

   myName=argv[0];
   ch_flag = 0;
   terminate = 0;

   fprintf(stderr,"%s daemon start.\n", myName);

   pthread_attr_init(&sched_attr);
   pthread_attr_setinheritsched(&sched_attr, PTHREAD_EXPLICIT_SCHED);
   pthread_attr_setschedpolicy(&sched_attr, /*SCHED_RR */ SCHED_FIFO);

   maxprio = sched_get_priority_max(SCHED_FIFO);
   minprio = sched_get_priority_min(SCHED_FIFO);

   sigaction(SIGCHLD, &ignoreChildDeath, NULL);		/*zombie protection */
   sigaction(SIGHUP, &hupAction, NULL);
   sigaction(SIGTERM, &termAction, NULL);

   if (terminate == TERM_TERM) {
      go = 0;
   } else {
      go = 1;
   }

   while (go) {			/*The main restart loop */
      terminate = 0;
      /*read config file here */
      cfg_read(CONFIG_FILE, "", "");
      /* do command line option processing, they override config file opts */
      do_opts(argc, argv);
      if (!foreground) {
	 daemon();
      }
      wxin = serial_open(opts.ttydev);
      last_write_time = time(NULL);
      if (wxin > 0) {
	 sane_defaults();
	 init_db();
	 if (setupio(wxin) < 0) {
	    errlog(9, "setupio bailed.");
	 }
	 iobuf = make_cbuf(BSIZE);
	 pthread_mutex_init(&current_obs_lock, pthread_mutexattr_default);
	 pthread_mutex_init(&current_cal_lock, pthread_mutexattr_default);
	 pthread_mutex_init(&terminate_lock, pthread_mutexattr_default);
	 pthread_mutex_init(&cond_update_lock, pthread_mutexattr_default);
	 pthread_cond_init(&cond_update, pthread_condattr_default); 

#if USE_CBUF

	 /*	 fifo_param.sched_priority = (minprio + maxprio) / 2;
		 pthread_attr_setschedparam(&sched_attr, &fifo_param);*/
	 
	 pthread_create(&reader, /*pthread_attr_default */ NULL, (pthread_startroutine_t) serial_reader, (pthread_addr_t) iobuf);

	 pthread_create(&parser, NULL /*&sched_attr*/, (pthread_startroutine_t) parse_input, (pthread_addr_t) iobuf);
#if SCREENOUT
	 pthread_create(&writer, NULL /*&sched_attr*/, (pthread_startroutine_t) screen_writer, (pthread_addr_t) NULL);
#else				/* Make a db writer thread */
	 pthread_create(&writer, NULL /*&sched_attr*/, (pthread_startroutine_t) db_writer, (pthread_addr_t) NULL);
#endif


	 pthread_join(reader, NULL);
	 pthread_join(parser, NULL);
	 pthread_join(writer, NULL);


#else
	 parse_input(iobuf);
#endif
	 release_cbuf(iobuf);
	 serial_close(opts.ttydev);
	 if (terminate == TERM_TERM) {
	    errlog1(1, "%s: TERMINATE.", argv[0]);
	    go = 0;
	 }
	 if (terminate == TERM_RESTART) {
	    errlog1(1, "%s: RESTART.", argv[0]);
	    go = 1;
	 }
#if SCREENOUT
#else
	 db_getout(dbconn);
#endif
      } else {
	 go = 0;
	 errlog2(1, "%s: cannot open serial port: %s", argv[0], opts.ttydev);
      }
   }
   errlog1(1,"%s daemon shutdown.", myName);
   exit(0);
}
示例#5
0
void 
screen_writer(void)
{
   double rain;
   int write_screen = 1;

   pthread_mutex_lock(&terminate_lock);
   if (terminate)
      write_screen = 0;;
   pthread_mutex_unlock(&terminate_lock);
   while (write_screen) {
      pthread_mutex_lock(&cond_update_lock);
      pthread_cond_wait(&cond_update, &cond_update_lock);
      pthread_mutex_unlock(&cond_update_lock);
      pthread_mutex_lock(&current_obs_lock);
      if (ch_flag != 0) {
	 if (test_bit(ch_flag, RAINTOT)) {
	    rain = current_obs.rain_tot + current_obs.rtot_offset;
	    errlog1(8, "Rain total: %d mm", rain);
	    clear_bit(ch_flag, RAINTOT);
	 }
	 if (test_bit(ch_flag, RAINRATE)) {
	    errlog1(8, "Rain rate: %d mm/hr", current_obs.rain_rate);
	    clear_bit(ch_flag, RAINRATE);
	 }
	 if (test_bit(ch_flag, TEMPIN)) {
	    errlog1(8, "Indoor temp: %gC", current_obs.temp_in);
	    clear_bit(ch_flag, TEMPIN);
	 }
	 if (test_bit(ch_flag, TEMPOUT)) {
	    errlog1(8, "Outdoor temp: %gC", current_obs.temp_out);
	    clear_bit(ch_flag, TEMPOUT);
	 }
	 if (test_bit(ch_flag, WCHILL)) {
	    errlog1(8, "Wind chill: %gC", current_obs.chill);
	    clear_bit(ch_flag, WCHILL);
	 }
	 if (test_bit(ch_flag, DEWIN)) {
	    errlog1(8, "Indoor dewpoint: %gC", current_obs.dp_in);
	    clear_bit(ch_flag, DEWIN);
	 }
	 if (test_bit(ch_flag, DEWOUT)) {
	    errlog1(8, "Outdoor dewpoint: %gC", current_obs.dp_out);
	    clear_bit(ch_flag, DEWOUT);
	 }
	 if (test_bit(ch_flag, HUMIN)) {
	    errlog1(8, "Indoor humidity: %d%%", current_obs.rh_in);
	    clear_bit(ch_flag, HUMIN);
	 }
	 if (test_bit(ch_flag, HUMOUT)) {
	    errlog1(8, "Outdoor humidity: %d%%", current_obs.rh_out);
	    clear_bit(ch_flag, HUMOUT);
	 }
	 if (test_bit(ch_flag, BARO)) {
	    errlog1(8, "Barometer %g mb", current_obs.barometer);
	    clear_bit(ch_flag, BARO);
	 }
	 if (test_bit(ch_flag, GUSTDIR) && test_bit(ch_flag, GUST)) {
	    errlog1(8, "Wind gust direction: %d deg", current_obs.gust_dir);
	    clear_bit(ch_flag, GUSTDIR);
	 }
	 if (test_bit(ch_flag, GUST)) {
	    errlog1(8, "Wind gust: %g m/s", current_obs.gust);
	    clear_bit(ch_flag, GUST);
	 }
	 if (test_bit(ch_flag, WAVGDIR) && test_bit(ch_flag, WAVG)) {
	    errlog1(8, "Wind avg direction: %d deg", current_obs.wavg_dir);
	    clear_bit(ch_flag, WAVGDIR);
	 }
	 if (test_bit(ch_flag, WAVG)) {
	    errlog1(8, "Wind avg: %g m/s", current_obs.wavg);
	    clear_bit(ch_flag, WAVG);
	 }
      }
      pthread_mutex_unlock(&current_obs_lock);
      pthread_mutex_lock(&terminate_lock);
      if (terminate)
	 write_screen = 0;;
      pthread_mutex_unlock(&terminate_lock);
      /*sleep(1);*/
   }
   errlog(8, "Screenwriter exits.");
   pthread_exit(0);
}
示例#6
0
文件: tok.c 项目: BPaden/garglk
/* get the next token, removing it from the input stream */
int toknext(tokcxdef *ctx)
{
    char   *p;
    tokdef *tok = &ctx->tokcxcur;
    int     len;

    /* 
     *   Check for the special case that we pushed an open paren prior to
     *   a string containing an embedded expression.  If this is the case,
     *   immediately return the string we previously parsed. 
     */
    if ((ctx->tokcxflg & TOKCXF_EMBED_PAREN_PRE) != 0)
    {
        /* 
         *   convert the token to a string - note that the offset
         *   information for the string is already in the current token
         *   structure, since we set everything up for it on the previous
         *   call where we actually parsed the beginning of the string 
         */
        tok->toktyp = TOKTDSTRING;

        /* clear the special flag - we've now consumed the pushed string */
        ctx->tokcxflg &= ~TOKCXF_EMBED_PAREN_PRE;

        /* immediately return the string */
        return tok->toktyp;
    }

    /* set up at the current scanning position */
    p = ctx->tokcxptr;
    len = ctx->tokcxlen;

    /* scan off whitespace and comments until we find something */
    do
    {
    skipblanks:
        /* if there's nothing on this line, get the next one */
        if (len == 0)
        {
            /* if we're in a macro expansion, continue after it */
            if (ctx->tokcxmlvl)
            {
                ctx->tokcxmlvl--;
                p = ctx->tokcxmsav[ctx->tokcxmlvl];
                len = ctx->tokcxmsvl[ctx->tokcxmlvl];
            }
            else
            {
                if (tokgetlin(ctx, TRUE))
                {
                    tok->toktyp = TOKTEOF;
                    goto done;
                }
                p = ctx->tokcxptr;
                len = ctx->tokcxlen;
            }
        }
        while (len && t_isspace(*p)) ++p, --len;     /* scan off whitespace */
        
        /* check for comments, and remove if present */
        if (len >= 2 && *p == '/' && *(p+1) == '/')
            len = 0;
        else if (len >= 2 && *p == '/' && *(p+1) == '*')
        {
            while (len < 2 || *p != '*' || *(p+1) != '/')
            {
                if (len != 0)
                    ++p, --len;

                if (len == 0)
                {
                    if (ctx->tokcxmlvl != 0)
                    {
                        ctx->tokcxmlvl--;
                        p = ctx->tokcxmsav[ctx->tokcxmlvl];
                        len = ctx->tokcxmsvl[ctx->tokcxmlvl];
                    }
                    else
                    {
                        if (tokgetlin(ctx, FALSE))
                        {
                            ctx->tokcxptr = p;
                            tok->toktyp = TOKTEOF;
                            goto done;
                        }
                        p = ctx->tokcxptr;
                        len = ctx->tokcxlen;
                    }
                }
            }
            p += 2;
            len -= 2;
            goto skipblanks;
        }
    } while (len == 0);
    
nexttoken:
    if (isalpha((uchar)*p) || *p == '_' || *p == '$')
    {
        int       l;
        int       hash;
        char     *q;
        toktdef  *tab;
        int       found = FALSE;
        uchar     thischar;
        tokdfdef *df;
        
        for (hash = 0, l = 0, q = tok->toknam ;
             len != 0 && TOKISSYM(*p) && l < TOKNAMMAX ;
             (thischar = ((isupper((uchar)*p)
                           && (ctx->tokcxflg & TOKCXCASEFOLD))
                          ? tolower((uchar)*p) : *p)),
             (hash = ((hash + thischar) & (TOKHASHSIZE - 1))),
             (*q++ = thischar), ++p, --len, ++l) ;
        *q = '\0';
        if (len != 0 && TOKISSYM(*p))
        {
            while (len != 0 && TOKISSYM(*p)) ++p, --len;
            errlog1(ctx->tokcxerr, ERR_TRUNC, ERRTSTR,
                    errstr(ctx->tokcxerr, tok->toknam, tok->toklen));
        }
        tok->toklen = l;
        tok->tokhash = hash;

        /*
         *   check for the special defined() preprocessor operator 
         */
        if (l == 9 && !memcmp(tok->toknam,
                              ((ctx->tokcxflg & TOKCXCASEFOLD)
                               ? "__defined" : "__DEFINED"),
                              (size_t)9)
            && len > 2 && *p == '(' && TOKISSYM(*(p+1))
            && !isdigit((uchar)*(p+1)))
        {
            int symlen;
            char mysym[TOKNAMMAX];
            
            /* find the matching ')', allowing only symbolic characters */
            ++p, --len;
            for (symlen = 0, q = p ; len && *p != ')' && TOKISSYM(*p) ;
                 ++p, --len, ++symlen) ;

            /* make sure we found the closing paren */
            if (!len || *p != ')')
                errsig(ctx->tokcxerr, ERR_BADISDEF);
            ++p, --len;

            /* if we're folding case, convert the symbol to lower case */
            q = tok_casefold_defsym(ctx, mysym, q, symlen);

            /* check to see if it's defined */
            tok->toktyp = TOKTNUMBER;
            tok->tokval = (tok_find_define(ctx, q, symlen) != 0);
            goto done;
        }

        /* substitute the preprocessor #define, if any */
        if ((df = tok_find_define(ctx, tok->toknam, l)) != 0)
        {
            /* save the current parsing position */
            if (ctx->tokcxmlvl >= TOKMACNEST)
                errsig(ctx->tokcxerr, ERR_MACNEST);
            ctx->tokcxmsav[ctx->tokcxmlvl] = p;
            ctx->tokcxmsvl[ctx->tokcxmlvl] = len;
            ctx->tokcxmlvl++;

            /* point to the token's expansion and keep going */
            p = df->expan;
            len = df->explen;
            goto nexttoken;
        }
        
        /* look up in symbol table(s), if any */
        for (tab = ctx->tokcxstab ; tab ; tab = tab->toktnxt)
        {
            if ((found = (*tab->toktfsea)(tab, tok->toknam, l, hash,
                                          &tok->toksym)) != 0)
                break;
        }
        
        if (found && tok->toksym.tokstyp == TOKSTKW)
            tok->toktyp = tok->toksym.toksval;
        else
        {
            tok->toktyp = TOKTSYMBOL;
            if (!found) tok->toksym.tokstyp = TOKSTUNK;
        }
        goto done;
    }
    else if (isdigit((uchar)*p))
    {
        long acc = 0;
        
        /* check for octal/hex */
        if (*p == '0')
        {
            ++p, --len;
            if (len && (*p == 'x' || *p == 'X'))
            {
                /* hex */
                ++p, --len;
                while (len && TOKISHEX(*p))
                {
                    acc = (acc << 4) + TOKHEX2INT(*p);
                    ++p, --len;
                }
            }
            else
            {
                /* octal */
                while (len && TOKISOCT(*p))
                {
                    acc = (acc << 3) + TOKOCT2INT(*p);
                    ++p, --len;
                }
            }
        }
        else
        {
            /* decimal */
            while (len && isdigit((uchar)*p))
            {
                acc = (acc << 1) + (acc << 3) + TOKDEC2INT(*p);
                ++p, --len;
            }
        }
        tok->tokval = acc;
        tok->toktyp = TOKTNUMBER;
        goto done;
    }
    else if (*p == '"' || *p == '\'')
    {
        char  delim;                 /* closing delimiter we're looking for */
        char *strstart;                       /* pointer to start of string */
        int   warned;
        
        delim = *p;
        --len;
        strstart = ++p;

        if (delim == '"' && len >= 2 && *p == '<' && *(p+1) == '<')
        {
            /* save the current parsing position */
            if (ctx->tokcxmlvl >= TOKMACNEST)
                errsig(ctx->tokcxerr, ERR_MACNEST);
            ctx->tokcxmsav[ctx->tokcxmlvl] = p + 2;
            ctx->tokcxmsvl[ctx->tokcxmlvl] = len - 2;
            ctx->tokcxmlvl++;

            /* 
             *   read from the special "<<" expansion string - use the
             *   version for a "<<" at the very beginning of the string 
             */
            p = tokmac1s;
            len = strlen(p);
            ctx->tokcxflg |= TOKCXFINMAC;
            goto nexttoken;
        }
        tok->toktyp = (delim == '"' ? TOKTDSTRING : TOKTSSTRING);
        
        tok->tokofs = (*ctx->tokcxsst)(ctx->tokcxscx);  /* start the string */
        for (warned = FALSE ;; )
        {
            if (len >= 2 && *p == '\\')
            {
                if (*(p+1) == '"' || *(p+1) == '\'')
                {
                    (*ctx->tokcxsad)(ctx->tokcxscx, strstart,
                                     (ushort)(p - strstart));
                    strstart = p + 1;
                }
                p += 2;
                len -= 2;
            }
            else if (len == 0 || *p == delim ||
                     (delim == '"' && len >= 2 && *p == '<' && *(p+1) == '<'
                      && !(ctx->tokcxflg & TOKCXFINMAC)))
            {
                (*ctx->tokcxsad)(ctx->tokcxscx, strstart,
                                 (ushort)(p - strstart));
                if (len == 0)
                {
                    if (ctx->tokcxmlvl)
                    {
                        ctx->tokcxmlvl--;
                        p = ctx->tokcxmsav[ctx->tokcxmlvl];
                        len = ctx->tokcxmsvl[ctx->tokcxmlvl];
                    }
                    else
                        (*ctx->tokcxsad)(ctx->tokcxscx, " ", (ushort)1);
                    
                    while (len == 0)
                    {
                        if (tokgetlin(ctx, FALSE))
                            errsig(ctx->tokcxerr, ERR_STREOF);
                        p = ctx->tokcxptr;
                        len = ctx->tokcxlen;

                        /* warn if it looks like the end of an object */
                        if (!warned && len && (*p == ';' || *p == '}'))
                        {
                            errlog(ctx->tokcxerr, ERR_STREND);
                            warned = TRUE;     /* warn only once per string */
                        }

                        /* scan past whitespace at start of line */
                        while (len && t_isspace(*p)) ++p, --len;
                    }
                    strstart = p;
                }
                else break;
            }
            else
                ++p, --len;
        }

        /* end the string */
        (*ctx->tokcxsend)(ctx->tokcxscx);

        /* check to see how it ended */
        if (len != 0 && *p == delim)
        {
            /* 
             *   We ended with the matching delimiter.  Move past the
             *   closing delimiter. 
             */
            ++p;
            --len;

            /*
             *   If we have a pending close paren we need to put in
             *   because of an embedded expression that occurred earlier
             *   in the string, parse the macro to provide the paren.  
             */
            if ((ctx->tokcxflg & TOKCXF_EMBED_PAREN_AFT) != 0
                && !(ctx->tokcxflg & TOKCXFINMAC))
            {
                /* clear the flag */
                ctx->tokcxflg &= ~TOKCXF_EMBED_PAREN_AFT;

                /* push the current parsing position */
                if (ctx->tokcxmlvl >= TOKMACNEST)
                    errsig(ctx->tokcxerr, ERR_MACNEST);
                ctx->tokcxmsav[ctx->tokcxmlvl] = p;
                ctx->tokcxmsvl[ctx->tokcxmlvl] = len;
                ctx->tokcxmlvl++;

                /* parse the macro */
                p = tokmac4;
                len = strlen(p);
            }
        }
        else if (len != 0 && *p == '<')
        {
            /* save the current parsing position */
            if (ctx->tokcxmlvl >= TOKMACNEST)
                errsig(ctx->tokcxerr, ERR_MACNEST);
            ctx->tokcxmsav[ctx->tokcxmlvl] = p + 2;
            ctx->tokcxmsvl[ctx->tokcxmlvl] = len - 2;
            ctx->tokcxmlvl++;

            /* read from the "<<" expansion */
            p = tokmac1;
            len = strlen(p);
            ctx->tokcxflg |= TOKCXFINMAC;

            /* 
             *   Set the special push-a-paren flag: we'll return an open
             *   paren now, so that we have an open paren before the
             *   string, and then on the next call to toknext() we'll
             *   immediately return the string we've already parsed here.
             *   This will ensure that everything in the string is
             *   properly grouped together as a single indivisible
             *   expression.
             *   
             *   Note that we only need to do this for the first embedded
             *   expression in a string.  Once we have a close paren
             *   pending, we don't need more open parens.  
             */
            if (!(ctx->tokcxflg & TOKCXF_EMBED_PAREN_AFT))
            {
                ctx->tokcxflg |= TOKCXF_EMBED_PAREN_PRE;
                tok->toktyp = TOKTLPAR;
            }
        }
        goto done;
    }
    else if (len >= 2 && *p == '>' && *(p+1) == '>'
             && (ctx->tokcxflg & TOKCXFINMAC) != 0)
    {
        /* skip the ">>" */
        ctx->tokcxflg &= ~TOKCXFINMAC;
        p += 2;
        len -= 2;

        /* save the current parsing position */
        if (ctx->tokcxmlvl >= TOKMACNEST)
            errsig(ctx->tokcxerr, ERR_MACNEST);
        ctx->tokcxmsav[ctx->tokcxmlvl] = p;
        ctx->tokcxmsvl[ctx->tokcxmlvl] = len;
        ctx->tokcxmlvl++;

        if (*p == '"')
        {
            ++(ctx->tokcxmsav[ctx->tokcxmlvl - 1]);
            --(ctx->tokcxmsvl[ctx->tokcxmlvl - 1]);
            p = tokmac3;

            /* 
             *   we won't need an extra closing paren now, since tokmac3
             *   provides it 
             */
            ctx->tokcxflg &= ~TOKCXF_EMBED_PAREN_AFT;
        }
        else
        {
            /* 
             *   The string is continuing.  Set a flag to note that we
             *   need to provide a close paren after the end of the
             *   string, and parse the glue (tokmac2) that goes between
             *   the expression and the resumption of the string. 
             */
            ctx->tokcxflg |= TOKCXF_EMBED_PAREN_AFT;
            p = tokmac2;
        }

        len = strlen(p);
        goto nexttoken;
    }
    else
    {
        tokscdef *sc;
        
        for (sc = ctx->tokcxsc[ctx->tokcxinx[(uchar)*p]] ; sc ;
             sc = sc->tokscnxt)
        {
            if (toksceq(sc->tokscstr, p, sc->toksclen, len))
            {
                tok->toktyp = sc->toksctyp;
                p += sc->toksclen;
                len -= sc->toksclen;
                goto done;
            }
        }
        errsig(ctx->tokcxerr, ERR_INVTOK);
    }
    
done:
    ctx->tokcxptr = p;
    ctx->tokcxlen = len;
    return(tok->toktyp);
}
示例#7
0
文件: tok.c 项目: BPaden/garglk
/* process a #include directive */
static void tokinclude(tokcxdef *ctx, char *p, int len)
{
    linfdef *child;
    tokpdef *path;
    char    *fname;
    int      match;
    int      flen;
    linfdef *lin;
    char    *q;
    size_t   flen2;

    /* find the filename portion */
    fname = p + 1;                            /* remember start of filename */
    path = ctx->tokcxinc;                    /* start with first path entry */

    if (!len)
    {
        errlog(ctx->tokcxerr, ERR_INCNOFN);
        return;
    }
    
    switch(*p)
    {
    case '<':
        match = '>';
        if (path && path->tokpnxt) path = path->tokpnxt;   /* skip 1st path */
        goto find_matching_delim;

    case '"':
        match = '"';

    find_matching_delim:
        for (++p, --len ; len && *p != match ; --len, ++p) ;
        if (len == 0 || *p != match) errlog(ctx->tokcxerr, ERR_INCMTCH);
        break;
        
    default:
        errlog(ctx->tokcxerr, ERR_INCSYN);
        return;
    }
    
    flen = p - fname;                         /* compute length of filename */
    for (q = p, flen2 = 0 ;
         q > fname && *(q-1) != OSPATHCHAR && !strchr(OSPATHALT, *(q-1)) ;
         --q, ++flen2) ;
    
    /* check to see if this file has already been included */
    for (lin = ctx->tokcxhdr ; lin ; lin = (linfdef *)lin->linflin.linnxt)
    {
        char *p = lin->linfnam;
        
        p += strlen(p);
        
        while (p > lin->linfnam && *(p-1) != OSPATHCHAR
               && !strchr(OSPATHALT, *(p-1)))
            --p;
        if (strlen(p) == flen2
            && !memicmp(p, q, flen2))
        {
            errlog1(ctx->tokcxerr, ERR_INCRPT, ERRTSTR,
                    errstr(ctx->tokcxerr, fname, flen));
            return;
        }
    }
    
    /* initialize the line source */
    child = linfini(ctx->tokcxmem, ctx->tokcxerr, fname, flen, path, TRUE,
                    (ctx->tokcxflg & TOKCXFLIN2) != 0);
    
    /* if not found, signal an error */
    if (!child) errsig1(ctx->tokcxerr, ERR_INCSEAR,
                        ERRTSTR, errstr(ctx->tokcxerr, fname, flen));
    
    /* link into tokenizer list of line records */
    child->linflin.linnxt = (lindef *)ctx->tokcxhdr;
    ctx->tokcxhdr = child;

    /* if we're tracking sources for debugging, add into the chain */
    if (ctx->tokcxdbg)
    {
        ctx->tokcxdbg->dbgcxlin = &child->linflin;
        child->linflin.linid = ctx->tokcxdbg->dbgcxfid++;
    }

    /* remember my C-mode setting */
    if (ctx->tokcxflg & TOKCXFCMODE)
        ctx->tokcxlin->linflg |= LINFCMODE;
    else
        ctx->tokcxlin->linflg &= ~LINFCMODE;
    
    child->linflin.linpar = ctx->tokcxlin;   /* remember parent line source */
    ctx->tokcxlin = &child->linflin;   /* make the child the current source */
}
示例#8
0
文件: tok.c 项目: BPaden/garglk
/* process a #error */
static void tok_p_error(tokcxdef *ctx, char *p, int len)
{
    errlog1(ctx->tokcxerr, ERR_P_ERROR,
            ERRTSTR, errstr(ctx->tokcxerr, p, len));
}