vanaards%t7@uk.ac.man.cs (01/21/91)
Recetly I noticed a lot of talk about a routine to convert UNIX filenames to RISC OS filenames, but as of yet no one has come up with the goods ! So to start the ball rolling I'll post this rather awful routine which does the job. It's written in C and is probably too unintelligible to be ported to any other language. I use it in my programs - which I've just posted, and it hasn't failed me yet. When compiling, try : cc c.ufn_rofn -DTEST if you want to test it out. That's all folks ! Steven van Aardt (If we've any Dutch Users I'd like your opinion of the origins of my surname, it apparently has an Afrikanns background.) -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. | | | | | | | | | | | | C U T B E L O W | | | | | | | | | | | | | | | | | '-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-' /*----------------------------------------------------* * Module : c.ufn_rofn * Purpose: Convert UNIX filenames to RiscOS filename * Author : Steven van Aardt *----------------------------------------------------*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #define FALSE 0 #define TRUE (!FALSE) #define MAX_FILENAME 10 /*---------------------------- Reverse ------------------------* * Purpose: Reverse the character sequence within a string * Arguments: Pointer to string * Returns: Pointer to the same string given as an argument. *-------------------------------------------------------------*/ static char *reverse(char *string) { int hd=0,tl=strlen(string); char tmp_c; /* reverse the name */ while (--tl>hd) { /* work way back from end of string */ tmp_c=string[hd]; string[hd++]=string[tl]; string[tl]=tmp_c; } return string; } /*---------------------------- isvowel --------------------------------* * Purpose: Determines whether a character is an alphabetical vowel * Arguments: character (integer form) * Returns: TRUE if vowel, otherwise FALSE. *---------------------------------------------------------------------*/ static int isvowel(int c) { int vowel=FALSE; switch (c) { case 'a': case 'A': /* if c matches with */ case 'e': case 'E': /* any of these function */ case 'i': case 'I': /* will return TRUE */ case 'o': case 'O': case 'u': case 'U': vowel=TRUE; } return vowel; } /*-------------------- squeeze ------------------------* * Purpose: remove any space characters from a string * Arguments: pointer to string * Returns: pointer to a new string. *-------------------------------------------------------*/ static char *squeeze(char *ptr) { int i=0,j=0; char *nn=NULL; /* squeeze in-place */ for (i=j=0; ptr[i]!='\0';i++) if (ptr[i]!=' ') ptr[j++]=ptr[i]; /* and copy into a new string */ nn=calloc(j+2,sizeof(char)); /* allocate enough memory for new string */ strncpy(nn,ptr,j); return nn; } /*---------------------------- rm_vowels -----------------------------* * Purpose: removes some vowels from a string thus shortening it * Arguments: pointer to string * Returns: pointer to a new string. *--------------------------------------------------------------------*/ static char *rm_vowels(char *word,int maxlen) { char *new_word=NULL; if (word) { int len=strlen(word); char *cpy=calloc(len+1,sizeof(char)); strcpy(cpy,word); if (len>maxlen) { /* remove every 2nd vowel */ int i; len--; /* leave last letter */ for (i=1; i<len; i+=2) { while ((i<len) && (!isvowel(cpy[i]))) i++; /* skip non-vowels */ if ((i<len) && (isvowel(cpy[i]))) cpy[i]=' '; /* overwrite vowels */ } } new_word=squeeze(cpy); free(cpy); } return new_word; } /*------------------- shorten ----------------------* * Purpose: Shortens a string to a specified length * Arguments: pointer to string * max length of string to be. * Returns: Pointer to new string *----------------------------------------------------*/ static char *shorten(char *ptr,int maxlen) { char *new_ptr; int l=strlen(ptr); if (l>maxlen) { /* quick shortening by removing a chunk from the middle */ int num=l-maxlen; /* number to remove to get length of 10 */ int i,j=0; for (i=(l-num)/2; j<num; j++) ptr[i+j]=' '; } new_ptr=squeeze(ptr); return new_ptr; } /*--------------------- ufn_rofn ------------------------* * Purpose: Convert UNIX filename to RISC OS filename * Arguments: pointer to UNIX filename string * Returns: pointer to RISC OS filename *-------------------------------------------------------*/ extern char *ufn_rofn(char *unix_name) { typedef struct l List; /* structure for constituent parts */ struct l { char *ptr; struct l *last,*next; }; int len; char *uname=calloc(strlen(unix_name)+1,sizeof(char)),*rname=NULL,*ptr=NULL; List *lptr=NULL,*hdptr=NULL,*tlptr=NULL; while ((unix_name) && (*unix_name==' ')) unix_name++; if ((unix_name) && (*unix_name)) { strcpy(uname,unix_name); /* look for root directory '/' at beginning of unix filename */ if (uname[0]=='/') { char *tmp=calloc(2,sizeof(char)); strcpy(tmp,"$"); lptr=(List *) malloc(sizeof(List)); tlptr=lptr; /* pointer to beginning of list */ lptr->ptr=tmp; lptr->next=NULL; lptr->last=hdptr; hdptr=lptr; /* pointer to end of list */ } /* * Break down the name into its directory components - destroys uname */ ptr=strtok(uname,"/"); /* ignores / if at beginning of list */ while (ptr) { char *tmp=calloc(strlen(ptr)+1,sizeof(char)); strcpy(tmp,ptr); lptr=(List *) malloc(sizeof(List)); if (!tlptr) tlptr=lptr; /* make pointer to beginning of list */ if (hdptr) hdptr->next=lptr; /* link previous element onto this */ lptr->ptr=tmp; lptr->next=NULL; lptr->last=hdptr; /* reverse chained list */ hdptr=lptr; ptr=strtok(NULL,"/"); /* find next '/' */ } /* * Now go through each component looking for a '.' within each. */ lptr=tlptr; /* beginning of list */ while (lptr) { char *dp=NULL; /* dot position */ dp=strchr(lptr->ptr,'.'); if (dp) { int len=strlen(lptr->ptr); /* * special cases */ /* if only 1 dot then refers to the UNIX csd */ if (len==1) { char *tmp=calloc(2,sizeof(char)); strcpy(tmp,"@"); lptr->ptr=tmp; } else { if (len==2) { char *tmp=calloc(2,sizeof(char)); strcpy(tmp,"^"); lptr->ptr=tmp; } else { /* * General case requires reversing of parts around '.' */ List *dlptr=NULL, *dhdptr=NULL, *dtlptr=NULL,*tmp_next=lptr->next; char *dptr=NULL,*cpy=calloc(len+1,sizeof(char)); strcpy(cpy,lptr->ptr); reverse(cpy); /* reverse complete text */ dptr=strtok(cpy,"."); while (dptr) { char *tmp=calloc(strlen(dptr)+1,sizeof(char)); strcpy(tmp,dptr); /* make a copy of part */ dlptr=(List *) malloc(sizeof(List)); if (!dtlptr) dtlptr=dlptr; /* remember beginning of this list */ if (dhdptr) dhdptr->next=dlptr; /* link previous one onto this */ dlptr->ptr=reverse(tmp); /* and reverse it's text back again */ dlptr->next=NULL; dlptr->last=dhdptr; /* reverse chaining */ dhdptr=dlptr; dptr=strtok(NULL,"."); } /* endwhile */ if (lptr->last) { free(lptr->ptr); /* free text worked on by above */ lptr=lptr->last; /* move back */ free(lptr->next); /* free text's list element */ lptr->next=dtlptr; /* link */ dtlptr->last=lptr; dlptr->next=tmp_next; if (tmp_next) { tmp_next->last=dlptr; lptr=tmp_next->last; } else lptr=dlptr; } else { /* case when this is the head of the list */ free(lptr->ptr); free(lptr); lptr=dtlptr; tlptr=lptr; lptr->last=NULL; dlptr->next=tmp_next; if (tmp_next) { tmp_next->last=dlptr; lptr=tmp_next->last; } else lptr=dlptr; } /* endif */ } /* endif */ } /* endif */ } /* endif */ lptr=lptr->next; /* move onto next directory component in list */ } /* endwhile */ /* * Check the lengths of each component and adjust to that for RISC OS */ lptr=tlptr; len=0; while (lptr) { char *new_ptr=NULL; if (lptr->next) len+=1; /* for the RISC OS directory separator */ new_ptr=rm_vowels(lptr->ptr,MAX_FILENAME); free(lptr->ptr); lptr->ptr=new_ptr; new_ptr=shorten(lptr->ptr,MAX_FILENAME); free(lptr->ptr); lptr->ptr=new_ptr; len+=strlen(lptr->ptr); lptr=lptr->next; } /* * Copy linked list into result string */ rname=calloc(len+1,sizeof(char)); /* make suitable string space */ lptr=tlptr; len=0; while (lptr) { strcat((rname+len),lptr->ptr); free(lptr->ptr); len=strlen(rname); lptr=lptr->next; if (lptr) strcat(rname,"."); /* append RISC OS directory separator */ } /* * Tidy up, by freeing memory used by list */ lptr=tlptr; while (lptr) { List *tmp; tmp=lptr; lptr=lptr->next; free(tmp); } } /* endif */ free(uname); return rname; } #ifdef TEST int main(void) { char unix_filename[256],*riscos_filename; while (!feof(stdin)) { printf("Enter Unix filename : "); scanf("%s",&unix_filename); if (!feof(stdin)) { riscos_filename=ufn_rofn(unix_filename); printf("Risc OS filename : %s\n",riscos_filename); free(riscos_filename); } } return 0; } #endif +--------------------------------+-----------------------------------------+ | ()()TEVEN () | | | () ()() | | | ()() () ()AN () () | | | () ()() ()()()() +-----------------------------------------+ | ()() () () ()ARDT |JANET E-mail : vanaards@uk.ac.man.cs.p4 | +--------------------------------+-----------------------------------------+