/* Handles assembly directives; returns non-zero if the line was a directive. */ static int handle_directive(char *line) { char *s,*name; hashdata data; s=skip(line); if(!ISIDSTART(*s)) return 0; name=s; while(ISIDCHAR(*s)) s++; if(!find_namelen(dirhash,name,s-name,&data)) return 0; directives[data.idx].func(skip(s)); return 1; }
/* checks for a valid directive, and return index when found, -1 otherwise */ static int check_directive(char **line) { char *s,*name; hashdata data; s = skip(*line); if (!ISIDSTART(*s) && *s!='=') return -1; name = s++; while (ISIDCHAR(*s) || *s=='.') s++; if (*name=='.') /* leading dot is optional for all directives */ name++; if (!find_namelen_nc(dirhash,name,s-name,&data)) return -1; *line = s; return data.idx; }
/* checks for a valid directive, and return index when found, -1 otherwise */ static int check_directive(char **line) { char *s,*name; hashdata data; s = skip(*line); if (!ISIDSTART(*s)) return -1; name = s++; while (ISIDCHAR(*s)) s++; if (*name == '.') name++; else if (!nodotneeded) return -1; if (!find_namelen(dirhash,name,s-name,&data)) return -1; *line = s; return data.idx; }
static void handle_section(char *s) { char *name,*attr; if(*s!='\"'){ name=s; if(!ISIDSTART(*s)){ syntax_error(10); return; } while(ISIDCHAR(*s)) s++; name=cnvstr(name,s-name); s=skip(s); }else{ s++; name=s; while(*s&&*s!='\"') s++; name=cnvstr(name,s-name); s=skip(s+1); } if(*s==','){ s=skip(s+1); attr=s; if(*s!='\"') syntax_error(7); else s++; attr=s; while(*s&&*s!='\"') s++; attr=cnvstr(attr,s-attr); s=skip(s+1); }else attr=""; new_section(name,attr,1); switch_section(name,attr); eol(s); }
int main(int argc,char **argv) { int i; for(i=1; i<argc; i++) { if(argv[i][0]=='-'&&argv[i][1]=='F') { output_format=argv[i]+2; argv[i][0]=0; } if(!strcmp("-quiet",argv[i])) { verbose=0; argv[i][0]=0; } } if(!init_output(output_format)) general_error(16,output_format); if(!init_main()) general_error(10,"main"); if(verbose) printf("%s\n%s\n%s\n%s\n",copyright,cpu_copyright,syntax_copyright,output_copyright); for(i=1; i<argc; i++) { if(argv[i][0]==0) continue; if(argv[i][0]!='-') { if(inname) general_error(11); inname=argv[i]; continue; } if(!strcmp("-o",argv[i])&&i<argc-1) { if(outname) general_error(28,'o'); outname=argv[++i]; continue; } if(!strcmp("-L",argv[i])&&i<argc-1) { if(listname) general_error(28,'L'); listname=argv[++i]; produce_listing=1; continue; } if(!strcmp("-Lnf",argv[i])) { listformfeed=0; continue; } if(!strcmp("-Lns",argv[i])) { listnosyms=1; continue; } if(!strncmp("-Ll",argv[i],3)) { sscanf(argv[i]+3,"%i",&listlinesperpage); continue; } if(!strncmp("-D",argv[i],2)) { char *def=NULL; expr *val; if(argv[i][2]) def=&argv[i][2]; else if (i<argc-1) def=argv[++i]; if(def) { char *s=def; if(ISIDSTART(*s)) { s++; while(ISIDCHAR(*s)) s++; def=cnvstr(def,s-def); if(*s=='=') { s++; val=parse_expr(&s); } else val=number_expr(1); if(*s) general_error(23,'D'); /* trailing garbage after option */ new_abs(def,val); myfree(def); continue; } } } if(!strncmp("-I",argv[i],2)) { char *path=NULL; if(argv[i][2]) path=&argv[i][2]; else if (i<argc-1) path=argv[++i]; if(path) { new_include_path(path); continue; } } if(!strcmp("-unnamed-sections",argv[i])) { unnamed_sections=1; continue; } if(!strcmp("-ignore-mult-inc",argv[i])) { ignore_multinc=1; continue; } if(!strcmp("-nocase",argv[i])) { nocase=1; continue; } if(!strcmp("-noesc",argv[i])) { esc_sequences=0; continue; } if(!strcmp("-nosym",argv[i])) { no_symbols=1; continue; } if(!strncmp("-nowarn=",argv[i],8)) { int wno; sscanf(argv[i]+8,"%i",&wno); disable_warning(wno); continue; } else if(!strcmp("-w",argv[i])) { no_warn=1; continue; } if(!strncmp("-maxerrors=",argv[i],11)) { sscanf(argv[i]+11,"%i",&max_errors); continue; } else if(!strcmp("-pic",argv[i])) { pic_check=1; continue; } if(cpu_args(argv[i])) continue; if(syntax_args(argv[i])) continue; if(output_args(argv[i])) continue; if (!strncmp("-x",argv[i],2)) { auto_import=0; continue; } general_error(14,argv[i]); } if(inname) { setfilename(inname); setdebugname(inname); include_source(inname); } else general_error(15); if(!init_parse()) general_error(10,"parse"); if(!init_syntax()) general_error(10,"syntax"); if(!init_cpu()) general_error(10,"cpu"); parse(); if(errors==0||produce_listing) resolve(); if(errors==0||produce_listing) assemble(); if(errors==0&&!auto_import) undef_syms(); if(!listname) listname="a.lst"; if(produce_listing) write_listing(listname); if(!outname) outname="a.out"; if(errors==0) { if(verbose) statistics(); outfile=fopen(outname,"wb"); if(!outfile) general_error(13,outname); write_object(outfile,first_section,first_symbol); } leave(); return 0; /* not reached */ }
void parse(void) { char *s,*line,*ext[MAX_QUALIFIERS?MAX_QUALIFIERS:1],*op[MAX_OPERANDS]; char *labname,*start; int inst_len,ext_len[MAX_QUALIFIERS?MAX_QUALIFIERS:1],op_len[MAX_OPERANDS]; int ext_cnt,op_cnt; instruction *ip; while (line=read_next_line()){ if (clev >= MAXCONDLEV) syntax_error(16,clev); /* nesting depth exceeded */ if (!cond[clev]) { /* skip source until ELSE or ENDIF */ int idx; s = line; idx = check_directive(&s); if (idx >= 0) { if (!strncmp(directives[idx].name,"if",2)) { ifnesting++; } else if (ifnesting==0 && !strncmp(directives[idx].name,"else",4)) { cond[clev] = 1; } else if (directives[idx].func == handle_endif) { if (ifnesting == 0) { if (clev > 0) clev--; else syntax_error(14); /* endif without if */ } else ifnesting--; } } continue; } s=skip(line); if(handle_directive(s)) continue; /* skip spaces */ s=skip(s); if(!*s||*s==commentchar) continue; /* check for label */ start=s; if(labname=get_local_label(&s)){ /* local label? */ if(*s!=':'){ s=start; myfree(labname); labname=NULL; } } else if(ISIDSTART(*s)){ /* or global label? */ s++; while(ISIDCHAR(*s)) s++; if(*s!=':') s=start; else labname=cnvstr(start,s-start); } if(labname){ /* we have found a valid global or local label */ add_atom(0,new_label_atom(new_labsym(0,labname))); s=skip(s+1); myfree(labname); } if(!*s||*s==commentchar) continue; s=skip(parse_cpu_special(s)); if(*s==0||*s==commentchar) continue; if(handle_directive(s)) continue; /* read mnemonic name */ start=s; ext_cnt=0; if(!ISIDSTART(*s)){ syntax_error(10); continue; } #if MAX_QUALIFIERS==0 while(*s&&!isspace((unsigned char)*s)) s++; inst_len=s-start; #else s=parse_instruction(s,&inst_len,ext,ext_len,&ext_cnt); #endif s=skip(s); if(execute_macro(start,inst_len,ext,ext_len,ext_cnt,s,clev)) continue; /* read operands, terminated by comma (unless in parentheses) */ op_cnt=0; while(*s&&*s!=commentchar&&op_cnt<MAX_OPERANDS){ op[op_cnt]=s; s=skip_operand(s); op_len[op_cnt]=oplen(s,op[op_cnt]); #if !ALLOW_EMPTY_OPS if(op_len[op_cnt]<=0) syntax_error(5); else #endif op_cnt++; s=skip(s); if(*s!=','){ break; }else{ s=skip(s+1); } } s=skip(s); if(*s!=0&&*s!=commentchar) syntax_error(6); ip=new_inst(start,inst_len,op_cnt,op,op_len); #if MAX_QUALIFIERS>0 if(ip){ int i; for(i=0;i<ext_cnt;i++) ip->qualifiers[i]=cnvstr(ext[i],ext_len[i]); for(;i<MAX_QUALIFIERS;i++) ip->qualifiers[i]=0; } #endif if(ip){ add_atom(0,new_inst_atom(ip)); }else ; } if (clev > 0) syntax_error(15); /* if without endif */ }