Ejemplo n.º 1
0
PRIVATE int cmd_load(struct comal_line *line)
{
	char *fn;

	if (!line->lc.str && !curenv->name)
		run_error(CMD_ERR, "Missing program name (to LOAD)");
	else if (check_changed()) {
		if (line->lc.str)
			fn = line->lc.str->s;
		else {
			fn = curenv->name;
			my_printf(MSG_DIALOG, 1, fn);
		}

		fn = my_strdup(MISC_POOL, fn);
		prog_load(fn);
		curenv->name = fn;
		prog_structure_scan();
		mem_freepool(PARSE_POOL);

		longjmp(RESTART, JUST_RESTART);
	}

	return 0;
}
Ejemplo n.º 2
0
void prog_load(Prog* prog, const char* cmdpipe, const char* filename)
{
   int   bufsize = BUF_EXT;
   char* buf     = malloc((size_t)bufsize);
   MFP*  fp;
   char* s;
   int   lineno  = 1;
   char  newname [1024];
   char* temp;
   char* myfilename;
   
   assert(prog     != NULL);
   assert(filename != NULL);
   assert(buf      != NULL);
   assert(filename != NULL);

   if (cmdpipe == NULL)
      myfilename = strdup(filename);
   else
   {
      myfilename = malloc(strlen(filename) + strlen(cmdpipe) + 1024);
      
      sprintf(&myfilename[1], cmdpipe, filename);
      myfilename[0] = '#';
   }
   if (NULL == (fp = mio_open(myfilename, ".zpl")))
      zpl_exit(EXIT_FAILURE);

   if (verbose)
      printf("Reading %s\n", myfilename);
   
   while((s = get_line(&buf, &bufsize, fp, &lineno)) != NULL)
   {
      assert(!isspace(*s));

      /* This could happen if we have a ;; somewhere.
       */
      if (*s == '\0')
         continue;

      if (1 == sscanf(s, "include \"%1023[^\"]\"", newname))
      {
         temp = malloc(strlen(filename) + strlen(newname) + 2);
         prog_load(prog, cmdpipe, make_pathname(temp, filename, newname));
         free(temp);
      }
      else
      { 
         add_stmt(prog, filename, lineno, s);
      }
   }
   mio_close(fp);
   free(myfilename);
   free(buf);
}
Ejemplo n.º 3
0
int create_filtered_socket_fd(struct bpf_insn *insns, size_t insns_count) {
  int progfd = prog_load(insns, insns_count);

  // hook eBPF program up to a socket
  // sendmsg() to the socket will trigger the filter
  // returning 0 in the filter should toss the packet
  int socks[2];
  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socks))
    err(1, "socketpair");
  if (setsockopt(socks[0], SOL_SOCKET, SO_ATTACH_BPF, &progfd, sizeof(int)))
    err(1, "setsockopt");
  return socks[1];
}
Ejemplo n.º 4
0
static int attach_filter(int cg_fd, int type, int verdict)
{
	int prog_fd, map_fd, ret, key;
	long long pkt_cnt, byte_cnt;

	map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY,
				sizeof(key), sizeof(byte_cnt),
				256, 0);
	if (map_fd < 0) {
		printf("Failed to create map: '%s'\n", strerror(errno));
		return EXIT_FAILURE;
	}

	prog_fd = prog_load(map_fd, verdict);
	printf("Output from kernel verifier:\n%s\n-------\n", bpf_log_buf);

	if (prog_fd < 0) {
		printf("Failed to load prog: '%s'\n", strerror(errno));
		return EXIT_FAILURE;
	}

	ret = bpf_prog_attach(prog_fd, cg_fd, type);
	if (ret < 0) {
		printf("Failed to attach prog to cgroup: '%s'\n",
		       strerror(errno));
		return EXIT_FAILURE;
	}
	while (1) {
		key = MAP_KEY_PACKETS;
		assert(bpf_lookup_elem(map_fd, &key, &pkt_cnt) == 0);

		key = MAP_KEY_BYTES;
		assert(bpf_lookup_elem(map_fd, &key, &byte_cnt) == 0);

		printf("cgroup received %lld packets, %lld bytes\n",
		       pkt_cnt, byte_cnt);
		sleep(1);
	}

	return EXIT_SUCCESS;
}
Ejemplo n.º 5
0
static int test_foo_bar(void)
{
	int drop_prog, allow_prog, foo = 0, bar = 0, rc = 0;

	allow_prog = prog_load(1);
	if (!allow_prog)
		goto err;

	drop_prog = prog_load(0);
	if (!drop_prog)
		goto err;

	if (setup_cgroup_environment())
		goto err;

	/* Create cgroup /foo, get fd, and join it */
	foo = create_and_get_cgroup(FOO);
	if (foo < 0)
		goto err;

	if (join_cgroup(FOO))
		goto err;

	if (bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS,
			    BPF_F_ALLOW_OVERRIDE)) {
		log_err("Attaching prog to /foo");
		goto err;
	}

	printf("Attached DROP prog. This ping in cgroup /foo should fail...\n");
	assert(system(PING_CMD) != 0);

	/* Create cgroup /foo/bar, get fd, and join it */
	bar = create_and_get_cgroup(BAR);
	if (bar < 0)
		goto err;

	if (join_cgroup(BAR))
		goto err;

	printf("Attached DROP prog. This ping in cgroup /foo/bar should fail...\n");
	assert(system(PING_CMD) != 0);

	if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS,
			    BPF_F_ALLOW_OVERRIDE)) {
		log_err("Attaching prog to /foo/bar");
		goto err;
	}

	printf("Attached PASS prog. This ping in cgroup /foo/bar should pass...\n");
	assert(system(PING_CMD) == 0);

	if (bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS)) {
		log_err("Detaching program from /foo/bar");
		goto err;
	}

	printf("Detached PASS from /foo/bar while DROP is attached to /foo.\n"
	       "This ping in cgroup /foo/bar should fail...\n");
	assert(system(PING_CMD) != 0);

	if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS,
			    BPF_F_ALLOW_OVERRIDE)) {
		log_err("Attaching prog to /foo/bar");
		goto err;
	}

	if (bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS)) {
		log_err("Detaching program from /foo");
		goto err;
	}

	printf("Attached PASS from /foo/bar and detached DROP from /foo.\n"
	       "This ping in cgroup /foo/bar should pass...\n");
	assert(system(PING_CMD) == 0);

	if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS,
			    BPF_F_ALLOW_OVERRIDE)) {
		log_err("Attaching prog to /foo/bar");
		goto err;
	}

	if (!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, 0)) {
		errno = 0;
		log_err("Unexpected success attaching prog to /foo/bar");
		goto err;
	}

	if (bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS)) {
		log_err("Detaching program from /foo/bar");
		goto err;
	}

	if (!bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS)) {
		errno = 0;
		log_err("Unexpected success in double detach from /foo");
		goto err;
	}

	if (bpf_prog_attach(allow_prog, foo, BPF_CGROUP_INET_EGRESS, 0)) {
		log_err("Attaching non-overridable prog to /foo");
		goto err;
	}

	if (!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, 0)) {
		errno = 0;
		log_err("Unexpected success attaching non-overridable prog to /foo/bar");
		goto err;
	}

	if (!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS,
			     BPF_F_ALLOW_OVERRIDE)) {
		errno = 0;
		log_err("Unexpected success attaching overridable prog to /foo/bar");
		goto err;
	}

	if (!bpf_prog_attach(allow_prog, foo, BPF_CGROUP_INET_EGRESS,
			     BPF_F_ALLOW_OVERRIDE)) {
		errno = 0;
		log_err("Unexpected success attaching overridable prog to /foo");
		goto err;
	}

	if (bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS, 0)) {
		log_err("Attaching different non-overridable prog to /foo");
		goto err;
	}

	goto out;

err:
	rc = 1;

out:
	close(foo);
	close(bar);
	cleanup_cgroup_environment();
	if (!rc)
		printf("### override:PASS\n");
	else
		printf("### override:FAIL\n");
	return rc;
}
Ejemplo n.º 6
0
Bool zpl_read_with_args(char** argv, int argc, Bool with_management, void* user_data)
{
   const char* options = "D:mP:sv:";

   unsigned long seed = 13021967UL;
   char**        param_table;
   int           param_count = 0;
   int           c;
   int           i;
   Prog*         prog = NULL;
   Set*          set;
   void*         lp  = NULL;
   Bool          ret = FALSE;
   char*         inppipe = NULL;
   Bool          use_startval = FALSE;
   
   stkchk_init();

   yydebug       = 0;
   yy_flex_debug = 0;
   param_table   = malloc(sizeof(*param_table));

   zpl_print_banner(stdout, FALSE);

   /* getopt might be called more than once
    */
   optind = 1;
   
   while((c = getopt(argc, argv, options)) != -1)
   {
      switch(c)
      {
      case 'D' :
         param_table =
            realloc(param_table, ((unsigned int)param_count + 1) * sizeof(*param_table));
         param_table[param_count] = strdup(optarg);

         if (verbose >= VERB_DEBUG)
            printf("Parameter %d [%s]\n", param_count, param_table[param_count]);

         param_count++;
         break;
      case 'm' :
         use_startval = TRUE;
         break;
      case 'P' :
         inppipe = strdup(optarg);
         break;
      case 's' :
         seed = (unsigned long)atol(optarg);
         break;
      case 'v' :
         verbose = atoi(optarg);
         break;
      case '?':
         fprintf(stderr, "Unknown option '%c'\n", c);
         return FALSE;
      default :
         abort();
      }
   }
   if ((argc - optind) < 1)
   {
      fprintf(stderr, "Filename missing\n");
      free(param_table);

      return FALSE;
   }

   blk_init();
   str_init();
   rand_init(seed);
   numb_init(with_management);
   elem_init();
   set_init();
   mio_init();
   interns_init();
   local_init();
   
   if (0 == setjmp( zpl_read_env))
   {
      is_longjmp_ok = TRUE;
      
      /* Make symbol to hold entries of internal variables
       */
      set = set_pseudo_new();
      (void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL);
      set_free(set);
   
      /* Now store the param defines
       */
      for(i = 0; i < param_count; i++)
         zpl_add_parameter(param_table[i]);

      prog = prog_new();

      for(i = optind; i < argc; i++)
         prog_load(prog, inppipe, argv[i]);

      if (prog_is_empty(prog))
         fprintf(stderr, "*** Error 168: No program statements to execute\n");
      else
      {
         if (verbose >= VERB_DEBUG)
            prog_print(stderr, prog);
   
         lp = xlp_alloc(argv[optind], use_startval, user_data);

         prog_execute(prog, lp);

         ret = TRUE;
      }
   }
   is_longjmp_ok = FALSE;

   if (lp != NULL)
      xlp_free(lp);

   /* Now clean up. 
    */
   if (inppipe != NULL)
      free(inppipe);
   
   for(i = 0; i < param_count; i++)
      free(param_table[i]);
   free(param_table);

   if (prog != NULL)
      prog_free(prog);

   local_exit();
   interns_exit();
   mio_exit();
   symbol_exit();
   define_exit();
   set_exit();
   elem_exit();
   numb_exit();
   str_exit();
   blk_exit();

   return ret;
}
Ejemplo n.º 7
0
Bool zpl_read(const char* filename, Bool with_management, void* user_data)
{
   Prog*       prog = NULL;
   Set*        set;
   void*       lp  = NULL;
   Bool        ret = FALSE;

   stkchk_init();
   
   yydebug       = 0;
   yy_flex_debug = 0;

   zpl_print_banner(stdout, FALSE);

   blk_init();
   str_init();
   rand_init(13021967UL);
   numb_init(with_management);
   elem_init();
   set_init();
   mio_init();
   interns_init();
   local_init();
   
   if (0 == setjmp(zpl_read_env))
   {
      is_longjmp_ok = TRUE;
      
      set = set_pseudo_new();
      (void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL);
      set_free(set);
   
      prog = prog_new();

      prog_load(prog, NULL, filename);

      if (prog_is_empty(prog))
         fprintf(stderr, "*** Error 168: No program statements to execute\n");
      else
      {
         if (verbose >= VERB_DEBUG)
            prog_print(stderr, prog);
   
         lp = xlp_alloc(filename, FALSE, user_data);

         prog_execute(prog, lp);

         ret = TRUE;
      }
   }
   is_longjmp_ok = FALSE;

   if (lp != NULL)
      xlp_free(lp);

   if (prog != NULL)
      prog_free(prog);

   local_exit();
   interns_exit();
   mio_exit();
   symbol_exit();
   define_exit();
   set_exit();
   elem_exit();
   numb_exit();
   str_exit();
   blk_exit();
   
   return ret;
}
Ejemplo n.º 8
0
int main(int argc, char **argv) {
    size_t      i;
    qcint_t       fnmain = -1;
    qc_program_t *prog;
    size_t      xflags = VMXF_DEFAULT;
    bool        opts_printfields = false;
    bool        opts_printdefs   = false;
    bool        opts_printfuns   = false;
    bool        opts_disasm      = false;
    bool        opts_info        = false;
    bool        noexec           = false;
    const char *progsfile        = nullptr;
    const char **dis_list        = nullptr;
    int         opts_v           = 0;

    arg0 = argv[0];

    if (argc < 2) {
        usage();
        exit(EXIT_FAILURE);
    }

    while (argc > 1) {
        if (!strcmp(argv[1], "-h") ||
            !strcmp(argv[1], "-help") ||
            !strcmp(argv[1], "--help"))
        {
            usage();
            exit(EXIT_SUCCESS);
        }
        else if (!strcmp(argv[1], "-v")) {
            ++opts_v;
            --argc;
            ++argv;
        }
        else if (!strncmp(argv[1], "-vv", 3)) {
            const char *av = argv[1]+1;
            for (; *av; ++av) {
                if (*av == 'v')
                    ++opts_v;
                else {
                    usage();
                    exit(EXIT_FAILURE);
                }
            }
            --argc;
            ++argv;
        }
        else if (!strcmp(argv[1], "-version") ||
                 !strcmp(argv[1], "--version"))
        {
            version();
            exit(EXIT_SUCCESS);
        }
        else if (!strcmp(argv[1], "-trace")) {
            --argc;
            ++argv;
            xflags |= VMXF_TRACE;
        }
        else if (!strcmp(argv[1], "-profile")) {
            --argc;
            ++argv;
            xflags |= VMXF_PROFILE;
        }
        else if (!strcmp(argv[1], "-info")) {
            --argc;
            ++argv;
            opts_info = true;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-disasm")) {
            --argc;
            ++argv;
            opts_disasm = true;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-disasm-func")) {
            --argc;
            ++argv;
            if (argc <= 1) {
                usage();
                exit(EXIT_FAILURE);
            }
            vec_push(dis_list, argv[1]);
            --argc;
            ++argv;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-printdefs")) {
            --argc;
            ++argv;
            opts_printdefs = true;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-printfuns")) {
            --argc;
            ++argv;
            opts_printfuns = true;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-printfields")) {
            --argc;
            ++argv;
            opts_printfields = true;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-vector") ||
                 !strcmp(argv[1], "-string") ||
                 !strcmp(argv[1], "-float") )
        {
            qcvm_parameter p;
            if (argv[1][1] == 'f')
                p.vtype = TYPE_FLOAT;
            else if (argv[1][1] == 's')
                p.vtype = TYPE_STRING;
            else if (argv[1][1] == 'v')
                p.vtype = TYPE_VECTOR;
            else
                p.vtype = TYPE_VOID;

            --argc;
            ++argv;
            if (argc < 2) {
                usage();
                exit(EXIT_FAILURE);
            }
            p.value = argv[1];

            vec_push(main_params, p);
            --argc;
            ++argv;
        }
        else if (!strcmp(argv[1], "--")) {
            --argc;
            ++argv;
            break;
        }
        else if (argv[1][0] != '-') {
            if (progsfile) {
                fprintf(stderr, "only 1 program file may be specified\n");
                usage();
                exit(EXIT_FAILURE);
            }
            progsfile = argv[1];
            --argc;
            ++argv;
        }
        else
        {
            fprintf(stderr, "unknown parameter: %s\n", argv[1]);
            usage();
            exit(EXIT_FAILURE);
        }
    }

    if (argc == 2 && !progsfile) {
        progsfile = argv[1];
        --argc;
        ++argv;
    }

    if (!progsfile) {
        fprintf(stderr, "must specify a program to execute\n");
        usage();
        exit(EXIT_FAILURE);
    }

    prog = prog_load(progsfile, noexec);
    if (!prog) {
        fprintf(stderr, "failed to load program '%s'\n", progsfile);
        exit(EXIT_FAILURE);
    }

    prog->builtins       = qc_builtins;
    prog->builtins_count = GMQCC_ARRAY_COUNT(qc_builtins);

    if (opts_info) {
        printf("Program's system-checksum = 0x%04x\n", (unsigned int)prog->crc16);
        printf("Entity field space: %u\n", (unsigned int)prog->entityfields);
        printf("Globals: %zu\n", prog->globals.size());
        printf("Counts:\n"
               "      code: %zu\n"
               "      defs: %zu\n"
               "    fields: %zu\n"
               " functions: %zu\n"
               "   strings: %zu\n",
               prog->code.size(),
               prog->defs.size(),
               prog->fields.size(),
               prog->functions.size(),
               prog->strings.size());
    }

    if (opts_info) {
        prog_delete(prog);
        return 0;
    }
    for (i = 0; i < vec_size(dis_list); ++i) {
        size_t k;
        printf("Looking for `%s`\n", dis_list[i]);
        for (k = 1; k < prog->functions.size(); ++k) {
            const char *name = prog_getstring(prog, prog->functions[k].name);
            if (!strcmp(name, dis_list[i])) {
                prog_disasm_function(prog, k);
                break;
            }
        }
    }
    if (opts_disasm) {
        for (i = 1; i < prog->functions.size(); ++i)
            prog_disasm_function(prog, i);
        return 0;
    }
    if (opts_printdefs) {
        const char *getstring = nullptr;
        for (auto &it : prog->defs) {
            printf("Global: %8s %-16s at %u%s",
                   type_name[it.type & DEF_TYPEMASK],
                   prog_getstring(prog, it.name),
                   (unsigned int)it.offset,
                   ((it.type & DEF_SAVEGLOBAL) ? " [SAVE]" : ""));
            if (opts_v) {
                switch (it.type & DEF_TYPEMASK) {
                    case TYPE_FLOAT:
                        printf(" [init: %g]", ((qcany_t*)(&prog->globals[0] + it.offset))->_float);
                        break;
                    case TYPE_INTEGER:
                        printf(" [init: %i]", (int)( ((qcany_t*)(&prog->globals[0] + it.offset))->_int ));
                        break;
                    case TYPE_ENTITY:
                    case TYPE_FUNCTION:
                    case TYPE_FIELD:
                    case TYPE_POINTER:
                        printf(" [init: %u]", (unsigned)( ((qcany_t*)(&prog->globals[0] + it.offset))->_int ));
                        break;
                    case TYPE_STRING:
                        getstring = prog_getstring(prog, ((qcany_t*)(&prog->globals[0] + it.offset))->string);
                        printf(" [init: `");
                        print_escaped_string(getstring, strlen(getstring));
                        printf("`]\n");
                        break;
                    default:
                        break;
                }
            }
            printf("\n");
        }
    }
    if (opts_printfields) {
        for (auto &it : prog->fields) {
            printf("Field: %8s %-16s at %d%s\n",
                   type_name[it.type],
                   prog_getstring(prog, it.name),
                   it.offset,
                   ((it.type & DEF_SAVEGLOBAL) ? " [SAVE]" : ""));
        }
    }
    if (opts_printfuns) {
        for (auto &it : prog->functions) {
            int32_t a;
            printf("Function: %-16s taking %u parameters:(",
                   prog_getstring(prog, it.name),
                   (unsigned int)it.nargs);
            for (a = 0; a < it.nargs; ++a) {
                printf(" %i", it.argsize[a]);
            }
            if (opts_v > 1) {
                int32_t start = it.entry;
                if (start < 0)
                    printf(") builtin %i\n", (int)-start);
                else {
                    size_t funsize = 0;
                    prog_section_statement_t *st = &prog->code[0] + start;
                    for (;st->opcode != INSTR_DONE; ++st)
                        ++funsize;
                    printf(") - %zu instructions", funsize);
                    if (opts_v > 2) {
                        printf(" - locals: %i + %i\n",
                               it.firstlocal,
                               it.locals);
                    }
                    else
                        printf("\n");
                }
            }
            else if (opts_v) {
                printf(") locals: %i + %i\n",
                       it.firstlocal,
                       it.locals);
            }
            else
                printf(")\n");
        }
    }
    if (!noexec) {
        for (i = 1; i < prog->functions.size(); ++i) {
            const char *name = prog_getstring(prog, prog->functions[i].name);
            if (!strcmp(name, "main"))
                fnmain = (qcint_t)i;
        }
        if (fnmain > 0)
        {
            prog_main_setparams(prog);
            prog_exec(prog, &prog->functions[fnmain], xflags, VM_JUMPS_DEFAULT);
        }
        else
            fprintf(stderr, "No main function found\n");
    }

    prog_delete(prog);
    return 0;
}
Ejemplo n.º 9
0
int main(int argc, char* const* argv)
{
   Prog*         prog;
   Set*          set;
   void*         lp;
   const char*   extension = "";
   char*         filter    = strdup("%s");
   char*         outfile;
   char*         tblfile;
   char*         ordfile;
   char*         mstfile;
   char*         basefile = NULL;
   char*         inppipe  = NULL;
   char*         outpipe;
   LpFormat      format   = LP_FORM_LPF;
   FILE*         fp;
   Bool          write_order = FALSE;
   Bool          write_mst   = FALSE;
   Bool          presolve    = FALSE;
   int           name_length = 0;
   char*         prog_text;
   unsigned long seed = 13021967UL;
   char**        param_table;
   int           param_count = 0;
   int           c;
   int           i;
   FILE*         (*openfile)(const char*, const char*) = fopen;
   int           (*closefile)(FILE*)                   = fclose;

   stkchk_init();
   
   yydebug       = 0;
   yy_flex_debug = 0;
   verbose       = VERB_NORMAL;
   param_table   = malloc(sizeof(*param_table));
   
   while((c = getopt(argc, argv, options)) != -1)
   {
      switch(c)
      {
      case 'b' :
         yydebug = 1;
         break;
      case 'D' :
         param_table =
            realloc(param_table, ((unsigned int)param_count + 1) * sizeof(*param_table));
         param_table[param_count] = strdup(optarg);
         param_count++;
         break;
      case 'h' :
         zpl_print_banner(stdout, TRUE);
         printf(usage, argv[0]);
         puts(help);
         exit(0);
      case 'f' :
         yy_flex_debug = 1;
         break;
      case 'F' :
         free(filter);
         
         filter    = strdup(optarg);
         openfile  = popen;
         closefile = pclose;
         break;
      case 'l' :
         name_length = atoi(optarg);
         break;
      case 'm' :
         write_mst = TRUE;
         break;
      case 'n' :
         if (*optarg != 'c')
         {
            fprintf(stderr, usage, argv[0]);
            exit(0);
         }
         switch(optarg[1])
         {
         case 'm' :
            conname_format(CON_FORM_MAKE);
            break;
         case 'n' :
            conname_format(CON_FORM_NAME);
            break;
         case 'f' :
            conname_format(CON_FORM_FULL);
            break;
         default :
            fprintf(stderr, usage, argv[0]);
            exit(0);
         }
         break;
      case 'o' :
         basefile = strdup(optarg);
         break;
      case 'O' :
         presolve = TRUE;
         break;
      case 'P' :
         inppipe = strdup(optarg);
         break;
      case 's' :
         seed = (unsigned long)atol(optarg);
         break;
      case 'r' :
         write_order = TRUE;
         break;
      case 't' :
         switch(tolower(*optarg))
         {
         case 'h' :
            format = LP_FORM_HUM;
            break;
         case 'm' :
            format = LP_FORM_MPS;
            break;
         case 'l' :
            format = LP_FORM_LPF;
            break;
         case 'p' :
            format = LP_FORM_PIP;
            break;
         case 'r' :
            format = LP_FORM_RLP;
            break;
         default :
            if (verbose > VERB_QUIET)
               fprintf(stderr,
                  "--- Warning 103: Output format \"%s\" not supported, using LP format\n",
                  optarg);
            format = LP_FORM_LPF;
            break;
         }
         break;
      case 'v' :
         verbose = atoi(optarg);
         break;
      case 'V' :
         printf("%s\n", VERSION);
         exit(0);
      case '?':
         fprintf(stderr, usage, argv[0]);
         exit(0);
      default :
         abort();
      }
   }
   if ((argc - optind) < 1)
   {
      fprintf(stderr, usage, argv[0]);      
      exit(0);
   }

   zpl_print_banner(stdout, TRUE);
   
   if (basefile == NULL)
      basefile = strip_extension(strdup(strip_path(argv[optind])));

   switch(format)
   {
   case LP_FORM_LPF :
      extension = ".lp";
      break;
   case LP_FORM_MPS :
      extension = ".mps";
      break;
   case LP_FORM_HUM :
      extension = ".hum";
      break;
   case LP_FORM_RLP :
      extension = ".rlp";
      break;
   case LP_FORM_PIP :
      extension = ".pip";
      break;
   default :
      abort();
   }
   assert(extension != NULL);

   outfile = add_extention(basefile, extension);
   tblfile = add_extention(basefile, ".tbl");
   ordfile = add_extention(basefile, ".ord");
   mstfile = add_extention(basefile, ".mst");
   
   outpipe = malloc(strlen(basefile) + strlen(filter) + 256);

   assert(outpipe != NULL);

   blk_init();
   str_init();
   rand_init(seed);
   numb_init(TRUE);
   elem_init();
   set_init();
   mio_init();
   interns_init();
   local_init();
   
   /* Make symbol to hold entries of internal variables
    */
   set = set_pseudo_new();
   (void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL);
   set_free(set);
   
   /* Now store the param defines
    */
   for(i = 0; i < param_count; i++)
      zpl_add_parameter(param_table[i]);

   /* Next we read in the zpl program(s)
    */
   prog = prog_new();

   for(i = optind; i < argc; i++)
      prog_load(prog, inppipe, argv[i]);

   if (prog_is_empty(prog))
   {
      fprintf(stderr, "*** Error 168: No program statements to execute\n");
      exit(EXIT_FAILURE);
   }
   if (verbose >= VERB_DEBUG)
      prog_print(stderr, prog);
   
   lp = xlp_alloc(argv[optind], write_mst || write_order, NULL);
   zlp_setnamelen(lp, name_length);
   
   prog_execute(prog, lp);

   /* Presolve
    */
   if (presolve)
      fprintf(stderr, "--- Warning: Presolve no longer support. If you need it, send me an email\n");
#if 0 
      if (!zlp_presolve())
         exit(EXIT_SUCCESS);
#endif
   if (verbose >= VERB_NORMAL)
      zlp_stat(lp);
   
   /* Write order file 
    */
   if (write_order)
   {
      sprintf(outpipe, filter, ordfile, "ord");

      if (verbose >= VERB_NORMAL)
         printf("Writing [%s]\n", outpipe);

      if (NULL == (fp = (*openfile)(outpipe, "w")))
      {
         fprintf(stderr, "*** Error 104: File open failed ");
         perror(ordfile);
         exit(EXIT_FAILURE);
      }
      zlp_orderfile(lp, fp, format);
         
      check_write_ok(fp, ordfile);
         
      (void)(*closefile)(fp);
   }
   /* Write MST file 
    */
   if (write_mst)
   {
      sprintf(outpipe, filter, mstfile, "mst");

      if (verbose >= VERB_NORMAL)
         printf("Writing [%s]\n", outpipe);

      if (NULL == (fp = (*openfile)(outpipe, "w")))
      {
         fprintf(stderr, "*** Error 104: File open failed ");
         perror(mstfile);
         exit(EXIT_FAILURE);
      }
      zlp_mstfile(lp, fp, format);
         
      check_write_ok(fp, mstfile);
         
      (void)(*closefile)(fp);
   }
   /* Write Output
    */
   sprintf(outpipe, filter, outfile, "lp");

   if (verbose >= VERB_NORMAL)
      printf("Writing [%s]\n", outpipe);

   if (NULL == (fp = (*openfile)(outpipe, "w")))
   {
      fprintf(stderr, "*** Error 104: File open failed ");
      perror(outfile);
      exit(EXIT_FAILURE);
   }
   if (format != LP_FORM_RLP)
      prog_text = prog_tostr(prog, format == LP_FORM_MPS ? "* " : "\\ ", title, 128);
   else
   {
      prog_text = malloc(strlen(title) + 4);
      
      assert(prog_text != NULL);

      sprintf(prog_text, "\\%s\n", title);
   }
   zlp_write(lp, fp, format, prog_text);

   check_write_ok(fp, outfile);

   (void)(*closefile)(fp);

   /* We do not need the translation table for human readable format
    * Has to be written after the LP file, so the scaling has been done.
    */
   if (format != LP_FORM_HUM)
   {
      /* Write translation table
       */
      sprintf(outpipe, filter, tblfile, "tbl");

      if (verbose >= VERB_NORMAL)
         printf("Writing [%s]\n", outpipe);

      if (NULL == (fp = (*openfile)(outpipe, "w")))
      {
         fprintf(stderr, "*** Error 104: File open failed");
         perror(tblfile);
         exit(EXIT_FAILURE);
      }
      zlp_transtable(lp, fp, format);

      check_write_ok(fp, tblfile);

      (void)(*closefile)(fp);
   }




   free(prog_text);
   
   if (verbose >= VERB_DEBUG) 
      symbol_print_all(stderr);

#if defined(__INSURE__) || !defined(NDEBUG) || defined(FREEMEM)
   
   /* Now clean up. 
    */
   if (inppipe != NULL)
      free(inppipe);
   
   for(i = 0; i < param_count; i++)
      free(param_table[i]);
   free(param_table);
   
   prog_free(prog);

   local_exit();
   interns_exit();
   xlp_free(lp);
   mio_exit();
   symbol_exit();
   define_exit();
   set_exit();
   elem_exit();
   numb_exit();
   str_exit();
   blk_exit();
   
   free(mstfile);
   free(ordfile);
   free(outfile);
   free(tblfile);
   free(basefile);
   free(filter);
   free(outpipe);

   if (verbose >= VERB_NORMAL)
   {
      mem_display(stdout);
      stkchk_maximum(stdout);
   }
#endif /* __INSURE__ || !NDEBUG || FREEMEM */
   return 0;
}
Ejemplo n.º 10
0
int main(int argc, char **argv)
{
    size_t      i;
    qcint       fnmain = -1;
    qc_program *prog;
    size_t      xflags = VMXF_DEFAULT;
    bool        opts_printfields = false;
    bool        opts_printdefs   = false;
    bool        opts_printfuns   = false;
    bool        opts_disasm      = false;
    bool        opts_info        = false;
    bool        noexec           = false;
    const char *progsfile        = NULL;

    arg0 = argv[0];

    if (argc < 2) {
        usage();
        exit(1);
    }

    while (argc > 1) {
        if (!strcmp(argv[1], "-h") ||
            !strcmp(argv[1], "-help") ||
            !strcmp(argv[1], "--help"))
        {
            usage();
            exit(0);
        }
        else if (!strcmp(argv[1], "-v") ||
                 !strcmp(argv[1], "-version") ||
                 !strcmp(argv[1], "--version"))
        {
            version();
            exit(0);
        }
        else if (!strcmp(argv[1], "-trace")) {
            --argc;
            ++argv;
            xflags |= VMXF_TRACE;
        }
        else if (!strcmp(argv[1], "-profile")) {
            --argc;
            ++argv;
            xflags |= VMXF_PROFILE;
        }
        else if (!strcmp(argv[1], "-info")) {
            --argc;
            ++argv;
            opts_info = true;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-disasm")) {
            --argc;
            ++argv;
            opts_disasm = true;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-printdefs")) {
            --argc;
            ++argv;
            opts_printdefs = true;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-printfuns")) {
            --argc;
            ++argv;
            opts_printfuns = true;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-printfields")) {
            --argc;
            ++argv;
            opts_printfields = true;
            noexec = true;
        }
        else if (!strcmp(argv[1], "-vector") ||
                 !strcmp(argv[1], "-string") ||
                 !strcmp(argv[1], "-float") )
        {
            qcvm_parameter p;
            if (argv[1][1] == 'f')
                p.vtype = TYPE_FLOAT;
            else if (argv[1][1] == 's')
                p.vtype = TYPE_STRING;
            else if (argv[1][1] == 'v')
                p.vtype = TYPE_VECTOR;

            --argc;
            ++argv;
            if (argc < 3) {
                usage();
                exit(1);
            }
            p.value = argv[1];

            vec_push(main_params, p);
            --argc;
            ++argv;
        }
        else if (!strcmp(argv[1], "--")) {
            --argc;
            ++argv;
            break;
        }
        else if (argv[1][0] != '-') {
            if (progsfile) {
                printf("only 1 program file may be specified\n");
                usage();
                exit(1);
            }
            progsfile = argv[1];
            --argc;
            ++argv;
        }
        else
        {
            usage();
            exit(1);
        }
    }

    if (argc > 2) {
        usage();
        exit(1);
    }
    if (argc > 1) {
        if (progsfile) {
            printf("only 1 program file may be specified\n");
            usage();
            exit(1);
        }
        progsfile = argv[1];
        --argc;
        ++argv;
    }

    if (!progsfile) {
        usage();
        exit(1);
    }

    prog = prog_load(progsfile);
    if (!prog) {
        printf("failed to load program '%s'\n", progsfile);
        exit(1);
    }

    prog->builtins       = qc_builtins;
    prog->builtins_count = qc_builtins_count;

    if (opts_info) {
        printf("Program's system-checksum = 0x%04x\n", (unsigned int)prog->crc16);
        printf("Entity field space: %u\n", (unsigned int)prog->entityfields);
        printf("Globals: %u\n", (unsigned int)vec_size(prog->globals));
    }

    if (opts_info) {
        prog_delete(prog);
        return 0;
    }
    if (opts_disasm) {
        for (i = 1; i < vec_size(prog->functions); ++i)
            prog_disasm_function(prog, i);
        return 0;
    }
    if (opts_printdefs) {
        for (i = 0; i < vec_size(prog->defs); ++i) {
            printf("Global: %8s %-16s at %u%s\n",
                   type_name[prog->defs[i].type & DEF_TYPEMASK],
                   prog_getstring(prog, prog->defs[i].name),
                   (unsigned int)prog->defs[i].offset,
                   ((prog->defs[i].type & DEF_SAVEGLOBAL) ? " [SAVE]" : ""));
        }
    }
    if (opts_printfields) {
        for (i = 0; i < vec_size(prog->fields); ++i) {
            printf("Field: %8s %-16s at %u%s\n",
                   type_name[prog->fields[i].type],
                   prog_getstring(prog, prog->fields[i].name),
                   (unsigned int)prog->fields[i].offset,
                   ((prog->fields[i].type & DEF_SAVEGLOBAL) ? " [SAVE]" : ""));
        }
    }
    if (opts_printfuns) {
        for (i = 0; i < vec_size(prog->functions); ++i) {
            int32_t a;
            printf("Function: %-16s taking %i parameters:(",
                   prog_getstring(prog, prog->functions[i].name),
                   (unsigned int)prog->functions[i].nargs);
            for (a = 0; a < prog->functions[i].nargs; ++a) {
                printf(" %i", prog->functions[i].argsize[a]);
            }
            printf(") locals: %i + %i\n",
                   prog->functions[i].firstlocal,
                   prog->functions[i].locals);
        }
    }
    if (!noexec) {
        for (i = 1; i < vec_size(prog->functions); ++i) {
            const char *name = prog_getstring(prog, prog->functions[i].name);
            if (!strcmp(name, "main"))
                fnmain = (qcint)i;
        }
        if (fnmain > 0)
        {
            prog_main_setparams(prog);
            prog_exec(prog, &prog->functions[fnmain], xflags, VM_JUMPS_DEFAULT);
        }
        else
            printf("No main function found\n");
    }

    prog_delete(prog);
    return 0;
}