Back to index

tetex-bin  3.0
Classes | Enumerations | Functions | Variables
strexpr.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "basics.h"

Go to the source code of this file.

Classes

struct  val
union  val.u

Enumerations

enum  token {
  ADD, SUB, MUL, DIV,
  MOD, LP, RP, OPERAND,
  EOI
}

Functions

struct valmake_int (int i)
struct valmake_str (char *s)
void free_value (struct val *vp)
int is_integer (struct val *vp, int *r)
int to_integer (struct val *vp)
void to_string (struct val *vp)
void nexttoken ()
struct valeval6 ()
struct valeval4 ()
struct valeval3 ()
int strexpr (int *result, char *expression)

Variables

const char * OPERATORS = "+-*/%()"
enum token struct valtokval
char * pexpr

Class Documentation

union val.u

Definition at line 27 of file strexpr.c.

Class Members
int i
char * s

Enumeration Type Documentation

enum token
Enumerator:
ADD 
SUB 
MUL 
DIV 
MOD 
LP 
RP 
OPERAND 
EOI 

Definition at line 17 of file strexpr.c.

           {
       ADD, SUB, MUL, DIV, MOD, LP, RP, OPERAND, EOI
};

Function Documentation

struct val* eval3 ( void  ) [read]

Definition at line 245 of file strexpr.c.

{
       struct val     *l, *r;
       enum token    op;

       l = eval4();
       while ((op = token) == ADD || op == SUB) {
              nexttoken();
              r = eval4();

              if (!to_integer(l) || !to_integer(r)) {
                     fatal("non-numeric argument\n");
              }

              if (op == ADD) {
                     l->u.i += r->u.i;
              } else {
                     l->u.i -= r->u.i;
              }

              free_value(r);
       }

       return l;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct val* eval4 ( void  ) [read]

Definition at line 210 of file strexpr.c.

{
       struct val     *l, *r;
       enum token    op;

       l = eval6();
       while ((op = token) == MUL || op == DIV || op == MOD) {
              nexttoken();
              r = eval6();

              if (!to_integer(l) || !to_integer(r)) {
                     fatal("non-numeric argument\n");
              }

              if (op == MUL) {
                     l->u.i *= r->u.i;
              } else {
                     if (r->u.i == 0) {
                            fatal("division by zero\n");
                     }
                     if (op == DIV) {
                            l->u.i /= r->u.i;
                     } else {
                            l->u.i %= r->u.i;
                     }
              }

              free_value(r);
       }

       return l;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct val* eval6 ( void  ) [read]

Definition at line 187 of file strexpr.c.

{
       struct val *eval3(void);
       struct val     *v;

       if (token == OPERAND) {
              nexttoken();
              return tokval;

       } else if (token == LP) {
              nexttoken();
              v = eval3();

              if (token != RP)
                 fatal("missing parenthesis in expression\n");
              nexttoken();
              return v;
       } else fatal("expression error\n");
       /* NOTREACHED */
}

Here is the call graph for this function:

Here is the caller graph for this function:

void free_value ( struct val vp)

Definition at line 78 of file strexpr.c.

{
       if (vp->type == string)
              free(vp->u.s);
       free(vp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int is_integer ( struct val vp,
int r 
)

Definition at line 88 of file strexpr.c.

{
       char           *s;
       int             neg;
       int             i;

       if (vp->type == integer) {
              *r = vp->u.i;
              return 1;
       }

       /*
        * POSIX.2 defines an "integer" as an optional unary minus 
        * followed by digits.
        */
       s = vp->u.s;
       i = 0;

       neg = (*s == '-');
       if (neg)
              s++;

       while (*s) {
              if (!isdigit(*s))
                     return 0;

              i *= 10;
              i += *s - '0';

              s++;
       }

       if (neg)
              i *= -1;

       *r = i;
       return 1;
}

Here is the caller graph for this function:

struct val* make_int ( int  i) [read]

Definition at line 38 of file strexpr.c.

{
       struct val     *vp;

       vp = (struct val *) malloc(sizeof(*vp));
       if (vp == NULL) fatal("expression error\n");
       vp->type = integer;
       vp->u.i = i;
       return vp;
}
struct val* make_str ( char *  s) [read]

Definition at line 51 of file strexpr.c.

{
       char operand[32]; int i;

       struct val     *vp;

       vp = (struct val *) malloc(sizeof(*vp));
       if (vp == NULL) fatal("expression error\n");

        pexpr = s; i = 0;
        while (1) {
          if (isspace(*pexpr) || *pexpr == '\0') break;
          if (strchr(OPERATORS, *pexpr) != NULL) break;
          if (i == 30) fatal("operand too large\n");
          operand[i++] = *pexpr++;
       }
       if (i == 0) fatal("invalid operand\n");
       operand[i] = '\0';
       vp->u.s = malloc(i+1);
       if (vp->u.s == NULL) fatal("Out of memory\n");
       strcpy(vp->u.s, operand);
       vp->type = string;
       return vp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 165 of file strexpr.c.

{
       char           *i;   /* index */

       while (isspace(*pexpr)) pexpr++;

       if (*pexpr == '\0') {
              token = EOI;
              return;
       }

       if ((i = strchr(OPERATORS, *pexpr)) != NULL) {
              pexpr++;
              token = i - OPERATORS;
              return;
       }
       tokval = make_str(pexpr);
       token = OPERAND;
       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int strexpr ( int result,
char *  expression 
)

Definition at line 276 of file strexpr.c.

                                           {
       struct val     *vp;

       pexpr = expression;

        nexttoken();
       vp = eval3();

       if (token != EOI) return 1;

       if (vp->type == integer || to_integer(vp)) {
              *result = vp->u.i;
              return 0;
       }

        return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int to_integer ( struct val vp)

Definition at line 130 of file strexpr.c.

{
       int             r;

       if (vp->type == integer)
              return 1;

       if (is_integer(vp, &r)) {
              free(vp->u.s);
              vp->u.i = r;
              vp->type = integer;
              return 1;
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void to_string ( struct val vp)

Definition at line 150 of file strexpr.c.

{
       char           *tmp;

       if (vp->type == string)
              return;

       tmp = malloc(25);
       if (tmp == NULL) fatal("Out of memory\n");
       sprintf(tmp, "%d", vp->u.i);
       vp->type = string;
       vp->u.s = tmp;
}

Here is the call graph for this function:


Variable Documentation

const char* OPERATORS = "+-*/%()"

Definition at line 15 of file strexpr.c.

char* pexpr

Definition at line 35 of file strexpr.c.

enum token struct val* tokval

Definition at line 34 of file strexpr.c.