Example #1
0
void stack(node_t *n, bool focused)
{
    if (IS_FLOATING(n->client) && !auto_raise) {
        return;
    }

    if (stack_head == NULL) {
        stack_insert_after(NULL, n);
    } else {
        stacking_list_t *s = (focused ? limit_above(n) : limit_below(n));
        if (s == NULL) {
            return;
        }
        int i = stack_cmp(n->client, s->node->client);
        if (i < 0 || (i == 0 && !focused)) {
            stack_insert_before(s, n);
            window_below(n->client->window, s->node->client->window);
        } else {
            stack_insert_after(s, n);
            window_above(n->client->window, s->node->client->window);
        }
    }
}
Example #2
0
File: type.c Project: certik/nwcc
/*
 * XXX  warn about ``unsigned char *'' vs ``char *'',
 * unlike gcc
 */
static int
compare_tlist(struct type_node *dest, struct type_node *src, int flag) {
	struct type_node	*dest_start = dest;

	for (;
		dest != NULL && src != NULL;
		dest = dest->next, src = src->next) {

		if (src->type == TN_FUNCTION
			|| dest->type == TN_FUNCTION) {
			if (dest->type != src->type) {
				/* XXX fix this later */
				if (dest == dest_start) {
					/*
					 * Ordinary function symbols are
					 * compatible with pointers to
					 * functions
					 */
					if (dest->type == TN_FUNCTION) {
						if (src->type
							== TN_POINTER_TO) {
							src = src->next;
						} else {
							return -1;
						}	
					} else {
						if (dest->type
							== TN_POINTER_TO) {
							dest = dest->next;
						} else {
							return -1;
						}	
					}	
				}	
			}
		}

		if (dest->type != src->type) {
			/* Pointer vs array vs function */
			if (flag & CMPTY_ARRAYPTR) {
				if ((dest->type == TN_ARRAY_OF
					|| src->type == TN_ARRAY_OF
					|| dest->type == TN_VARARRAY_OF
					|| src->type == TN_VARARRAY_OF)

					&& (dest->type == TN_POINTER_TO
					|| src->type == TN_POINTER_TO)) {
					continue;
				}	
			}
			return -1;
		}

		switch (dest->type) {
		case TN_ARRAY_OF:
		case TN_VARARRAY_OF:	
			if (flag & CMPTY_TENTDEC) {
#if REMOVE_ARRARG
				if (!dest->have_array_size
					|| !src->have_array_size) {	
#else
				if (dest->arrarg->const_value == NULL
					|| src->arrarg->const_value == NULL) {
#endif
					/*
					 * probably
					 * extern int foo[];
					 * int foo[123];
					 * -> OK!
					 */
					break;
				}
			}
			if (dest->arrarg_const != src->arrarg_const
				&& ((flag & CMPTY_ARRAYPTR) == 0
				|| dest_start != dest)) {
#if REMOVE_ARRARG
				if (!src->have_array_size
					|| !dest->have_array_size) {	
#else
				if (src->arrarg->const_value == NULL
					|| dest->arrarg->const_value == NULL) {
#endif
					/*
					 * One side has unspecified size, this
					 * is OK!
					 * extern char foo[];
					 * char (*p)[5] = &foo;
					 * char bar[5];
					 * char (*p2)[] = &bar;
					 */
					break;
				} else {
					/* Array sizes differ */
					return -1;
				}	
			}
			break;
		case TN_POINTER_TO:
			break;
		case TN_FUNCTION:
			if (compare_tfunc(dest->tfunc, src->tfunc) == -1) {
				return -1;
			}
			break;
		}
	}
	if (dest != NULL || src != NULL) {
		/* One list is longer, so it differs by definition */
		return -1;
	}
	return 0;
}
#endif /* #ifndef PREPROCESSOR */

int
compare_types(struct type *dest, struct type *src, int flag) {
	int	is_void_ptr = 0;


	/* 04/08/08: Changed this (for the better, hopefully!) */
	if (dest->tlist != NULL
		&& dest->tlist->type == TN_POINTER_TO	
		&& dest->tlist->next == NULL
		&& dest->code == TY_VOID) {
		is_void_ptr = 1;
	} else if (src->tlist != NULL
		&& src->tlist->type == TN_POINTER_TO
		&& src->tlist->next == NULL
		&& src->code == TY_VOID) {
		is_void_ptr = 1;
	}
	
	if (dest->code != src->code) {
		/*
		 * Differing base type - This is ok if we have a void
		 * pointer vs a non-void pointer, otherwise return error
		 */
		if (!is_void_ptr || src->tlist == NULL || dest->tlist == NULL) {
			return -1;
		}
	}

	if (flag & CMPTY_SIGN) {
		if (dest->sign != dest->sign) {
			/* Differing sign */
			return -1;
		}
	}
	if (flag & CMPTY_CONST) {
		if (IS_CONST(dest->flags) != IS_CONST(src->flags)) {
			/* One is const-qualified */
			/*return -1;*/
		}
	}

	/*
	 * 04/08/08: Skip the tlist comparison if this is void pointer
	 * vs non-void pointer; Otherwise tlists of different length
	 * will compare uneven, as in void * vs int **, which is wrong
	 */
	if (is_void_ptr) {
		return 0;
	}

#ifndef PREPROCESSOR
	return compare_tlist(dest->tlist, src->tlist, flag);
#else
	return -1;
#endif
}


int
check_init_type(struct type *ofwhat, struct expr *init) {
	if (ofwhat->tlist == NULL) {
		if (init->next != NULL) {
		}
	} else if (ofwhat->tlist->type == TN_ARRAY_OF) {
		if (init->type->code == TOK_STRING_LITERAL) {
			return 0;
		} else {
			struct expr	*ex;
			for (ex = init; ex != NULL; ex = ex->next) {
		}
		}
	}
	return 0;
}

void
copy_type(struct type *dest, const struct type *src, int fullcopy) {
	if (fullcopy) {
		memcpy(dest, src, sizeof *dest);
	} else {
		memcpy(dest, src, sizeof *dest);
	}
}

struct type_node *
copy_tlist(struct type_node **dest, const struct type_node *src) {
	struct type_node	*head;
	struct type_node	*tail;
	struct type_node	*tn;

	if (src == NULL) {
		*dest = NULL;
		return NULL;
	}
	head = tail = NULL;
	do {
		tn = n_xmalloc(sizeof *tn);
		memcpy(tn, src, sizeof *tn);
		if (head == NULL) {
			head = tail = tn;
		} else {
			tail->next = tn;
			tail = tail->next;
		}	
	} while ((src = src->next) != NULL);	
	*dest = head;
	return tail;
}
		

void
set_type_sign(struct type *ty) {
	if (ty->code == TY_UCHAR
		|| ty->code == TY_USHORT
		|| ty->code == TY_UINT
		|| ty->code == TY_ULONG
		|| ty->code == TY_ULLONG) {
		ty->sign = TOK_KEY_UNSIGNED;
	} else if (!IS_FLOATING(ty->code)
		&& ty->code != TY_STRUCT
		&& ty->code != TY_UNION) {
		ty->sign = TOK_KEY_SIGNED;
	}
}
			

struct type *
make_basic_type(int code) {
#define N_TYPES (TY_MAX - TY_MIN)
#if 0
	static struct type	basic_types[N_TYPES];
#endif
	static int		inited;
	static struct type	*basic_types;

	if (!inited) {
		int	i;
		int	nbytes = N_TYPES * sizeof(struct type);
		int	need_mprotect = 1;

		basic_types = debug_malloc_pages(nbytes);
		if (basic_types == NULL) {
			/*
			 * Probably debug_malloc_pages() doesn't work
		 	 * on this system
			 */
			basic_types = n_xmalloc(nbytes);
			need_mprotect = 0;
		}
		memset(basic_types, 0, nbytes);
		for (i = 0; i < N_TYPES; ++i) {
			basic_types[i].code = i + TY_MIN;
			set_type_sign(&basic_types[i]);
		}		
		inited = 1;

		if (need_mprotect) {
			/*
			 * We make the array unwritable because it really
			 * should not be written to; Modifying it is a bug
			 * that has happend more than once. 
			 * 
			 * The void cast is necessary because of a broken
			 * Solaris prototype that takes caddr_t :-/
			 */
			mprotect((void *)basic_types, nbytes, PROT_READ); 
		}
	}
	if (code < 0 || (code - TY_MIN) >= N_TYPES) {
		printf("BUG: bad code for make_basic_type: %d\n", code);
		abort();
	}

#if 0 
	if (code == TY_PSEUDEO_SIZE_T) {
		static struct type	ty;
		static struct type	*p;

		if (p == NULL) {
			ty = basic_types[TY_UINT];
		}
	}
#endif

#if 0
	/* As of Jan 6 2007, the basic types may not be modified anymore */
	basic_types[code - TY_MIN].tlist = NULL;
#endif
	return &basic_types[code - TY_MIN];
}

struct type *
make_void_ptr_type(void) {
	static struct type	*ty;

	if (ty == NULL) {
		ty = make_basic_type(TY_VOID);
		ty = n_xmemdup(ty, sizeof *ty);
		append_typelist(ty, TN_POINTER_TO, NULL, NULL, NULL);
	}
	return ty;
}

struct type *
make_array_type(int size, int is_wide_char) {
	struct type	*ret = alloc_type();

	if (is_wide_char) {
		ret->code = backend->get_wchar_t()->code;
		ret->sign = backend->get_wchar_t()->sign;
	} else {
		ret->code = TY_CHAR;
		if (CHAR_MAX == UCHAR_MAX) { /* XXX */
			ret->sign = TOK_KEY_UNSIGNED;
		} else {
			ret->sign = TOK_KEY_SIGNED;
		}
	}
	ret->storage = TOK_KEY_STATIC;

	ret->tlist = alloc_type_node();
	ret->tlist->type = TN_ARRAY_OF;
	ret->tlist->arrarg_const = size;
#if REMOVE_ARRARG
	ret->tlist->have_array_size = 1;
#endif
	return ret;
}


/*
 * Helper function for parse_declarator()- stores pointer/array-of/function
 * property (specified by ``type'' argument) with optional arguments type_arg
 * (for pointer/array-of) and tf (for function) in type specified by t
 *
 * 01/26/08: Extended to do some sanity checking (functions may not return
 * functions or arrays). This means some type constructions are now REQUIRED
 * to go through append_typelist()! May not be the best approach, needs
 * testing?!
 */
void
append_typelist(struct type *t, 
		int type,
		void *type_arg,
		struct ty_func *tf,
		struct token *tok) {
	struct type_node	*te;
	struct expr		*ex;

	(void) tok; /* XXX unneeded?!?! */

	/* Allocate and insert new type node */
	if (t->tlist == NULL) {
		te = t->tlist = t->tlist_tail = alloc_type_node();
		te->prev = NULL;
		if (type == TN_FUNCTION) {
			/*
			 * If the first node in the type list is a function
			 * designator, this means we are dealing with a genuine
			 * function declaration/definition (as opposed to a
			 * pointer)
			 */
			t->is_func = 1;
		}
	} else {
		/*
		 * 01/26/08: Some sanity checking!
		 */
		int	tailtype = t->tlist_tail->type;

		if (tailtype == TN_ARRAY_OF || tailtype == TN_VARARRAY_OF) {
			if (type == TN_FUNCTION) {
				errorfl(tok, "Invalid declaration of `array of "
					"functions' - Maybe you meant `array "
					"of pointer to function'; `void (*ar[N])();'?");
				return /* -1  XXX */   ;
			}
		} else if (tailtype == TN_FUNCTION) {
			if (type == TN_ARRAY_OF || type == TN_VARARRAY_OF) {
				errorfl(tok, "Invalid declaration of `function "
					"returning array' - If you really want "
					"to return an array by value, put it "
					"into a structure!");
				return /* -1  XXX */   ;
			} else if (type == TN_FUNCTION) {
				errorfl(tok, "Invalid declaration of `function "
					"returning function' - You can at most "
					"return a pointer to a function; "
					"`void (*foo())();'");
				return /* -1 XXX */   ;
			}
		}

		te = alloc_type_node();
		te->prev = t->tlist_tail;
		t->tlist_tail->next = te;
		t->tlist_tail = t->tlist_tail->next;
	}

	te->next = NULL;

	te->type = type;

	switch (type) {
	case TN_VARARRAY_OF:	
	case TN_ARRAY_OF:
#if REMOVE_ARRARG
		ex = type_arg;
		if (ex->const_value == NULL) {
			/* Size not specified - extern char buf[]; */
			te->have_array_size = 0;
		} else {
			te->have_array_size = 1;
			ex->const_value->type =
				n_xmemdup(ex->const_value->type,
						sizeof(struct type));
			cross_convert_tyval(ex->const_value, NULL, NULL);
			te->arrarg_const = cross_to_host_size_t(
					ex->const_value);
			if (te->arrarg_const == 0) {
				/*
				 * In GNU C,
				 * int foo[0];
				 * may be a flexible array member
				 */
				te->have_array_size = 0;
#if 0
				errorfl(tok,
					"Cannot create zero-sized arrays");
#endif
			}	
		}
		if (type == TN_VARARRAY_OF) {
			te->variable_arrarg = ex;
		}
#else /* Using arrarg */
		te->arrarg = type_arg;
		if (te->arrarg->const_value) {
			te->arrarg->const_value->type =
				n_xmemdup(te->arrarg->const_value->type,
				sizeof(struct type));
			cross_convert_tyval(te->arrarg->const_value, NULL, NULL);
			te->arrarg_const = /* *(size_t *) */
				cross_to_host_size_t(
				te->arrarg->const_value);  /*->value; */
			if (te->arrarg_const == 0) {
				/*
				 * In GNU C,
				 * int foo[0];
				 * may be a flexible array member
				 */
				te->arrarg->const_value = NULL;
#if 0
				errorfl(tok,
					"Cannot create zero-sized arrays");
#endif
			}	
		}	
#endif /* REMOVE_ARRARG is disabled */
		break;
	case TN_POINTER_TO:
		te->ptrarg = type_arg? *(int *)type_arg: 0;
		break;
	case TN_FUNCTION:
		te->tfunc = tf; 
		break;
	}
}

static struct {
	char	*name;
	int	code;
} basic_type_names[] = {
	{ "char", TY_CHAR },
	{ "unsigned char", TY_UCHAR },
	{ "signed char", TY_SCHAR },
	{ "short", TY_SHORT },
	{ "unsigned short", TY_USHORT },
	{ "int", TY_INT },
	{ "unsigned int", TY_UINT },
	{ "long", TY_LONG },
	{ "unsigned long", TY_ULONG },
	{ "float", TY_FLOAT },
	{ "double", TY_DOUBLE },
	{ "long double", TY_LDOUBLE },
	{ "struct", TY_STRUCT },
	{ "union", TY_UNION },
	{ "enum", TY_ENUM },
	{ "void", TY_VOID },
	{ "long long", TY_LLONG },
	{ "unsigned long long", TY_ULLONG },
	{ "_Bool", TY_BOOL },
	{ NULL, 0 }
};

char *
ret_type_to_text(struct type *ty) {
	struct type_node	*orig_tlist = NULL;
	char			*ret;

	if (ty->tlist != NULL) {
		orig_tlist = ty->tlist;
		if (ty->tlist->type == TN_FUNCTION) {
			ty->tlist = ty->tlist->next;
		} else if (ty->tlist->type == TN_POINTER_TO
			&& ty->tlist->next != NULL
			&& ty->tlist->next->type == TN_FUNCTION) {
			ty->tlist = ty->tlist->next->next;
		}
		ret = type_to_text(ty);
		ty->tlist = orig_tlist;
	} else {
		ret = type_to_text(ty);
	}
	return ret;
}

char *
type_to_text(struct type *dt) {
	struct type_node	*t;
	char			*buf = NULL;
	char			*p = NULL;
	size_t			size = 0;
	size_t			used = 0;
	int			i;

	for (t = dt->tlist; t != NULL; t = t->next) {
		switch (t->type) {
		case TN_ARRAY_OF:
		case TN_VARARRAY_OF:
			make_room(&buf, &size, used + 64);
			used += sprintf(buf+used, "an array of %d ",
				(int)t->arrarg_const);
			break;
		case TN_POINTER_TO: {
			char	*quali = "";
			if (t->ptrarg != 0) {
				switch (t->ptrarg) {
				case TOK_KEY_VOLATILE:
					quali = "volatile";
					break;
				case TOK_KEY_CONST:
					quali = "constant";
					break;
				case TOK_KEY_RESTRICT:
					quali = "restricted";
					break;
				}
			}
			make_room(&buf, &size, used + 32);
			used += sprintf(buf+used, "a %s pointer to ", quali);
			break;
		}
		case TN_FUNCTION:
			make_room(&buf, &size, used + 32);
			used += sprintf(buf+used, "a function (with %d args) returning ", t->tfunc->nargs);
			break;
		}
	}	

#if 0
	p = basic_type_names[dt->code - TY_MIN];
#endif
	for (i = 0; basic_type_names[i].name != NULL; ++i) {
		if (dt->code == basic_type_names[i].code) {
			p = basic_type_names[i].name;
			break;
		}
	}
	make_room(&buf, &size, strlen(p) + 5);
	used += sprintf(buf+used, "%s", p);
	if (dt->code == TY_STRUCT) {
		if (dt->tstruc && dt->tstruc->tag) {
			make_room(&buf, &size,
				used + strlen(dt->tstruc->tag) + 2);
			sprintf(buf+used, " %s", dt->tstruc->tag);
		}	
	}	

	return buf;
}

#ifndef PREPROCESSOR

extern void	put_ppc_llong(struct num *);

/*
 * XXX same stupid size_t cross-compilaion bug as const_from_value()..
 * this stuff SUCKS!!!
 */
struct token *
const_from_type(struct type *ty, int from_alignment, int extype, struct token *t) {
	struct token	*ret = alloc_token();
	size_t		size;
	int		size_t_size;

#if 0
	ret->type = TY_ULONG; /* XXX size_t */
#endif
	ret->type = backend->get_size_t()->code;
	if (from_alignment) {
		size = backend->get_align_type(ty);
	} else {	
		size = backend->get_sizeof_type(ty, t);
	}
	/*ret->data = n_xmemdup(&size, sizeof size);*/
	ret->data = n_xmalloc(16); /* XXX */

	size_t_size = backend->get_sizeof_type(backend->get_size_t(), NULL);
	if (sizeof size == size_t_size) {
		memcpy(ret->data, &size, sizeof size);
	} else if (sizeof(int) == size_t_size) {
		unsigned int	i = (unsigned int)size;
		memcpy(ret->data, &i, sizeof i);
	} else if (sizeof(long) == size_t_size) {
		unsigned long	l = (unsigned long)size;
		memcpy(ret->data, &l, sizeof l);
	} else if (sizeof(long long) == size_t_size) {
		unsigned long long ll = (unsigned long long)size;
		memcpy(ret->data, &ll, sizeof ll);
	} else {
		unimpl();
	}	
	  
	if (backend->abi == ABI_POWER64
		&& extype != EXPR_CONST
		&& extype != EXPR_CONSTINIT
		/* What about EXPR_OPTCONSTINIT?! */ ) {
		struct num	*n = n_xmalloc(sizeof *n);
		
		/*
		 * XXX see definition of put_ppc_llong() for an
		 * explanation of this mess
		 */
		n->type = ret->type;
		n->value = ret->data;
		put_ppc_llong(n);
		/*ret->data = llong_const;*/
		ret->data2 = llong_const;
	}	
	return ret;
}


/*
 * XXX this interface is ROTTEN!!
 * too easy to pass a ``size_t'' for value with ty=NULL by accident!!
 *
 * XXXX WOAH this was totally broken WRT cross-compilation! ``type''
 * is interpreted as host type when dealing with ``value'', and as
 * target type too by making it the type of the token! Current ad-hoc
 * kludge sucks!
 */
struct token *
const_from_value(void *value, struct type *ty) {
	struct token	*ret = alloc_token();
	size_t		size;

	if (ty == NULL) {
		ret->type = TY_INT;
		size = backend->get_sizeof_type(make_basic_type(
			TY_INT), NULL);;
	} else {
		ret->type = ty->code;
		size = backend->get_sizeof_type(ty, NULL);
	}
	if (ty && (IS_LONG(ty->code) || IS_LLONG(ty->code))) {
		if (sizeof(long) == size) {
			/* Size matches - nothing to do */
			;
		} else {
			static long long	llv;
			llv = *(int *)value;
			value = &llv;
		}
	}
	ret->data = n_xmemdup(value, size);
	if (backend->abi == ABI_POWER64
		&& ty != NULL
		&& is_integral_type(ty)
		&& size == 8) {
		struct num	*n = n_xmalloc(sizeof *n);
		static struct num nullnum;
		*n = nullnum;
		n->type = ret->type;
		n->value = ret->data;
		put_ppc_llong(n);
		ret->data2 = llong_const;
	}
	return ret;
}	

/*
 * Construct a floating point constant token of type ``type'' 
 * containing ``value'' (which must be a string parsable by sscanf().)
 */
struct token *
fp_const_from_ascii(const char *value, int type) {
	struct num	*n;
	struct token	*ret = n_xmalloc(sizeof *ret);

	n = cross_scan_value(value, type, 0, 0, 1);
	if (n == NULL) {
		return NULL;
	}
	
	/*
	 * XXX token.data is ``struct ty_float'', not 
	 * ``struct num''. Because the interfaces are
	 * still messed up, we have to get the current
	 * ty_float corresponding to ``n'' from the
	 * float list. This SUCKS!
	 */
	ret->data = float_const/*n->value*/;
	ret->type = type;
	ret->ascii = n_xstrdup(value);
	return ret;
}


struct token *
const_from_string(const char *value) {
	struct token		*ret = alloc_token();
	struct type		*ty;
	struct ty_string        *tmpstr;
	
	tmpstr = alloc_ty_string();
	tmpstr->size = strlen(value) + 1;
	tmpstr->str = n_xmemdup(value, tmpstr->size);
	tmpstr->is_wide_char = 0;

	ret->type = TOK_STRING_LITERAL;
	ty = make_array_type(tmpstr->size, tmpstr->is_wide_char);
	tmpstr->ty = ty;

	ret->data = tmpstr;
	return ret;
}


int
is_integral_type(struct type *t) {
	if (t->tlist != NULL) {
		return 0;
	}
	if (IS_CHAR(t->code)
		|| IS_SHORT(t->code)
		|| IS_INT(t->code)
		|| IS_LONG(t->code)
		|| IS_LLONG(t->code)
		|| t->code == TY_ENUM) {
		return 1;
	}
	return 0;
}

int
is_floating_type(struct type *t) {
	if (t->tlist != NULL) {
		return 0;
	}
	if (t->code == TY_FLOAT
		|| t->code == TY_DOUBLE
		|| t->code == TY_LDOUBLE) {
		return 1;
	}
	return 0;
}	
			

int
is_arithmetic_type(struct type *t) {
	if (t->tlist != NULL) {
		return 0;
	}
	if (IS_FLOATING(t->code)
		|| is_integral_type(t)) {
		return 1;
	}
	return 0;
}


int
is_array_type(struct type *t) {
	struct type_node	*tn;

	if (t->tlist == NULL) {
		return 0;
	}	
	for (tn = t->tlist; tn != NULL; tn = tn->next) {
		if (tn->type != TN_ARRAY_OF) {
			return 0;
		} else {
			break;
		}	
	}
	return 1;
}	


int
is_basic_agg_type(struct type *t) {
	if (t->tlist == NULL) {
		if (t->code == TY_STRUCT || t->code == TY_UNION) {
			return 1;
		}
	} else if (is_array_type(t)) {
		return 1;
	}
	return 0;
}

int
is_scalar_type(struct type *t) {
	if (t->tlist == NULL
		&& (t->code == TY_STRUCT
		|| t->code == TY_UNION
		|| t->code == TY_VOID)) {
		return 0;
	}
	return 1;
}	

int
is_arr_of_ptr(struct type *t) {
	struct type_node	*tn;

	for (tn = t->tlist; tn != NULL; tn = tn->next) {
		if (tn->type == TN_POINTER_TO) {
			return 1;
		} else if (tn->type == TN_FUNCTION) {
			return 0;
		}	
	}
	return 0;
}

int
is_nullptr_const(struct token *constant, struct type *ty) {
	if (IS_INT(ty->code)
		&& *(unsigned *)constant->data == 0) {
		return 1;
	} else if (IS_LONG(ty->code)
		&& *(unsigned long *)constant->data == 0) {
		return 1;
	}
	return 0;
}



/*
 * The source type must be passed with a vreg because we need the null
 * pointer constant and object backing information it gives us
 */
int
check_types_assign(
	struct token *t,
	struct type *left,
	struct vreg *right,
	int to_const_ok,
	int silent) {

	struct type	*ltype = left;
	struct type	*rtype = right->type;

	if (ltype == NULL || rtype == NULL) {
		printf("attempt to assign to/from value without type :(\n");
		abort();
	}

	/*
	 * 01/26/08: Changed this to call is_modifyable(), which also
	 * rules out assignment to const-qualified pointers
	 */
	/*if (ltype->tlist == NULL && ltype->is_const && !to_const_ok) { */
	if (!is_modifyable(ltype) && !to_const_ok) {
		if (!silent) {
			errorfl(t,
				"Assignment to const-qualified object");	
		}
		return -1;
	}	

	if (is_arithmetic_type(ltype)) {
		if (!is_arithmetic_type(rtype)) {
			if (ltype->code == TY_BOOL
				&& rtype->tlist != NULL) {
				/* ok - pointer to bool */
				return 0;
			} else {
				int	allow = 0;

				if (rtype->tlist != NULL
					&& is_integral_type(ltype)) {
					/*
					 * 03/09/09: Give in and allow pointer
					 * to integer assignment with a warning
					 */
					allow = 1;
				}

				if (!silent) {
					if (allow) {
						warningfl(t,
						"Assignment from non-arithmetic to "
						"arithmetic type");
					} else {
						errorfl(t,
						"Assignment from non-arithmetic to "
						"arithmetic type");
					}
				}
				if (allow) {
					return 0;
				} else {
					return -1;
				}
			}	
		} else if (ltype->sign != rtype->sign
			&& !right->from_const) {
			/*
			 * Do not warn about signedness differences if the
			 * right side is a constant!
			 */
#if 0
			/* XXX Too verbose */
			warningfl(t,
			"Assignment from type of differing signedness");
#endif
			return 0;
		}
		return 0;		
	} else if (ltype->tlist == NULL) {
		/* Must be struct/union */
		if (rtype->tlist != NULL) {
			if (ltype->code == TY_BOOL) {
				return 0;
			} else {	
				if (!silent) {
					/* 06/01/08: Warn, not error */
					warningfl(t,
				"Assignment from pointer to non-pointer type");
				}

				/*
				 * 07/20/08: The return below was commented out!
				 * That's wrong because pointer to struct will
				 * compare assignable to struct
				 * Why was this removed?
				 */
				return -1;
			}	
		} else if (ltype->code == TY_BOOL) {
			return 0; /* _Bool b = ptr; is OK */
		} else if (rtype->code != ltype->code
			|| rtype->tstruc != ltype->tstruc) {
			if (!silent) {
				errorfl(t,
				"Assignment from incompatible type");
			}
			return -1;
		} else {
			return 0;
		}
	} else {
		/* Left is pointer of some sort */
		if (right->is_nullptr_const) {
			; /* ok */
		} else if (rtype->tlist == NULL) {
			if (!silent) {
				warningfl(t, "Assignment from non-pointer "
					"to pointer type");
			}
/*			return -1;*/
		} else if (rtype->code == TY_VOID
			&& rtype->tlist->type == TN_POINTER_TO
			&& rtype->tlist->next == NULL) {
			; /* void pointer - compatible */
		} else if (ltype->code == TY_VOID
			&& ltype->tlist->type == TN_POINTER_TO
			&& ltype->tlist->next == NULL) {
			; /* void pointer - compatible */
		} else if (compare_tlist(ltype->tlist, rtype->tlist,
				CMPTY_ARRAYPTR)) {
			if (!silent) {
			warningfl(t, "Assignment from incompatible pointer type"
					" (illegal in ISO C, and very "
					"probably not what you want)");
			} else {
				/*
				 * This is only used for transparent_union
				 * right now... in that case we do not want
				 * to allow this assignment because type-
				 * checking is the whole point of that
				 * language extension
				 */
				return -1;
			}
			return 0;
		} else if (!IS_CONST(ltype->flags) && IS_CONST(rtype->flags)) {
			if (!silent) {
				warningfl(t,
					"Assignment from const-qualified type "
					"to unqualified one");
			}
			return 0;
		} else if (rtype->code != ltype->code
			&& rtype->code != TY_VOID
			&& ltype->code != TY_VOID
		/* XXX */ && (!IS_CHAR(ltype->code) || !IS_CHAR(rtype->code))) {
			if (type_without_sign(ltype->code)
				== type_without_sign(rtype->code)) {
				if (!silent) {
					warningfl(t, "Assignment from pointer of "
						"differing signedness");
				} else {
					return -1;
				}	
				return 0;
			} else {	
				if (!silent) {
					warningfl(t, "Assignment from incompatible "
					"pointer type (illegal in ISO C, and "
					"very probably not what you want)");
				} else {
					return -1;
				}
#if 0
				return -1;
#endif
				return 0;
			}	
		} else if (IS_CONST(ltype->flags) && !IS_CONST(rtype->flags)
			&& ltype->tlist != NULL
			&& ltype->tlist->next != NULL) {
			if (!silent) {
				warningfl(t, "ISO C does not allow assignment "
					"from `T **' to `const T **' without a "
					"cast (otherwise invalid code like "
					"`const char dont_modify; char *p; const "
					"char **cp = &p; *cp = &dont_modify; *p = 0;' "
					"would pass without warning)");
			}
			return 0;
		}
	}	

	return 0;
}

struct type *
addrofify_type(struct type *ty) {
	struct type		*ret = n_xmemdup(ty, sizeof *ty);
	struct type_node	*tn;

	copy_tlist(&ret->tlist, ret->tlist);
	tn = alloc_type_node();
	tn->type = TN_POINTER_TO;
	tn->next = ret->tlist;
	ret->tlist = tn;
	return ret;
}

int
type_without_sign(int code) {
	int	rc = code;

	if (code == TY_UCHAR) rc = TY_CHAR;
	else if (code == TY_USHORT) rc = TY_SHORT;
	else if (code == TY_UINT) rc = TY_INT;
	else if (code == TY_ULONG) rc = TY_LONG;
	else if (code == TY_ULLONG) rc = TY_LLONG;
	return rc;
}	
Example #3
0
int stack_level(client_t *c)
{
    int layer_level = (c->layer == LAYER_NORMAL ? 1 : (c->layer == LAYER_BELOW ? 0 : 2));
    int state_level = (IS_TILED(c) ? 0 : (IS_FLOATING(c) ? 2 : 1));
    return 3 * layer_level + state_level;
}
Example #4
0
File: Value.c Project: carthy/beard
bool
is_floating (Value* self)
{
	return IS_FLOATING(self);
}
Example #5
0
void grab_pointer(pointer_action_t pac)
{
	PRINTF("grab pointer %u\n", pac);

	xcb_window_t win = XCB_NONE;
	xcb_point_t pos;

	query_pointer(&win, &pos);

	coordinates_t loc;
	if (locate_window(win, &loc)) {
		client_t *c = NULL;
		frozen_pointer->position = pos;
		frozen_pointer->action = pac;
		c = loc.node->client;
		frozen_pointer->monitor = loc.monitor;
		frozen_pointer->desktop = loc.desktop;
		frozen_pointer->node = loc.node;
		frozen_pointer->client = c;
		frozen_pointer->window = c->window;
		frozen_pointer->horizontal_fence = NULL;
		frozen_pointer->vertical_fence = NULL;

		switch (pac)  {
			case ACTION_FOCUS:
				if (loc.node != mon->desk->focus) {
					bool backup = pointer_follows_monitor;
					pointer_follows_monitor = false;
					focus_node(loc.monitor, loc.desktop, loc.node);
					pointer_follows_monitor = backup;
				} else if (focus_follows_pointer) {
					stack(loc.node, true);
				}
				frozen_pointer->action = ACTION_NONE;
				break;
			case ACTION_MOVE:
			case ACTION_RESIZE_SIDE:
			case ACTION_RESIZE_CORNER:
				if (IS_FLOATING(c)) {
					frozen_pointer->rectangle = c->floating_rectangle;
					frozen_pointer->is_tiled = false;
				} else if (IS_TILED(c)) {
					frozen_pointer->rectangle = c->tiled_rectangle;
					frozen_pointer->is_tiled = (pac == ACTION_MOVE || c->state == STATE_PSEUDO_TILED);
				} else {
					frozen_pointer->action = ACTION_NONE;
					return;
				}
				if (pac == ACTION_RESIZE_SIDE) {
					float W = frozen_pointer->rectangle.width;
					float H = frozen_pointer->rectangle.height;
					float ratio = W / H;
					float x = pos.x - frozen_pointer->rectangle.x;
					float y = pos.y - frozen_pointer->rectangle.y;
					float diag_a = ratio * y;
					float diag_b = W - diag_a;
					if (x < diag_a) {
						if (x < diag_b)
							frozen_pointer->side = SIDE_LEFT;
						else
							frozen_pointer->side = SIDE_BOTTOM;
					} else {
						if (x < diag_b)
							frozen_pointer->side = SIDE_TOP;
						else
							frozen_pointer->side = SIDE_RIGHT;
					}
				} else if (pac == ACTION_RESIZE_CORNER) {
					int16_t mid_x = frozen_pointer->rectangle.x + (frozen_pointer->rectangle.width / 2);
					int16_t mid_y = frozen_pointer->rectangle.y + (frozen_pointer->rectangle.height / 2);
					if (pos.x > mid_x) {
						if (pos.y > mid_y)
							frozen_pointer->corner = CORNER_BOTTOM_RIGHT;
						else
							frozen_pointer->corner = CORNER_TOP_RIGHT;
					} else {
						if (pos.y > mid_y)
							frozen_pointer->corner = CORNER_BOTTOM_LEFT;
						else
							frozen_pointer->corner = CORNER_TOP_LEFT;
					}
				}
				if (frozen_pointer->is_tiled) {
					if (pac == ACTION_RESIZE_SIDE) {
						switch (frozen_pointer->side) {
							case SIDE_TOP:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
								break;
							case SIDE_RIGHT:
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
								break;
							case SIDE_BOTTOM:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
								break;
							case SIDE_LEFT:
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
								break;
						}
					} else if (pac == ACTION_RESIZE_CORNER) {
						switch (frozen_pointer->corner) {
							case CORNER_TOP_LEFT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
								break;
							case CORNER_TOP_RIGHT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
								break;
							case CORNER_BOTTOM_RIGHT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
								break;
							case CORNER_BOTTOM_LEFT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
								break;
						}
					}
					if (frozen_pointer->horizontal_fence != NULL)
						frozen_pointer->horizontal_ratio = frozen_pointer->horizontal_fence->split_ratio;
					if (frozen_pointer->vertical_fence != NULL)
						frozen_pointer->vertical_ratio = frozen_pointer->vertical_fence->split_ratio;
				}
				break;
			case ACTION_NONE:
				break;
		}
	} else {
		if (pac == ACTION_FOCUS) {
			monitor_t *m = monitor_from_point(pos);
			if (m != NULL && m != mon)
				focus_node(m, m->desk, m->desk->focus);
		}
		frozen_pointer->action = ACTION_NONE;
	}
}
Example #6
0
void track_pointer(int root_x, int root_y)
{
	if (frozen_pointer->action == ACTION_NONE)
		return;

	int delta_x, delta_y, x = 0, y = 0, w = 1, h = 1;

	pointer_action_t pac = frozen_pointer->action;
	monitor_t *m = frozen_pointer->monitor;
	desktop_t *d = frozen_pointer->desktop;
	node_t *n = frozen_pointer->node;
	client_t *c = frozen_pointer->client;
	xcb_window_t win = frozen_pointer->window;
	xcb_rectangle_t rect = frozen_pointer->rectangle;
	node_t *vertical_fence = frozen_pointer->vertical_fence;
	node_t *horizontal_fence = frozen_pointer->horizontal_fence;

	delta_x = root_x - frozen_pointer->position.x;
	delta_y = root_y - frozen_pointer->position.y;

	switch (pac) {
		case ACTION_MOVE:
			if (frozen_pointer->is_tiled) {
				xcb_window_t pwin = XCB_NONE;
				query_pointer(&pwin, NULL);
				if (pwin == win)
					return;
				coordinates_t loc;
				bool is_managed = (pwin == XCB_NONE ? false : locate_window(pwin, &loc));
				if (is_managed && !IS_FLOATING(loc.node->client) && loc.monitor == m) {
					swap_nodes(m, d, n, m, d, loc.node);
					arrange(m, d);
				} else {
					if (is_managed && loc.monitor == m) {
						return;
					} else if (!is_managed) {
						xcb_point_t pt = (xcb_point_t) {root_x, root_y};
						monitor_t *pmon = monitor_from_point(pt);
						if (pmon == NULL || pmon == m) {
							return;
						} else {
							loc.monitor = pmon;
							loc.desktop = pmon->desk;
						}
					}
					bool focused = (n == mon->desk->focus);
					transfer_node(m, d, n, loc.monitor, loc.desktop, loc.desktop->focus);
					if (focused)
						focus_node(loc.monitor, loc.desktop, n);
					frozen_pointer->monitor = loc.monitor;
					frozen_pointer->desktop = loc.desktop;
				}
			} else {
				x = rect.x + delta_x;
				y = rect.y + delta_y;
				window_move(win, x, y);
				c->floating_rectangle.x = x;
				c->floating_rectangle.y = y;
				xcb_point_t pt = (xcb_point_t) {root_x, root_y};
				monitor_t *pmon = monitor_from_point(pt);
				if (pmon == NULL || pmon == m)
					return;
				bool focused = (n == mon->desk->focus);
				transfer_node(m, d, n, pmon, pmon->desk, pmon->desk->focus);
				if (focused)
					focus_node(pmon, pmon->desk, n);
				frozen_pointer->monitor = pmon;
				frozen_pointer->desktop = pmon->desk;
			}
			break;
		case ACTION_RESIZE_SIDE:
		case ACTION_RESIZE_CORNER:
			if (frozen_pointer->is_tiled) {
				if (vertical_fence != NULL) {
					double sr = frozen_pointer->vertical_ratio + (double) delta_x / vertical_fence->rectangle.width;
					sr = MAX(0, sr);
					sr = MIN(1, sr);
					vertical_fence->split_ratio = sr;
				}
				if (horizontal_fence != NULL) {
					double sr = frozen_pointer->horizontal_ratio + (double) delta_y / horizontal_fence->rectangle.height;
					sr = MAX(0, sr);
					sr = MIN(1, sr);
					horizontal_fence->split_ratio = sr;
				}
				arrange(m, d);
			} else {
				if (pac == ACTION_RESIZE_SIDE) {
					switch (frozen_pointer->side) {
						case SIDE_TOP:
							x = rect.x;
							y = rect.y + delta_y;
							w = rect.width;
							h = rect.height - delta_y;
							break;
						case SIDE_RIGHT:
							x = rect.x;
							y = rect.y;
							w = rect.width + delta_x;
							h = rect.height;
							break;
						case SIDE_BOTTOM:
							x = rect.x;
							y = rect.y;
							w = rect.width;
							h = rect.height + delta_y;
							break;
						case SIDE_LEFT:
							x = rect.x + delta_x;
							y = rect.y;
							w = rect.width - delta_x;
							h = rect.height;
							break;
					}
				} else if (pac == ACTION_RESIZE_CORNER) {
					switch (frozen_pointer->corner) {
						case CORNER_TOP_LEFT:
							x = rect.x + delta_x;
							y = rect.y + delta_y;
							w = rect.width - delta_x;
							h = rect.height - delta_y;
							break;
						case CORNER_TOP_RIGHT:
							x = rect.x;
							y = rect.y + delta_y;
							w = rect.width + delta_x;
							h = rect.height - delta_y;
							break;
						case CORNER_BOTTOM_LEFT:
							x = rect.x + delta_x;
							y = rect.y;
							w = rect.width - delta_x;
							h = rect.height + delta_y;
							break;
						case CORNER_BOTTOM_RIGHT:
							x = rect.x;
							y = rect.y;
							w = rect.width + delta_x;
							h = rect.height + delta_y;
							break;
					}
				}

				int oldw = w, oldh = h;
				restrain_floating_size(c, &w, &h);

				if (c->state == STATE_FLOATING) {
					if (oldw == w) {
						c->floating_rectangle.x = x;
						c->floating_rectangle.width = w;
					}
					if (oldh == h) {
						c->floating_rectangle.y = y;
						c->floating_rectangle.height = h;
					}
					window_move_resize(win, c->floating_rectangle.x,
					                        c->floating_rectangle.y,
					                        c->floating_rectangle.width,
					                        c->floating_rectangle.height);
				} else {
					c->floating_rectangle.width = w;
					c->floating_rectangle.height = h;
					arrange(m, d);
				}
			}
			break;
		case ACTION_FOCUS:
		case ACTION_NONE:
			break;
	}
}
Example #7
0
void configure_request(xcb_generic_event_t *evt)
{
	xcb_configure_request_event_t *e = (xcb_configure_request_event_t *) evt;

	coordinates_t loc;
	bool is_managed = locate_window(e->window, &loc);
	client_t *c = (is_managed ? loc.node->client : NULL);
	int w = 0, h = 0;

	if (is_managed && !IS_FLOATING(c)) {
		if (e->value_mask & XCB_CONFIG_WINDOW_X) {
			c->floating_rectangle.x = e->x;
		}
		if (e->value_mask & XCB_CONFIG_WINDOW_Y) {
			c->floating_rectangle.y = e->y;
		}
		if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
			w = e->width;
		}
		if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
			h = e->height;
		}

		if (w != 0) {
			restrain_floating_width(c, &w);
			c->floating_rectangle.width = w;
		}

		if (h != 0) {
			restrain_floating_height(c, &h);
			c->floating_rectangle.height = h;
		}

		xcb_configure_notify_event_t evt;
		unsigned int bw = c->border_width;

		xcb_rectangle_t rect = get_rectangle(loc.desktop, loc.node);

		evt.response_type = XCB_CONFIGURE_NOTIFY;
		evt.event = e->window;
		evt.window = e->window;
		evt.above_sibling = XCB_NONE;
		evt.x = rect.x;
		evt.y = rect.y;
		evt.width = rect.width;
		evt.height = rect.height;
		evt.border_width = bw;
		evt.override_redirect = false;

		xcb_send_event(dpy, false, e->window, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *) &evt);

		if (c->state == STATE_PSEUDO_TILED) {
			arrange(loc.monitor, loc.desktop);
		}
	} else {
		uint16_t mask = 0;
		uint32_t values[7];
		unsigned short i = 0;

		if (e->value_mask & XCB_CONFIG_WINDOW_X) {
			mask |= XCB_CONFIG_WINDOW_X;
			values[i++] = e->x;
			if (is_managed) {
				c->floating_rectangle.x = e->x;
			}
		}

		if (e->value_mask & XCB_CONFIG_WINDOW_Y) {
			mask |= XCB_CONFIG_WINDOW_Y;
			values[i++] = e->y;
			if (is_managed) {
				c->floating_rectangle.y = e->y;
			}
		}

		if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
			mask |= XCB_CONFIG_WINDOW_WIDTH;
			w = e->width;
			if (is_managed) {
				restrain_floating_width(c, &w);
				c->floating_rectangle.width = w;
			}
			values[i++] = w;
		}

		if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
			mask |= XCB_CONFIG_WINDOW_HEIGHT;
			h = e->height;
			if (is_managed) {
				restrain_floating_height(c, &h);
				c->floating_rectangle.height = h;
			}
			values[i++] = h;
		}

		if (!is_managed && e->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) {
			mask |= XCB_CONFIG_WINDOW_BORDER_WIDTH;
			values[i++] = e->border_width;
		}

		if (!is_managed && e->value_mask & XCB_CONFIG_WINDOW_SIBLING) {
			mask |= XCB_CONFIG_WINDOW_SIBLING;
			values[i++] = e->sibling;
		}

		if (!is_managed && e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) {
			mask |= XCB_CONFIG_WINDOW_STACK_MODE;
			values[i++] = e->stack_mode;
		}

		xcb_configure_window(dpy, e->window, mask, values);

		if (is_managed && mask & XCB_CONFIG_WINDOW_X_Y_WIDTH_HEIGHT) {
			xcb_rectangle_t r = c->floating_rectangle;
			put_status(SBSC_MASK_NODE_GEOMETRY, "node_geometry 0x%X 0x%X 0x%X %ux%u+%i+%i\n", loc.monitor->id, loc.desktop->id, e->window, r.width, r.height, r.x, r.y);
		}
	}

	if (is_managed) {
		monitor_t *m = monitor_from_client(c);
		adapt_geometry(&m->rectangle, &loc.monitor->rectangle, loc.node);
	}
}