cql_noexport void cg_c_main()

in sources/cg_c.c [8052:8221]


cql_noexport void cg_c_main(ast_node *head) {
  cql_exit_on_semantic_errors(head);
  exit_on_validating_schema();

  CSTR header_file_name = options.file_names[0];
  CSTR body_file_name = options.file_names[1];
  CSTR exports_file_name = NULL;

  int32_t export_file_index = 2;

  if (options.generate_exports) {
    if (options.file_names_count <= export_file_index) {
      cql_error("--cg had the wrong number of arguments, argument %d was needed\n", export_file_index + 1);
      cql_cleanup_and_exit(1);
    }

    exports_file_name = options.file_names[export_file_index];
  }

  cg_c_init();

  cg_scratch_masks global_scratch_masks;
  cg_current_masks = &global_scratch_masks;
  cg_zero_masks(cg_current_masks);

  if (options.compress) {
    // seed the fragments with popular ones based on statistics
    CHARBUF_OPEN(ignored);

    cg_statement_pieces(", ", &ignored);
    cg_statement_pieces("AS ", &ignored);
    cg_statement_pieces("NOT ", &ignored);
    cg_statement_pieces(".", &ignored);
    cg_statement_pieces(",", &ignored);
    cg_statement_pieces(",\n  ", &ignored);
    cg_statement_pieces("id ", &ignored);
    cg_statement_pieces("id,", &ignored);
    cg_statement_pieces("KEY", &ignored);
    cg_statement_pieces("KEY ", &ignored);
    cg_statement_pieces("TEXT", &ignored);
    cg_statement_pieces("LONG_", &ignored);
    cg_statement_pieces("INT ", &ignored);
    cg_statement_pieces("INTEGER ", &ignored);
    cg_statement_pieces("ON ", &ignored);
    cg_statement_pieces("TEXT ", &ignored);
    cg_statement_pieces("CAST", &ignored);
    cg_statement_pieces("TABLE ", &ignored);
    cg_statement_pieces("(", &ignored);
    cg_statement_pieces(")", &ignored);
    cg_statement_pieces("( ", &ignored);
    cg_statement_pieces(") ", &ignored);
    cg_statement_pieces("0", &ignored);
    cg_statement_pieces("1", &ignored);
    cg_statement_pieces("= ", &ignored);
    cg_statement_pieces("__", &ignored);
    cg_statement_pieces("NULL ", &ignored);
    cg_statement_pieces("NULL,", &ignored);
    cg_statement_pieces("EXISTS ", &ignored);
    cg_statement_pieces("CREATE ", &ignored);
    cg_statement_pieces("DROP ", &ignored);
    cg_statement_pieces("TABLE ", &ignored);
    cg_statement_pieces("VIEW ", &ignored);
    cg_statement_pieces("PRIMARY ", &ignored);
    cg_statement_pieces("IF ", &ignored);
    cg_statement_pieces("(\n", &ignored);

    CHARBUF_CLOSE(ignored);
  }

  CHARBUF_OPEN(exports_file);
  CHARBUF_OPEN(header_file);
  CHARBUF_OPEN(body_file);
  CHARBUF_OPEN(indent);

  if (exports_file_name) {
    exports_output = &exports_file;

    if (rt->exports_prefix) {
      bprintf(exports_output, "%s", rt->exports_prefix);
    }
  }

  cg_stmt_list(head);

  bprintf(&body_file, "%s", rt->source_prefix);

  if (options.c_include_namespace) {
    bprintf(&body_file, "#include \"%s/%s\"\n\n", options.c_include_namespace, options.file_names[0]);
  } else {
    bprintf(&body_file, "#include \"%s\"\n\n", options.file_names[0]);
  }

  bprintf(&body_file, "%s", rt->source_wrapper_begin);
  bprintf(&body_file, "#pragma clang diagnostic push\n");
  bprintf(&body_file, "#pragma clang diagnostic ignored \"-Wunknown-warning-option\"\n");
  bprintf(&body_file, "#pragma clang diagnostic ignored \"-Wbitwise-op-parentheses\"\n");
  bprintf(&body_file, "#pragma clang diagnostic ignored \"-Wshift-op-parentheses\"\n");
  bprintf(&body_file, "#pragma clang diagnostic ignored \"-Wlogical-not-parentheses\"\n");
  bprintf(&body_file, "#pragma clang diagnostic ignored \"-Wlogical-op-parentheses\"\n");
  bprintf(&body_file, "#pragma clang diagnostic ignored \"-Wliteral-conversion\"\n");
  bprintf(&body_file, "#pragma clang diagnostic ignored \"-Wunused-but-set-variable\"\n");

  bprintf(&body_file, "%s", cg_fwd_ref_output->ptr);
  bprintf(&body_file, "%s", cg_constants_output->ptr);

  if (cg_pieces_output->used > 1) {
    bprintf(&body_file, "static const char _pieces_[] = \n%s;\n", cg_pieces_output->ptr);
  }
  bprintf(&body_file, "%s", cg_declarations_output->ptr);

  // main function after constants and decls (if needed)

  bool_t global_proc_needed = cg_main_output->used > 1 || cg_scratch_vars_output->used > 1;

  if (global_proc_needed) {
    exit_on_no_global_proc();

    bprintf(&body_file, "#define _PROC_ %s\n", global_proc_name);

    bindent(&indent, cg_scratch_vars_output, 2);
    bprintf(&body_file, "\ncql_code %s(sqlite3 *_Nonnull _db_) {\n", global_proc_name);
    cg_emit_rc_vars(&body_file);

    bprintf(&body_file, "%s", indent.ptr);
    bprintf(&body_file, "%s", cg_main_output->ptr);
    bprintf(&body_file, "\n");
    if (error_target_used) {
      bprintf(&body_file, "%s:\n", error_target);
    }
    bprintf(&body_file, "%s", cg_cleanup_output->ptr);
    bprintf(&body_file, "  return _rc_;\n");
    bprintf(&body_file, "}\n");
    bprintf(&body_file, "\n#undef _PROC_\n");
  }

  bprintf(&body_file, "#pragma clang diagnostic pop\n");
  bprintf(&body_file, "%s", rt->source_wrapper_end);

  bprintf(&header_file, "%s", rt->header_prefix);
  bprintf(&header_file, rt->cqlrt_template, rt->cqlrt);
  bprintf(&header_file, "%s", rt->header_wrapper_begin);
  bprintf(&header_file, "%s", cg_header_output->ptr);
  bprintf(&header_file, "%s", rt->header_wrapper_end);

  CHARBUF_CLOSE(indent);

  cql_write_file(header_file_name, header_file.ptr);

  if (options.nolines || options.test) {
    cql_write_file(body_file_name, body_file.ptr);
  }
  else {
    CHARBUF_OPEN(body_with_line_directives);

    cg_insert_line_directives(body_file.ptr, &body_with_line_directives);
    cql_write_file(body_file_name, body_with_line_directives.ptr);

    CHARBUF_CLOSE(body_with_line_directives);
  }

  if (exports_file_name) {
    cql_write_file(exports_file_name, exports_file.ptr);
  }

  CHARBUF_CLOSE(body_file);
  CHARBUF_CLOSE(header_file);
  CHARBUF_CLOSE(exports_file);

  cg_c_cleanup();
}