Beispiel #1
0
/* Libera el registro AL ocupado usando la variable parametro y lo retorna */
Element *free_AL(Element *variable) {
	Stack *pila_aux = (Stack *)0;
	Element *elem_aux = (Element *)malloc(sizeof(Element));
	Element *ret = (Element *)malloc(sizeof(Element));
	
	/* Busco el registro AL ocupado para liberarlo */
	spop(&pila, (void *)&elem_aux);
	while (elem_aux->code != REGISTRO || (elem_aux->code == REGISTRO && elem_aux->value != 0)) {
		spush(&pila_aux, (void *)elem_aux);
		spop(&pila, (void *)&elem_aux);
	}
	/* Vuelco el contenido del registro a liberar en la variable parametro */
	fprintf(output_fd, "\t\tMOV\t_%s, %s\n", variable->name, elem_aux->name);
	/* Apilo la variable en lugar del registro y    *
	 * guardo en la variable el registro a retornar */
	spush(&pila, (void *)variable);
	ret = load_register(0);
	/* Apilo nuevamente los demas operandos sacados de la pila */	
	while (pila_aux != (Stack *)0) {
		spop(&pila_aux, (void *)&elem_aux);
		spush(&pila, (void *)elem_aux);
	}
	
	return ret;
}
Beispiel #2
0
/* Libera cualquier registro ocupado usando la variable parametro y lo retorna */
Element *free_any_notA(Element *variable) {
	Stack *pila_aux;
	Element *elem_aux = (Element *)malloc(sizeof(Element));
	Element *ret = (Element *)malloc(sizeof(Element));
	
	/* Busco un registro ocupado que no sea ni AH ni AL, para liberarlo */
	spop(&pila, (void *)&elem_aux);
	while (elem_aux->code != REGISTRO || (elem_aux->code == REGISTRO && (elem_aux->value == 0 || elem_aux->value == 1))) {
		spush(&pila_aux, (void *)elem_aux);
		spop(&pila, (void *)&elem_aux);
	}
	/* Vuelco el contenido del registro a liberar en la variable parametro */
	fprintf(output_fd, "\t\tMOV\t_%s, %s\n", variable->name, elem_aux->name);
	/* Apilo la variable en lugar del registro y    *
	 * guardo en la variable el registro a retornar */
	spush(&pila, (void *)variable);
	ret->code = REGISTRO;
	strcpy(ret->name, elem_aux->name);
	ret->value = elem_aux->value;
	/* Apilo nuevamente los demas operandos sacados de la pila */
	spop(&pila_aux, (void *)&elem_aux);
	while (elem_aux != (Element *)0) {
		spush(&pila, (void *)elem_aux);
		spop(&pila_aux, (void *)&elem_aux);
	}
	
	return ret;
}
Beispiel #3
0
void generar_or(Element *obj) {
	Element *operando1 = (Element *)malloc(sizeof(Element));
	Element *operando2 = (Element *)malloc(sizeof(Element));
	
	spop(&pila, (void *)&operando2);
	spop(&pila, (void *)&operando1);
	if (operando1->code == REGISTRO) {
		if (operando2->code == REGISTRO) {
			//Registro-Registro
			fprintf(output_fd, "\t\tOR\t%s, %s\n", operando2->name, operando1->name);
			state[operando1->value] = 0; /*Libero el registro*/
			spush(&pila, (void *)operando2);
		} else {
			//Registro-Operando
			if (operando2->code == IDENTIFICADOR)
				fprintf(output_fd, "\t\tOR\t%s, _%s\n", operando1->name, operando2->name);
			else
				fprintf(output_fd, "\t\tOR\t%s, %d\n", operando1->name, operando2->value);
			spush(&pila, (void *)operando1);
		}
	} else {
		if (operando2->code == REGISTRO) {
			//Operando-Registro
			if (operando1->code == IDENTIFICADOR)
				fprintf(output_fd, "\t\tOR\t%s, _%s\n", operando2->name, operando1->name);
			else
				fprintf(output_fd, "\t\tOR\t%s, %d\n", operando2->name, operando1->value);
			spush(&pila, (void *)operando2);
		} else {
			//Operando-Operando
			Element *op_aux = get_free();
			if (operando1->code == IDENTIFICADOR) {
				if (operando2->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando1->name);
					fprintf(output_fd, "\t\tOR\t%s, _%s\n", op_aux->name, operando2->name);
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando1->name);
					fprintf(output_fd, "\t\tOR\t%s, %d\n", op_aux->name, operando2->value);
				}
			} else {
				if (operando2->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando1->value);
					fprintf(output_fd, "\t\tOR\t%s, _%s\n", op_aux->name, operando2->name);
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando1->value);
					fprintf(output_fd, "\t\tOR\t%s, %d\n", op_aux->name, operando2->value);
				}
			}
			spush(&pila, (void *)op_aux);
			state[op_aux->value] = 1;
		}
	}
}
Beispiel #4
0
err_t connect_cb(void *arg, struct tcp_pcb *newpcb, err_t err)
{
  cell *up = callback_up;
  if (!connect_forth_cb) {
    return 0;
  }
  spush((cell)err, up);
  spush((cell)newpcb, up);
  spush(arg, up);

  return execute_xt_pop(connect_forth_cb, up);
}
Beispiel #5
0
void gethostbyname_cb(char *name, struct ip_addr *ipaddr, void *arg)
{
  cell *up = callback_up;
  if (!gethostbyname_forth_cb) {
    return;
  }
  SWITCH_STACKS("gh");
  spush(arg, up);
  spush((cell)ipaddr, up);
  spush((cell)name, up);

  execute_xt(gethostbyname_forth_cb, up);
  RESTORE_STACKS;
}
Beispiel #6
0
void err_cb(void *arg, err_t err)
{
  cell *up = callback_up;
  if (!err_forth_cb) {
    return;
  }

  SWITCH_STACKS("err");
  spush((cell)err, up);
  spush(arg, up);

  execute_xt(err_forth_cb, up);
  RESTORE_STACKS;
}
Beispiel #7
0
err_t poll_cb(void *arg, struct tcp_pcb *tpcb)
{
  cell *up = callback_up;
  if (!poll_forth_cb) {
    return 0;
  }
  SWITCH_STACKS("poll");
  spush((cell)tpcb, up);
  spush(arg, up);

  err_t retval = execute_xt_pop(poll_forth_cb, up);
  RESTORE_STACKS;
  return retval;
}
Beispiel #8
0
err_t sent_cb(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
  cell *up = callback_up;
  if (!sent_forth_cb) {
    return 0;
  }
  SWITCH_STACKS("sent");
  spush((cell)len, up);
  spush((cell)tpcb, up);
  spush(arg, up);

  err_t retval = execute_xt_pop(sent_forth_cb, up);
  RESTORE_STACKS;
  return retval;
}
Beispiel #9
0
err_t accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err)
{
  cell *up = callback_up;
  if (!accept_forth_cb) {
    return 0;
  }
  SWITCH_STACKS("ac");
  spush((cell)err, up);
  spush((cell)newpcb, up);
  spush(arg, up);

  err_t retval = execute_xt_pop(accept_forth_cb, up);
  RESTORE_STACKS;
  return retval;
}
Beispiel #10
0
err_t continuation_cb(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
  cell *up = callback_up;
  if (!sent_forth_cb) {
    return 0;
  }
  SWITCH_STACKS("cont");
  spush((cell)len, up);
  spush((cell)tpcb, up);
  spush(arg, up);

  err_t retval = inner_interpreter(up);
  RESTORE_STACKS;
  return retval;
}
Beispiel #11
0
void parsearglist(void) {
	vpush((numvar) arg);				// save base of current argblock
#if defined(STRING_POOL)
	vpush((numvar) stringPool);			// save stringPool base for later release
	strpush(idbuf);						// save called function's name as arg[-1]
#endif
	numvar *newarg = &vstack[vsptr];	// move global arg pointer to base of new block
	vpush(0);							// initialize new arg(0) (a/k/a argc) to 0

	if (sym == s_lparen) {
		getsym();		// eat arglist '('
		while ((sym != s_rparen) && (sym != s_eof)) {

#if defined(STRING_POOL)
			if (sym == s_quote) {
				vpush((numvar) stringPool);	// push the string pointer
				parsestring(&spush);		// parse it into the pool
				spush(0);					// and terminate it
				getsym();					// eat closing "
			} else 
#endif
			vpush(getnum());				// push the value
			newarg[0]++;					// bump the count
			if (sym == s_comma) getsym();	// eat arglist ',' and go around
			else break;
		}
		if (sym == s_rparen) getsym();		// eat the ')'
		else expected(M_rparen);
	}
	arg = newarg;		// activate new argument frame
}
Beispiel #12
0
int _ol_grow_and_rehash_db(ol_database *db) {
    int i;
    ol_bucket *bucket;
    ol_bucket **tmp_hashes = NULL;

    size_t to_alloc = db->cur_ht_size * 2;
    debug("Growing DB to %zu bytes.", to_alloc);
    tmp_hashes = calloc(1, to_alloc);
    check_mem(tmp_hashes);

    struct ol_stack *orphans = NULL;
    orphans = malloc(sizeof(struct ol_stack));
    check_mem(orphans);
    orphans->next = NULL;
    orphans->data = NULL;
    int orphans_found = 0;

    int iterations = ol_ht_bucket_max(db->cur_ht_size);
    for (i = 0; i < iterations; i++) {
        bucket = db->hashes[i];
        if (bucket != NULL) {
            if (bucket->next != NULL) {
                ol_bucket *tmp_bucket = bucket;
                do {
                    spush(&orphans, tmp_bucket->next);

                    ol_bucket *next = tmp_bucket->next;
                    tmp_bucket->next = NULL;
                    tmp_bucket = next;

                    orphans_found++;
                } while (tmp_bucket->next != NULL);
            }
            /* Rehash the bucket itself. */
            _ol_rehash_insert_bucket(tmp_hashes, to_alloc, bucket);
        }
    }

    /* Take care of our orphans */
    ol_log_msg(LOG_INFO, "Have %i orphans to take care of.", orphans_found);
    do {
        ol_bucket *rebucket = spop(&orphans);
        _ol_rehash_insert_bucket(tmp_hashes, to_alloc, rebucket);

        orphans_found--;
    } while (orphans->next != NULL);
    ol_log_msg(LOG_INFO, "We now have %i orphans not accounted for.", orphans_found);

    free(orphans);
    free(db->hashes);
    db->hashes = tmp_hashes;
    db->cur_ht_size = to_alloc;
    debug("Current hash table size is now: %zu bytes.", to_alloc);
    return 0;

error:
    if (tmp_hashes != NULL)
        free(tmp_hashes);
    return -1;
}
Beispiel #13
0
void generar_comparacion(Element *obj, char *etiqueta) {
	Element *operando1 = (Element *)malloc(sizeof(Element));
	Element *operando2 = (Element *)malloc(sizeof(Element));

	spop(&pila, (void *)&operando2);
	spop(&pila, (void *)&operando1);
	if (operando1->code == REGISTRO) {
		if (operando2->code == REGISTRO) {
			//Registro-Registro
			fprintf(output_fd, "\t\tCMP\t%s, %s\n", operando1->name, operando2->name);
		} else {
			//Registro-Operando
			if (operando2->code == IDENTIFICADOR)
				fprintf(output_fd, "\t\tCMP\t%s, _%s\n", operando1->name, operando2->name);
			else
				fprintf(output_fd, "\t\tCMP\t%s, %d\n", operando1->name, operando2->value);
		}
	} else {
		Element *op_aux2 = get_free(state);
		if (operando2->code == REGISTRO) {
			//Operando-Registro
			if (operando1->code == IDENTIFICADOR) {
				fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name);
				fprintf(output_fd, "\t\tCMP\t%s, %s\n", operando2->name, op_aux2->name);
			} else {
				fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value);
				fprintf(output_fd, "\t\tCMP\t%s, %s\n", operando2->name, op_aux2->name);
			}
		} else {
			//Operando-Operando
			if (operando1->code == IDENTIFICADOR) {
				if (operando2->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name);
					fprintf(output_fd, "\t\tCMP\t%s, _%s\n", op_aux2->name, operando2->name);
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name);
					fprintf(output_fd, "\t\tCMP\t%s, %d\n", op_aux2->name, operando2->value);
				}
			} else {
				if (operando2->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value);
					fprintf(output_fd, "\t\tCMP\t%s, _%s\n", op_aux2->name, operando2->name);
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value);
					fprintf(output_fd, "\t\tCMP\t%s, %d\n", op_aux2->name, operando2->value);
				}
			}
		}
	}
	Element *op_aux = get_free();
	state[op_aux->value] = 1;
	spush(&pila, (void *)op_aux);
	fprintf(output_fd, "\t\t%s\tLABEL00%d\n", etiqueta, labelnumber);
	fprintf(output_fd, "\t\tMOV\t%s, 0\n", op_aux->name);
	fprintf(output_fd, "\t\tJMP\tLABEL00%d\n", labelnumber+1);
	fprintf(output_fd, "\tLABEL00%d:\n\t\tMOV\t%s, 1\n", labelnumber, op_aux->name);
	labelnumber++;
	fprintf(output_fd, "\tLABEL00%d:\n", labelnumber);
	labelnumber++;
}
Beispiel #14
0
err_t recv_cb(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
  cell *up = callback_up;

  if (!recv_forth_cb) {
    return 0;
  }
  SWITCH_STACKS("recv");
  spush((cell)err, up);
  spush((cell)p, up);
  spush((cell)tpcb, up);
  spush(arg, up);

  err_t retval = execute_xt_pop(recv_forth_cb, up);
  RESTORE_STACKS;
  return retval;
}
Beispiel #15
0
void generar_not(Element *obj) {
	Element *operando = (Element *)malloc(sizeof(Element));

	spop(&pila, (void *)&operando);
	if (operando->code == REGISTRO) {
		fprintf(output_fd, "\t\tNOT\t%s\n", operando->name);
		spush(&pila, (void *)operando);
	} else {
		Element *op_aux = get_free();
		if (operando->code == IDENTIFICADOR) {
			fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando->name);
		} else {
			fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando->value);
		}
		fprintf(output_fd, "\t\tNOT\t%s\n", op_aux->name);
		state[op_aux->value] = 1;
		spush(&pila, (void *)op_aux);
	}
}
Beispiel #16
0
void stack_init (void)
{
   what_are_we_in_stk = more_chars ();
   wawi_push (0);
   if ((while_stack = more_whiles ()) == NULL)
   {
      perror ("no more whiles");
      return;
   }
   switch_stack = more_switches ();
   wpush (NULL);
   in_while--; 
   wawi_stk_ptr--;
   spush (NULL);
   in_switch--;
   wawi_stk_ptr--;
}
Beispiel #17
0
/* Generar el codigo con el algoritmo de seguimiento de registros */
void generate() {
	Element *obj;
	extern Symbol *symbol_table;

	fprintf(output_fd, ".MODEL SMALL\n.CODE\n\t\tORG\t100h\n__MAIN:\t\t\t\t\t; Cuerpo\n");
	while (element_stack != (Element *)0) {
		obj = pop();
		if (is_operand(obj)) {
			spush(&pila, (void *)obj);
		} else {
			switch (obj->code) {
				case '+':
					generar_suma(obj);
					break;
				case '-':
					generar_resta(obj);
					break;
				case '*':
					generar_multiplicacion(obj);
					break;
				case '/':
					generar_division(obj);
					break;
				case '=':
					generar_asignacion(obj);
					break;
				case '!':
					generar_not(obj);
					break;
				case AND:
					generar_and(obj);
					break;
				case OR:
					generar_or(obj);
					break;
				case MENOR_IGUAL:
					generar_comparacion(obj, "JBE");
					break;
				case MAYOR_IGUAL:
					generar_comparacion(obj, "JAE");
					break;
				case DISTINTO:
					generar_comparacion(obj, "JNE");
					break;
				case IGUAL:
					generar_comparacion(obj, "JE");
					break;
				case '>':
					generar_comparacion(obj, "JA");
					break;
				case '<':
					generar_comparacion(obj, "JB");
					break;
				case BF:
					generar_BF(obj);
					break;
				case BI:
					generar_BI(obj);
					break;
				case CL:
					create_label(obj);
					break;
			}
		}
	}
	// Rutina de fin de programa
	fprintf(output_fd, "\tLABEL FIN:\t\t\t; Fin de programa\n");
	fprintf(output_fd, "\t\tMOV\tAH, 00h\n");
	fprintf(output_fd, "\t\tINT\t21h\n");
	
	/* Generar las declaraciones de variables a partir de la tabla de simbolos */
	Symbol *sym;

	fprintf(output_fd, "\n\n\t\tORG\t1000h\t\t; Definicion de variables\n");
	while (symbol_table != (Symbol *)0) {
		sym = get_first();
		fprintf(output_fd, "\t\t_%s", sym->name);
		fprintf(output_fd, "\tDB\t0\n");
	}
	
	// Cierre de __MAIN
	fprintf(output_fd, "END __MAIN\n");
}
Beispiel #18
0
void generar_division(Element *obj) {
	Element *operando1 = (Element *)malloc(sizeof(Element));
	Element *operando2 = (Element *)malloc(sizeof(Element));

	spop(&pila, (void *)&operando2);
	spop(&pila, (void *)&operando1);
	if (operando1->code == REGISTRO && operando1->value == 0) {
		//operando1 ya esta en AL, pasar operando2 a un registro distinto de AH, si es necesario
		;
	} else {
		if (operando2->code == REGISTRO && operando2->value == 0) {
			//operando2 esta en AL, pasar a operando2 a un registro distinto y pasar operando1 a AL
			Element *op_aux = get_free_notA();
			fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando2->name);
			fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando2->name);
			operando2 = op_aux;
			state[operando2->value] = 1;
			
			Element *op_aux2 = get_free_AL();
			if (operando1->code == REGISTRO) {
				fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux2->name, operando1->name);
				state[operando1->value] = 0;
				operando1 = op_aux2;
			} else {
				if (operando1->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name);
					operando1 = op_aux2;
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value);
					operando1 = op_aux2;				
				}
			}
		} else {
			//ninguno esta en AL. Pasar operando1 a AL y operando2 a un registro distinto de AH, si es necesario
			Element *op_aux = get_free_AL();
			if (operando1->code == REGISTRO) {
				fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando1->name);
				state[operando1->value] = 0;
				operando1 = op_aux;
			} else {
				if (operando1->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando1->name);
					operando1 = op_aux;
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando1->value);
					operando1 = op_aux;
				}
			}
			state[0] = 1;
		}
	}
	if (operando2->code == REGISTRO) {
		if (operando2->value == 1) {
			//esta en AH, moverlo a otro registro libre.
			Element *op_aux = get_free_notA();
			fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando2->name);
			operando2 = op_aux;
			state[operando2->value] = 1;
		} else {
			//esta en otro registro. No hacer nada.
			;
		}
	} else {
		//conseguir un registro libre distinto de AH y mover operando2 alli.
		Element *op_aux = get_free_notA();
		if (operando2->code == IDENTIFICADOR) {
			fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando2->name);
			operando2 = op_aux;
		} else {
			fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando2->value);
			operando2 = op_aux;
		}
		state[operando2->value] = 1;
	}
	state[1] = 0;
	
	// Chequear por división por cero
	fprintf(output_fd, "\t\tJNZ\tLABEL00%d\t; Chequeo de división por cero\n", labelnumber);

  incluir_recuperacion_div_cero(operando2);

	fprintf(output_fd, "\tLABEL00%d:\n\t\tCBW\n", labelnumber);
	labelnumber++;


	//A esta altura, operando1 es AL y operando2 es otro registro distinto de AH
	fprintf(output_fd, "\t\tIDIV\t%s\n", operando2->name);
	state[operando2->value] = 0; /*Libero el registro*/
	//Apilo AL, el cociente
	spush(&pila, (void *)operando1);
}
Beispiel #19
0
 void lpush()           { spush(); spush(); }
Beispiel #20
0
// push a string into the string pool
void strpush(char *ptr) {
	while (*ptr) spush(*ptr++);
	spush(0);
}
Beispiel #21
0
static inline char *
tparam_internal(const char *string, int *dataptr)
{
#define NUM_VARS 26
    char *p_is_s[9];
    int param[9];
    int lastpop;
    int popcount;
    int number;
    int len;
    int level;
    int x, y;
    int i;
    int len2;
    register const char *cp;
    static int len_fmt = MAX_FORMAT_LEN;
    static char dummy[] = "";
    static char format[MAX_FORMAT_LEN];
    static int dynamic_var[NUM_VARS];
    static int static_vars[NUM_VARS];

    out_used = 0;
    if (string == NULL)
	return NULL;

    if ((len2 = grub_strlen(string)) > len_fmt) {
	return NULL;
    }

    /*
     * Find the highest parameter-number referred to in the format string.
     * Use this value to limit the number of arguments copied from the
     * variable-length argument list.
     */

    number = 0;
    lastpop = -1;
    popcount = 0;
    grub_memset(p_is_s, 0, sizeof(p_is_s));

    /*
     * Analyze the string to see how many parameters we need from the varargs
     * list, and what their types are.  We will only accept string parameters
     * if they appear as a %l or %s format following an explicit parameter
     * reference (e.g., %p2%s).  All other parameters are numbers.
     *
     * 'number' counts coarsely the number of pop's we see in the string, and
     * 'popcount' shows the highest parameter number in the string.  We would
     * like to simply use the latter count, but if we are reading termcap
     * strings, there may be cases that we cannot see the explicit parameter
     * numbers.
     */
    for (cp = string; (cp - string) < (int) len2;) {
	if (*cp == '%') {
	    cp++;
	    cp = parse_format(cp, format, &len);
	    switch (*cp) {
	    default:
		break;

	    case 'd':		/* FALLTHRU */
	    case 'o':		/* FALLTHRU */
	    case 'x':		/* FALLTHRU */
	    case 'X':		/* FALLTHRU */
	    case 'c':		/* FALLTHRU */
		number++;
		lastpop = -1;
		break;

	    case 'l':
	    case 's':
		if (lastpop > 0)
		    p_is_s[lastpop - 1] = dummy;
		++number;
		break;

	    case 'p':
		cp++;
		i = (*cp - '0');
		if (i >= 0 && i <= 9) {
		    lastpop = i;
		    if (lastpop > popcount)
			popcount = lastpop;
		}
		break;

	    case 'P':
	    case 'g':
		cp++;
		break;

	    case '\'':
		cp += 2;
		lastpop = -1;
		break;

	    case '{':
		cp++;
		while (*cp >= '0' && *cp <= '9') {
		    cp++;
		}
		break;

	    case '+':
	    case '-':
	    case '*':
	    case '/':
	    case 'm':
	    case 'A':
	    case 'O':
	    case '&':
	    case '|':
	    case '^':
	    case '=':
	    case '<':
	    case '>':
	    case '!':
	    case '~':
		lastpop = -1;
		number += 2;
		break;

	    case 'i':
		lastpop = -1;
		if (popcount < 2)
		    popcount = 2;
		break;
	    }
	}
	if (*cp != '\0')
	    cp++;
    }

    if (number > 9)
	number = 9;
    for (i = 0; i < max(popcount, number); i++) {
	/*
	 * A few caps (such as plab_norm) have string-valued parms.
	 * We'll have to assume that the caller knows the difference, since
	 * a char* and an int may not be the same size on the stack.
	 */
	if (p_is_s[i] != 0) {
	  p_is_s[i] = (char *)(*(dataptr++));
	} else {
	  param[i] = (int)(*(dataptr++));
	}
    }

    /*
     * This is a termcap compatibility hack.  If there are no explicit pop
     * operations in the string, load the stack in such a way that
     * successive pops will grab successive parameters.  That will make
     * the expansion of (for example) \E[%d;%dH work correctly in termcap
     * style, which means tparam() will expand termcap strings OK.
     */
    stack_ptr = 0;
    if (popcount == 0) {
	popcount = number;
	for (i = number - 1; i >= 0; i--)
	    npush(param[i]);
    }

    while (*string) {
        /* skip delay timings */
	if (*string == '$' && *(string + 1) == '<') {
	    while( *string && *string != '>') 
	        string++;
	    if ( *string == '>' ) string++;
	} else if ( *string == '%') {
	    string++;
	    string = parse_format(string, format, &len);
	    switch (*string) {
	    default:
		break;
	    case '%':
		save_char('%');
		break;

	    case 'd':		/* FALLTHRU */
	    case 'o':		/* FALLTHRU */
	    case 'x':		/* FALLTHRU */
	    case 'X':		/* FALLTHRU */
	    case 'c':		/* FALLTHRU */
		save_number(format, npop(), len);
		break;

	    case 'l':
		save_number("%d", strlen(spop()), 0);
		break;

	    case 's':
		save_text(format, spop(), len);
		break;

	    case 'p':
		string++;
		i = (*string - '1');
		if (i >= 0 && i < 9) {
		    if (p_is_s[i])
			spush(p_is_s[i]);
		    else
			npush(param[i]);
		}
		break;

	    case 'P':
		string++;
		if (isUPPER(*string)) {
		    i = (*string - 'A');
		    static_vars[i] = npop();
		} else if (isLOWER(*string)) {
		    i = (*string - 'a');
		    dynamic_var[i] = npop();
		}
		break;

	    case 'g':
		string++;
		if (isUPPER(*string)) {
		    i = (*string - 'A');
		    npush(static_vars[i]);
		} else if (isLOWER(*string)) {
		    i = (*string - 'a');
		    npush(dynamic_var[i]);
		}
		break;

	    case '\'':
		string++;
		npush(*string);
		string++;
		break;

	    case '{':
		number = 0;
		string++;
		while (*string >= '0' && *string <= '9') {
		    number = number * 10 + *string - '0';
		    string++;
		}
		npush(number);
		break;

	    case '+':
		npush(npop() + npop());
		break;

	    case '-':
		y = npop();
		x = npop();
		npush(x - y);
		break;

	    case '*':
		npush(npop() * npop());
		break;

	    case '/':
		y = npop();
		x = npop();
		npush(y ? (x / y) : 0);
		break;

	    case 'm':
		y = npop();
		x = npop();
		npush(y ? (x % y) : 0);
		break;

	    case 'A':
		npush(npop() && npop());
		break;

	    case 'O':
		npush(npop() || npop());
		break;

	    case '&':
		npush(npop() & npop());
		break;

	    case '|':
		npush(npop() | npop());
		break;

	    case '^':
		npush(npop() ^ npop());
		break;

	    case '=':
		y = npop();
		x = npop();
		npush(x == y);
		break;

	    case '<':
		y = npop();
		x = npop();
		npush(x < y);
		break;

	    case '>':
		y = npop();
		x = npop();
		npush(x > y);
		break;

	    case '!':
		npush(!npop());
		break;

	    case '~':
		npush(~npop());
		break;

	    case 'i':
		if (p_is_s[0] == 0)
		    param[0]++;
		if (p_is_s[1] == 0)
		    param[1]++;
		break;

	    case '?':
		break;

	    case 't':
		x = npop();
		if (!x) {
		    /* scan forward for %e or %; at level zero */
		    string++;
		    level = 0;
		    while (*string) {
			if (*string == '%') {
			    string++;
			    if (*string == '?')
				level++;
			    else if (*string == ';') {
				if (level > 0)
				    level--;
				else
				    break;
			    } else if (*string == 'e' && level == 0)
				break;
			}

			if (*string)
			    string++;
		    }
		}
		break;

	    case 'e':
		/* scan forward for a %; at level zero */
		string++;
		level = 0;
		while (*string) {
		    if (*string == '%') {
			string++;
			if (*string == '?')
			    level++;
			else if (*string == ';') {
			    if (level > 0)
				level--;
			    else
				break;
			}
		    }

		    if (*string)
			string++;
		}
		break;

	    case ';':
		break;

	    }			/* endswitch (*string) */
	} else {             	/* endelse (*string == '%') */
	    save_char(*string);
	}

	if (*string == '\0')
	    break;

	string++;
    }				/* endwhile (*string) */

    get_space(1);
    out_buff[out_used] = '\0';

    return (out_buff);
}
Beispiel #22
0
// Algoritme 'Shunting Yard' pour faire la conversion du type Infixée pour le RPN
char *shuntingYard(char *stringRPN){
#define spush(x) conversionStack[l_stack++].valeur = x
#define spop()   conversionStack[--l_stack].valeur

    char *valeurIndiv = (char*) strtok(stringRPN, " ");
    char *postFixe = malloc(100 * sizeof(char));
    opAssoc conversionStack[100];
    int l_stack = 0;
    int flag = 0;

    strcpy(postFixe, "");

    while(valeurIndiv != NULL) {
        // Si le caractère est constante mettre dans la pile
        if((ILESTNOMBRE) || (ILESTVARIABLE)) {
            strcat(postFixe, valeurIndiv);
            strcat(postFixe, " ");
        
        // Si non, on doit verifier sa priorité et associativité    
        } else {
            if (PRIORITEDEUX) {
                conversionStack[l_stack].priorite = 2;
                conversionStack[l_stack].associativite = 1;
            }
            else if (PRIORITETROIS) {
                conversionStack[l_stack].priorite = 3;
                conversionStack[l_stack].associativite = 1;
            }
            
            else {
                conversionStack[l_stack].priorite = 0;
                conversionStack[l_stack].associativite = 0;
            }
            
            // Verification s'il y a la presence d'un ()
            if (valeurIndiv[0] == '(')
                flag = l_stack;
            
            // Verification de la priorite de l'algoritme
            if (l_stack && conversionStack[l_stack-1].priorite == conversionStack[l_stack].priorite) {
                strcat(postFixe, spop());
                strcat(postFixe, " ");
                
                conversionStack[l_stack].priorite = conversionStack[l_stack+1].priorite;
            }
            
            spush(valeurIndiv);
        }
        
        if(valeurIndiv[0] == ')') {
                l_stack--;
                while(l_stack != flag+1) {
                    strcat(postFixe, spop());
                    strcat(postFixe, " ");
                }
                l_stack--;
        }
        
        valeurIndiv = (char*) strtok(NULL, " ");
    }
    
    // Si il a déjà fini fait le pop jusqu'à le fin
    while(l_stack) {
        strcat(postFixe, spop());
        strcat(postFixe, " ");
    }

    free(valeurIndiv);
    return postFixe;

}
Beispiel #23
0
static _cstackitem *
_push_frame(_pit *cp)
{
    return spush(current_ctx->cs, cp);
}
Beispiel #24
0
void generar_multiplicacion(Element *obj) {
	Element *operando1 = (Element *)malloc(sizeof(Element));
	Element *operando2 = (Element *)malloc(sizeof(Element));

	spop(&pila, (void *)&operando2);
	spop(&pila, (void *)&operando1);
	if (operando1->code == REGISTRO && operando1->value == 0) {
		//operando1 ya esta en AL, pasar operando2 a un registro distinto de AH, si es necesario
		;
	} else {
		if (operando2->code == REGISTRO && operando2->value == 0) {
			//operando2 esta en AL, swapear las variables y pasar a operando2 a un registro distinto de AH, si es necesario
			Element *aux = operando1;
			operando1 = operando2;
			operando2 = aux;
		} else {
			//ninguno esta en AL. Pasar operando1 a AL y operando2 a un registro distinto de AH, si es necesario
			Element *op_aux = get_free_AL();
			if (operando1->code == REGISTRO) {
				fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando1->name);
				state[operando1->value] = 0;
				operando1 = op_aux;
			} else {
				if (operando1->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando1->name);
					operando1 = op_aux;
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando1->value);
					operando1 = op_aux;				
				}
			}
			state[0] = 1;
		}
	}
	if (operando2->code == REGISTRO) {
		if (operando2->value == 1) {
			//esta en AH, moverlo a otro registro libre.
			Element *op_aux = get_free_notA();
			fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando2->name);
			operando2 = op_aux;
			state[operando2->value] = 1;
		} else {
			//esta en otro registro. No hacer nada.
			;
		}
	} else {
		//conseguir un registro libre distinto de AH y mover operando2 alli.
		Element *op_aux = get_free_notA();
		if (operando2->code == IDENTIFICADOR) {
			fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando2->name);
			operando2 = op_aux;
		} else {
			fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando2->value);
			operando2 = op_aux;
		}
		state[operando2->value] = 1;
	}
	state[1] = 0;

	//A esta altura, operando1 es AL y operando2 es otro registro distinto de AH
	fprintf(output_fd, "\t\tIMUL\t%s\n", operando2->name);

  incluir_chequeo_overflow(operando1);

	state[operando2->value] = 0; /*Libero el registro*/
	//Apilo AL, la parte baja del resultado
	spush(&pila, (void *)operando1);
}
Beispiel #25
0
static char *receive_chunked_http(const int request_fd) {
	char *raw_buf = NULL;
	size_t buf_size = 0;
	int times_read = 0;

	fd_set chan_fds;
	FD_ZERO(&chan_fds);
	FD_SET(request_fd, &chan_fds);
	const int maxfd = request_fd;

	while (1) {
		times_read++;

		/* Wait for data to be read. */
		struct timeval tv = {
			.tv_sec = SELECT_TIMEOUT,
			.tv_usec = 0
		};
		select(maxfd + 1, &chan_fds, NULL, NULL, &tv);

		int count;
		/* How many bytes should we read: */
		ioctl(request_fd, FIONREAD, &count);
		if (count <= 0)
			break;
		int old_offset = buf_size;
		buf_size += count;
		if (raw_buf != NULL) {
			char *new_buf = realloc(raw_buf, buf_size);
			if (new_buf != NULL) {
				raw_buf = new_buf;
			} else {
				goto error;
			}
		} else {
			raw_buf = calloc(1, buf_size);
		}

		int recvd = recv(request_fd, raw_buf + old_offset, count, 0);
		if (recvd != count) {
			log_msg(LOG_WARN, "Could not receive entire message.");
		}
	}
	/* printf("Full message is %s\n.", raw_buf); */
	/* Check for a 200: */
	if (raw_buf == NULL || strstr(raw_buf, "200") == NULL) {
		log_msg(LOG_ERR, "Could not find 200 return code in response.");
		goto error;
	}

	/* 4Chan throws us data as chunk-encoded HTTP. Rad. */
	char *header_end = strstr(raw_buf, "\r\n\r\n");
	char *cursor_pos = header_end  + (sizeof(char) * 4);

	size_t json_total = 0;
	char *json_buf = NULL;

	while (1) {
		/* This is where the data begins. */
		char *chunk_size_start = cursor_pos;
		char *chunk_size_end = strstr(chunk_size_start, "\r\n");
		const int chunk_size_end_oft = chunk_size_end - chunk_size_start;

		/* We cheat a little and set the first \r to a \0 so strtol will
		 * do the right thing. */
		chunk_size_start[chunk_size_end_oft] = '\0';
		const int chunk_size = strtol(chunk_size_start, NULL, 16);

		/* printf("Chunk size is %i. Thing is: %s.\n", chunk_size, chunk_size_start); */
		/* The chunk string, the \r\n after it, the chunk itself and then another \r\n: */
		cursor_pos += chunk_size + chunk_size_end_oft + 4;

		/* Copy the json into a pure buffer: */
		int old_offset = json_total;
		json_total += chunk_size;
		if (json_total >= old_offset) {
			if (json_buf != NULL) {
				char *new_buf = realloc(json_buf, json_total);
				if (new_buf != NULL) {
					json_buf = new_buf;
				} else {
					goto error;
				}
			} else {
				json_buf = calloc(1, json_total);
			}
		}
		/* Copy it from after the <chunk_size>\r\n to the end of the chunk. */
		memcpy(json_buf + old_offset, chunk_size_end + 2, chunk_size);
		/* Stop reading if we am play gods: */
		if ((cursor_pos - raw_buf) > buf_size || chunk_size <= 0)
			break;
	}
	/* printf("The total json size is %zu.\n", json_total); */
	/* printf("JSON:\n%s", json_buf); */
	free(raw_buf);

	return json_buf;

error:
	if (raw_buf != NULL)
		free(raw_buf);
	return NULL;
}

static int connect_to_host(const char *host) {
	struct addrinfo hints = {0};
	struct addrinfo *res = NULL;
	int request_fd;

	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;

	getaddrinfo(host, "80", &hints, &res);

	request_fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if (request_fd < 0) {
		log_msg(LOG_ERR, "Could not create socket.");
		goto error;
	}

	int opt = 1;
	setsockopt(request_fd, SOL_SOCKET, SO_REUSEADDR, (void*) &opt, sizeof(opt));

	int rc = connect(request_fd, res->ai_addr, res->ai_addrlen);
	if (rc == -1) {
		log_msg(LOG_ERR, "Could not connect to host %s.", host);
		goto error;
	}

	freeaddrinfo(res);
	return request_fd;

error:
	freeaddrinfo(res);
	close(request_fd);
	return -1;
}

static char *receive_http(const int request_fd, size_t *out) {
	char *raw_buf = NULL;
	size_t buf_size = 0;
	int times_read = 0;

	fd_set chan_fds;
	FD_ZERO(&chan_fds);
	FD_SET(request_fd, &chan_fds);
	const int maxfd = request_fd;

	while (1) {
		times_read++;

		/* Wait for data to be read. */
		struct timeval tv = {
			.tv_sec = SELECT_TIMEOUT,
			.tv_usec = 0
		};
		select(maxfd + 1, &chan_fds, NULL, NULL, &tv);

		int count;
		/* How many bytes should we read: */
		ioctl(request_fd, FIONREAD, &count);
		if (count <= 0)
			break;
		int old_offset = buf_size;
		buf_size += count;
		if (raw_buf != NULL) {
			char *new_buf = realloc(raw_buf, buf_size);
			if (new_buf != NULL) {
				raw_buf = new_buf;
			} else {
				goto error;
			}
		} else {
			raw_buf = calloc(1, buf_size);
		}
		/* printf("IOCTL: %i.\n", count); */

		recv(request_fd, raw_buf + old_offset, count, 0);
	}
	/* printf("Full message is %s\n.", raw_buf); */
	/* Check for a 200: */
	if (raw_buf == NULL || strstr(raw_buf, "200") == NULL) {
		log_msg(LOG_ERR, "Could not find 200 return code in response.");
		goto error;
	}

	/* 4Chan throws us data as chunk-encoded HTTP. Rad. */
	char *header_end = strstr(raw_buf, "\r\n\r\n");
	char *cursor_pos = header_end  + (sizeof(char) * 4);

	size_t result_size = 0;
	char *offset_for_clength = strnstr(raw_buf, "Content-Length: ", buf_size);
	if (offset_for_clength == NULL) {
		log_msg(LOG_ERR, "Could not find content-length.");
		goto error;
	}

	char siz_buf[128] = {0};
	int i = 0;

	const char *to_read = offset_for_clength + strlen("Content-Length: ");
	while (to_read[i] != '\r' && to_read[i + 1] != '\n' && i < sizeof(siz_buf)) {
		siz_buf[i] = to_read[i];
		i++;
	}
	result_size = strtol(siz_buf, NULL, 10);
	log_msg(LOG_INFO, "Received %lu bytes.", result_size);

	char *to_return = malloc(result_size);
	memcpy(to_return, cursor_pos, result_size);
	*out = result_size;
	free(raw_buf);

	return to_return;

error:
	if (raw_buf != NULL)
		free(raw_buf);
	return NULL;
}

static void ensure_directory_for_board(const char *board) {
	/* Long enough for WEBMS_DIR, a /, the board and a NULL terminator */
	const size_t buf_siz = strlen(webm_location()) + sizeof(char) * 2 + strnlen(board, MAX_BOARD_NAME_SIZE);
	char to_create[buf_siz];
	memset(to_create, '\0', buf_siz);

	/* ./webms/b */
	snprintf(to_create, buf_siz, "%s/%s", webm_location(), board);

	struct stat st = {0};
	if (stat(to_create, &st) == -1) {
		log_msg(LOG_WARN, "Creating directory %s.", to_create);
		mkdir(to_create, 0755);
	}
}

static ol_stack *build_thread_index() {
	int request_fd = 0;
	request_fd = connect_to_host(FOURCHAN_API_HOST);
	if (request_fd < 0) {
		log_msg(LOG_ERR, "Could not connect to %s.", FOURCHAN_API_HOST);
		goto error;
	}
	log_msg(LOG_INFO, "Connected to %s.", FOURCHAN_API_HOST);

	/* This is where we'll queue up images to be downloaded. */
	ol_stack *images_to_download = NULL;
	images_to_download = malloc(sizeof(ol_stack));
	images_to_download->next = NULL;
	images_to_download->data = NULL;

	int i;
	for (i = 0; i < (sizeof(BOARDS)/sizeof(BOARDS[0])); i++) {
		const char *current_board = BOARDS[i];

		const size_t api_request_siz = strlen(CATALOG_REQUEST) + strnlen(current_board, MAX_BOARD_NAME_SIZE);
		char new_api_request[api_request_siz];
		memset(new_api_request, '\0', api_request_siz);

		snprintf(new_api_request, api_request_siz, CATALOG_REQUEST, current_board);
		int rc = send(request_fd, new_api_request, strlen(new_api_request), 0);
		if (strlen(new_api_request) != rc)
			goto error;

		log_msg(LOG_INFO, "Sent request to %s.", FOURCHAN_API_HOST);
		char *all_json = receive_chunked_http(request_fd);
		if (all_json == NULL) {
			log_msg(LOG_WARN, "Could not receive chunked HTTP from board for /%s/.", current_board);
			continue;
		}

		ol_stack *matches = parse_catalog_json(all_json, current_board);

		while (matches->next != NULL) {
			/* Pop our thread_match off the stack */
			thread_match *match = (thread_match*) spop(&matches);
			ensure_directory_for_board(match->board);

			log_msg(LOG_INFO, "/%s/ - Requesting thread %i...", current_board, match->thread_num);

			/* Template out a request to the 4chan API for it */
			/* (The 30 is because I don't want to find the length of the
			 * integer thread number) */
			const size_t thread_req_size = sizeof(THREAD_REQUEST) + strnlen(match->board, MAX_BOARD_NAME_SIZE) + 30;
			char templated_req[thread_req_size];
			memset(templated_req, '\0', thread_req_size);

			snprintf(templated_req, thread_req_size, THREAD_REQUEST,
					match->board, match->thread_num);

			/* Send that shit over the wire */
			rc = send(request_fd, templated_req, strlen(templated_req), 0);
			if (rc != strlen(templated_req)) {
				log_msg(LOG_ERR, "Could not send all of request.");
				continue;
			}

			char *thread_json = receive_chunked_http(request_fd);
			if (thread_json == NULL) {
				log_msg(LOG_WARN, "Could not receive chunked HTTP for thread. continuing.");
				/* Reopen and manipulate the socket. */
				close(request_fd);
				request_fd = connect_to_host(FOURCHAN_API_HOST);
				free(match);
				continue;
			}

			ol_stack *thread_matches = parse_thread_json(thread_json, match);
			while (thread_matches->next != NULL) {
				post_match *p_match = (post_match *)spop(&thread_matches);
				/* TODO: Don't add it to the images to download if we already
				 * have that image, with that size, from that board. */
				char fname[MAX_IMAGE_FILENAME_SIZE] = {0};
				get_image_filename(fname, p_match);

				struct stat ifname = {0};
				if (stat(fname, &ifname) != -1 &&
					ifname.st_size == p_match->size) {
					log_msg(LOG_INFO, "Skipping %s.", fname);
					free(p_match);
					continue;
				}

				spush(&images_to_download, p_match);
			}
			free(thread_matches);
			free(thread_json);

			free(match);
		}
		free(matches);

		free(all_json);
	}
	/* We don't need the API socket anymore. */
	close(request_fd);

	return images_to_download;

error:
	if (images_to_download != NULL) {
		while (images_to_download->next != NULL) {
			post_match *_match = (post_match *)spop(&images_to_download);
			free(_match);
		}
		free(images_to_download);
	}
	close(request_fd);
	return NULL;
}