📄 aplibtool.c
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <process.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
typedef char bool;
#define false 0
#define true (!false)
bool silent = false;
bool shared = false;
bool export_all = false;
enum mode_t { mCompile, mLink, mInstall };
enum output_type_t { otGeneral, otObject, otProgram, otStaticLibrary, otDynamicLibrary };
#ifdef __EMX__
# define SHELL_CMD "sh"
# define CC "gcc"
# define GEN_EXPORTS "emxexp"
# define DEF2IMPLIB_CMD "emximp"
# define SHARE_SW "-Zdll -Zmtd"
# define USE_OMF true
# define TRUNCATE_DLL_NAME
# define DYNAMIC_LIB_EXT "dll"
# define EXE_EXT ".exe"
# if USE_OMF
/* OMF is the native format under OS/2 */
# define STATIC_LIB_EXT "lib"
# define OBJECT_EXT "obj"
# define LIBRARIAN "emxomfar"
# else
/* but the alternative, a.out, can fork() which is sometimes necessary */
# define STATIC_LIB_EXT "a"
# define OBJECT_EXT "o"
# define LIBRARIAN "ar"
# endif
#endif
typedef struct {
char *arglist[1024];
int num_args;
enum mode_t mode;
enum output_type_t output_type;
char *output_name;
char *stub_name;
char *tmp_dirs[1024];
int num_tmp_dirs;
char *obj_files[1024];
int num_obj_files;
} cmd_data_t;
void parse_args(int argc, char *argv[], cmd_data_t *cmd_data);
bool parse_long_opt(char *arg, cmd_data_t *cmd_data);
int parse_short_opt(char *arg, cmd_data_t *cmd_data);
bool parse_input_file_name(char *arg, cmd_data_t *cmd_data);
bool parse_output_file_name(char *arg, cmd_data_t *cmd_data);
void post_parse_fixup(cmd_data_t *cmd_data);
bool explode_static_lib(char *lib, cmd_data_t *cmd_data);
int execute_command(cmd_data_t *cmd_data);
char *shell_esc(const char *str);
void cleanup_tmp_dirs(cmd_data_t *cmd_data);
void generate_def_file(cmd_data_t *cmd_data);
char *nameof(char *fullpath);
char *truncate_dll_name(char *path);
int main(int argc, char *argv[])
{
int rc;
cmd_data_t cmd_data;
memset(&cmd_data, 0, sizeof(cmd_data));
cmd_data.mode = mCompile;
cmd_data.output_type = otGeneral;
parse_args(argc, argv, &cmd_data);
rc = execute_command(&cmd_data);
if (rc == 0 && cmd_data.stub_name) {
fopen(cmd_data.stub_name, "w");
}
cleanup_tmp_dirs(&cmd_data);
return rc;
}
void parse_args(int argc, char *argv[], cmd_data_t *cmd_data)
{
int a;
char *arg;
bool argused;
for (a=1; a < argc; a++) {
arg = argv[a];
argused = false;
if (arg[0] == '-') {
if (arg[1] == '-') {
argused = parse_long_opt(arg + 2, cmd_data);
} else if (arg[1] == 'o' && a+1 < argc) {
cmd_data->arglist[cmd_data->num_args++] = arg;
arg = argv[++a];
argused = parse_output_file_name(arg, cmd_data);
} else {
int num_used = parse_short_opt(arg + 1, cmd_data);
argused = num_used > 0;
if (num_used > 1) {
a += num_used - 1;
}
}
} else {
argused = parse_input_file_name(arg, cmd_data);
}
if (!argused) {
cmd_data->arglist[cmd_data->num_args++] = arg;
}
}
post_parse_fixup(cmd_data);
}
bool parse_long_opt(char *arg, cmd_data_t *cmd_data)
{
char *equal_pos = strchr(arg, '=');
char var[50];
char value[500];
if (equal_pos) {
strncpy(var, arg, equal_pos - arg);
var[equal_pos - arg] = 0;
strcpy(value, equal_pos + 1);
} else {
strcpy(var, arg);
}
if (strcmp(var, "silent") == 0) {
silent = true;
} else if (strcmp(var, "mode") == 0) {
if (strcmp(value, "compile") == 0) {
cmd_data->mode = mCompile;
cmd_data->output_type = otObject;
}
if (strcmp(value, "link") == 0) {
cmd_data->mode = mLink;
}
if (strcmp(value, "install") == 0) {
cmd_data->mode = mInstall;
}
} else if (strcmp(var, "shared") == 0) {
shared = true;
} else if (strcmp(var, "export-all") == 0) {
export_all = true;
} else {
return false;
}
return true;
}
int parse_short_opt(char *arg, cmd_data_t *cmd_data)
{
if (strcmp(arg, "export-dynamic") == 0) {
return 1;
}
if (strcmp(arg, "module") == 0) {
return 1;
}
if (strcmp(arg, "Zexe") == 0) {
return 1;
}
if (strcmp(arg, "avoid-version") == 0) {
return 1;
}
if (strcmp(arg, "prefer-pic") == 0) {
return 1;
}
if (strcmp(arg, "prefer-non-pic") == 0) {
return 1;
}
if (strcmp(arg, "version-info") == 0 ) {
return 2;
}
return 0;
}
bool parse_input_file_name(char *arg, cmd_data_t *cmd_data)
{
char *ext = strrchr(arg, '.');
char *name = strrchr(arg, '/');
int pathlen;
char *newarg;
if (!ext) {
return false;
}
ext++;
if (name == NULL) {
name = strrchr(arg, '\\');
if (name == NULL) {
name = arg;
} else {
name++;
}
} else {
name++;
}
pathlen = name - arg;
if (strcmp(ext, "lo") == 0) {
newarg = (char *)malloc(strlen(arg) + 10);
strcpy(newarg, arg);
strcpy(newarg + (ext - arg), OBJECT_EXT);
cmd_data->arglist[cmd_data->num_args++] = newarg;
cmd_data->obj_files[cmd_data->num_obj_files++] = newarg;
return true;
}
if (strcmp(ext, "la") == 0) {
newarg = (char *)malloc(strlen(arg) + 10);
strcpy(newarg, arg);
newarg[pathlen] = 0;
strcat(newarg, ".libs/");
if (strncmp(name, "lib", 3) == 0) {
name += 3;
}
strcat(newarg, name);
ext = strrchr(newarg, '.') + 1;
if (shared && cmd_data->mode == mInstall) {
strcpy(ext, DYNAMIC_LIB_EXT);
newarg = truncate_dll_name(newarg);
} else {
strcpy(ext, STATIC_LIB_EXT);
}
cmd_data->arglist[cmd_data->num_args++] = newarg;
return true;
}
if (strcmp(ext, "c") == 0) {
if (cmd_data->stub_name == NULL) {
cmd_data->stub_name = (char *)malloc(strlen(arg) + 4);
strcpy(cmd_data->stub_name, arg);
strcpy(strrchr(cmd_data->stub_name, '.') + 1, "lo");
}
}
if (strcmp(name, CC) == 0 || strcmp(name, CC EXE_EXT) == 0) {
if (cmd_data->output_type == otGeneral) {
cmd_data->output_type = otObject;
}
}
return false;
}
bool parse_output_file_name(char *arg, cmd_data_t *cmd_data)
{
char *name = strrchr(arg, '/');
char *ext = strrchr(arg, '.');
char *newarg = NULL, *newext;
int pathlen;
if (name == NULL) {
name = strrchr(arg, '\\');
if (name == NULL) {
name = arg;
} else {
name++;
}
} else {
name++;
}
if (!ext) {
cmd_data->stub_name = arg;
cmd_data->output_type = otProgram;
newarg = (char *)malloc(strlen(arg) + 5);
strcpy(newarg, arg);
strcat(newarg, EXE_EXT);
cmd_data->arglist[cmd_data->num_args++] = newarg;
cmd_data->output_name = newarg;
return true;
}
ext++;
pathlen = name - arg;
if (strcmp(ext, "la") == 0) {
cmd_data->stub_name = arg;
cmd_data->output_type = shared ? otDynamicLibrary : otStaticLibrary;
newarg = (char *)malloc(strlen(arg) + 10);
mkdir(".libs", 0);
strcpy(newarg, ".libs/");
if (strncmp(arg, "lib", 3) == 0) {
arg += 3;
}
strcat(newarg, arg);
newext = strrchr(newarg, '.') + 1;
strcpy(newext, shared ? DYNAMIC_LIB_EXT : STATIC_LIB_EXT);
#ifdef TRUNCATE_DLL_NAME
if (shared) {
newarg = truncate_dll_name(newarg);
}
#endif
cmd_data->arglist[cmd_data->num_args++] = newarg;
cmd_data->output_name = newarg;
return true;
}
if (strcmp(ext, "lo") == 0) {
cmd_data->stub_name = arg;
cmd_data->output_type = otObject;
newarg = (char *)malloc(strlen(arg) + 2);
strcpy(newarg, arg);
ext = strrchr(newarg, '.') + 1;
strcpy(ext, OBJECT_EXT);
cmd_data->arglist[cmd_data->num_args++] = newarg;
cmd_data->output_name = newarg;
return true;
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -