This is makelanguage.c in view mode; [Download] [Up]
/*
* makelanguage.c version 1.0, Dec 06 1995 (Nikolo edition)
* Copyright (C) Stefan Schneider 1994,95
*
*/
/*
* This source code is freeware, supplied "as is".
* Use it to your liking, but don't bother me if
* something goes wrong. For suggestions of any kind,
* you're welcome to contact me at <stefan@ping.at>.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <c.h>
#include <sys/param.h>
#import <sys/types.h>
#import <sys/stat.h>
#import <sys/dir.h>
#import <errno.h>
static const char *LANGUAGE_DIR_EXT = ".lproj";
static const char *HELP_DIR = "Help";
static const char *HELP_STORE = "Help.store";
static const char *FASTCP = "/usr/lib/fastcp";
static const char *COMPRESSHELP = "/usr/bin/compresshelp";
#define MAX_SUBPROJECTS 255
#define MAX_CAT_TOKENS 1024
#define MAX_LINE_LENGTH 1024
typedef struct {
const char *path; // path of /Makefile
const char *category; // search string, e.g "HFILES ="
int tokens; // # of found tokens for above category
char *token[MAX_CAT_TOKENS]; // found tokens (not NULL-terminated!)
} t_token_list;
char *subproj[MAX_SUBPROJECTS + 1]; // subproject paths (main is first one)
int subprojs = 0; // # of above paths (incl. main one)
t_token_list *
scan_makefile_for_category (const char *path, const char *category)
// scan 'path'/Makefile for 'category',
// generate and return t_token_list of tokens
{
t_token_list *tl;
FILE *file;
char name[MAXPATHLEN];
char line[MAX_LINE_LENGTH];
int found = FALSE;
int cat_length = strlen(category);
char *start, *end;
tl = (t_token_list *)malloc(sizeof(t_token_list));
tl -> path = path;
tl -> category = category;
tl -> tokens = 0;
strcpy(name, path);
strcat(name, "/Makefile");
if ((file = fopen(name, "r")) == NULL) {
fprintf(stderr, "makelanguage: can't open %s\n", name);
return tl;
}
while (fgets(line, MAX_LINE_LENGTH, file))
if (strncmp(line, category, cat_length) == 0) {
found = TRUE;
break;
}
if (!found) {
fclose(file);
return tl;
}
start = line + cat_length;
while (TRUE) {
int length;
char *token;
while (isspace(*start))
start++;
if ((*start == '\n') || (*start == '\0'))
break;
if (*start == '\\') {
if ((fgets(line, MAX_LINE_LENGTH, file) == NULL) || (!isspace(line[0])))
break;
start = line;
continue;
}
for (end = start + 1; (!isspace(*end)) && (*end != '\n') && (*end != '\\') && (*end != '\0'); end++) ;
length = end - start;
token = malloc(length + 1);
strncpy(token, start, length);
token[length] = '\0';
tl -> token[tl -> tokens++] = token;
if (tl -> tokens == MAX_CAT_TOKENS)
break;
start = end;
}
fclose(file);
return tl;
}
void
add_subproj (const char *path)
// scan 'path'/Makefile for subprojects (using a temporary t_token_list),
// tell each one found to do the same (recursively), then add 'path'
// as a subproject itself
{
t_token_list *subs = scan_makefile_for_category(path, "SUBPROJECTS =");
int ti;
// add all subprojects of this one
for (ti = 0; ti < subs -> tokens; ti++) {
char subpath[MAXPATHLEN];
strcpy(subpath, subs -> path);
strcat(subpath, "/");
strcat(subpath, subs -> token[ti]);
add_subproj(subpath);
}
// add this subproject
subproj[subprojs] = malloc(strlen(path) + 1);
strcpy(subproj[subprojs], path);
subprojs++;
free(subs);
}
int
file_exists (const char *path)
{
FILE *fp = fopen(path, "r");
if (fp) {
fclose(fp);
return TRUE;
}
return FALSE;
}
int
dir_exists (const char *path)
{
DIR *d_ptr = opendir(path);
if (d_ptr) {
(void)closedir(d_ptr);
return TRUE;
}
return FALSE;
}
int
main (int argc, char *argv[])
{
int pi, ti; // path & token walkers
t_token_list **local_resources; // will be NULL-terminated due to calloc + 1
FILE *file;
char project_path[MAXPATHLEN];
char target_path[MAXPATHLEN];
char target_language_path[MAXPATHLEN];
char source_language_path[MAXPATHLEN];
char name[MAXPATHLEN];
char command[MAXPATHLEN * 10];
if ((argc < 3) || (argc > 4)) {
fprintf(stderr, "usage: makelanguage language project_name <project path>\n");
return -1;
} else if (argc == 4)
strcpy(project_path, argv[3]);
else
getwd(project_path);
strcpy(target_path, project_path);
strcat(target_path, "/");
strcat(target_path, argv[2]);
strcpy(target_language_path, target_path);
strcat(target_language_path, "/");
strcat(target_language_path, argv[1]);
strcat(target_language_path, LANGUAGE_DIR_EXT);
if (!dir_exists(target_language_path)) {
if (mkdir(target_language_path, 0775)) {
fprintf(stderr, "makelanguage: can't create %s: %s\n", target_language_path, sys_errlist[errno]);
return -1;
}
}
fprintf(stderr, "Making %s version\n", argv[1]);
// generate subproj paths recursively
subprojs = 0;
add_subproj(project_path);
// generate token lists of local resource files, one for each subproj
local_resources = (t_token_list **)calloc(subprojs + 1, sizeof(t_token_list *));
for (pi = 0; pi < subprojs; pi++)
local_resources[pi] = scan_makefile_for_category(subproj[pi], "LOCAL_RESOURCES =");
// fastcp local resource files of each subproj
for (pi = 0; pi < subprojs; pi++) {
int any_files = FALSE;
if (local_resources[pi] -> tokens < 1)
continue;
// check whether argv[1]LANGUAGE_DIR_EXT exists
strcpy(source_language_path, subproj[pi]);
strcat(source_language_path, "/");
strcat(source_language_path, argv[1]);
strcat(source_language_path, LANGUAGE_DIR_EXT);
if (!dir_exists(source_language_path)) {
fprintf(stderr, "makelanguage: can't find %s\n", source_language_path);
continue;
}
// concat files to FASTCP
sprintf(command, "cd %s; %s", source_language_path, FASTCP);
for (ti = 0; ti < local_resources[pi] -> tokens; ti++) {
if (strcmp(local_resources[pi] -> token[ti], HELP_DIR)) {
strcat(command, " ");
strcat(command, local_resources[pi] -> token[ti]);
any_files = TRUE;
}
}
// perform FASTCP if any_files
if (any_files) {
strcat(command, " ");
strcat(command, target_language_path);
system(command);
}
// check for HELP_DIR
for (ti = 0; ti < local_resources[pi] -> tokens; ti++) {
if (!strcmp(local_resources[pi] -> token[ti], HELP_DIR)) {
int do_compress = TRUE;
// check whether to COMPRESSHELP
sprintf(name, "%s/%s", source_language_path, HELP_DIR);
if (!dir_exists(name))
do_compress = FALSE;
else {
sprintf(name, "%s/%s", target_language_path, HELP_STORE);
if (file_exists(name)) {
struct stat buf;
if (stat(name, &buf) == 0) {
time_t target_mtime = buf.st_mtime;
sprintf(name, "%s/%s", source_language_path, HELP_DIR);
if (stat(name, &buf) == 0) {
if (buf.st_mtime <= target_mtime)
do_compress = FALSE;
}
}
}
}
// perform COMPRESSHELP
if (do_compress) {
sprintf(command, "%s %s/%s -o %s/%s", COMPRESSHELP, source_language_path, HELP_DIR, target_language_path, HELP_STORE);
system(command);
}
break;
}
}
}
return 0;
} /* main() */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.