示例#1
0
文件: device.c 项目: Synapseware/avra
// Pre-define devices. B.A. : Return value change from void to int 
int predef_dev(struct prog_info *pi) 
{
	int i;
	char temp[MAX_DEV_NAME+1];
	def_dev(pi);
	for (i=0;(!i)||(device_list[i].name);i++) {
		strncpy(temp,DEV_PREFIX,MAX_DEV_NAME);
		if (!i) strncat(temp,DEF_DEV_NAME,MAX_DEV_NAME);
		else strncat(temp,device_list[i].name,MAX_DEV_NAME);
		strncat(temp,DEV_SUFFIX,MAX_DEV_NAME);
		/* B.A. : New. Forward references allowed. But check, if everything is ok ... */
		if(pi->pass==PASS_1) { /* Pass 1 */
      if(test_constant(pi,temp,NULL)!=NULL) {
        fprintf(stderr,"Error: Can't define symbol %s twice. Please don't use predefined symbols !\n", temp);
        return(False);
      }
      if(def_const(pi, temp, i)==False)
        return(False);
	  } else { /* Pass 2 */
			int j;
			if(get_constant(pi, temp, &j)==False) {   /* Defined in Pass 1 and now missing ? */
   	    fprintf(stderr,"Constant %s is missing in pass 2\n",temp);
 	      return(False);
			}
		  if(i != j) {
 	      fprintf(stderr,"Constant %s changed value from %d in pass1 to %d in pass 2\n",temp,j,i);
 	      return(False);
			}
			/* OK. definition is unchanged */
	  }
	}
	return(True);
}
示例#2
0
文件: main.cpp 项目: dmilos/color
int main(int argc, char const *argv[])
 {
  print< ::color::rgb< ::color::type::split422_t >::category_type  >();
  print< ::color::rgb< ::color::type::split242_t >::category_type  >();
  print< ::color::rgb< ::color::type::split224_t >::category_type  >();

  print< ::color::bgr< ::color::type::split422_t >::category_type  >();
  print< ::color::bgr< ::color::type::split242_t >::category_type  >();
  print< ::color::bgr< ::color::type::split224_t >::category_type  >();

  print< ::color::abgr< ::color::type::split2AAA_t >::category_type  >();
  print< ::color::bgra< ::color::type::splitAAA2_t >::category_type  >();

  print< ::color::rgba< ::color::type::splitAAA2_t >::category_type  >();
  print< ::color::argb< ::color::type::split2AAA_t >::category_type  >();

  sandbox_test();

  extern void test_constant();
  test_constant();

  extern void check_sizeof();
  check_sizeof();

  void test_operation();
  test_operation();

  void image_conversion();
  image_conversion();

  test_pallete();

  ctor_test();

  void main_place();
  main_place();

  void check_get();
  check_get();

  extern int gray_test( int argc, char const *argv[] );
  gray_test( argc, argv );

  extern int decompose_test( int argc, char const *argv[] );
  decompose_test( argc, argv );

  extern void print_bound();
  print_bound();

  make_blue();

  invoke();

  extern void check_conversion();
  check_conversion();

  void make_test_gray_scale();
  make_test_gray_scale();

  void test_set_invoke();
  test_set_invoke();

  void test_get_invoke( double value );
  test_get_invoke(0.5);

  return 0;
 }
示例#3
0
文件: parser.c 项目: mnemnion/imp
int parse_line(struct prog_info *pi, char *line) 
{
	char *ptr=NULL;
	int k;
	int flag=0, i;
	int global_label = False;
	char temp[LINEBUFFER_LENGTH];
	struct label *label = NULL;
	struct macro_call *macro_call;

	while(IS_HOR_SPACE(*line)) line++;			/* At first remove leading spaces / tabs */
	if(IS_END_OR_COMMENT(*line))				/* Skip comment line or empty line */
		return(True);
								/* Filter out .stab debugging information */
								/* .stabs sometimes contains colon : symbol - might be interpreted as label */
	if(*line == '.') {					/* minimal slowdown of existing code */
		if(strncmp(temp,".stabs ",7) == 0 ) {		/* compiler output is always lower case */
			strcpy(temp,line);			/* TODO : Do we need this temp variable ? Please check */
			return parse_stabs( pi, temp );
		}
		if(strncmp(temp,".stabn ",7) == 0 ) {
			strcpy(temp,line);
			return parse_stabn( pi, temp );
		}
	}
								/* Meta information translation */
	ptr=line;
	k=0;
	while((ptr=strchr(ptr, '%')) != NULL) {
		if(!strncmp(ptr, "%MINUTE%", 8) ) {		/* Replacement always shorter than tag -> no length check */
			k=strftime(ptr,3,"%M", localtime(&pi->time));
			strcpy(ptr+k,ptr+8); 
			ptr+=k;
			continue;
		}
		if(!strncmp(ptr, "%HOUR%", 6) ) {			
			k=strftime(ptr,3,"%H", localtime(&pi->time));
			strcpy(ptr+k,ptr+6); 
			ptr+=k;
			continue;
		}
		if(!strncmp(ptr, "%DAY%", 5) ) {
			k=strftime(ptr,3,"%d", localtime(&pi->time));
			strcpy(ptr+k,ptr+5); 
			ptr+=k;
			continue;
		}
		if(!strncmp(ptr, "%MONTH%", 7) ) {
			k=strftime(ptr,3,"%m", localtime(&pi->time));
			strcpy(ptr+k,ptr+7); 
			ptr+=k;
			continue;
		}
		if(!strncmp(ptr, "%YEAR%", 6) ) {
			k=strftime(ptr,5,"%Y", localtime(&pi->time));
			strcpy(ptr+k,ptr+6); 
			ptr+=k;
			continue;
		}
		ptr++;
	}

//	if(pi->pass == PASS_2)		// TODO : Test
//		strcpy(pi->list_line, line);

	strcpy(pi->fi->scratch,line);

	for(i = 0; IS_LABEL(pi->fi->scratch[i]) || (pi->fi->scratch[i] == ':'); i++)
		if(pi->fi->scratch[i] == ':') {	/* it is a label */
			pi->fi->scratch[i] = '\0';
			if(pi->pass == PASS_1) {
				for(macro_call = pi->macro_call; macro_call; macro_call = macro_call->prev_on_stack) {
					for(label = pi->macro_call->first_label; label; label = label->next) {
						if(!nocase_strcmp(label->name, &pi->fi->scratch[0])) {
							print_msg(pi, MSGTYPE_ERROR, "Can't redefine local label %s", &pi->fi->scratch[0]);
							break;
						}
					}
				}
				if(test_label(pi,&pi->fi->scratch[0],"Can't redefine label %s")!=NULL) 
					break;
				if(test_variable(pi,&pi->fi->scratch[0],"%s have already been defined as a .SET variable")!=NULL) 
					break;
				if(test_constant(pi,&pi->fi->scratch[0],"%s has already been defined as a .EQU constant")!=NULL) 
					break;
				label = malloc(sizeof(struct label));
				if(!label) {
					print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
					return(False);
				}
				label->next = NULL;
				label->name = malloc(strlen(&pi->fi->scratch[0]) + 1);
				if(!label->name) {
					print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
					return(False);
				}
				strcpy(label->name, &pi->fi->scratch[0]);
				switch(pi->segment) {
					case SEGMENT_CODE:
						label->value = pi->cseg_addr;
						break;
					case SEGMENT_DATA:
						label->value = pi->dseg_addr;
						break;
					case SEGMENT_EEPROM:
						label->value = pi->eseg_addr;
						break;
				}
				if(pi->macro_call && !global_label) {
					if(pi->macro_call->last_label)
						pi->macro_call->last_label->next = label;
				  	else
						pi->macro_call->first_label = label;
				  	pi->macro_call->last_label = label;
				} else {
					if(pi->last_label)
				  		pi->last_label->next = label;
					else
						pi->first_label = label;
					pi->last_label = label;
				}
			} 
			i++;
			while(IS_HOR_SPACE(pi->fi->scratch[i]) && !IS_END_OR_COMMENT(pi->fi->scratch[i])) i++;
			if(IS_END_OR_COMMENT(pi->fi->scratch[i])) {
				if((pi->pass == PASS_2) && pi->list_on) { // Diff tilpassing
					fprintf(pi->list_file, "          %s\n", pi->list_line);
					pi->list_line = NULL;
				}
				return(True);
			}
			strcpy(pi->fi->scratch, &pi->fi->scratch[i]);
			break;
		}

#if 0
	if(pi->fi->scratch[0] == '.') {
#else
	if((pi->fi->scratch[0] == '.') || (pi->fi->scratch[0] == '#')) {
#endif
		pi->fi->label = label;
		flag = parse_directive(pi);
		if((pi->pass == PASS_2) && pi->list_on && pi->list_line) { // Diff tilpassing 
  			fprintf(pi->list_file, "          %s\n", pi->list_line);
			pi->list_line = NULL;
		}
		return(flag);
	} else {
		return parse_mnemonic(pi);
	}
}


/*
 * Get the next token, and terminate the last one.
 * Termination identifier is specified.
 */

char *get_next_token(char *data, int term)
{
	int i = 0, j, anti_comma = False;
	switch(term) {
		case TERM_END:
//			while(!IS_END_OR_COMMENT(data[i])) i++; 	Problems with 2. operand == ';'
			while( ((data[i] != ',') || anti_comma) && !(((data[i] == ';') && !anti_comma) || IS_ENDLINE(data[i])) ) {
				if((data[i] == '\'') || (data[i] == '"')) 
					anti_comma = anti_comma ? False : True;
				i++;
			}
			break;
		case TERM_SPACE:
			while(!IS_HOR_SPACE(data[i]) && !IS_END_OR_COMMENT(data[i])) i++;
			break;
		case TERM_DASH:
			while((data[i] != '-') && !IS_END_OR_COMMENT(data[i])) i++;
			break;
		case TERM_COLON:
			while((data[i] != ':') && !IS_ENDLINE(data[i])) i++;
			break;
		case TERM_DOUBLEQUOTE:
			while((data[i] != '"') && !IS_ENDLINE(data[i])) i++;
			break;
		case TERM_COMMA:
			while(((data[i] != ',') || anti_comma) && !(((data[i] == ';') && !anti_comma) || IS_ENDLINE(data[i])) ) {
				if((data[i] == '\'') || (data[i] == '"')) 
					anti_comma = anti_comma ? False : True;
				i++;
			}
			break;
		case TERM_EQUAL:
			while((data[i] != '=') && !IS_END_OR_COMMENT(data[i])) i++;
			break;
	}
	if(IS_END_OR_COMMENT(data[i])) {
		data[i--] = '\0';
		while(IS_HOR_SPACE(data[i])) data[i--] = '\0';
		return(0);
	}
	j = i - 1;
	while(IS_HOR_SPACE(data[j])) data[j--] = '\0';
	data[i++] = '\0';
	while(IS_HOR_SPACE(data[i]) && !IS_END_OR_COMMENT(data[i])) i++;
	if(IS_END_OR_COMMENT(data[i]))
		return(0);
	return(&data[i]);
}
示例#4
0
int parse_directive(struct prog_info *pi)
{
	int directive, pragma;
	int ok = True;
	int i;
	char *next, *data, buf[140];
	struct file_info *fi_bak;

	struct def *def;
	struct data_list *incpath, *dl;

	next = get_next_token(pi->fi->scratch, TERM_SPACE);

	my_strupr(pi->fi->scratch);
	directive = lookup_keyword(directive_list, pi->fi->scratch + 1, True);
	if(directive == -1) {
		print_msg(pi, MSGTYPE_ERROR, "Unknown directive: %s", pi->fi->scratch);
		return(True);
	}
	switch(directive) {
		case DIRECTIVE_BYTE:
			if (!next) {
				print_msg(pi, MSGTYPE_ERROR, ".BYTE needs a size operand");
				return(True);
			}
			if (pi->segment == pi->cseg)
				print_msg(pi, MSGTYPE_ERROR, ".BYTE directive cannot be used within the code segment (.CSEG)");
			get_next_token(next, TERM_END);
			if (!get_expr(pi, next, &i))
				return(False);
			if ((pi->pass == PASS_2) && pi->list_line && pi->list_on) {
				fprintf(pi->list_file, "%c:%06x    %s\n", 
					pi->segment->ident, pi->segment->addr, pi->list_line);
				pi->list_line = NULL;
			}
			if (i > 0) {
					fix_orglist(pi->segment);
					advance_ip(pi->segment, i);
					def_orglist(pi->segment);
			}
			break;
		case DIRECTIVE_CSEG:
			fix_orglist(pi->segment);
			def_orglist(pi->cseg);
			break;
		case DIRECTIVE_CSEGSIZE:
			break;
		case DIRECTIVE_DB:
			if((pi->pass == PASS_2) && pi->list_line && pi->list_on) {
				fprintf(pi->list_file, "          %s\n", pi->list_line);
				pi->list_line = NULL;
			}
			return(parse_db(pi, next));
//			break;
		/* Directive .def */
		case DIRECTIVE_DEF:
			if(!next) {
				print_msg(pi, MSGTYPE_ERROR, ".DEF needs an operand");
				return(True);
			}
			data = get_next_token(next, TERM_EQUAL);
			if(!(data && (tolower(data[0]) == 'r') && isdigit(data[1]))) {
				print_msg(pi, MSGTYPE_ERROR, "%s needs a register (e.g. .def BZZZT = r16)", next);
				return(True);
			}
			i = atoi(&data[1]);
			/* check range of given register */
			if(i > 31)
				print_msg(pi, MSGTYPE_ERROR, "R%d is not a valid register", i);
			/* check if this reg is already assigned */
			for(def = pi->first_def; def; def = def->next) {
				if(def->reg == i && pi->pass == PASS_1 && !pi->NoRegDef) {
				    print_msg(pi, MSGTYPE_WARNING, "r%d is already assigned to '%s'!", i, def->name);
					return(True);
				}
			}
			/* check if this regname is already defined */
			for(def = pi->first_def; def; def = def->next) {
				if(!nocase_strcmp(def->name, next)) {
					if(pi->pass == PASS_1 && !pi->NoRegDef) {
						print_msg(pi, MSGTYPE_WARNING, "'%s' is already assigned as r%d but will now be set to r%i!", next, def->reg, i);
					}
					def->reg = i;
					return(True);
				}
			}
			/* B.A.: Check, if symbol is already defined as a label or constant */
			if(pi->pass == PASS_2) {
				if(get_label(pi,next,NULL))
					print_msg(pi, MSGTYPE_WARNING, "Name '%s' is used for a register and a label", next);
				if(get_constant(pi,next,NULL))
					print_msg(pi, MSGTYPE_WARNING, "Name '%s' is used for a register and a constant", next);
			}

			def = malloc(sizeof(struct def));
			if(!def) {
				print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
				return(False);
			}
			def->next = NULL;
			if(pi->last_def)
				pi->last_def->next = def;
			else
				pi->first_def = def;
			pi->last_def = def;
			def->name = malloc(strlen(next) + 1);
			if(!def->name) {
				print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
				return(False);
			}
			strcpy(def->name, next);
			def->reg = i;
			break;
		case DIRECTIVE_DEVICE:
			if(pi->pass == PASS_2)
				return(True);
			if(!next) {
				print_msg(pi, MSGTYPE_ERROR, ".DEVICE needs an operand");
				return(True);
			}
			if (pi->device->name != NULL) { /* B.A.: Check for multiple device definitions */
				print_msg(pi, MSGTYPE_ERROR, "More than one .DEVICE definition");
			}
			if (pi->cseg->count || pi->dseg->count || pi->eseg->count) { 
				/* B.A.: Check if something was already assembled */
				print_msg(pi, MSGTYPE_ERROR, ".DEVICE definition must be before any code lines");
			} else {
				if ((pi->cseg->addr != pi->cseg->lo_addr ) 
				 || (pi->dseg->addr != pi->dseg->lo_addr )
				 || (pi->eseg->addr != pi->eseg->lo_addr )) { 
					/* B.A.: Check if something was already assembled XXX probably redundant */
					print_msg(pi, MSGTYPE_ERROR, ".DEVICE definition must be before any .ORG directive");
				}
			}

			get_next_token(next, TERM_END);
			pi->device = get_device(pi,next);
			if (!pi->device) {
				print_msg(pi, MSGTYPE_ERROR, "Unknown device: %s", next);
				pi->device = get_device(pi,NULL); /* B.A.: Fix segmentation fault if device is unknown */
			}

			/* Now that we know the device type, we can
			 * start memory allocation from the correct offsets.
			 */
			fix_orglist(pi->segment);
			rewind_segments(pi);
			def_orglist(pi->segment);
			break;
		case DIRECTIVE_DSEG:
			fix_orglist(pi->segment);
			def_orglist(pi->dseg);
			if (pi->dseg->hi_addr == 0) {
				/* XXX move to emit */
				print_msg(pi, MSGTYPE_ERROR, "Can't use .DSEG directive because device has no RAM");
			}
			break;
		case DIRECTIVE_DW:
			if (pi->segment->flags & SEG_BSS_DATA) {
				print_msg(pi, MSGTYPE_ERROR, "Can't use .DW directive in data segment (.DSEG)");
				return(True);
			}
			while (next) {
				data = get_next_token(next, TERM_COMMA);
				if(pi->pass == PASS_2) {
				  if(!get_expr(pi, next, &i))
				    return(False);
				  if((i < -32768) || (i > 65535))
				    print_msg(pi, MSGTYPE_WARNING, "Value %d is out of range (-32768 <= k <= 65535). Will be masked", i);
                }
				if (pi->pass == PASS_2) {
					if (pi->list_line && pi->list_on) {
						fprintf(pi->list_file, "          %s\n", pi->list_line);
						pi->list_line = NULL;
						fprintf(pi->list_file, "%c:%06x %04x\n", 
							pi->segment->ident, pi->segment->addr, i);
					}
					if (pi->segment == pi->eseg) {
						write_ee_byte(pi, pi->eseg->addr, (unsigned char)i);
						write_ee_byte(pi, pi->eseg->addr + 1, (unsigned char)(i >> 8));
					}
					if (pi->segment == pi->cseg) {
						write_prog_word(pi, pi->cseg->addr, i);
					}
				}
				if (pi->segment == pi->eseg) 
					advance_ip(pi->eseg, 2);
				if (pi->segment == pi->cseg) 
					advance_ip(pi->cseg, 1);
				next = data;
			}
			break;
		case DIRECTIVE_ENDM:
		case DIRECTIVE_ENDMACRO:
			print_msg(pi, MSGTYPE_ERROR, "No .MACRO found before .ENDMACRO");
			break;
		case DIRECTIVE_EQU:
			if(!next) {
				print_msg(pi, MSGTYPE_ERROR, ".EQU needs an operand");
				return(True);
			}
			data = get_next_token(next, TERM_EQUAL);
			if(!data) {
				print_msg(pi, MSGTYPE_ERROR, "%s needs an expression (e.g. .EQU BZZZT = 0x2a)", next);
				return(True);
			}
			get_next_token(data, TERM_END);
			if(!get_expr(pi, data, &i))
				return(False);
			if(test_label(pi,next,"%s have already been defined as a label")!=NULL) 
				return(True);
			if(test_variable(pi,next,"%s have already been defined as a .SET variable")!=NULL) 
				return(True);
			/* B.A. : New. Forward references allowed. But check, if everything is ok ... */
			if(pi->pass==PASS_1) { /* Pass 1 */
				if(test_constant(pi,next,"Can't redefine constant %s, use .SET instead")!=NULL) 
					return(True);
				if(def_const(pi, next, i)==False)
					return(False);
			} else { /* Pass 2 */
				int j;
				if(get_constant(pi, next, &j)==False) {   /* Defined in Pass 1 and now missing ? */
					print_msg(pi, MSGTYPE_ERROR, "Constant %s is missing in pass 2", next);
					return(False);
				}
				if(i != j) {
					print_msg(pi, MSGTYPE_ERROR, "Constant %s changed value from %d in pass1 to %d in pass 2", next,j,i);
					return(False);
				}
				/* OK. Definition is unchanged */
			}
			if((pi->pass == PASS_2) && pi->list_line && pi->list_on) {
				fprintf(pi->list_file, "          %s\n", pi->list_line);
				pi->list_line = NULL;
			}
			break;
		case DIRECTIVE_ESEG:
			fix_orglist(pi->segment);
			def_orglist(pi->eseg);
			if(pi->device->eeprom_size == 0) { /* XXX */
				print_msg(pi, MSGTYPE_ERROR, "Can't use .ESEG directive because device has no EEPROM");
			}
			break;
		case DIRECTIVE_EXIT:
			pi->fi->exit_file = True;
			break;
		/*** .include ***/
		case DIRECTIVE_INCLUDE:    
			if(!next) {
				print_msg(pi, MSGTYPE_ERROR, "Nothing to include");
				return(True);
			}
			next = term_string(pi, next);
			if((pi->pass == PASS_2) && pi->list_line && pi->list_on) {
				fprintf(pi->list_file, "          %s\n", pi->list_line);
				pi->list_line = NULL;
			}
			// Test if include is in local directory
			ok = test_include(next);
			data = NULL;
			if(!ok)
				for(incpath = GET_ARG_LIST(pi->args, ARG_INCLUDEPATH); incpath && !ok; incpath = incpath->next) {
					i = strlen(incpath->data);
					if(data)
						free(data);
					data = malloc(i + strlen(next) + 2);
					if(!data) {
						print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
						return(False);
					}
					strcpy(data, incpath->data);
					if((data[i - 1] != '\\') && (data[i - 1] != '/'))
						data[i++] = '/';
					strcpy(&data[i], next);
                    //printf("testing: %s\n", data);
					ok = test_include(data);
				}
			if(ok) {
				fi_bak = pi->fi;
				ok = parse_file(pi, data ? data : next);
				pi->fi = fi_bak;
			}
			else
				print_msg(pi, MSGTYPE_ERROR, "Cannot find include file: %s", next);
			if(data)
				free(data);
			break;
		/*** .includepath ***/
		case DIRECTIVE_INCLUDEPATH:
			if(!next) {
				print_msg(pi, MSGTYPE_ERROR, ".INCLUDEPATH needs an operand");
				return(True);
			}
			data = get_next_token(next, TERM_SPACE);
			if(data) {
				print_msg(pi, MSGTYPE_ERROR, ".INCLUDEPATH needs an operand!!!");
				get_next_token(data, TERM_END);
				if(!get_expr(pi, data, &i))
				        return(False);
			}
			next = term_string(pi, next);
			/* get arg list start pointer */
			incpath = GET_ARG_LIST(pi->args, ARG_INCLUDEPATH);
        /* search for last element */
        if(incpath == NULL) {
         	dl = malloc(sizeof(struct data_list));
         	data = malloc(strlen(next)+1);
	        if(dl && data) {
         		dl->next = NULL;
         		strcpy(data, next);
		        dl->data = data;
            SET_ARG_LIST(pi->args, ARG_INCLUDEPATH, dl);
         	}
         	else {
         		printf("Error: Unable to allocate memory\n");
        		return(False);
         	}
        }
        else
          add_arg(&incpath, next);
			break;
		case DIRECTIVE_LIST:
			if(pi->pass == PASS_2)
				if(pi->list_file)
          pi->list_on = True;
			break;
		case DIRECTIVE_LISTMAC:
			if(pi->pass == PASS_2)
				SET_ARG_I(pi->args, ARG_LISTMAC, True);
			break;
		case DIRECTIVE_MACRO:
			return(read_macro(pi, next));
//			break;
		case DIRECTIVE_NOLIST:
			if(pi->pass == PASS_2)
				pi->list_on = False;
			break;
		case DIRECTIVE_ORG:
			if(!next) {
				print_msg(pi, MSGTYPE_ERROR, ".ORG needs an operand");
				return(True);
			}
			get_next_token(next, TERM_END);
			if(!get_expr(pi, next, &i))
				return(False);
			fix_orglist(pi->segment);
			pi->segment->addr = i; /* XXX advance */
			def_orglist(pi->segment);
			if(pi->fi->label)
				pi->fi->label->value = i;
			if((pi->pass == PASS_2) && pi->list_line && pi->list_on) {
				fprintf(pi->list_file, "          %s\n", pi->list_line);
				pi->list_line = NULL;
			}
			break;
		case DIRECTIVE_SET:
			if(!next) {
				print_msg(pi, MSGTYPE_ERROR, ".SET needs an operand");
				return(True);
			}
			data = get_next_token(next, TERM_EQUAL);
			if(!data) {
				print_msg(pi, MSGTYPE_ERROR, "%s needs an expression (e.g. .SET BZZZT = 0x2a)", next);
				return(True);
			}
			get_next_token(data, TERM_END);
			if(!get_expr(pi, data, &i))
				return(False);

      if(test_label(pi,next,"%s have already been defined as a label")!=NULL) 
        return(True);
      if(test_constant(pi,next,"%s have already been defined as a .EQU constant")!=NULL) 
        return(True);
      return(def_var(pi, next, i));
//			break;
		case DIRECTIVE_DEFINE:
			if(!next) {
				print_msg(pi, MSGTYPE_ERROR, ".DEFINE needs an operand");
				return(True);
			}
			data = get_next_token(next, TERM_SPACE);
			if(data) {
				get_next_token(data, TERM_END);
				if(!get_expr(pi, data, &i))
				        return(False);
			}
			else
				i = 1;
      if(test_label(pi,next,"%s have already been defined as a label")!=NULL) 
        return(True);
      if(test_variable(pi,next,"%s have already been defined as a .SET variable")!=NULL) 
        return(True);
			/* B.A. : New. Forward references allowed. But check, if everything is ok ... */
			if(pi->pass==PASS_1) { /* Pass 1 */
	      if(test_constant(pi,next,"Can't redefine constant %s, use .SET instead")!=NULL) 
  	      return(True);
	      if(def_const(pi, next, i)==False)
    	      return(False);
			} else { /* Pass 2 */
				int j;
				if(get_constant(pi, next, &j)==False) {   /* Defined in Pass 1 and now missing ? */
   	      print_msg(pi, MSGTYPE_ERROR, "Constant %s is missing in pass 2", next);
  	      return(False);
				}
				if(i != j) {
   	      print_msg(pi, MSGTYPE_ERROR, "Constant %s changed value from %d in pass1 to %d in pass 2", next,j,i);
  	      return(False);
				}
				/* OK. Definition is unchanged */
			}
			if((pi->pass == PASS_2) && pi->list_line && pi->list_on) {
				fprintf(pi->list_file, "          %s\n", pi->list_line);
				pi->list_line = NULL;
			}
			break;
		case DIRECTIVE_NOOVERLAP:
			if (pi->pass == PASS_1) {
				fix_orglist(pi->segment);
				pi->segment_overlap = SEG_DONT_OVERLAP;
				def_orglist(pi->segment);
			}
			break;
		case DIRECTIVE_OVERLAP:
			if (pi->pass == PASS_1) {
				fix_orglist(pi->segment);
				pi->segment_overlap = SEG_ALLOW_OVERLAP;
				def_orglist(pi->segment);
			}
			break;
		case DIRECTIVE_PRAGMA:
			if (!next) {
				print_msg(pi, MSGTYPE_ERROR, "PRAGMA needs an operand, %s should be specified",
					snprint_list(buf, sizeof(buf), pragma_list));
				return(True);
			}
			my_strupr(next);
			data = get_next_token(next, TERM_SPACE);
			pragma = lookup_keyword(pragma_list, next, False);
			switch (pragma) {

				case PRAGMA_OVERLAP:
					if (pi->pass == PASS_1) {
						int overlap_setting = OVERLAP_UNDEFINED;
						if (data) {
								my_strupr(data);
								overlap_setting = lookup_keyword(overlap_value, data, False);
						};
						switch (overlap_setting) {
								case OVERLAP_DEFAULT:
									pi->effective_overlap = GET_ARG_I(pi->args, ARG_OVERLAP);
									break;

								case OVERLAP_IGNORE:
								case OVERLAP_WARNING:
								case OVERLAP_ERROR:
									pi->effective_overlap = overlap_setting;
									break;

								default:
									print_msg(pi, MSGTYPE_ERROR, "For PRAGMA %s directive" 
										" %s should be specified as the parameter", next, 
										snprint_list(buf, sizeof(buf), overlap_value));
									return(False);
						}
					}
					return(True);
					break;
				default:
					if(pi->pass == PASS_2)
						print_msg(pi, MSGTYPE_MESSAGE, "PRAGMA %s directive currently ignored", next);
					return(True);
			}
			break;
		case DIRECTIVE_UNDEF: // TODO
			break;
		case DIRECTIVE_IFDEF:
			if(!next)
				{
				print_msg(pi, MSGTYPE_ERROR, ".IFDEF needs an operand");
				return(True);
				}
			get_next_token(next, TERM_END);
			/* B.A. : Forward referenc is not allowed for ifdef and ifndef */
			/* Store undefined symbols in blacklist in pass1 and check, if they are still undefined in pass2 */
			if(get_symbol(pi, next, NULL)) {
#if 0
					// If it's not defined in the first pass, but was defined later
					// then it should be considered OK with regards to ifdef..endif and
					// ifndef..endif code sections. Removed this code.
				if(pi->pass==PASS_2) { /* B.A. : 'Still undefined'-test in pass 2 */
 		          if(test_blacklist(pi,next,"Forward reference (%s) not allowed in .ifdef directive")!=NULL)
					return(False);
				}
#else
				pi->conditional_depth++;
#endif
			} else {
				if(pi->pass==PASS_1) { /* B.A. : Store undefined symbols in pass 1 */
          if(def_blacklist(pi, next)==False) 
   	        return(False);
 				}
				if(!spool_conditional(pi, False))
	        return(False);
			}
			break;
		case DIRECTIVE_IFNDEF:
			if(!next)
				{
				print_msg(pi, MSGTYPE_ERROR, ".IFNDEF needs an operand");
				return(True);
				}
			get_next_token(next, TERM_END);
			/* B.A. : Forward referenc is not allowed for ifdef and ifndef */
			/* Store undefined symbols in blacklist in pass1 and check, if they are still undefined in pass2 */
			if(!get_symbol(pi, next, NULL))
		        {
#if 0
				if(pi->pass==PASS_2) { /* B.A. : 'Still undefined'-test in pass 2 */
					// If it's not defined in the first pass, but was defined later
					// then it should be considered OK with regards to ifdef..endif and
					// ifndef..endif code sections. Removed this code.
 		          if(test_blacklist(pi,next,"Forward reference (%s) not allowed in .ifndef directive")!=NULL)
					return(False);
				}
				if(!spool_conditional(pi, False))
				        return(False);
#else
				pi->conditional_depth++;
#endif
				}
			else {
				if(pi->pass==PASS_1) { /* B.A. : Store undefined symbols in pass 1 */
		          if(def_blacklist(pi, next)==False) 
		   	        return(False);
 				}
				if(!spool_conditional(pi, False))
					return(False);
			}
			break;
		case DIRECTIVE_IF:
			if(!next)
				{
				print_msg(pi, MSGTYPE_ERROR, ".IF needs an expression");
				return(True);
				}
			get_next_token(next, TERM_END);
			if(!get_expr(pi, next, &i))
			        return(False);
			if(i)
				pi->conditional_depth++;
			else
			        {
				if(!spool_conditional(pi, False))
				        return(False);
				}
			break;
		case DIRECTIVE_ELSE:
		case DIRECTIVE_ELIF: 
		case DIRECTIVE_ELSEIF: 
		        if(!spool_conditional(pi, True))
			        return(False);
			break;
		case DIRECTIVE_ENDIF:
		        if(pi->conditional_depth == 0)
			        print_msg(pi, MSGTYPE_ERROR, "Too many .ENDIF");
			else
			        pi->conditional_depth--;
			break;
		case DIRECTIVE_MESSAGE:
			if(pi->pass == PASS_1)
				return(True);
			if(!next) {
				print_msg(pi, MSGTYPE_ERROR, "No message parameter supplied");
				return(True);
			} 
			/* B.A : Extended .MESSAGE. Now a comma separated list like in .db is possible and not only a string */
			print_msg(pi, MSGTYPE_MESSAGE_NO_LF, NULL); 	/* Prints Line Header (filename, linenumber) without trailing /n */
		    while(next) { 	/* Modified code from parse_db(). Thank you :-) */
			  data = get_next_token(next, TERM_COMMA);
				if(next[0] == '\"') { 	/* string parsing */
	              next = term_string(pi, next);
		 		  print_msg(pi, MSGTYPE_APPEND,"%s",next);
			      while(*next != '\0') {
					next++;
	    		  }
				} else {
 		          if(!get_expr(pi, next, &i)) {
			 		print_msg(pi, MSGTYPE_APPEND,"\n"); /* Add newline */
  		            return(False);
				  }
		 		  print_msg(pi, MSGTYPE_APPEND,"0x%02X",i);
	           }			
    	   	next = data;
		    }
	 		print_msg(pi, MSGTYPE_APPEND,"\n"); /* Add newline */
			break;
		case DIRECTIVE_WARNING:
			if(pi->pass == PASS_1)
				return(True);
			if(!next) {
				print_msg(pi, MSGTYPE_ERROR, "No warning string supplied");
				return(True);
			}
			next = term_string(pi, next);
			print_msg(pi, MSGTYPE_WARNING, next);
			break;
		case DIRECTIVE_ERROR:		
			if(!next) { /* B.A : Fix segfault bug if .error without parameter was used */
				print_msg(pi, MSGTYPE_ERROR, "No error string supplied");
				return(True);
		    }
			next = term_string(pi, next);		
			print_msg(pi, MSGTYPE_ERROR, "%s", next);
            pi->error_count = pi->max_errors;
			if(pi->pass == PASS_1)
				return(True);
			break;
	}