05-19-05 10:52 PM
Billy Patton <bpatton@ti.com> writes:
> I have a 5k+ lines of tcsh file taht I use to set many environment variabl
es.
> The majority is pod documentation.
>
> At the top of the file I have
> #!/bin/tcsh -f
> I use tcsh because some of the variables are more than 22 chars long.
> csh will set them but it doesn't like to print them
> I would like to be able to source this file to either a csh
> source my_init
> or
> to include into a sh with a
> . my_file
> The problem being the switch statement and the setenv in csh syntax.
> I dont want to maintain 2 seperate file but would do something more
> easily visable, even if it ment doubling the size of the file
>
> I now have this:
>
> setenv ABC cats_dogs_pigs
>
> What I would like to have is
>
> if ( shell == sh ) then
> export ABC=cats_dogs_pigs
> else
> setenv ABC cats_dogs_pigs
> endif
>
> But the syntax above is csh if/then/else
It _is_ possible to write a source file that can be interpreted both
by csh, sh, fortran and c, and perhaps even more languages.
---Makefile-------------------------------------------------------------
all: happy-c happy-f happy-sh happy-csh
happy-c:happy.source Makefile
@ cp happy.source happy-c.c
@ gcc -o happy-c happy-c.c
@ echo -n '(C) '
@ ./happy-c || true
happy-f:happy.source Makefile
@ cp happy.source happy-f.f
@ f77 -o happy-f happy-f.f 2> /dev/null
@ echo -n '(FORTRAN) '
@ ./happy-f
happy-sh:happy.source Makefile
@ cp happy.source happy-sh
@ echo -n '(Bourne Shell) '
@ chmod 755 happy-sh
@ sh ./happy-sh
happy-csh:happy.source Makefile
@ cp happy.source happy-csh
@ chmod 755 happy-csh
@ echo -n '(C Shell) '
@ csh ./happy-csh
clean:
-rm -f *.o *~ happy-csh happy-sh happy-f happy-f.f happy-c happy-c.c
---happy.source---------------------------------------------------------
cat /*dev/null; echo "Happy New Year"\!
cat <<c*/ /*dev/null | cat > /dev/null
c */ () {} /*
c */ main() { cat(); printf("Happy New Year!\n"); } /*
17 format('Happy New Year!')
write (6,17)
stop
end
c*/
------------------------------------------------------------------------
But you won't want to do it. What you could do:
1- decide that you won't be using csh anymore. Bash is better and you
have the source so you can transport it and compile it on whatever
system you'll ever be using. And if you ever want to pass over to
ksh or zsh, they've got the same syntax as bash!
2- write the variables in a separate file, and transform it to either
one of the syntaxes. For example, with the following program, or
with some sed or awk script.
----environment.c-------------------------------------------------------
/ ****************************************
***********************************
***
FILE: environment.c
LANGUAGE: ANSI-C
SYSTEM: POSIX
USER-INTERFACE: POSIX
DESCRIPTION
Generate sh or csh environment variable definitions from a common file.
USAGE
sh 'environment -sh < ~/.environment > env.sh ; . env.sh'
csh 'environment -csh < ~/.environment > env.csh ; source env.csh'
AUTHORS
<PJB> Pascal J. Bourguignon
MODIFICATIONS
19??-??-?? <PJB> Creation.
BUGS
LEGAL
GPL
Copyright Pascal J. Bourguignon 19?? - 2002
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING; if not, write to
the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
****************************************
************************************
**/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
const char* pname="environment"; /*default name*/
static void report_error(const char* message)
{
fprintf(stderr,"%s: %s\n",pname,message);
}/*report_error*/
typedef void (*print_environment_pr)(const char* name,const char* value);
typedef void (*print_environment_header_pr)(void);
print_environment_pr print_environment=(print_environment_pr)
0;
print_environment_header_pr print_environment_header
=(print_environment_header_pr)0;
static void print_environment_header_csh(void)
{
printf("#!/bin/csh\n");
}/*print_environment_header_csh*/
static void print_environment_csh(const char* name,const char* value)
{
if(value[0]=='\0'){
printf("unsetenv %s\n",name);
}else{
printf("setenv %s %s\n",name,value);
}
}/*print_environment_csh*/
static void print_environment_header_sh(void)
{
printf("#!/bin/sh\n");
}/*print_environment_header_sh*/
static void print_environment_sh(const char* name,const char* value)
{
if(value[0]=='\0'){
printf("unset %s\n",name);
}else{
printf("export %s=%s\n",name,value);
}
}/*print_environment_sh*/
static char* string_new(const char* string)
{
char* that=(char*)malloc(sizeof(char)*(strlen(
string)+1));
strcpy(that,string);
return(that);
}/*string_new*/
typedef struct environment_list_s {
struct environment_list_s* next;
const char* name;
const char* value;
} environment_list_t;
static environment_list_t* environment_list_new(const char* name,
const char* value)
{
environment_list_t* that;
that=(environment_list_t*)malloc(sizeof(
environment_list_t));
that->next=(environment_list_t*)0;
that->name=string_new(name);
that->value=string_new(value);
return(that);
}/*environment_list_new*/
static void environment_list_append(environment_list
_t* that,
environment_list_t* tail)
{
while(that->next!=(environment_list_t*)0){
that=that->next;
}
that->next=tail;
}/*environment_list_append*/
static void environment_list_print(environment_list_
t* that,
print_environment_pr print_env)
{
while(that!=(environment_list_t*)0){
print_env(that->name,that->value);
that=that->next;
}
}/*environment_list_print*/
typedef FILE environment_file_t;
static environment_list_t* environment_file_load(environment_file_t
* file)
{
environment_list_t* list=(environment_list_t*)0;
char line[1024];
int linum=1;
while((char*)0!=fgets(line,sizeof(line)-1,file)){
char name[1024];
char value[1024];
environment_list_t* current=(environment_list_t*)0;
int i=0;
int j=0;
enum & #123;before_name,in_name,before_value,in
_value_single_quote,
in_value_double_quote,in_value_back_quot
e,
in_value_unquoted,between_value,after_va
lue} state=before_name;
short escaped=0;
char quote=' ';
i=strlen(line)-1;
if(line[i]=='\n'){
line[i]='\0';
}
name[0]='\0';
value[0]='\0';
i=0;
while((state!=after_value)&&(line[i]!='\0')){
switch(state){
case before_name:
if(isalpha(line[i])||(line[i]=='_')){
state=in_name;
j=0;
name[j++]=line[i];
name[j]='\0';
}else if(/*GNU extension*/isblank(line[i])){
/* Let's skip it */
}else if(line[i]=='#'){
state=after_value;
}else{
char message[1024];
sprintf(message,"Invalid character '%c' (0x%02x) "
"at line %d",line[i],line[i],linum);
report_error(message);
exit(1);
}
break;
case in_name:
if(isalnum(line[i])||(line[i]=='_')){
name[j++]=line[i];
name[j]='\0';
}else if(/*GNU extension*/isblank(line[i])){
state=before_value;
j=0;
}else if(line[i]=='#'){
state=after_value;
}else{
char message[1024];
sprintf(message,"Invalid character '%c' (0x%02x) "
"at line %d",line[i],line[i],linum);
report_error(message);
exit(1);
}
break;
case before_value:
/* fall thru */
case between_value:
if(line[i]=='''){
state=in_value_single_quote;
value[j++]=line[i];
value[j]='\0';
quote=line[i];
}else if(line[i]=='"'){
state=in_value_double_quote;
value[j++]=line[i];
value[j]='\0';
quote=line[i];
}else if(line[i]=='`'){
state=in_value_back_quote;
value[j++]=line[i];
value[j]='\0';
quote=line[i];
}else if(line[i]=='\'){
state=in_value_unquoted;
value[j++]=line[i];
value[j]='\0';
escaped=1;
}else if(/*GNU extension*/isblank(line[i])){
if(state==between_value){
state=after_value;
}else{
/* Let's skip it */
}
}else if(line[i]=='#'){
state=after_value;
}else{
state=in_value_unquoted;
value[j++]=line[i];
value[j]='\0';
}
break;
case in_value_single_quote:
if(escaped){
value[j++]=line[i];
value[j]='\0';
escaped=0;
}else{
if(line[i]=='''){
value[j++]=line[i];
value[j]='\0';
state=between_value;
}else if(line[i]=='\'){
value[j++]=line[i];
value[j]='\0';
escaped=1;
}else{
value[j++]=line[i];
value[j]='\0';
}
}
break;
case in_value_double_quote:
if(escaped){
value[j++]=line[i];
value[j]='\0';
escaped=0;
}else{
if(line[i]=='"'){
value[j++]=line[i];
value[j]='\0';
state=between_value;
}else if(line[i]=='\'){
value[j++]=line[i];
value[j]='\0';
escaped=1;
}else{
value[j++]=line[i];
value[j]='\0';
}
}
break;
case in_value_back_quote:
if(escaped){
value[j++]=line[i];
value[j]='\0';
escaped=0;
}else{
if(line[i]=='`'){
value[j++]=line[i];
value[j]='\0';
state=between_value;
}else if(line[i]=='\'){
value[j++]=line[i];
value[j]='\0';
escaped=1;
}else{
value[j++]=line[i];
value[j]='\0';
}
}
break;
case in_value_unquoted:
if(escaped){
value[j++]=line[i];
value[j]='\0';
escaped=0;
}else{
if(line[i]=='\'){
value[j++]=line[i];
value[j]='\0';
escaped=1;
}else if(line[i]=='''){
value[j++]=line[i];
value[j]='\0';
state=in_value_single_quote;
}else if(line[i]=='"'){
value[j++]=line[i];
value[j]='\0';
state=in_value_double_quote;
}else if(line[i]=='`'){
value[j++]=line[i];
value[j]='\0';
state=in_value_back_quote;
}else if((/*GNU extension*/isblank(line[i]))
||(line[i]=='#')){
state=after_value;
}else{
value[j++]=line[i];
value[j]='\0';
}
}
break;
default:
report_error("Internal error: invalid state.");
exit(1);
}
i++;
}/*while line[i]*/
switch(state){
case before_name:
break;
case in_name:
/* fall thru */
case before_value:
/* fall thru */
case in_value_unquoted:
/* fall thru */
case between_value:
/* fall thru */
case after_value:
if(name[0]!='\0'){
current=environment_list_new(name,value)
;
if(list==(environment_list_t*)0){
list=current;
}else{
environment_list_append(list,current);
}
}
break;
case in_value_single_quote:
case in_value_double_quote:
case in_value_back_quote:
{
char message[1024];
sprintf(message,"Missing closing quote (%c) at line %d.",
quote,linum);
report_error(message);
exit(1);
}
break;
default:
report_error("Internal error: invalid state.");
exit(1);
}
linum++;
}/*while fgets*/
return(list);
}/*environment_file_load*/
static void environment_file_close(environment_file_
t* file)
{
fclose(file);
}/*environment_file_close*/
static void usage(const char* upname)
{
fprintf(stderr,"%s usage:\n"
" %s --sh|-s|--csh|-c--help|-h \n",upname,upname);
}/*usage*/
int main(int argc,char** argv)
{
environment_file_t* envfile;
environment_list_t* envlist;
int i;
pname=argv[0];
i=1;
while(i<argc){
if((strcmp(argv[i],"--csh")==0)
||(strcmp(argv[i],"-c")==0)){
print_environment=print_environment_csh;
print_environment_header=print_environme
nt_header_csh;
}else if((strcmp(argv[i],"--sh")==0)
||(strcmp(argv[i],"-s")==0)){
print_environment=print_environment_sh;
print_environment_header=print_environme
nt_header_sh;
}else if((strcmp(argv[i],"--help")==0)
||(strcmp(argv[i],"-h")==0)){
usage(pname);
exit(1);
}else{
usage(pname);
exit(1);
}
i++;
}
if(print_environment==(print_environment
_pr)0){
fprintf(stderr,"%s: Please select either --sh or --csh.\n",pname);
usage(pname);
exit(1);
}
/*envfile=environment_file_open(".environment");*/
envfile=(environment_file_t*)stdin;
envlist=environment_file_load(envfile);
environment_file_close(envfile);
print_environment_header();
environment_list_print(envlist,print_env
ironment);
return(0);
}/*main*/
/*** environment.c -- 2003-12-02 11:28:07 -- pascal ***
/
----example.enviroment--------------------------------------------------
#
# My compilation environment:
#
COMMON "$HOME"/src/public/common
MAKEDIR "$COMMON"/makedir
TARGET Linux
#
# The PATH:
#
PATH /bin:/usr/bin:/sbin:/usr/sbin:/usr/X11R6/bin
PATH "$PATH":/usr/games:/opt/kde/bin:/opt/kde2/bin:/opt/gnome/b
in
PATH /local/JavaApps:"$JAVA_HOME"/bin:"$PATH"
PATH /local/apps/netscape:"$PATH"
PATH /local/apps/Acrobat4/bin:"$PATH"
PATH /local/apps/WordPerfect/wpbin:"$PATH"
PATH "$HOME"/bin:/local/bin:"$PATH":.
LD_LIBRARY_PATH "$LD_LIBRARY_PATH":/opt/kde/lib:/opt/kde2/bin:/opt/gnome/l
ib
LD_LIBRARY_PATH /local/apps/rvplayer5.0:"$LD_LIBRARY_PATH"
------------------------------------------------------------------------
--
__Pascal Bourguignon__ http://www.informatimago.com/
Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.
[ Post a follow-up to this message ]
|