This is generated from a plaintext file,  dsh.doc.


Next |End The DSH is a minimal shell based on standard algebraic notation with infix operators such as A+B. The results of the calculations may easily be moved into e-mail messages, the World Wide Web and other documents. The user interface is similar to a pocket calculator with AOS (Algebraic Operating system) and also to the UNIX shell developed in the 1960s. There are imitations of many of the classical UNIX commands such as alias, awk, bc, du, find, grep, history, info, ls, man, rm, tar and vi. The DSH is also called the D-shell. Like a simple push button calculator the DSH uses the whole display. The entry of numbers, which may be thousands of digits long, involves full screen editing for almost every display. Example 1: $ 2+2 4 Example 2: $ find *.txt search hard disk for files ending with .txt The idea of submitting whole economies to calculations became popular in the twentieth century firstly with the Russian Revolution and later on the the Cold War and the formal divisions between centrally planned economies and the so called Free World. K.Iverson added the idea of extending the ordinary arithmetic operations to whole tables of data all at once. A Globally planned economy was already a real possibility in the 1960s. Iverson's Algebra ran on IBM computers for decades. It now runs on Windows, Linux, and Psion. It will run on Mars or wherever the Empire will site its Capital City in the Galaxy. D-shell commands are translated to algebraic expressions and simplified. Sometimes the results of the commands are thrown to the computer for evaluation. This can be very slow even for simple calculations; and even after extensive calculations and searching there may still be no answer. This is the case with prime numbers and conjectures that require proof or dis-proof. D-shell commands can be typed after a prompt. On supplied scripts the prompt is a '$', but this could be changed to any character string. D-shell commands normally start with a lower case letter. If the user types a line which is not a D-shell command, then it is taken to be a D4 expression, as defined in <d4.doc>. All commands are defined in scripts or ascii files with the extension .d4f. The D-shell is a postcard sized function in one of the main scripts, test.afn, or dsh.afn. New commands can be added by use of the alias function 'a', editing a script, or editing one of the alias lists. Most .d4f files add commands when they are loaded. Some D-shell commands merely act as starting points for scripts. Start D4 with command line:- D4X test.afn v=14 x=gong#gong This will cause the D4 interpretor to run test.afn. The startup function (STARTUP) loads another script food.d4f, and immediately does the D-shell command 'pizza'. The syntax of a function is:- name {optional argument list} ARGS in scripts. Arguments are often UNIX style file types, with the '*' character meaning any string. Sometimes thay may refer to objects in the workspace. Several aliases can be used for one function, so LINUX and WINDOWS users can run the same scripts, although results will be slightly different. The full list of D-shell commands is stored in an alias-list. This may be permanently changed by either editing test.afn or d4s.lst. The current list of D-shell commands can always be seen by typing 'a'. Many of the D-Shell commands which generate information take you to either a menu, or to an 'edit' window. Always use the ESC (escape) key to exit a menu or the CR (Return) key to select a menu option. Most of the time mouse clicks have no effect if the mouse cursor is within the D-Shell window. If a command gives an edit window then the program is running the #sed editor, a built-in function to edit text buffers. Help is often available by pressing F2 or ^B. The 'vi' editor itself can be customised to be a real 'read-only' editor. It is merely a D4 script. Many supplied script files such as hebrew.d4f or farsi.d4f contain localised versions of 'vi'. The existing version of 'vi' is already customised to follow links in .html files, or '#include' statements in C/C++ programs. It can also follow links in many other files by using ^L (Control-L). The UNIX script can work transparently on compressed files. 'vi' differs very much from the UNIX program of the same name. There are far less commands and special keys. The ^D key takes you to a one line version of the D-shell with a '>$' prompt. The cursor movement keys up, down, left, right and the keys marked HOME, END, PgUp, PgDN and Del have the expected effect. Typing text either overwrites existing text, or pushes text to the right, depending the parity of the number of times the INS (insert key) has been pressed. ESC exits the editor, while pressing the Up arrow or CR will take you to editing text. The command line for the editor is highlighted but a poorly selected colour scheme may not reveal this. On linux platforms running X-windows the mouse will work. Two buttons are used. The left button is equivalent to return (CR), and the right button acts as escape (ESC). In editor mode a mouse click is meant to follow links based on the context of the screen. The right button always acts as a sort of return key. Think of it as navigation via plaintext links. The D-shell is usually started as an intereactive shell. Unlike the various shells given with UNIX it tries to get all of it's user input using full screen mode. It is also meant to be adapted to international languages including Arabic, Chinese and Hebrew inter alia.


Next | Back|Top|End Name Argument Comment ! DOS-command Run a DOS command. < DOS-command Run a DOS command, and edit the output. awk D4-expression Run within editor. String processing. a Edit alias list. cd Directory Change working directory. cls Clear screen. cp src dst Copy files src to dst. cr object-name display object to screen. cut grab D4.CUT screen, using cursor keys. See 'ww'. del files delete files. See 'rm' dir pathname Same as DOS directory. du c:/ Disk usage by directory. ed file {/string} Edit file, at first line containg string ev object-name Edit object f1 Select DOS console font. .bin format f2 Select DOS console font. Old .com format f3 Select DOS console font. LINUX .fnt format file path/selection Select files for editing find selection Find files on disk matching selection string. fns Edit functions in workspace goto For use in D-shell scripts. Very flakey. grep string files Search for string in files. help {/string} Look at d4.doc. same as 'man'. h Types history list to screen. Try 'ev D4.H' info Browse UNIX style 'info' files. ldtar Load tar file archiver ld d4f-file Reads in a new script. ls List files. Same as 'dir'. man Same as help. md pathname Make a new directory more filename Don't use. Run d4x rather than d4t. mv src dst Maps onto DOS move. phone name Searches phone file database. pwd Print working directory quit Exit program rc Read default alias list. rerun Delete all names, and restart shell. rm files Delete files save Write default alias list si colour Select console colour. Takes a number 0-255. subtree path Expands directory structure tar similar to UNIX tar vars Edit variables in workspace. vdel file-selector Delete selected files. ver Version vi file {/string} Edit file ww Same as 'cut' xg Exchange location of block graphic characters xoff Turn off pulldown menus on error. All of these commands are aliases. They are defined in many different places. The effects of the commands will vary greatly for different users on a UNIX system. The shell itself is defined in a script, normally 'test.afn'. Startup processing looks for an alias file called 'd4s.lst'. This adds further aliases. These alias files may be filled with operating system specific substitutions so that WINDOWS-NT/95 and LINUX may be made to look very much the same. This passes to the user the problems of different flavours for different releases. Effectively every user will have an individual release by customising the alias definitions. Many will simply be two or three letter shortcut combinations with a function and variable list syntax. The user gets the customised shell required. This can greatly assist internet viewing by storing common URLS in the alias list which work as portable bookmarks. Because the shell is itself a script it can easily be adapted to include system wide variables such as $INET_BROWSER. There are already several magic variables including $VA which may be mapped to to block input-output to any device, and $T which works for streams and character devices. More exotic magic variables can be put in the C source code to support new features. There are several for dealing with the keyboard mappings, and the language interpretor can easily look at local files. The magic variables act as file and device mappings. $SCR imitates a memory mapped screen. It's use is $SCR[Z]<-DATA where Z is a set of pixel positions in (y,x) values and DATA is a set of characters or numbers representing pixel values. D4, like APL and C is a language with variable types. Scalars may be integer, character or floating point. Explicit type conversion functions exist, and they must be used to get the correct results. To convert from integer to floating point it is always necessary for a floating point constant to appear somewhere in a calculation. Arithmetic may be done on character strings but the results will always remain character strings. Example: $ 34 0 z 123456789123456*888777444123 109725609496777417037971456 '34 0 z' is a format specification asking for 34 digits. The result is not completely accurate because the interpretor converts large numbers to floating point (sometimes). Full precision may be maintained by entering the numbers as string literals. $ "123456789123456"*"888777444123" 109725609496777409188649088 When a command contains an error a message is printed and a pull down menu bar appears. Select the 'Shell' option to return to command mode. If the error appeared during the saving of a file, then the 'Windows' option allows editing of the text which could not be saved. It is possible to write this text to a temporary file by typing ESC, ":w " and a file name. This sort of intereaction expects the user to write file names in full, usually at the bottom of the screen. There is little place for form filling beaurocracy when dealing with this type of software. It is best to avoid file names with embedded spaces. While many operating systems attempt to support this type of 'user friendly' rubbish few do it really well; embedded blanks in file names are often necessary to support Japanese or Chinese names, but with a desktop environment it is easy to create kana icons to point to these files. It is possible to change the behaviour on error. There is an alias called 'xoff' which cancels error handling. At an error the interpretor awaits keyboard input and treats any line as APL. Example: $ xoff 0 $ 6y ERROR [121]: 6y 2+2 4 The line '6y' gives an error. 'y' is a function, and the context requires an argument. The meaning of the error number is available from the include files in the source code distribution. Next the user types '2+2' and the interpretor gives 4. All APL interpretors give this result. This is known as calculator mode. The shell just includes calculations. It ensures that the user can check whether the system has become so degraded that it needs to restarted.


Next | Back|Top|End Traditional APL recognised a small number of fairly homogeneous data types. These were character data, integers and real numbers. D4 represents these in the machine with one, four (or two on 16-bit version) or eight bytes respectively. Given a symbol "A" the function #nc"A" gives the name class of the viriable as 0 for undefined and then 1,4,8 etc for the type of object. A character scalar represents a character with ascii value from 0 to 255. A character vector is any number of characters grouped into a string. A character matrix is a table, or array of characters with a certain number of rows and columns. Atomic data types (char, int, double) are grouped in only two possible ways. These are scalar, vector, and matrix. There is no difference between a scalar and a one element vector. The null object may have any type. The size of the object is the number of elements. The rank of an object is a vector representing the number of dimensions of the object. Since objects may only have a maximimum of two dimensions the rank is always either a single number, or a pair of numbers. Unlike traditional APL there is no scalar with an empty rank. Numeric literals are represented as strings of decimal digits with optional decimal points and a preceding sign written as underscore (_). Text literals are enclosed in double quotes ("). If the double quote is itself to be included in a string literal, then it must be doubled. Traditionally a single point has no dimension, a vector had one dimension, and arrays had two or more dimensions.


Next | Back|Top|End These functions are given as single keystrokes. They include +, -, *, % for ordinary arithmetic. Other function symbols include '/', '\', '=', '!', '~', '>' ,'<', ',', and a selection of lower case letters. All lower case letters are reserved for use as functions, although not all are defined. It should also be noticed that many of the functions are not defined for all ranges of values. This is quite important for writing programs. A sensible user is not expected to divide by zero, and similarly a program should not replicate meaningless data. Most functions in APL are partial functions: that is, they are not defined for all posible values of the data. This reflects the most 'State of the Art' hardware technology, where even fairly ordinary operations of arithmetic can return 'NaN' or 'not a number'. When a function receives data that it is not designed for it returns an error code and the system stops for user input.


Next | Back|Top|End 'r' 'r' stands for 'rho', the traditional function for giving or setting the rank of an object. It used the greek letter rho in Iverson's first definition of APL. Like most APL functions 'rho' has two forms. N <- r X returns rank of X Z <- N r X constructor. Here Z becomes a table of rank N whose elements are taken from the source X. If X is any object of size zero the result has no meaning, but otherwise the elements of Z are replicated from those of X. With text vectors this gives a convenient way of replicating words: thus we can write 12r"cat" to get the string "catcatcat". 0 r X constructs an empty vector. Expect DOMAIN ERROR or unspecified silly behaviour if N does not have sensible values when setting the size and shape of an array. If N is a single number then Z<- N r X creates a vector with N elements. If N is the pair {n m} the Z <- N r X creates a matrix with m rows and n columns. A matrix with just one row looks just like a vector. It is possible to access subsets of elements of vectors or matrices by subscripting. The syntax for subscripting is to write a subscript expression within square brackets. The subscript expression evaluates to a list of integers. Indexing starts with zero. V[0] is the first element of a vector V. Example: 5 12 r "ABCD WXYZ STUV" ABCD WXYZ ST UVABCD WXYZ STUVABCD WXY Z STUVABCD W XYZ STUVABCD Example: 5 5 ri25 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Example: X<-"this is text" rX 12


Next | Back|Top|End i 'iota'. Iota is a greek letter. In the original version of APL it became known as 'index generator'. Its function is to generate a vector of counting numbers. Traditionally these could be set to start from either zero or one, but D4 simply uses zero as the index origin. i0 is the empty vector, while i1 is the constant 0 and i2 is the vector {0 1}. For negative values i has no meaning and large values of the number N in Z<-iN will test the limits of the computer. Generally the statemement Z<-iN will have no meaning if N > 500000 or so. Example: Z<-i11 0 1 2 3 4 5 6 7 8 9 10


Next | Back|Top|End In APL the operation for concatenating objects is written with the comma. Thus 1, 2 gives the vector {1 2}. For ordinary strings and vectors the results do not seem surprising. The value C<- A, B is a vector of length (rA) + rB, and the elements are those of A followed by those of B. If either A or B is of character type and the other operand is numeric the operation should return domain error. If one oporand is integer and the other is double the result is also double precision. The integer values are 'floated'. Because APL deals with arrays there is the possibility that the expression C<-A,B also yields a table. Example: A<-5 5 r i25 & B<-5 2 r 7 8 C<-A,B 0 1 2 3 4 7 8 5 6 7 8 9 7 8 10 11 12 13 14 7 8 15 16 17 18 19 7 8 20 21 22 23 24 7 8 Example: A<- 4 4 r "abcdefghijklmnop" & B<-4 2r"| "


Next | Back|Top|End abcd| abcd efgh| efgh ijkl| ijkl mnop| mnop It can be seen that the comma (,) function is useful in joining together matrices. Traditional APL allowed the operation to take an axis modifier so that the user could write C<-A ,[x] B where x stood for a dimension along which to join A and B. If x was a fraction then a new dimension was created. Since D4 allows just two dimensions there is not so much choice. The expression A<-B ,: C simply creates a matrix with B over C. The colon serves as the axis modifier. More generally if A and B are matrices with sizes rA and rB the C<-A, B requires A and B to have the same number of rows (rA)[0] = (rB)[0] while C<- A ,:B requires the matrices to have the same number of columns. In the case either of the argeuments is a single element vector then it is stretched to match the appropriate dimension of the other arguement. Example: A<-3 3 r "abcdefghi" A,"|" A,:"-" abc| abc def| def ghi| ghi ---


Next | Back|Top|End APL has operations for the re-dimensioning of arrays. These are called take and drop, and they used to be written with upwards and downwards pointing arrows. In D4 they are abbreviated to 't' and 'd'. If X is an array (or vector) with size N then the expression S t X gives a new array of size S.


Next | Back|Top|End Default arithmetic works on integers. 'Division' is integer division. so 5 % 2 is 2 but 5 % 2.0 is 2.5. Numbers are 'floated' by adding a decimal point. Results of floating point operations often get to the console in a garbled form. When working extensively with floating point numbers it is necessary to set a format for the data. The numeric formatting function is written 'z', and it attempts to format numeric data. Integer lists are printed as a stream of numbers separated by blanks, while matrices are formatted so that columns do not overlap. Negative signs are printed as '_' (underscore), rather than '-'. This is so that the interpretor can re evaluate the output of a numeric expression to get the resulting numbers. Several format options have been tried for floating point numbers. Field widths such as the pair (w,d) z X or the decimal fraction w.d z X should give a field width w, with d digits after the decimal point. Another alternative is a picture format: V<-3.1415926 2.718281828 " #.####" z V gives 3.1416 2.7183 Because APL is an array processing language the printing of several objects in one statement would often require the arrangement of objects in tables. This means that no single glorified formatting function would meet every possible need. Generally a formatting specification applies to every element in the array which is the right argument of 'z'. The formatting function has an inverse function 'x' for execute. This takes any string as an APL expression and evaluates it. x"2+2" 4


Next | Back|Top|End Z <- A #outer f B where f is one of the operators: '+','*','f','c','=','>','<', and '^' for #and. If A is a vector with m elements, and B a vector with n elements, then the result Z is an m x n matrix whose elements z[i, j] are given by: z[i,j] = a[i] f b[j] where f is one of the functions in the list. Outer products are related to Cartesian products. The outer product takes a function or operator as argument besides two data values. The function reduces any pair of values (x,y) to a single scalar z by means of the formula z <- x f y. The function reduces the pair x,y to a value in the same set from which x and y were drawn. Example: A<-2 3 4 & B <- 3 5 7 11 A #outer + B 5 7 9 13 6 8 10 14 7 9 11 15 A #outer f B 2 2 2 2 3 3 3 3 3 4 4 4 A #outer = B 0 0 0 0 1 0 0 0 0 0 0 0 A #outer ^ B 2 0 2 2 3 1 3 3 0 4 4 0 Example: prime numbers up to N P<-2,(~A #member A #outer * A)/A<-1+2*1+iN<-400 14 10 rP 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 This example from Education Vector, Vol 10 No 4. A Note on Primes, Ted Emms. modend.doc


Next | Back|Top|End If A and B are two matrices, then the matrix vector pruduct of A and B is given by the expression Z<-A #inner B. Where X is a square matrix, the matrix inverse of X (if it exists) is given by the expression Z<- #domino X. By its matrix algebra APL deals with the set of endomorphisms of a ring. Because the programmer was lazy, the matrix algebra functions in integer domains stay integer, even at the expense of word wrapping. With small numbers such as sets of pixel colour values and immediate array co-ordinates this does not really matter. Image edge sharpening algorithms can be performed by integer matrix multiplication. Examples: A<-?5 5 r 10 & B<-?5 5r10 A 8 7 1 3 7 5 4 7 9 6 2 4 8 4 0 6 8 9 1 9 6 0 8 8 3 B 2 1 3 5 2 7 3 0 1 5 1 0 1 5 6 4 4 4 6 3 7 1 7 7 0 A #inner B 127 48 86 119 66 Matrix vector product. 123 59 100 160 99 56 30 30 78 84 144 43 94 152 109 73 41 79 139 84 A<-?3 3r6 Random values 0 to 5 A 5 3 3 3 2 0 4 3 0 " #.###" z #domino A Inverse matrix of A 0.000 3.000 -2.000 0.000 -4.000 3.000 0.333 -1.000 0.333 " #.####" z #domino A+N #outer = N<-i3 0.0000 0.3333 0.0000 Inverse matrix of A+1 0.0000 0.3333 0.0000 0.3333 -0.6667 -0.0000 The #domino function is matrix inversion. For this real numbers are usually required. JPEG decoding is based on matrix multiplication by special arrays representing roots of unity, that is to say numbers x satisfying x^n=1 for some n with a value such as 16 or 32. The algorithm is based on a frequency analysis of colour changes in the image, or as mathematicians would say a discrete cosine transform.


Next | Back|Top|End APL had operators known as encode and decode. These work on numbers and they can be used to display numbers in bases different to 10. Old APL used a T-sign and an inverted T-sign for these two functions. D4 uses the keywords #base and #represent. These keywords may be abbreviated to single letter function codes. Use 'b' for #base and 'n' for #represent. Integer to hexadecimal conversion provides a good example of these functions. To convert the numbers 34881 12045 _1 to four digit hexadecimal numbers use the expression:- (4 r 16) #represent 34881 12045 _1 8 8 4 1 2 15 0 13 15 15 15 15 The result is a matrix with 3 rows and 4 columns. There is one row for each integer on the right hand side. When a number requires more than 4 places for its representation the result is truncated. This happens for nagative values. To convert a matrix to numbers use the #base function. Example: 5 5 #base 2 2 r 0 1 2 3 1 13 G<-(4 r 16) #represent 34881 12045 _1 G 8 8 4 1 2 15 0 13 15 15 15 15 (4r16) #base G 34881 12045 65535 The #base function can be explained in terms of the matrix vector product. If A is an (m,n) matrix with m rows and n columns and B is a vector with components B[0],B[1]...B[n-1] then the expression Z<- B #base A gives the same result as Z<- A #inner *\ 1, 1 #drop 1 #phi B It is possible to use these operators to write functions to convert numbers to and from hexadecimal, to decode and encode base64 attachments for e-mail and to manipulate fixed width font files inter alia. Example: Z<-C2HEX STR |Characters to hex Z<-"0123456789ABCDEF"[,(2r16) #represent #av STR] Z<-HEX2N X |Hexadecimal to numbers Z<-16 16 b (((rX)%2),2)r"0123456789ABCDEF"iX $ H<-C2HEX "Have a nice day" $ H


Next | Back|Top|End $ HEX2N H 72 97 118 101 32 97 32 110 105 99 101 32 100 97 121 $ #av HEX2N H Have a nice day The function '#av' which has no abbreviation is used for data conversions. Y<-#av X will convert a matrix X to characters or numbers depending on the original type of X. People who learned BASIC will recognise #av as an extension of the functions ASC() and CHR$(). #av "cat" is 99 97 116 and #av 99 97 116 is "cat". The functions for base64 encoding are given.


Next | Back|Top|End ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ Z<-B64_ENCODE STR;N;K |Base 64 encode with endpoints. K<-(N<-rSTR)#mod 3 STR<-STR,(2-K)/ #av 0 & N<-(N+2*K>0)%3 Z<-,(4r64)n(3r256) b (N,3)r #av STR Z<-BASE64[Z] ->(K=0)/0 |Correction Z[(rZ)-i1+3-K]<-"=" Z<-B64_DECODE STR;N;K |Base 64 decode with endpoint K<-+/STR="=" N<-(rZ<-BASE64iSTR)%4 Z<-#av ,(3r256)n(4 r 64)b(N,4)rZ Z<-(-K)dZ Example of use: $ H<-B64_ENCODE "Send $1000 immediately" $ H U2VuZCAkMTAwMCBpbW1lZGlhdGVseQ== $ B64_DECODE H Send $1000 immediately


Next | Back|Top|End #!/home/d4/cp/d4x # test input from stdin #do 0 r INIT;Z<-MASSAGE_STDIN;#quit Z<-INIT Z<-EV.KB<-EV.ALX<-"DIE" Z<-MASSAGE_STDIN;T | "Massage file" AA: ->(_1 #equiv T<-#read 0)/XX (T, #av 10) #write 0 4 #print T ->AA XX: 0 r #close 0 Z<-#sed ":w out.tmp" Z<-DIE ("bailing out near line 0",#av 10 13) #write 0 Z<-#quit


Next | Back|Top|End #!/home/d4/cp/d4x # print arguement list # define global variables. The first single symbol line in this # file is the initialisation function. INIT Z<-INIT "run file name ", $1 |Symbolic links to this file can substitute different functions. |$1 can be parsed and tested. "args ",ARGS<-$$[2+i17] Z<-#quit Z<-TAB GETOPTS STR;_J;_V;_EXP |Parse -option {value} arguements Z<-"" & TAB<-#sstomat "|",TAB & STR<-#deb STR WHILE 0<r_V<-SHIFT _J<-,((_V," ") #find TAB)[:0] IF 0<+/_J; _EXP<-(1+r _V)d _J/:TAB; 0 r #do _EXP; REPEATIF 1 Z<-Z," ",_V WEND Z<-1dZ Z<-SEP SHIFT NN;K;L;Q;X |Get next token from string named NN and update NN |Unquote quoted text SEP<-" " #ifndef "SEP" X<-"" #ifndef NN<-"STR" #ifndef "NN" L<-0 & IF Q<-X[0] e "'"""; L<-1+(1dX)iX[0] K<-L+(LdX)iSEP & Z<-KtX $NL[NN]<-(~f\SEP=X)/X<-(K+1)dX IF Q; Z<-1d _1dZ


Next | Back|Top|End The make files for the interpretor were created by APL scripts back in 1986. It appears that make files are almost never written by humans. Instead make files are created by running lists of source code files through various macro processors. These involve a long shell script called configure. The Gnugo project consists of not more than a few dozen source files, but the configure script is 5720 lines long. Many lines of the configure use 'sed', the stream editor. "hfiles.sh" #!/bin/sh # # This script looks to see if a directory contains .h files # for dir in $@; do for hfile in $dir/*.h; do if [ -f $hfile ]; then echo $dir; fi break done done exit 0 "hfiles.df" #!/home/d4/cp/d4x # # check include files in a list of directories


| Back|Top|End Z<-HFILES;I;X I<-2 WHILE<rX<-$$[I++] (0<r, #files X,"/*.h")/X WEND Z<-#quit In fact the second script is worse than useless. It does not test any individual file and the expression $$[I++] allows only a limited number of $$ names: the size of the symbol table. This is currently set to be a few hundred only. That's easy to fix by looking at the argc variable for the command line and incorporating this into the original symbol table. The next thing to do is to add further symbol tables to reflect the external environment. These will be the usual pointers to applications and websites or resource files.
Back to the Top