ftp.nice.ch/pub/next/unix/developer/makelanguage.1.0.s.tar.gz#/makelanguage/makelanguage.c

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.