STR convarg4(STR a, STR s) { int i; s = newstr(s); if(is_empty(a)){ clrstr(a); return(s); } for(i=0;a[i];i++){ if(a[i] == '/'){ s = basestr(s); continue; } if(a[i] == '.'){ s = dotstr(s); continue; } clrstr(s); s = newstr("{"); s = catstr(s, a); s = catstr(s, "}"); clrstr(a); return(s); } clrstr(a); return(s); }
const char *nodeset_string (nodeset_t *n) { assert (n->magic == NS_MAGIC); const char *sep = ""; int used = 0; uint32_t r, lo = 0, hi = 0; bool inrange = false; char tmp[128]; if (!n->s_valid) { if (!n->s) { n->s_size = string_initsize; if (!(n->s = malloc (n->s_size))) oom (); } n->s[0] = '\0'; if (n->conf_brackets && !nodeset_single (n)) catstr (&n->s, &n->s_size, &used, "["); r = NS_FIRST (n); while (r < NS_SIZE (n) || inrange) { if (n->conf_ranges) { if (!inrange) { lo = hi = r; inrange = true; } else if (r < NS_SIZE (n) && r == hi + 1) { hi++; } else if (lo == hi) { snprintf (tmp, sizeof (tmp), "%s%0*u", sep, n->conf_padding, lo); catstr (&n->s, &n->s_size, &used, tmp); sep = n->conf_separator; inrange = false; continue; } else { snprintf (tmp, sizeof (tmp), "%s%0*u-%0*u", sep, n->conf_padding, lo, n->conf_padding, hi); catstr (&n->s, &n->s_size, &used, tmp); sep = n->conf_separator; inrange = false; continue; } } else { snprintf (tmp, sizeof (tmp), "%s%0*u", sep, n->conf_padding, r); catstr (&n->s, &n->s_size, &used, tmp); sep = n->conf_separator; inrange = false; } if (r < NS_SIZE (n)) r = NS_NEXT (n, r); } if (n->s[0] == '[') catstr (&n->s, &n->s_size, &used, "]"); n->s_valid = true; } return n->s; }
char *frobPath(char *path) { char *suffix = strrchr(path, '.'); if (suffix != NULL && strcmpi(suffix, ".jar") == 0) { path = catstr("javaw.exe -jar \"", path); path = catstr(path, "\""); } return path; }
static void prepvalue(struct rnndb *db, struct rnnvalue *val, char *prefix, struct rnnvarinfo *parvi) { val->fullname = catstr(prefix, val->name); prepvarinfo (db, val->fullname, &val->varinfo, parvi); if (val->varinfo.dead) return; if (val->varinfo.prefix) val->fullname = catstr(val->varinfo.prefix, val->fullname); }
static void prepbitfield(struct rnndb *db, struct rnnbitfield *bf, char *prefix, struct rnnvarinfo *parvi) { bf->fullname = catstr(prefix, bf->name); prepvarinfo (db, bf->fullname, &bf->varinfo, parvi); if (bf->varinfo.dead) return; if (bf->high == 63) bf->mask = - (1ULL<<bf->low); else bf->mask = (1ULL<<(bf->high+1)) - (1ULL<<bf->low); preptypeinfo(db, &bf->typeinfo, bf->fullname, &bf->varinfo, bf->high - bf->low + 1, bf->file); if (bf->varinfo.prefix) bf->fullname = catstr(bf->varinfo.prefix, bf->fullname); }
static void prepdomain(struct rnndb *db, struct rnndomain *dom) { prepvarinfo (db, dom->name, &dom->varinfo, 0); int i; for (i = 0; i < dom->subelemsnum; i++) prepdelem(db, dom->subelems[i], dom->bare?0:dom->name, &dom->varinfo, dom->width); dom->fullname = catstr(dom->varinfo.prefix, dom->name); }
STR convarg2(STR a, MTNJOB *j) { int i; STR p; STR q; STR r; i = 0; p = newstr(a); while(*(p + i)){ if(*(p + i) == '}'){ *(p + i) = 0; i++; q = newstr(p); r = newstr(p + i); q = convarg3(q, j); a = modstr(a, q); a = catstr(a, r); clrstr(q); clrstr(r); break; } i++; } clrstr(p); return(a); }
STR convarg(STR a, MTNJOB *j) { int i; STR p; STR q; if(!a){ return(NULL); } if(!j){ return(a); } i = 0; p = newstr(a); while(*(p + i)){ if(*(p + i) == '{'){ *(p + i) = 0; i++; q = newstr(p + i); q = convarg2(q, j); a = modstr(a, p); a = catstr(a, q); p = modstr(p, a); q = clrstr(q); continue; } i++; } clrstr(p); return(a); }
static void prepbitset(struct rnndb *db, struct rnnbitset *bs) { prepvarinfo (db, bs->name, &bs->varinfo, 0); int i; if (bs->isinline) return; for (i = 0; i < bs->bitfieldsnum; i++) prepbitfield(db, bs->bitfields[i], bs->bare?0:bs->name, &bs->varinfo); bs->fullname = catstr(bs->varinfo.prefix, bs->name); }
static void prepdelem(struct rnndb *db, struct rnndelem *elem, char *prefix, struct rnnvarinfo *parvi, int width) { if (elem->type == RNN_ETYPE_USE_GROUP) { int i; struct rnngroup *gr = 0; for (i = 0; i < db->groupsnum; i++) if (!strcmp(db->groups[i]->name, elem->name)) { gr = db->groups[i]; break; } if (gr) { for (i = 0; i < gr->subelemsnum; i++) ADDARRAY(elem->subelems, copydelem(gr->subelems[i], elem->file)); } else { fprintf (stderr, "group %s not found!\n", elem->name); db->estatus = 1; } elem->type = RNN_ETYPE_STRIPE; elem->length = 1; elem->name = 0; } if (elem->name) elem->fullname = catstr(prefix, elem->name); prepvarinfo (db, elem->fullname?elem->fullname:prefix, &elem->varinfo, parvi); if (elem->varinfo.dead) return; if (elem->length != 1 && !elem->stride) { if (elem->type != RNN_ETYPE_REG) { fprintf (stderr, "%s has non-1 length, but no stride!\n", elem->fullname); db->estatus = 1; } else { elem->stride = elem->width/width; } } preptypeinfo(db, &elem->typeinfo, elem->name?elem->fullname:prefix, &elem->varinfo, elem->width, elem->file); int i; for (i = 0; i < elem->subelemsnum; i++) prepdelem(db, elem->subelems[i], elem->name?elem->fullname:prefix, &elem->varinfo, width); if (elem->varinfo.prefix && elem->name) elem->fullname = catstr(elem->varinfo.prefix, elem->fullname); }
STR mtnfile_console_path(STR opt) { int i; STR path; ARG dirs; path = newstr(ctx->remote_path); dirs = splitstr(opt, "/"); for(i=0;dirs[i];i++){ if(!strcmp(dirs[i], "..")){ path = modstr(path, dirname(path)); }else if(!strcmp(dirs[i], ".")){ }else{ if(lastchar(path) != '/'){ path = catstr(path, "/"); } path = catstr(path, dirs[i]); } } dirs = clrarg(dirs); return(path); }
static void prepenum(struct rnndb *db, struct rnnenum *en) { if (en->prepared) return; prepvarinfo (db, en->name, &en->varinfo, 0); int i; if (en->isinline) return; for (i = 0; i < en->valsnum; i++) prepvalue(db, en->vals[i], en->bare?0:en->name, &en->varinfo); en->fullname = catstr(en->varinfo.prefix, en->name); en->prepared = 1; }
int mtnfile_console() { int argc; ARG args; char *line; STR prompt = newstr("mtn:/> "); ctx->remote_path = newstr("/"); rl_attempted_completion_function = mtnfile_console_readline_callback; while((line = readline(prompt))){ if(!strlen(line)){ free(line); continue; } args = splitstr(line, " "); argc = cntarg(args); if(!argc){ free(line); continue; }else if(!strcmp(args[0], "exit")){ break; }else if(!strcmp(args[0], "quit")){ break; }else if(!strcmp(args[0], "help")){ mtnfile_console_help(args[1]); }else if(!strcmp(args[0], "ls" )){ mtnfile_console_ls(argc, args); }else if(!strcmp(args[0], "cd" )){ mtnfile_console_cd(argc, args); }else if(!strcmp(args[0], "lcd" )){ mtnfile_console_lcd(argc, args); }else if(!strcmp(args[0], "cat" )){ mtnfile_console_cat(argc, args); }else if(!strcmp(args[0], "get" )){ mtnfile_console_get(argc, args); }else if(!strcmp(args[0], "put" )){ mtnfile_console_put(argc, args); }else if(!strcmp(args[0], "del" )){ mtnfile_console_del(argc, args); }else{ mtnlogger(mtn, 0, "%s: no such command.\n", args[0]); } add_history(line); free(line); line = NULL; args = clrarg(args); prompt = modstr(prompt, "mtn:"); prompt = catstr(prompt, ctx->remote_path); prompt = catstr(prompt, "> "); } return(0); }
int main(int argc, char *argv[]) { char *t; string *str; int i; t = getenv("SHSQL"); if(t != NULL) { if(!strcmp(t, "postgres")) mode = SHSQL_POSTGRES; else if(!strcmp(t, "mysql")) mode = SHSQL_MYSQL; else if(!strcmp(t, "sqlite3")) mode = SHSQL_SQLITE3; else if(!strcmp(t, "odbc")) mode = SHSQL_ODBC; else if(!strcmp(t, "freetds")) mode = SHSQL_FREETDS; else mode = SHSQL_POSTGRES; } else mode = SHSQL_POSTGRES; str = new_string(); for(i=1;i<argc;i++) { catstr(str, argv[i]); if(string_len(str) && i < argc - 1) string_cat_c(str, ' '); } if(string_len(str)) { fputc('\'', stdout); fputs(string_s(str), stdout); fputc('\'', stdout); } else fputs("NULL", stdout); string_delete(str); return 0; }
int unreg(char *key) { HKEY regKey = NULL; char *subkey = catstr(KEY_PREFIX, key); LONG result; result = RegDeleteKey( HKEY_LOCAL_MACHINE, // handle of open key subkey); // address of name of subkey to delete //fprintf(stdout, "delete result is %ld\n", result); if (result != ERROR_SUCCESS) return 1; return 0; }
int fastq_pair_stream(char *left_fn, char *right_fn) { /* * read the left fastq file and store it in seqs * We can't use our normal read here because our * struct is slightly different */ gzFile fp; char line[MAXLINELEN]; int seqcounter=0; if ((fp = gzopen(left_fn, "rb")) == NULL) { fprintf(stderr, "Can't open file %s\n", left_fn); exit(1); } while ((ignored = gzgets(fp, line, MAXLINELEN)) != NULL) { /* define our fastq data element */ struct fastq_pair_stream *nfq; nfq = (struct fastq_pair_stream *) malloc(sizeof(*nfq)); if (nfq == NULL) { fprintf(stderr, "Can't allocate memory for pointer\n"); return 0; } nfq->seen = 0; /* store the whole line */ nfq->name = dupstr(line); /* store the sequence ID */ line[strcspn(line, " ")] = '\0'; nfq->seqid = dupstr(line); /* read the sequence and save it */ ignored = gzgets(fp, line, MAXLINELEN); if (line == NULL) { fprintf(stderr, "There was no sequence for %s", nfq->name); exit(1); } nfq->seq = dupstr(line); /* read the next line and ignore it */ ignored = gzgets(fp, line, MAXLINELEN); /* read the quality scores and save them */ ignored = gzgets(fp, line, MAXLINELEN); if (line == NULL) { fprintf(stderr, "There were no quality scores for %s", nfq->name); exit(1); } nfq->qual = dupstr(line); if (addfqs(nfq) != NULL) seqcounter++; free(nfq); } gzclose(fp); /* now we want to open output files for left_paired, right_paired, and right_single */ FILE * left_paired; FILE * left_single; FILE * right_paired; FILE * right_single; char *lpfn = catstr(dupstr(left_fn), ".paired.fq"); char *rpfn = catstr(dupstr(right_fn), ".paired.fq"); char *lsfn = catstr(dupstr(left_fn), ".single.fq"); char *rsfn = catstr(dupstr(right_fn), ".single.fq"); /* char *lpfn = "aaaaa.paired.fq"; char *rpfn = "bbbbb.paired.fq"; char *lsfn = "aaaaa.single.fq"; char *rsfn = "bbbbb.paired.fq"; */ printf("Writing the paired reads to %s and %s.\nWriting the single reads to %s and %s\n", lpfn, rpfn, lsfn, rsfn); if ((left_paired = fopen(lpfn, "w")) == NULL ) { fprintf(stderr, "Can't open file %s\n", lpfn); exit(1); } if ((left_single = fopen(lsfn, "w")) == NULL) { fprintf(stderr, "Can't open file %s\n", lsfn); exit(1); } if ((right_paired = fopen(rpfn, "w")) == NULL) { fprintf(stderr, "Can't open file %s\n", rpfn); exit(1); } if ((right_single = fopen(rsfn, "w")) == NULL) { fprintf(stderr, "Can't open file %s\n", rsfn); exit(1); } /* now we want to iterate through the right file, and print the reads to either paired or singles */ if ((fp = gzopen(right_fn, "rb")) == NULL) { fprintf(stderr, "Can't open file %s\n", right_fn); exit(1); } while ((ignored = gzgets(fp, line, MAXLINELEN)) != NULL) { /* store the whole line */ char *name = dupstr(line); /* store the sequence ID */ line[strcspn(line, " ")] = '\0'; char *seqid = dupstr(line); /* read the sequence and save it */ ignored = gzgets(fp, line, MAXLINELEN); if (line == NULL) { fprintf(stderr, "There was no sequence for %s", name); exit(1); } char *seq = dupstr(line); /* read the next line and ignore it */ ignored = gzgets(fp, line, MAXLINELEN); /* read the quality scores and save them */ ignored = gzgets(fp, line, MAXLINELEN); if (line == NULL) { fprintf(stderr, "There were no quality scores for %s", name); exit(1); } char *qual = dupstr(line); /* figure out if the read has been seen before */ /* * Paired reads usually end either .1 and .2 or /1 and /2. Either way, the last character is the l/r direction. * We are going to get the last character of the sequence ID and test if it is a 1 or 2, and use the alternate. * If it is neither 1 or 2, at the moment we'll throw an error. I'm not sure if people also use f/r for forward * reverse, but we may need to add those */ int lastcharidx = strlen(seqid)-1; char lastchar = seqid[lastcharidx]; switch(lastchar){ case '1': seqid[lastcharidx] = '2'; break; case '2': seqid[lastcharidx] = '1'; break; case 'f': seqid[lastcharidx] = 'r'; break; case 'r': seqid[lastcharidx] = 'f'; break; default: fprintf(stderr, "The last character in the sequence id is %c and we don't know if this is a forward or reverse read.\n", lastchar); exit(-1); } int hashval = hash(seqid); int found = 0; struct fastq_pair_stream *ptr; for (ptr = seqs[hashval]; ptr != NULL; ptr = ptr->next) if (strcmp(ptr->seqid, seqid) == 0) { ptr->seen = 1; found = 1; fprintf(left_paired, "%s%s+\n%s", ptr->name, ptr->seq, ptr->qual); fprintf(right_paired, "%s%s+\n%s", name, seq, qual); } if (!found) fprintf(right_single, "%s%s+\n%s", name, seq, qual); } gzclose(fp); /* now we just need to iterate through all the sequences and print the ones we haven't seen */ struct fastq_pair_stream *ptr; for (int i=0; i<HASHSIZE; i++) for (ptr = seqs[i]; ptr != NULL; ptr = ptr->next) if (!ptr->seen) fprintf(left_single, "%s%s+\n%s", ptr->name, ptr->seq, ptr->qual); /* error check and clean up */ if (ferror(left_paired)) fprintf(stderr, "WARNING: THERE WAS AN ERROR WRITING TO THE LEFT PAIRED FILE. Check it out. The error code is %d", ferror(left_paired)); fclose(left_paired); if (ferror(right_paired)) fprintf(stderr, "WARNING: THERE WAS AN ERROR WRITING TO THE RIGHT PAIRED FILE. Check it out. The error code is %d", ferror(right_paired)); fclose(right_paired); if (ferror(left_single)) fprintf(stderr, "WARNING: THERE WAS AN ERROR WRITING TO THE LEFT SINGLES FILE. Check it out. The error code is %d", ferror(left_single)); fclose(left_single); if (ferror(right_single)) fprintf(stderr, "WARNING: THERE WAS AN ERROR WRITING TO THE RIGHT SINGLES FILE. Check it out. The error code is %d", ferror(right_single)); fclose(right_single); return seqcounter; }
/* read the command-line options and set the global_config_filename and * local_config_filename fields accordingly */ int libconf_phase1(libconf_t * handle) { int argc = handle->argc; char ** argv = handle->argv; libconf_phase_error_t have_error; libconf_optparam_t * param; libconf_do_on_error_t error_action = DOE_ERROR; int have_param; char * param_name; char * tmp_str; libconf_opt_t * option; libconf_opt_t t_option; handle->argv0 = *argv; argv++; argc--; while (argc > 0) { have_error = PT_NONE; param = NULL; have_param = 0; tmp_str = NULL; switch (argv[0][0]) { case '-' : switch (argv[0][1]) { case '-' : /* we have a long option */ option = hash_get(handle->options, argv[0] + 2); if (option != NULL) { /* we've found the option */ param_name = option->co_name; error_action = option->do_on_error; if (option->co_long_takes_param != TP_NO) { if (argc > 1 && argv[1][0] && argv[1][0] != '-') { /* we have our option's param */ switch (option->co_long_param_type) { case PT_NUMERIC_LIST : case PT_STRING_LIST : case PT_FILENAME_LIST : param = hash_get(handle->tmp_hash, option->co_name); if (param != NULL) vector_push_back(param->val.vector_val, strdup(argv[1])); default : if (param == NULL) param = libconf_optparam_new(option->co_name, option->co_long_param_type, argv[1]); } if (param == NULL) have_error = ET_PARAM_MALFORMED; else if (param->have_error) have_error = ET_PARAM_MALFORMED; have_param = 1; } else if (option->co_long_takes_param == TP_YES) { /* we should have had a param, but we don't */ have_error = ET_EXPECTED_PARAM_TP_NOT_FOUND; } } hash_put(handle->tmp_hash, strdup(option->co_name), param); } else { have_error = ET_UNKNOWN_OPTION; } break; case 0 : /* we should stop treating command-line options and * concatenate the rest of the command-line, separated by * spaces. */ argv++; argc--; while (argc) { argv++; argc--; tmp_str = catstr(tmp_str, argv[0]); } param = libconf_optparam_new("-", PT_STRING, tmp_str); free(tmp_str); hash_put(handle->tmp_hash, strdup("-"), param); break; default : /* we have a short option */ t_option.co_short_opt = argv[0][1]; option = hash_search(handle->options, &t_option, libconf_phase1_helper1); if (option != NULL) { /* we have our option */ param_name = option->co_name; error_action = option->do_on_error; if (option->co_short_takes_param != TP_NO) { if (argv[0][2]) { /* we have a parameter directly following */ switch (option->co_short_param_type) { case PT_NUMERIC_LIST : case PT_STRING_LIST : case PT_FILENAME_LIST : param = hash_get(handle->tmp_hash, option->co_name); if (param != NULL) vector_push_back(param->val.vector_val, strdup(argv[0] + 2)); default : if (param == NULL) param = libconf_optparam_new(option->co_name, option->co_short_param_type, argv[0] + 2); } if (param == NULL) have_error = ET_PARAM_MALFORMED; else if (param->have_error) have_error = ET_PARAM_MALFORMED; // have_param = 1; we don't count these } else if (argc > 1 && argv[1][0] && argv[1][0] != '-' ) { /* we have a parameter */ switch (option->co_short_param_type) { case PT_NUMERIC_LIST : case PT_STRING_LIST : case PT_FILENAME_LIST : param = hash_get(handle->tmp_hash, option->co_name); if (param != NULL) vector_push_back(param->val.vector_val, strdup(argv[1])); default : if (param == NULL) param = libconf_optparam_new(option->co_name, option->co_short_param_type, argv[1]); } if (param == NULL) have_error = ET_PARAM_MALFORMED; else if (param->have_error) have_error = ET_PARAM_MALFORMED; have_param = 1; } else if (option->co_short_takes_param == TP_YES) { /* we should have had a param, but we don't */ have_error = ET_EXPECTED_PARAM_TP_NOT_FOUND; } } hash_put(handle->tmp_hash, strdup(option->co_name), param); } else { have_error = ET_UNKNOWN_OPTION; } break; } break; default : /* no option? */ have_error = ET_EXPECTED_OPTION_TP_NOT_FOUND; break; } if ((have_error != ET_NONE) && (error_action != DOE_NOTHING)) { switch (error_action) { case DOE_WARNING : fprintf(stderr, "%s: Warning: ", handle->argv0); break; case DOE_ERROR : fprintf(stderr, "%s: Error: ", handle->argv0); break; default : break; } switch (have_error) { case ET_EXPECTED_PARAM_TP_NOT_FOUND : fprintf(stderr, "expected parameter not found for option %s\n", argv[0]); break; case ET_PARAM_MALFORMED : fprintf(stderr, "parameter malformed for option %s\n", argv[0]); break; case ET_EXPECTED_OPTION_TP_NOT_FOUND : fprintf(stderr, "not an option %s\n", argv[0]); break; case ET_UNKNOWN_OPTION : fprintf(stderr, "unknown option %s\n", argv[0]); break; default : break; } if (error_action == DOE_ERROR) exit(1); } if (have_param) { argv++; argc--; } argv++; argc--; } return 0; }
int reg(char *key, char *displayName, char *version, char *path, char *instpath, char *datapath) { HKEY regKey = NULL; char *subkey = catstr(KEY_PREFIX, key); LONG result; DWORD disposition; /* * Create or open the appropriate key in the registry */ result = RegCreateKeyEx( HKEY_LOCAL_MACHINE, // handle of an open key subkey, // address of subkey name 0, // reserved "", // address of class string REG_OPTION_NON_VOLATILE, // special options flag KEY_ALL_ACCESS, // desired security access NULL, // address of key security structure ®Key, // address of buffer for opened handle &disposition // address of disposition value buffer ); if (result != ERROR_SUCCESS) return 1; /* * Store the name and path under the registry key */ result = RegSetValueEx( regKey, // handle of key to set value for DISPLAY, // address of name of value to set 0, // reserved REG_SZ, // flag for value type displayName, // address of value data strlen(displayName)+1 // size of value data ); result = RegSetValueEx( regKey, // handle of key to set value for VERSION, // address of name of value to set 0, // reserved REG_SZ, // flag for value type version, // address of value data strlen(displayName)+1 // size of value data ); path = frobPath(path); result = RegSetValueEx( regKey, // handle of key to set value for PATH, // address of name of value to set 0, // reserved REG_SZ, // flag for value type path, // address of value data strlen(path)+1 // size of value data ); result = RegSetValueEx( regKey, // handle of key to set value for INST_PATH, // address of name of value to set 0, // reserved REG_SZ, // flag for value type instpath, // address of value data strlen(path)+1 // size of value data ); result = RegSetValueEx( regKey, // handle of key to set value for DATA_PATH, // address of name of value to set 0, // reserved REG_SZ, // flag for value type datapath, // address of value data strlen(path)+1 // size of value data ); /* * Close the registry key */ RegCloseKey(regKey); /* * Delete the old uninstallation data created by InstallShield */ subkey = catstr(KEY_PREFIX, OLD_KEY); result = RegDeleteKey( HKEY_LOCAL_MACHINE, // handle of open key subkey); // address of name of subkey return 0; }
/* ---- program entry --------------------------- */ int main( int argc, cstr argv[] ) { double start = now(); // options: uint verbose = 1; // 0=off, 1=default, 2=verbose uint outputstyle = 'b'; // 0=none, 'b'=binary, 'x'=intel hex, 's'=motorola s-records uint liststyle = 1; // 0=none, 1=plain, 2=with objcode, 4=with label listing, 6=both, 8=clock cycles bool clean = no; bool ixcbr2 = no; bool ixcbxh = no; bool targetZ80 = no; bool target8080 = no; bool targetZ180 = no; bool asm8080 = no; bool dotnames = no; bool reqcolon = no; bool casefold = no; bool flatops = no; bool compare = no; bool selftest = no; bool cgi_mode = no; uint maxerrors = 30; // filepaths: cstr inputfile = NULL; cstr outputfile = NULL; // or dir cstr listfile = NULL; // or dir cstr tempdir = NULL; cstr c_compiler = NULL; cstr c_includes = NULL; cstr libraries = NULL; // eval arguments: for(int i=1; i<argc; ) { cptr s = argv[i++]; if(s[0] != '-') { if(!inputfile) { inputfile = s; continue; } // if outfile is not prefixed with -o then it must be the last argument: if(!outputfile && i==argc) { outputfile = s; continue; } if(!listfile) { listfile = s; continue; } goto h; } if(s[1]=='-') { if(eq(s,"--clean")) { clean = yes; continue; } if(eq(s,"--bin")) { outputstyle='b'; continue; } if(eq(s,"--hex")) { outputstyle='x'; continue; } if(eq(s,"--s19")) { outputstyle='s'; continue; } if(eq(s,"--opcodes")) { liststyle |= 2; continue; } if(eq(s,"--labels")) { liststyle |= 4; continue; } if(eq(s,"--cycles")) { liststyle |= 8; continue; } if(eq(s,"--ixcbr2")) { ixcbr2 = 1; continue; } if(eq(s,"--ixcbxh")) { ixcbxh = 1; continue; } if(eq(s,"--z80")) { targetZ80 = 1; continue; } if(eq(s,"--8080")) { target8080 = 1; continue; } if(eq(s,"--asm8080")) { asm8080 = 1; continue; } if(eq(s,"--z180")) { targetZ180 = 1; continue; } if(eq(s,"--dotnames")) { dotnames = 1; continue; } if(eq(s,"--reqcolon")) { reqcolon = 1; continue; } if(eq(s,"--casefold")) { casefold = 1; continue; } if(eq(s,"--flatops")) { flatops = 1; continue; } if(eq(s,"--compare")) { compare = 1; continue; } if(eq(s,"--test")) { selftest = 1; continue; } if(eq(s,"--cgi")) { cgi_mode = 1; continue; } if(startswith(s,"--maxerrors=")) { char* ep; ulong n = strtoul(s+12,&ep,10); if(*ep||n==0||n>999) goto h; maxerrors = (uint)n; continue; } goto h; } while(char c = *++s) { switch(c) { case 'e': compare = 1; continue; case 'T': selftest = 1; continue; case 'u': liststyle |= 2; continue; case 'w': liststyle |= 4; continue; case 'y': liststyle |= 8; continue; case 's': outputstyle=c; continue; case 'x': outputstyle=c; continue; case 'b': outputstyle=c; continue; case 'z': clean=yes; continue; case 'g': cgi_mode=yes; continue; case 'v': if(*(s+1)>='0' && *(s+1)<='3') verbose = *++s - '0'; else ++verbose; continue; case 'i': if(inputfile || i==argc) goto h; else inputfile = argv[i++]; continue; case 'o': if(*(s+1)=='0') { outputstyle = 0; ++s; continue; } if(outputfile || i==argc) goto h; else outputfile = argv[i++]; continue; case 'l': if(*(s+1)=='0') { liststyle = 0; ++s; continue; } if(listfile || i==argc) goto h; else listfile = argv[i++]; continue; case 'I': if(c_includes || i==argc) goto h; else c_includes = argv[i++]; continue; case 'L': if(libraries|| i==argc) goto h; else libraries= argv[i++]; continue; case 'c': if(c_compiler || i==argc) goto h; else c_compiler = argv[i++]; continue; case 't': if(tempdir || i==argc) goto h; else tempdir = argv[i++]; continue; default: goto h; } } } if(selftest) { // assemble a bunch of sources from the $PROJECT/Test/ directory // and compare them to old versions found in the original/ subdirectories. // if no path to the $PROJECT directory is given, then the current working directory is used. // all expected sources and original output files must be in place and match. cstr zasm = argv[0]; cstr testdir = fullpath( inputfile ? inputfile : outputfile ? outputfile : "./" ); if(errno==ok && lastchar(testdir)!='/') errno = ENOTDIR; if(errno) { if(verbose) fprintf(stderr, "--> %s: %s\nzasm: 1 error\n", testdir, strerror(errno)); return 1; } // if compiler was given, then it will be checked by the recursively called main() // else: no c compiler given: try to use scdd from $PROJECT/sdcc/bin/ if(!c_compiler) { #ifdef _BSD c_compiler = catstr(testdir,"sdcc/bin/sdcc"); #endif #ifdef _LINUX c_compiler = catstr(testdir,"sdcc/bin-Linux32/sdcc"); #endif if(!is_file(c_compiler) || !is_executable(c_compiler)) c_compiler = NULL; // passing "-c" + NULL should not crash main() } uint errors = 0; char opt[] = "-v0e"; opt[2] += verbose; change_working_dir(catstr(testdir,"Test/ZXSP/")); { cstr a[] = { zasm, opt, "template_o.asm", "original/" }; errors += main(NELEM(a),a); a[2] = "template_p.asm"; errors += main(NELEM(a),a); a[2] = "template_ace.asm"; errors += main(NELEM(a),a); a[2] = "template_tap.asm"; errors += main(NELEM(a),a); a[2] = "template_z80.asm"; errors += main(NELEM(a),a); a[2] = "template_sna.asm"; errors += main(NELEM(a),a); a[2] = "mouse.asm"; errors += main(NELEM(a),a); cstr b[] = { zasm, opt, "-c", c_compiler, "template_rom_with_c_code.asm", "original/" }; errors += main(NELEM(b),b); } change_working_dir(catstr(testdir,"Test/Z80/")); { cstr a[] = { zasm, opt, "ZX Spectrum Rom/zx82.asm", "original/" }; errors += main(NELEM(a),a); cstr c[] = { zasm, opt, "--casefold", "CAMEL80-12/camel80.asm", "original/" }; errors += main(NELEM(c),c); cstr d[] = { zasm, opt, "monitor_32k.asm", "original/" }; errors += main(NELEM(d),d); cstr e[] = { zasm, opt, "allsrc.asm", "original/" }; errors += main(NELEM(e),e); cstr f[] = { zasm, opt, "basic.asm", "original/" }; errors += main(NELEM(f),f); cstr g[] = { zasm, opt, "MS-Basic.asm", "original/" }; errors += main(NELEM(g),g); cstr h[] = { zasm, opt, "--reqcolon", "5bsort018.asm", "original/" }; errors += main(NELEM(h),h); cstr i[] = { zasm, opt, "64#4+016.asm", "original/" }; errors += main(NELEM(i),i); cstr j[] = { zasm, opt, "--8080", "CPM22.asm", "original/" }; errors += main(NELEM(j),j); cstr k[] = { zasm, opt, "EMUF/EMUF.asm", "original/" }; errors += main(NELEM(k),k); cstr l[] = { zasm, opt, "G007_MON_source_recreation.asm", "original/" }; errors += main(NELEM(l),l); cstr n[] = { zasm, opt, "--reqcolon", "Hello World.asm", "original/" }; errors += main(NELEM(n),n); cstr o[] = { zasm, opt, "--8080", "m80b.asm", "original/" }; errors += main(NELEM(o),o); cstr p[] = { zasm, opt, "monitor_32k.asm", "original/" }; errors += main(NELEM(p),p); cstr q[] = { zasm, opt, "MS-Basic.asm", "original/" }; errors += main(NELEM(q),q); cstr r[] = { zasm, opt, "mybios4_mod.asm", "original/" }; errors += main(NELEM(r),r); cstr s[] = { zasm, opt, "--dotnames", "--reqcolon", "OpenSE Basic/opense.asm", "original/" }; errors += main(NELEM(s),s); cstr b[] = { zasm, opt, "ZX Spectrum Rom/sc178.asm", "original/" }; errors += main(NELEM(b),b); cstr m[] = { zasm, opt, "test z80 cpu - prelim.asm", "original/" }; errors += main(NELEM(m),m); cstr t[] = { zasm, opt, "--reqcolon", "VZ200 RS232 Terminal/VZ RS232.asm", "original/" }; errors += main(NELEM(t),t); cstr u[] = { zasm, opt, "wmfw/wmfw2_5_orig.asm", "original/" }; errors += main(NELEM(u),u); cstr v[] = { zasm, opt, "z80mon.asm", "original/" }; errors += main(NELEM(v),v); cstr w[] = { zasm, opt, "z80sourc.asm", "original/" }; errors += main(NELEM(w),w); cstr x[] = { zasm, opt, "--reqcolon", "zx81v2.asm", "original/" }; errors += main(NELEM(x),x); cstr y[] = { zasm, opt, "--ixcbr2", "zasm-test-opcodes.asm", "original/" }; errors += main(NELEM(y),y); } change_working_dir(catstr(testdir,"Test/8080/")); { cstr a[] = { zasm, opt, "--asm8080", "--reqcolon", "Altair8800_Monitor.asm", "original/" }; errors += main(NELEM(a),a); cstr b[] = { zasm, opt, "8080PRE.asm", "original/" }; errors += main(NELEM(b),b); cstr y[] = { zasm, opt, "zasm-test-opcodes.asm", "original/" }; errors += main(NELEM(y),y); } change_working_dir(catstr(testdir,"Test/Z180/")); { cstr a[] = { zasm, opt, "--z180", "first.asm", "original/" }; errors += main(NELEM(a),a); cstr b[] = { zasm, opt, "--z180", "counter master.asm", "original/" }; errors += main(NELEM(b),b); cstr y[] = { zasm, opt, "zasm-test-opcodes.asm", "original/" }; errors += main(NELEM(y),y); } if(verbose) { fprintf(stderr, "\ntotal time: %3.4f sec.\n", now()-start); if(errors>1) fprintf(stderr, "\nzasm: %u errors\n\n", errors); else fprintf(stderr, errors ? "\nzasm: 1 error\n\n" : "zasm: no errors\n"); } return errors>0; } // check options: if(targetZ180) targetZ80 = yes; // implied if(asm8080 && !targetZ80) target8080 = yes; // only implied if not --Z80 set if(!target8080) targetZ80 = yes; // default to Z80 if not --8080 or --asm8080 set if(asm8080 && targetZ180) { fprintf(stderr,"--> %s\nzasm: 1 error\n", "the 8080 assembler does not support Z180 opcodes."); return 1; } if(target8080 && targetZ80) { fprintf(stderr,"--> %s\nzasm: 1 error\n", "--8080 and --z80|--z180 are mutually exclusive."); return 1; } if(ixcbr2 || ixcbxh) { if(target8080) { fprintf(stderr,"--> %s\nzasm: 1 error\n", "i8080 has no index registers and no prefix 0xCB instructions."); return 1; } if(targetZ180) { fprintf(stderr,"--> %s\nzasm: 1 error\n", "no --ixcb… allowed: the Z180 traps illegal instructions"); return 1; } if(asm8080) { fprintf(stderr,"--> %s\nzasm: 1 error\n", "the 8080 assembler does not support illegal opcodes."); return 1; } if(ixcbr2 && ixcbxh) { fprintf(stderr,"--> %s\nzasm: 1 error\n", "--ixcbr2 and --ixcbxh are mutually exclusive."); return 1; } } // check source file: if(!inputfile) { h: fprintf(stderr, help, version, compiledatestr(), _PLATFORM); return 1; } inputfile = fullpath(inputfile,no); if(errno) { if(verbose) fprintf(stderr, "--> %s: %s\nzasm: 1 error\n", inputfile, strerror(errno)); return 1; } if(!is_file(inputfile)) { if(verbose) fprintf(stderr, "--> %s: not a regular file\nzasm: 1 error\n", inputfile); return 1; } // check output file or dir: if(!outputfile) outputfile = directory_from_path(inputfile); outputfile = fullpath(outputfile); if(errno && errno!=ENOENT) { if(verbose) fprintf(stderr, "--> %s: %s\nzasm: 1 error\n", outputfile, strerror(errno)); return 1; } // check list file or dir: if(!listfile) listfile = directory_from_path(outputfile); listfile = fullpath(listfile); if(errno && errno!=ENOENT) { if(verbose) fprintf(stderr, "--> %s: %s\nzasm: 1 error\n", listfile, strerror(errno)); return 1; } // check temp dir: if(!tempdir) tempdir = directory_from_path(outputfile); tempdir = fullpath(tempdir); if(errno && errno!=ENOENT) { if(verbose) fprintf(stderr, "--> %s: %s\nzasm: 1 error\n", tempdir, strerror(errno)); return 1; } if(lastchar(tempdir)!='/') { if(verbose) fprintf(stderr, "--> %s: %s\nzasm: 1 error\n", tempdir, strerror(ENOTDIR)); return 1; } // check c_includes path: if(c_includes) { c_includes = fullpath(c_includes); if(errno==ok && lastchar(c_includes)!='/') errno = ENOTDIR; if(errno) { if(verbose) fprintf(stderr, "--> %s: %s\nzasm: 1 error\n", c_includes, strerror(errno)); return 1; } } // check c_libraries path: if(libraries) { libraries = fullpath(libraries); if(errno==ok && lastchar(libraries)!='/') errno = ENOTDIR; if(errno) { if(verbose) fprintf(stderr, "--> %s: %s\nzasm: 1 error\n", libraries, strerror(errno)); return 1; } } // check cc_path: if(c_compiler) { if(c_compiler[0]!='/') { cstr s = quick_fullpath(c_compiler); if(is_file(s)) c_compiler = s; else { Array<str> ss; split(ss, getenv("PATH"), ':'); for(uint i=0; i<ss.count(); i++) { s = catstr(ss[i],"/",c_compiler); if(is_file(s)) { c_compiler = s; break; } } } } c_compiler = fullpath(c_compiler); if(errno) { if(verbose) fprintf(stderr, "--> %s: %s\nzasm: 1 error\n", c_compiler, strerror(errno)); return 1; } if(!is_file(c_compiler)) { if(verbose) fprintf(stderr, "--> %s: not a regular file\nzasm: 1 error\n", c_compiler); return 1; } if(!is_executable(c_compiler)) { if(verbose) fprintf(stderr, "--> %s: not executable\nzasm: 1 error\n", c_compiler); return 1; } } // DO IT! Z80Assembler ass; ass.verbose = verbose; ass.ixcbr2_enabled = ixcbr2; ass.ixcbxh_enabled = ixcbxh; ass.target_8080 = target8080; ass.target_z80 = targetZ80; ass.target_z180 = targetZ180; ass.asm8080 = asm8080; ass.require_colon = reqcolon; ass.allow_dotnames = dotnames; ass.casefold= casefold; ass.flat_operators = flatops; ass.max_errors = maxerrors; ass.compare_to_old = compare; ass.cgi_mode = cgi_mode; if(c_includes) ass.c_includes = c_includes; if(libraries) ass.stdlib_dir = libraries; if(c_compiler) ass.c_compiler = c_compiler; ass.assembleFile( inputfile, outputfile, listfile, tempdir, liststyle, outputstyle, clean ); uint errors = ass.errors.count(); if(verbose) // show errors on stderr: { cstr current_file = NULL; for(uint i=0; i<errors; i++) { Error const& e = ass.errors[i]; SourceLine* sourceline = e.sourceline; if(!sourceline) { if(current_file) fprintf(stderr,"\n"); current_file=NULL; fprintf(stderr,"--> %s\n",e.text); continue; } cstr filename = sourceline->sourcefile; if(filename!=current_file) // note: compare pointers! { current_file = filename; fprintf(stderr, "\nin file %s:\n", filename_from_path(filename)); } cstr linenumber = numstr(sourceline->sourcelinenumber+1); fprintf(stderr, "%s: %s\n", linenumber, sourceline->text); fprintf(stderr, "%s%s^ %s\n", spacestr(strlen(linenumber)+2), sourceline->whitestr(), e.text); } fprintf(stderr, "assemble: %u lines\n", ass.source.count()); fprintf(stderr, "time: %3.4f sec.\n", now()-start); if(errors>1) fprintf(stderr, "\nzasm: %u errors\n\n", errors); else fprintf(stderr, errors ? "\nzasm: 1 error\n\n" : "zasm: no errors\n"); } return errors>0; // 0=ok, 1=errors }