📄 common.c
字号:
}
} while (c != tail_ptr);
c = tail_ptr->next;
tail_ptr->next = tail_ptr;
return(c);
}
//
// Merge sub-lists by value field
//
struct sym *merge_by_value(struct sym *a, struct sym *b)
{
struct sym *c;
c = tail_ptr;
do
{
if (a->val < b->val)
{
c->next = a;
c = a;
a = a->next;
}
else
{
c->next = b;
c = b;
b = b->next;
}
} while (c != tail_ptr);
c = tail_ptr->next;
tail_ptr->next = tail_ptr;
return(c);
}
//
// Check for redefinitions of label/symbol names
//
void chk_dup_name(struct sym *list, int count)
{
int i;
for (i=0; i<count; i++)
{
if (!strcasecmp(list->name, list->next->name))
{
printf("\nAttempted redefinition of '%s', value 0x%x,"
" as value 0x%x\n",
list->name, list->val, list->next->val);
exit(USER_ERROR);
}
list = list->next;
}
}
//
// Check for redefinitions of operand names
//
void chk_dup_op_name(struct sym *list, int count)
{
int i, adrs, val, next_adrs, next_val;
for (i=0; i<count; i++)
{
if (!strcasecmp(list->name, list->next->name))
{
adrs = list->val;
val = pgmmem[adrs];
if (pgmflags[adrs] & PF_WORD)
{
val <<= 8;
val |= pgmmem[adrs + 1];
}
next_adrs = list->next->val;
next_val = pgmmem[next_adrs];
if (pgmflags[next_adrs] & PF_WORD)
{
next_val <<= 8;
next_val |= pgmmem[next_adrs + 1];
}
if (val != next_val)
{
printf("\nAttempted redefinition of '%s', value 0x%x,"
" as value 0x%x\n",
list->name, val, next_val);
exit(USER_ERROR);
}
}
list = list->next;
}
}
//
// Check for redefinitions of values
//
void chk_dup_value(struct sym *list, int count)
{
int i;
for (i=0; i<count; i++)
{
if (list->val == list->next->val)
{
printf("\nAttempted redefinition of value 0x%x, '%s', as '%s'\n",
list->val, list->name, list->next->name);
exit(USER_ERROR);
}
list = list->next;
}
}
// Find symbol or label by value
//
// Binary search using table of pointers to list nodes.
// This search is based on the fact that:
// list[first-1] <= key < list[last+1]
// is an invariant. This allows the while loop to involve
// only one boolean expression, rather than two. The 'if'
// statement also involves only one boolean expression.
// The test for equality (has it been found?) is not done
// until the loop is complete. This significantly speeds
// up the search compared to a standard binary search.
//
char *find_entry(int val, int count, SYM_PTR *table)
{
struct sym *ptr;
int first, mid, last;
char *ret;
first = 1;
last = count;
while (first <= last) // while more to search...
{
mid = (first + last) >> 1; // begin in middle of remaining array
ptr = table[mid - 1]; // get pointer to node
if (ptr->val > val) // determine which way to go
last = mid - 1; // search before midpoint
else
first = mid + 1; // search after midpoint
}
ret = NULL; // assume not found
if (last > 0) // are we still within the array?
{
ptr = table[last - 1]; // if so, get last pointer
if (val == ptr->val) // is it what we're searching for?
{
ptr->used = TRUE; // label/symbol has been used
ret = ptr->name; // return pointer to caller
}
}
return(ret);
}
//
// Find symbol or label by name
// Table must be sorted by name
//
SYM_PTR find_name(char *name, int count, SYM_PTR *table)
{
int i;
SYM_PTR ptr;
int first, mid, last;
first = 1;
last = count;
while (first <= last) // while more to search...
{
mid = (first + last) >> 1; // begin in middle of remaining array
ptr = table[mid - 1]; // get pointer to node
i = strcasecmp(ptr->name, name);
if (i > 0)
last = mid - 1; // search before midpoint
else
first = mid + 1; // search after midpoint
}
ptr = NULL; // assume not found
if (last > 0) // are we still within the array?
{
ptr = table[last - 1]; // if so, get last pointer
if (strcasecmp(name, ptr->name))
ptr = NULL;
}
return(ptr);
}
//
// Allocate new entry in symbol table or label table
//
struct sym *get_smem(int type, int req_size)
{
struct sym *ptr;
ptr = (struct sym*) malloc(sizeof(struct sym) + req_size + 1);
// get memory from OS
if (ptr == NULL) // what? out of memory?...
{
printf("\nINTERNAL ERROR! - No memory for ");
switch (type)
{
case LABEL_TYPE:
printf("label");
break;
case SYMBOL_TYPE:
printf("symbol");
break;
case NAME_TYPE:
printf("name");
break;
default:
printf("\nUnknown table type: %d\n", type);
exit(PROGRAM_ERROR);
break;
}
printf(" table!\n");
exit(MEM_ERROR);
}
ptr->next = NULL;
return(ptr); // give caller the address
}
//
// Add symbol or label to table
//
void add_entry(int val, char *symbol, int type)
{
struct sym *nptr, *tbl_ptr;
char *cptr;
char tbl_name[8];
cptr = symbol; // ensure that input string is null terminated
while (*cptr)
{
if (!isgraph(*cptr))
break;
cptr++;
}
*cptr = '\0';
if (upperflag)
makeupper(symbol);
switch (type)
{
case LABEL_TYPE:
tbl_ptr = lab_tab; // get pointer to correct table
strcpy(tbl_name, "label");
label_count++;
break;
case SYMBOL_TYPE:
tbl_ptr = sym_tab;
strcpy(tbl_name, "symbol");
symbol_count++;
break;
case NAME_TYPE:
tbl_ptr = name_tab;
strcpy(tbl_name, "name");
name_count++;
break;
default:
printf("\nUnknown table type: %d\n", type);
exit(PROGRAM_ERROR);
break;
}
nptr = get_smem(type, strlen(symbol));
if (tbl_ptr == NULL) // if first symbol or label...
{
switch (type)
{
case LABEL_TYPE:
lab_tab = nptr;
break;
case SYMBOL_TYPE:
sym_tab = nptr;
break;
case NAME_TYPE:
name_tab = nptr;
break;
default:
printf("\nUnknown table type: %d\n", type);
exit(PROGRAM_ERROR);
break;
}
}
else
{
switch (type)
{
case LABEL_TYPE:
lab_tab_last->next = nptr;
break;
case SYMBOL_TYPE:
sym_tab_last->next = nptr;
break;
case NAME_TYPE:
name_tab_last->next = nptr;
break;
default:
printf("\nUnknown table type: %d\n", type);
exit(PROGRAM_ERROR);
break;
}
}
switch (type)
{
case LABEL_TYPE:
lab_tab_last = nptr;
break;
case SYMBOL_TYPE:
sym_tab_last = nptr;
break;
case NAME_TYPE:
name_tab_last = nptr;
break;
default:
printf("\nUnknown table type: %d\n", type);
exit(PROGRAM_ERROR);
break;
}
nptr->used = FALSE;
nptr->val = val; // set value in new entry
nptr->name = malloc(strlen(symbol) + 1);
if (!nptr->name)
{
printf("\nCan't allocate memory for ");
switch (type)
{
case LABEL_TYPE:
printf("label: %s\n", symbol);
break;
case SYMBOL_TYPE:
printf("symbol: %s\n", symbol);
break;
case NAME_TYPE:
printf("name: %s\n", symbol);
break;
default:
printf("Unknown table type: %d: %s\n", type, symbol);
break;
}
exit(MEM_ERROR);
}
strcpy(nptr->name, symbol); // and copy text to entry
}
//
// Output header comment(s) associated with 'adrs'
// Expand newlines
//
void output_comment(int adrs)
{
COMMENT_PTR cmt;
char *str;
cmt = comment_list;
while (cmt) // search through list for all
{ // entries that match adrs
if (cmt->adrs == adrs)
{
str = cmt->str;
fprintf(fp, "\n;");
if (strlen(str) > 3 && str[2] == '\\' && str[3] == 'n')
{
fprintf(fp, "\n; ");
str += 4;
}
else
str++;
while (*str)
{
if (*str == '\\' && *(str + 1) && (*(str + 1) == 'n'))
{
str++;
fprintf(fp, "\n;");
if (*(str + 1))
fputc(' ', fp);
}
else
fputc(*str, fp);
str++;
}
}
cmt = cmt->next;
}
}
//
// Output inline comment associated with 'adrs'
//
void output_icomment(int adrs)
{
COMMENT_PTR cmt;
cmt = icomment_list;
while (cmt) // search through list for all
{ // entries that match adrs
if (cmt->adrs == adrs)
fprintf(fp, "\t%s", cmt->str);
cmt = cmt->next;
}
}
//
// Output patch string(s) associated with 'adrs'
// Expand newlines
//
void output_patch(int adrs)
{
COMMENT_PTR patch;
char *str;
patch = patch_list;
while (patch) // search through list for all
{ // entries that match adrs
if (patch->adrs == adrs)
{
str = patch->str;
fprintf(fp, "\n");
while (*str)
{
if (*str == '\\' && *(str + 1) && (*(str + 1) == 'n'))
{
str++;
fprintf(fp, "\n");
}
else
fputc(*str, fp);
str++;
}
}
patch = patch->next;
}
}
//
// Add comment string to linked list in memory
//
void add_comment(int adrs, char *str)
{
int len;
char *ctext;
COMMENT_PTR cmt_ptr;
len = strlen(str) - 1;
if (len >= 0 && (str[len] == '\n' || str[len] == '\r'))
str[len] = '\0'; // get rid of newline
if (!comment_list) // first comment
{
comment_list = malloc(sizeof(struct comment));
if (comment_list == NULL)
{
printf("\nNo memory for comment struct");
exit(MEM_ERROR);
}
cmt_ptr = comment_list;
}
else // add comment to list
{
cmt_ptr = comment_list;
while (cmt_ptr->next) // find end of list
cmt_ptr = cmt_ptr->next;
cmt_ptr->next = malloc(sizeof(struct comment));
if (cmt_ptr->next == NULL)
{
printf("\nNo memory for comment struct");
exit(MEM_ERROR);
}
cmt_ptr = cmt_ptr->next;
}
cmt_ptr->adrs = adrs;
ctext = malloc(strlen(str) + 3);
if (ctext == NULL)
{
printf("\nNo memory for comment string");
exit(MEM_ERROR);
}
cmt_ptr->str = ctext;
if (len >= 0)
{
strcpy(ctext, "; ");
strcat(ctext, str);
}
else
strcpy(ctext, ";");
cmt_ptr->next = NULL;
}
void add_icomment(int adrs, char *str)
{
int len;
char *ctext;
COMMENT_PTR cmt_ptr;
len = strlen(str) - 1;
if (str[len] == '\n' || str[len] == '\r')
str[len] = '\0'; // get rid of newline
if (!icomment_list) // first comment
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -