Artifact 97098936a5608049ec59baef7de7525ce18d4f82:
File
src/tokenize_path.c
part of check-in
[58ee4e6e16]
- added missing #include
by
stephan on
2008-02-07 05:31:57.
0000: 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 #include <string
0010: 2e 68 3e 0d 0a 23 69 6e 63 6c 75 64 65 20 3c 73 .h>..#include <s
0020: 74 64 6c 69 62 2e 68 3e 0d 0a 23 69 6e 63 6c 75 tdlib.h>..#inclu
0030: 64 65 20 22 74 6f 6b 65 6e 69 7a 65 5f 70 61 74 de "tokenize_pat
0040: 68 2e 68 22 0d 0a 0d 0a 2f 2a 2a 0d 0a 74 6f 6b h.h"..../**..tok
0050: 65 6e 69 7a 65 5f 70 61 74 68 5f 66 72 65 65 28 enize_path_free(
0060: 29 20 69 73 20 74 68 65 20 6f 6e 6c 79 20 70 75 ) is the only pu
0070: 62 6c 69 63 61 6c 6c 79 2d 64 65 66 69 6e 65 64 blically-defined
0080: 20 77 61 79 20 74 6f 20 64 65 61 6c 6c 6f 63 61 way to dealloca
0090: 74 65 0d 0a 61 20 73 74 72 69 6e 67 20 61 72 72 te..a string arr
00a0: 61 79 20 63 72 65 61 74 65 64 20 62 79 20 74 6f ay created by to
00b0: 6b 65 6e 69 7a 65 5f 70 61 74 68 28 29 2e 20 20 kenize_path().
00c0: 49 74 20 6d 75 73 74 20 62 65 20 63 61 6c 6c 65 It must be calle
00d0: 64 20 65 78 61 63 74 6c 79 0d 0a 6f 6e 63 65 20 d exactly..once
00e0: 66 6f 72 20 65 61 63 68 20 72 65 74 75 72 6e 20 for each return
00f0: 76 61 6c 75 65 20 66 72 6f 6d 20 74 6f 6b 65 6e value from token
0100: 69 7a 65 5f 70 61 74 68 28 29 2e 20 46 61 69 6c ize_path(). Fail
0110: 69 6e 67 20 74 6f 20 63 61 6c 6c 20 69 74 0d 0a ing to call it..
0120: 77 69 6c 6c 20 72 65 73 75 6c 74 20 69 6e 20 61 will result in a
0130: 20 6d 65 6d 6f 72 79 20 6c 65 61 6b 2e 0d 0a 0d memory leak....
0140: 0a 49 66 20 28 21 70 29 20 74 68 65 6e 20 74 68 .If (!p) then th
0150: 69 73 20 66 75 6e 63 74 69 6f 6e 20 64 6f 65 73 is function does
0160: 20 6e 6f 74 68 69 6e 67 2e 20 20 50 61 73 73 69 nothing. Passi
0170: 6e 67 20 61 20 70 6f 69 6e 74 65 72 20 77 68 69 ng a pointer whi
0180: 63 68 20 77 61 73 0d 0a 6e 6f 74 20 72 65 74 75 ch was..not retu
0190: 72 6e 65 64 20 66 72 6f 6d 20 74 6f 6b 65 6e 69 rned from tokeni
01a0: 7a 65 5f 70 61 74 68 28 29 20 77 69 6c 6c 20 72 ze_path() will r
01b0: 65 73 75 6c 74 20 69 6e 20 75 6e 64 65 66 69 6e esult in undefin
01c0: 65 64 20 62 65 68 61 76 69 6f 75 72 2e 0d 0a 0d ed behaviour....
01d0: 0a 41 66 74 65 72 20 63 61 6c 6c 69 6e 67 20 74 .After calling t
01e0: 68 69 73 2c 20 70 27 73 20 63 6f 6e 74 65 6e 74 his, p's content
01f0: 73 20 61 72 65 20 69 6e 76 61 6c 69 64 2e 0d 0a s are invalid...
0200: 0d 0a 2a 2f 0d 0a 76 6f 69 64 20 74 6f 6b 65 6e ..*/..void token
0210: 69 7a 65 5f 70 61 74 68 5f 66 72 65 65 28 20 63 ize_path_free( c
0220: 68 61 72 20 2a 2a 20 70 20 29 0d 0a 7b 0d 0a 20 har ** p )..{..
0230: 20 69 66 28 20 70 20 29 0d 0a 20 20 7b 20 0d 0a if( p ).. { ..
0240: 20 20 20 20 2f 2a 20 46 72 65 65 20 74 68 65 20 /* Free the
0250: 74 6f 6b 65 6e 69 7a 65 64 20 73 74 72 69 6e 67 tokenized string
0260: 73 20 28 61 20 73 69 6e 67 6c 65 20 73 74 72 69 s (a single stri
0270: 6e 67 2c 20 61 63 74 75 61 6c 6c 79 29 3a 20 2a ng, actually): *
0280: 2f 0d 0a 20 20 20 20 66 72 65 65 28 20 2a 28 70 /.. free( *(p
0290: 2d 31 29 20 29 3b 0d 0a 20 20 20 20 2f 2a 20 46 -1) );.. /* F
02a0: 72 65 65 20 70 20 66 72 6f 6d 20 69 74 73 20 52 ree p from its R
02b0: 45 41 4c 20 73 74 61 72 74 69 6e 67 20 70 6f 69 EAL starting poi
02c0: 6e 74 2e 20 2a 2f 0d 0a 20 20 20 20 66 72 65 65 nt. */.. free
02d0: 28 20 70 2d 31 20 29 3b 0d 0a 20 20 7d 0d 0a 7d ( p-1 );.. }..}
02e0: 0d 0a 0d 0a 2f 2a 2a 0d 0a 74 6f 6b 65 6e 69 7a ..../**..tokeniz
02f0: 65 5f 70 61 74 68 5f 69 73 5f 73 65 70 61 72 61 e_path_is_separa
0300: 74 6f 72 28 29 20 69 73 20 74 68 65 20 64 65 66 tor() is the def
0310: 61 75 6c 74 20 70 72 65 64 69 63 61 74 65 20 66 ault predicate f
0320: 75 6e 63 74 69 6f 6e 20 66 6f 72 0d 0a 74 6f 6b unction for..tok
0330: 65 6e 69 7a 65 5f 70 61 74 68 28 29 2e 20 49 74 enize_path(). It
0340: 20 72 65 74 75 72 6e 73 20 31 20 69 66 20 28 63 returns 1 if (c
0350: 20 3d 3d 20 27 2f 27 29 2c 20 65 6c 73 65 20 69 == '/'), else i
0360: 74 20 72 65 74 75 72 6e 73 20 30 2e 0d 0a 0d 0a t returns 0.....
0370: 2a 2f 0d 0a 69 6e 74 20 74 6f 6b 65 6e 69 7a 65 */..int tokenize
0380: 5f 70 61 74 68 5f 69 73 5f 73 65 70 61 72 61 74 _path_is_separat
0390: 6f 72 28 20 69 6e 74 20 63 20 29 0d 0a 7b 0d 0a or( int c )..{..
03a0: 20 20 72 65 74 75 72 6e 20 28 63 20 3d 3d 20 27 return (c == '
03b0: 2f 27 29 3b 0d 0a 7d 0d 0a 2f 2a 2a 0d 0a 20 20 /');..}../**..
03c0: 20 74 6f 6b 65 6e 69 7a 65 5f 70 61 74 68 28 29 tokenize_path()
03d0: 20 74 61 6b 65 73 20 61 20 73 74 72 69 6e 67 2c takes a string,
03e0: 20 61 73 73 75 6d 65 64 20 74 6f 20 62 65 20 61 assumed to be a
03f0: 20 64 65 6c 69 6d 69 74 65 64 0d 0a 20 20 20 6e delimited.. n
0400: 75 6c 6c 2d 74 65 72 6d 69 6e 61 74 65 64 20 70 ull-terminated p
0410: 61 74 68 2d 73 74 79 6c 65 20 73 74 72 69 6e 67 ath-style string
0420: 20 28 6c 69 6b 65 20 61 20 70 61 74 68 20 74 6f (like a path to
0430: 20 61 20 66 69 6c 65 29 2c 20 61 6e 64 0d 0a 20 a file), and..
0440: 20 20 74 6f 6b 65 6e 69 7a 65 73 20 69 74 20 69 tokenizes it i
0450: 6e 74 6f 20 69 74 73 20 63 6f 6d 70 6f 6e 65 6e nto its componen
0460: 74 20 70 61 72 74 73 2e 20 54 68 65 20 27 6f 75 t parts. The 'ou
0470: 74 27 20 70 61 72 61 6d 65 74 65 72 20 28 69 66 t' parameter (if
0480: 20 6e 6f 74 0d 0a 20 20 20 6e 75 6c 6c 29 20 69 not.. null) i
0490: 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e 75 6d s set to the num
04a0: 62 65 72 20 6f 66 20 74 6f 6b 65 6e 69 7a 65 64 ber of tokenized
04b0: 20 69 74 65 6d 73 20 28 6d 61 79 20 62 65 20 30 items (may be 0
04c0: 29 2e 0d 0a 0d 0a 20 20 20 54 68 65 20 74 68 69 )..... The thi
04d0: 72 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20 61 rd argument is a
04e0: 20 75 6e 61 72 79 20 70 72 65 64 69 63 61 74 65 unary predicate
04f0: 20 66 75 6e 63 74 69 6f 6e 20 77 68 69 63 68 20 function which
0500: 74 61 6b 65 73 0d 0a 20 20 20 61 20 73 69 6e 67 takes.. a sing
0510: 6c 65 20 63 68 61 72 61 63 74 65 72 20 61 6e 64 le character and
0520: 20 72 65 74 75 72 6e 73 20 74 72 75 65 20 6f 6e returns true on
0530: 6c 79 20 69 66 20 74 68 61 74 20 63 68 61 72 61 ly if that chara
0540: 63 74 65 72 0d 0a 20 20 20 69 73 20 61 20 22 73 cter.. is a "s
0550: 65 70 61 72 61 74 6f 72 20 63 68 61 72 61 63 74 eparator charact
0560: 65 72 22 2e 20 49 66 20 74 68 65 20 33 72 64 20 er". If the 3rd
0570: 61 72 67 75 6d 65 6e 74 20 69 73 20 30 20 74 68 argument is 0 th
0580: 65 6e 0d 0a 20 20 20 74 6f 6b 65 6e 69 7a 65 5f en.. tokenize_
0590: 70 61 74 68 5f 69 73 5f 73 65 70 61 72 61 74 6f path_is_separato
05a0: 72 28 29 20 69 73 20 75 73 65 64 2e 0d 0a 0d 0a r() is used.....
05b0: 20 20 20 54 68 65 20 66 75 6e 63 74 69 6f 6e 20 The function
05c0: 72 65 74 75 72 6e 73 20 61 20 6c 69 73 74 20 6f returns a list o
05d0: 66 20 73 74 72 69 6e 67 73 20 28 6f 72 20 30 29 f strings (or 0)
05e0: 20 77 68 69 63 68 20 6d 75 73 74 20 62 65 20 66 which must be f
05f0: 72 65 65 64 0d 0a 20 20 20 76 69 61 20 74 6f 6b reed.. via tok
0600: 65 6e 69 7a 65 5f 70 61 74 68 5f 66 72 65 65 28 enize_path_free(
0610: 29 20 62 65 63 61 75 73 65 20 74 68 65 20 69 6e ) because the in
0620: 74 65 72 6e 61 6c 20 61 6c 6c 6f 63 61 74 69 6f ternal allocatio
0630: 6e 20 6f 66 20 74 68 65 0d 0a 20 20 20 72 65 74 n of the.. ret
0640: 75 72 6e 20 72 65 73 75 6c 74 20 69 73 20 61 20 urn result is a
0650: 62 69 74 20 74 72 69 63 6b 79 20 28 74 6f 20 6d bit tricky (to m
0660: 69 6e 69 6d 69 7a 65 20 6f 6e 20 61 6c 6c 6f 63 inimize on alloc
0670: 61 74 69 6f 6e 73 29 2e 20 20 44 4f 20 4e 4f 54 ations). DO NOT
0680: 0d 0a 20 20 20 70 61 73 73 20 74 68 65 20 72 65 .. pass the re
0690: 74 75 72 6e 20 72 65 73 75 6c 74 20 74 6f 20 66 turn result to f
06a0: 72 65 65 28 29 2c 20 61 73 20 74 68 61 74 20 77 ree(), as that w
06b0: 69 6c 6c 20 63 61 75 73 65 20 75 6e 64 65 66 69 ill cause undefi
06c0: 6e 65 64 0d 0a 20 20 20 62 65 68 61 76 69 6f 75 ned.. behaviou
06d0: 72 2e 20 42 65 63 61 75 73 65 20 74 68 65 20 72 r. Because the r
06e0: 65 74 75 72 6e 65 64 20 61 72 72 61 79 20 69 73 eturned array is
06f0: 20 6e 75 6c 6c 2d 74 65 72 6d 69 6e 61 74 65 64 null-terminated
0700: 2c 20 74 68 65 20 73 65 63 6f 6e 64 0d 0a 20 20 , the second..
0710: 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 6e 6f parameter is no
0720: 72 6d 61 6c 6c 79 20 6e 6f 74 20 6e 65 65 64 65 rmally not neede
0730: 64 20 62 65 63 61 75 73 65 20 74 68 65 20 61 72 d because the ar
0740: 72 61 79 20 63 61 6e 20 73 61 66 65 6c 79 0d 0a ray can safely..
0750: 20 20 20 62 65 20 6c 6f 6f 70 65 64 20 6f 76 65 be looped ove
0760: 72 20 77 69 74 68 6f 75 74 20 6b 6e 6f 77 69 6e r without knowin
0770: 67 20 69 74 73 20 6c 65 6e 67 74 68 20 69 6e 20 g its length in
0780: 61 64 76 61 6e 63 65 2e 20 4e 6f 6e 65 74 68 65 advance. Nonethe
0790: 6c 65 73 73 2c 0d 0a 20 20 20 68 61 76 69 6e 67 less,.. having
07a0: 20 74 68 65 20 63 6f 75 6e 74 20 62 65 66 6f 72 the count befor
07b0: 65 20 6c 6f 6f 70 69 6e 67 20 6d 61 79 20 62 65 e looping may be
07c0: 20 75 73 65 66 75 6c 20 66 6f 72 20 73 6f 6d 65 useful for some
07d0: 20 63 61 73 65 73 2e 0d 0a 0d 0a 48 6f 77 65 76 cases.....Howev
07e0: 65 72 2c 0d 0a 20 20 20 74 68 65 20 72 65 74 75 er,.. the retu
07f0: 72 6e 65 64 20 61 72 72 61 79 0d 0a 0d 0a 20 20 rned array....
0800: 20 54 68 65 20 72 65 74 75 72 6e 65 64 20 73 74 The returned st
0810: 72 69 6e 67 20 61 72 72 61 79 20 69 73 20 61 6c ring array is al
0820: 77 61 79 73 20 6e 75 6c 6c 2d 74 65 72 6d 69 6e ways null-termin
0830: 61 74 65 64 2c 20 74 6f 20 73 69 6d 70 6c 69 66 ated, to simplif
0840: 79 0d 0a 20 20 20 6c 6f 6f 70 69 6e 67 20 6f 76 y.. looping ov
0850: 65 72 20 69 74 2e 20 54 68 65 20 66 75 6e 63 74 er it. The funct
0860: 69 6f 6e 20 72 65 74 75 72 6e 73 20 6e 75 6c 6c ion returns null
0870: 20 69 66 20 74 68 65 20 69 6e 70 75 74 20 73 74 if the input st
0880: 72 69 6e 67 20 69 73 0d 0a 20 20 20 6e 75 6c 6c ring is.. null
0890: 2c 20 65 6d 70 74 79 2c 20 6f 72 20 63 6f 6e 74 , empty, or cont
08a0: 61 69 6e 73 20 6f 6e 6c 79 20 73 65 70 61 72 61 ains only separa
08b0: 74 6f 72 20 63 68 61 72 61 63 74 65 72 73 2e 0d tor characters..
08c0: 0a 0d 0a 20 20 20 54 6f 6b 65 6e 69 7a 69 6e 67 ... Tokenizing
08d0: 20 62 65 68 61 76 69 6f 75 72 3a 0d 0a 0d 0a 20 behaviour:....
08e0: 20 20 2d 20 49 74 20 61 73 73 75 6d 65 73 20 74 - It assumes t
08f0: 68 61 74 20 41 4c 4c 20 6e 6f 6e 2d 73 65 70 61 hat ALL non-sepa
0900: 72 61 74 6f 72 20 63 68 61 72 73 20 61 72 65 20 rator chars are
0910: 65 6e 74 72 79 20 6e 61 6d 65 73 2e 0d 0a 0d 0a entry names.....
0920: 20 20 20 2d 20 49 74 20 74 72 65 61 74 73 20 72 - It treats r
0930: 75 6e 73 20 6f 66 20 6d 75 6c 74 69 70 6c 65 20 uns of multiple
0940: 73 65 70 61 72 61 74 6f 72 73 20 63 68 61 72 73 separators chars
0950: 20 61 73 20 61 20 73 69 6e 67 6c 65 0d 0a 20 20 as a single..
0960: 20 73 65 70 61 72 61 74 6f 72 2c 20 4e 4f 54 20 separator, NOT
0970: 61 73 20 61 20 73 65 72 69 65 73 20 6f 66 20 65 as a series of e
0980: 6d 70 74 79 20 74 6f 6b 65 6e 73 2e 0d 0a 0d 0a mpty tokens.....
0990: 20 20 20 2d 20 49 74 20 68 61 73 20 6e 6f 20 6b - It has no k
09a0: 6e 6f 77 6c 65 64 67 65 20 6f 66 20 72 65 6c 61 nowledge of rela
09b0: 74 69 76 65 20 6f 72 20 61 62 73 6f 6c 75 74 65 tive or absolute
09c0: 20 70 61 74 68 73 2c 20 73 6f 0d 0a 20 20 20 22 paths, so.. "
09d0: 2e 22 20 61 6e 64 20 22 2e 2e 22 20 61 72 65 20 ." and ".." are
09e0: 63 6f 6e 73 69 64 65 72 65 64 20 74 6f 20 62 65 considered to be
09f0: 20 6e 6f 72 6d 61 6c 20 65 6e 74 72 69 65 73 2e normal entries.
0a00: 0d 0a 0d 0a 20 20 20 2d 20 54 68 65 20 72 65 74 .... - The ret
0a10: 75 72 6e 65 64 20 73 74 72 69 6e 67 73 20 61 72 urned strings ar
0a20: 65 20 6e 6f 6e 2d 63 6f 6e 73 74 2c 20 62 75 74 e non-const, but
0a30: 20 74 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 the caller must
0a40: 20 6e 6f 74 0d 0a 20 20 20 63 68 61 6e 67 65 20 not.. change
0a50: 74 68 65 69 72 20 73 69 7a 65 73 20 6f 72 20 72 their sizes or r
0a60: 65 61 6c 6c 6f 63 61 74 65 20 74 68 65 6d 20 61 eallocate them a
0a70: 74 20 64 69 66 66 65 72 65 6e 74 20 6d 65 6d 6f t different memo
0a80: 72 79 0d 0a 20 20 20 61 64 64 72 65 73 73 65 73 ry.. addresses
0a90: 2e 20 54 68 65 20 6f 6e 6c 79 20 6c 65 67 61 6c . The only legal
0aa0: 20 77 61 79 20 74 6f 20 64 65 61 6c 6c 6f 63 61 way to dealloca
0ab0: 74 65 20 74 68 65 6d 20 69 73 20 77 69 74 68 0d te them is with.
0ac0: 0a 20 20 20 74 6f 6b 65 6e 69 7a 65 5f 70 61 74 . tokenize_pat
0ad0: 68 5f 66 72 65 65 28 29 2e 20 43 68 61 6e 67 69 h_free(). Changi
0ae0: 6e 67 20 74 68 65 20 73 74 72 69 6e 67 20 63 6f ng the string co
0af0: 6e 74 65 6e 74 20 49 53 20 69 73 20 6c 65 67 61 ntent IS is lega
0b00: 6c 2e 0d 0a 0d 0a 20 20 20 65 2e 67 2e 3a 0d 0a l..... e.g.:..
0b10: 0d 0a 20 20 20 22 2f 70 61 74 68 2f 74 6f 2f 6e .. "/path/to/n
0b20: 6f 77 68 65 72 65 22 20 61 6e 64 20 22 70 61 74 owhere" and "pat
0b30: 68 2f 74 6f 2f 2f 2f 6e 6f 77 68 65 72 65 2f 22 h/to///nowhere/"
0b40: 20 62 6f 74 68 20 70 61 72 73 65 20 74 6f 3a 0d both parse to:.
0b50: 0a 0d 0a 20 20 20 50 61 72 73 65 73 20 74 6f 3a ... Parses to:
0b60: 20 7b 20 22 70 61 74 68 22 2c 20 22 74 6f 22 2c { "path", "to",
0b70: 20 22 6e 6f 77 68 65 72 65 22 20 7d 0d 0a 0d 0a "nowhere" }....
0b80: 20 20 20 22 2f 2e 2f 2e 2e 2f 22 0d 0a 0d 0a 20 "/./../"....
0b90: 20 20 50 61 72 73 65 73 20 74 6f 3a 20 7b 20 22 Parses to: { "
0ba0: 2e 22 2c 20 22 2e 2e 22 20 7d 0d 0a 0d 0a 20 20 .", ".." }....
0bb0: 20 22 68 74 74 70 3a 2f 2f 66 6f 6f 2e 63 6f 6d "http://foo.com
0bc0: 2f 62 61 72 22 0d 0a 0d 0a 20 20 20 50 61 72 73 /bar".... Pars
0bd0: 65 73 20 74 6f 3a 20 7b 20 22 68 74 74 70 3a 22 es to: { "http:"
0be0: 2c 20 22 66 6f 6f 2e 63 6f 6d 22 2c 20 22 62 61 , "foo.com", "ba
0bf0: 72 22 20 7d 0d 0a 0d 0a 20 20 20 28 4e 6f 74 65 r" }.... (Note
0c00: 20 74 68 61 74 20 74 68 6f 73 65 20 61 72 72 61 that those arra
0c10: 79 73 20 61 6c 6c 20 68 61 76 65 20 61 6e 20 69 ys all have an i
0c20: 6d 70 6c 69 63 69 74 20 4e 55 4c 4c 20 65 6e 74 mplicit NULL ent
0c30: 72 79 20 61 73 20 74 68 65 69 72 0d 0a 20 20 20 ry as their..
0c40: 6c 61 73 74 20 65 6c 65 6d 65 6e 74 2e 20 29 0d last element. ).
0c50: 0a 0d 0a 0d 0a 2a 2f 0d 0a 63 68 61 72 20 2a 2a .....*/..char **
0c60: 20 74 6f 6b 65 6e 69 7a 65 5f 70 61 74 68 28 20 tokenize_path(
0c70: 63 68 61 72 20 63 6f 6e 73 74 20 2a 20 69 6e 2c char const * in,
0c80: 0d 0a 09 09 20 20 20 20 20 20 20 69 6e 74 20 2a .... int *
0c90: 20 6f 75 74 2c 0d 0a 09 09 20 20 20 20 20 20 20 out,....
0ca0: 69 6e 74 20 28 2a 70 72 65 64 69 63 61 74 65 29 int (*predicate)
0cb0: 28 20 69 6e 74 20 29 0d 0a 09 09 20 20 20 20 20 ( int )....
0cc0: 20 20 29 0d 0a 7b 20 2f 2a 20 41 75 74 68 6f 72 )..{ /* Author
0cd0: 3a 20 73 67 62 65 61 6c 40 67 6f 6f 67 6c 65 6d : sgbeal@googlem
0ce0: 61 69 6c 2e 63 6f 6d 2e 20 4c 69 63 65 6e 73 65 ail.com. License
0cf0: 3a 20 50 75 62 6c 69 63 20 44 6f 6d 61 69 6e 2e : Public Domain.
0d00: 20 2a 2f 0d 0a 20 20 69 6e 74 20 69 67 6e 6f 72 */.. int ignor
0d10: 65 64 3b 0d 0a 20 20 69 66 28 20 21 20 6f 75 74 ed;.. if( ! out
0d20: 20 29 20 6f 75 74 20 3d 20 26 69 67 6e 6f 72 65 ) out = &ignore
0d30: 64 3b 0d 0a 20 20 2a 6f 75 74 20 3d 20 30 3b 0d d;.. *out = 0;.
0d40: 0a 20 20 74 79 70 65 64 65 66 20 69 6e 74 20 28 . typedef int (
0d50: 2a 73 65 70 5f 66 29 28 20 69 6e 74 20 29 3b 0d *sep_f)( int );.
0d60: 0a 20 20 73 65 70 5f 66 20 69 73 5f 73 65 70 20 . sep_f is_sep
0d70: 3d 20 28 70 72 65 64 69 63 61 74 65 20 3f 20 70 = (predicate ? p
0d80: 72 65 64 69 63 61 74 65 20 3a 20 74 6f 6b 65 6e redicate : token
0d90: 69 7a 65 5f 70 61 74 68 5f 69 73 5f 73 65 70 61 ize_path_is_sepa
0da0: 72 61 74 6f 72 29 3b 0d 0a 20 20 69 6e 74 20 69 rator);.. int i
0db0: 6e 6c 65 6e 20 3d 20 73 74 72 6c 65 6e 28 69 6e nlen = strlen(in
0dc0: 29 3b 0d 0a 20 20 69 66 28 20 28 21 20 69 6e 29 );.. if( (! in)
0dd0: 20 7c 7c 20 28 30 3d 3d 69 6e 6c 65 6e 29 20 29 || (0==inlen) )
0de0: 20 72 65 74 75 72 6e 20 30 3b 0d 0a 20 20 63 68 return 0;.. ch
0df0: 61 72 20 2a 20 63 70 20 3d 20 6d 61 6c 6c 6f 63 ar * cp = malloc
0e00: 28 20 69 6e 6c 65 6e 20 2b 20 31 20 29 3b 0d 0a ( inlen + 1 );..
0e10: 20 20 2f 2a 2a 0d 0a 20 20 20 20 20 57 65 20 6d /**.. We m
0e20: 61 6b 65 20 61 20 63 6f 70 79 20 62 65 63 61 75 ake a copy becau
0e30: 73 65 3a 0d 0a 20 20 20 20 20 20 0d 0a 20 20 20 se:.. ..
0e40: 20 20 4f 75 72 20 61 6c 67 6f 72 69 74 68 6d 20 Our algorithm
0e50: 69 73 20 74 6f 20 72 65 70 6c 61 63 65 20 73 65 is to replace se
0e60: 70 61 72 61 74 6f 72 73 20 77 69 74 68 20 30 20 parators with 0
0e70: 69 6e 20 6f 75 72 20 63 6f 70 79 2c 20 61 6e 64 in our copy, and
0e80: 0d 0a 20 20 20 20 20 75 73 65 20 74 68 61 74 20 .. use that
0e90: 63 6f 70 79 20 61 73 20 6f 75 72 20 72 65 74 75 copy as our retu
0ea0: 72 6e 20 76 61 6c 75 65 2e 20 54 68 69 73 20 61 rn value. This a
0eb0: 6c 6c 6f 77 73 20 75 73 20 74 6f 20 61 76 6f 69 llows us to avoi
0ec0: 64 0d 0a 20 20 20 20 20 61 6c 6c 6f 63 61 74 69 d.. allocati
0ed0: 6e 67 20 61 20 6e 65 77 20 73 74 72 69 6e 67 20 ng a new string
0ee0: 66 6f 72 20 65 61 63 68 20 72 65 74 75 72 6e 65 for each returne
0ef0: 64 20 72 65 73 75 6c 74 2e 0d 0a 20 20 2a 2f 0d d result... */.
0f00: 0a 20 20 73 74 72 63 70 79 28 20 63 70 2c 20 69 . strcpy( cp, i
0f10: 6e 20 29 3b 0d 0a 20 20 2f 2a 2a 0d 0a 20 20 20 n );.. /**..
0f20: 20 20 62 75 66 66 73 69 7a 65 20 3d 20 74 68 65 buffsize = the
0f30: 20 6c 61 72 67 65 73 74 20 70 6f 73 73 69 62 6c largest possibl
0f40: 65 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 74 75 e number of retu
0f50: 72 6e 20 72 65 73 75 6c 74 20 77 65 20 63 61 6e rn result we can
0f60: 0d 0a 20 20 20 20 20 68 61 76 65 2c 20 70 6c 75 .. have, plu
0f70: 73 20 31 20 28 74 6f 20 61 6c 6c 6f 77 20 66 6f s 1 (to allow fo
0f80: 72 20 74 72 75 6e 63 61 74 65 64 20 64 69 76 69 r truncated divi
0f90: 73 69 6f 6e 29 2e 20 54 68 65 20 6d 61 78 69 6d sion). The maxim
0fa0: 75 6d 20 73 69 7a 65 0d 0a 20 20 20 20 20 69 73 um size.. is
0fb0: 20 64 65 74 65 72 6d 69 6e 65 64 20 62 61 73 65 determined base
0fc0: 64 20 6f 6e 20 77 6f 72 73 74 2d 63 61 73 65 20 d on worst-case
0fd0: 73 63 65 6e 61 72 69 6f 3a 20 61 20 6c 69 73 74 scenario: a list
0fe0: 20 6f 66 20 73 69 6e 67 6c 65 0d 0a 20 20 20 20 of single..
0ff0: 20 63 68 61 72 61 63 74 65 72 73 2c 20 65 61 63 characters, eac
1000: 68 20 73 65 70 61 72 61 74 65 64 20 62 79 20 6f h separated by o
1010: 6e 65 20 73 65 70 61 72 61 74 6f 72 73 2c 20 65 ne separators, e
1020: 2e 67 2e 20 20 22 2f 31 2f 31 2f 31 2f 31 2f 31 .g. "/1/1/1/1/1
1030: 22 0d 0a 20 20 2a 2f 0d 0a 20 20 63 6f 6e 73 74 ".. */.. const
1040: 20 69 6e 74 20 62 75 66 66 73 69 7a 65 20 3d 20 int buffsize =
1050: 69 6e 6c 65 6e 20 2f 20 32 20 2b 20 31 3b 0d 0a inlen / 2 + 1;..
1060: 20 20 2f 2a 20 27 73 74 61 72 74 73 27 20 73 74 /* 'starts' st
1070: 6f 72 65 73 20 74 68 65 20 73 74 61 72 74 69 6e ores the startin
1080: 67 20 70 6f 69 6e 74 20 6f 66 20 65 61 63 68 20 g point of each
1090: 70 61 74 68 20 63 6f 6d 70 6f 6e 65 6e 74 0d 0a path component..
10a0: 20 20 20 20 20 73 75 62 73 74 72 69 6e 67 20 6f substring o
10b0: 66 20 27 63 70 27 2e 20 57 68 65 6e 20 77 65 20 f 'cp'. When we
10c0: 73 6c 69 63 65 20 75 70 20 27 63 70 27 20 62 65 slice up 'cp' be
10d0: 6c 6f 77 2c 20 73 74 61 72 74 73 5b 78 5d 0d 0a low, starts[x]..
10e0: 20 20 20 20 20 77 69 6c 6c 20 62 65 20 73 65 74 will be set
10f0: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20 70 to point to a p
1100: 61 72 74 69 63 75 6c 61 72 20 70 6f 73 69 74 69 articular positi
1110: 6f 6e 20 77 69 74 68 69 6e 20 27 63 70 27 2e 0d on within 'cp'..
1120: 0a 20 20 20 20 20 54 68 61 74 20 61 6c 6c 6f 77 . That allow
1130: 73 20 75 73 20 74 6f 20 61 76 6f 69 64 20 61 6c s us to avoid al
1140: 6c 6f 63 61 74 69 6e 67 2f 63 6f 70 79 69 6e 67 locating/copying
1150: 20 65 61 63 68 20 65 6c 65 6d 65 6e 74 0d 0a 20 each element..
1160: 20 20 20 20 73 65 70 61 72 61 74 65 6c 79 2e 0d separately..
1170: 0a 20 20 2a 2f 0d 0a 20 20 63 68 61 72 20 2a 20 . */.. char *
1180: 73 74 61 72 74 73 5b 62 75 66 66 73 69 7a 65 5d starts[buffsize]
1190: 3b 0d 0a 20 20 69 6e 74 20 69 20 3d 20 30 3b 0d ;.. int i = 0;.
11a0: 0a 20 20 66 6f 72 28 20 69 20 3d 20 30 3b 20 69 . for( i = 0; i
11b0: 20 3c 20 62 75 66 66 73 69 7a 65 3b 20 2b 2b 69 < buffsize; ++i
11c0: 20 29 20 73 74 61 72 74 73 5b 69 5d 20 3d 20 30 ) starts[i] = 0
11d0: 3b 0d 0a 0d 0a 20 20 63 68 61 72 20 2a 20 63 75 ;.... char * cu
11e0: 72 73 20 3d 20 63 70 3b 0d 0a 20 20 66 6f 72 28 rs = cp;.. for(
11f0: 20 63 75 72 73 20 3d 20 63 70 3b 20 69 73 5f 73 curs = cp; is_s
1200: 65 70 28 2a 63 75 72 73 29 3b 20 2b 2b 63 75 72 ep(*curs); ++cur
1210: 73 20 29 3b 0d 0a 20 20 2f 2a 20 5e 5e 5e 20 57 s );.. /* ^^^ W
1220: 65 20 73 6b 69 70 20 6c 65 61 64 69 6e 67 20 73 e skip leading s
1230: 65 70 61 72 61 74 6f 72 73 20 73 6f 20 77 65 20 eparators so we
1240: 63 61 6e 20 65 61 73 69 6c 79 0d 0a 20 20 20 20 can easily..
1250: 20 6d 61 72 6b 20 77 68 65 72 65 20 74 68 65 20 mark where the
1260: 66 69 72 73 74 20 65 6e 74 72 79 20 73 74 72 69 first entry stri
1270: 6e 67 20 61 63 74 75 61 6c 6c 79 20 62 65 67 69 ng actually begi
1280: 6e 73 2e 0d 0a 20 20 2a 2f 0d 0a 20 20 69 66 28 ns... */.. if(
1290: 20 27 5c 30 27 20 3d 3d 20 63 75 72 73 20 29 0d '\0' == curs ).
12a0: 0a 20 20 7b 0d 0a 20 20 20 20 66 72 65 65 28 20 . {.. free(
12b0: 63 70 20 29 3b 0d 0a 20 20 20 20 72 65 74 75 72 cp );.. retur
12c0: 6e 20 30 3b 0d 0a 20 20 7d 0d 0a 20 20 63 68 61 n 0;.. }.. cha
12d0: 72 20 2a 20 6d 61 72 6b 20 3d 20 63 75 72 73 3b r * mark = curs;
12e0: 20 2f 2a 20 70 6c 61 63 65 68 6f 6c 64 65 72 20 /* placeholder
12f0: 66 6f 72 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 for holding the
1300: 68 65 61 64 20 61 64 64 72 20 6f 66 20 73 74 72 head addr of str
1310: 69 6e 67 73 2e 20 2a 2f 0d 0a 20 20 69 6e 74 20 ings. */.. int
1320: 63 6f 75 6e 74 20 3d 20 30 3b 20 2f 2a 20 74 6f count = 0; /* to
1330: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 65 6c tal number of el
1340: 65 6d 65 6e 74 73 20 77 65 20 65 6e 64 20 75 70 ements we end up
1350: 20 74 6f 6b 65 6e 69 7a 69 6e 67 2e 20 2a 2f 0d tokenizing. */.
1360: 0a 20 20 69 6e 74 20 73 74 61 72 74 65 64 20 3d . int started =
1370: 20 30 3b 20 2f 2a 20 74 6f 67 67 6c 65 64 20 77 0; /* toggled w
1380: 68 65 6e 20 77 65 20 65 6e 74 65 72 20 61 20 6e hen we enter a n
1390: 65 77 20 70 61 74 68 20 65 6c 65 6d 65 6e 74 2e ew path element.
13a0: 20 2a 2f 0d 0a 20 20 66 6f 72 28 20 3b 20 2a 63 */.. for( ; *c
13b0: 75 72 73 20 21 3d 20 27 5c 30 27 3b 20 2b 2b 63 urs != '\0'; ++c
13c0: 75 72 73 20 29 0d 0a 20 20 7b 0d 0a 20 20 20 20 urs ).. {..
13d0: 2f 2a 2a 20 52 65 70 6c 61 63 65 20 27 2f 27 20 /** Replace '/'
13e0: 77 69 74 68 20 27 5c 30 27 2e 2e 2e 20 2a 2f 0d with '\0'... */.
13f0: 0a 20 20 20 20 69 66 28 20 69 73 5f 73 65 70 28 . if( is_sep(
1400: 2a 63 75 72 73 29 20 29 0d 0a 20 20 20 20 7b 0d *curs) ).. {.
1410: 0a 20 20 20 20 20 20 2a 63 75 72 73 20 3d 20 27 . *curs = '
1420: 5c 30 27 3b 0d 0a 20 20 20 20 20 20 6d 61 72 6b \0';.. mark
1430: 20 3d 20 63 75 72 73 2b 31 3b 0d 0a 20 20 20 20 = curs+1;..
1440: 20 20 73 74 61 72 74 65 64 20 3d 20 30 3b 0d 0a started = 0;..
1450: 20 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0d continue;.
1460: 0a 20 20 20 20 7d 0d 0a 20 20 20 20 69 66 28 20 . }.. if(
1470: 21 20 73 74 61 72 74 65 64 20 29 0d 0a 20 20 20 ! started )..
1480: 20 7b 20 2f 2a 2a 20 53 74 61 72 74 20 61 20 6e { /** Start a n
1490: 65 77 20 70 61 74 68 20 65 6c 65 6d 65 6e 74 2e ew path element.
14a0: 2e 2e 20 2a 2f 0d 0a 20 20 20 20 20 20 73 74 61 .. */.. sta
14b0: 72 74 73 5b 63 6f 75 6e 74 5d 20 3d 20 6d 61 72 rts[count] = mar
14c0: 6b 3b 0d 0a 20 20 20 20 20 20 73 74 61 72 74 65 k;.. starte
14d0: 64 20 3d 20 31 3b 0d 0a 20 20 20 20 20 20 2b 2b d = 1;.. ++
14e0: 63 6f 75 6e 74 3b 0d 0a 20 20 20 20 7d 0d 0a 20 count;.. }..
14f0: 20 7d 0d 0a 20 20 69 66 28 20 21 20 73 74 61 72 }.. if( ! star
1500: 74 73 5b 30 5d 20 29 0d 0a 20 20 7b 0d 0a 20 20 ts[0] ).. {..
1510: 20 20 66 72 65 65 28 20 63 70 20 29 3b 0d 0a 20 free( cp );..
1520: 20 20 20 72 65 74 75 72 6e 20 30 3b 0d 0a 20 20 return 0;..
1530: 7d 0d 0a 20 20 63 70 5b 69 6e 6c 65 6e 5d 20 3d }.. cp[inlen] =
1540: 20 27 5c 30 27 3b 0d 0a 20 20 63 68 61 72 20 2a '\0';.. char *
1550: 2a 20 72 65 74 20 3d 20 63 61 6c 6c 6f 63 28 20 * ret = calloc(
1560: 63 6f 75 6e 74 20 2b 20 32 2c 20 73 69 7a 65 6f count + 2, sizeo
1570: 66 28 63 68 61 72 2a 29 20 29 3b 0d 0a 20 20 2f f(char*) );.. /
1580: 2a 20 57 65 20 6f 76 65 72 2d 61 6c 6c 6f 63 61 * We over-alloca
1590: 74 65 20 62 79 20 32 20 65 6e 74 72 69 65 73 2e te by 2 entries.
15a0: 20 54 68 65 20 66 69 72 73 74 20 6f 6e 65 20 68 The first one h
15b0: 6f 6c 64 73 20 74 68 65 20 61 64 64 72 65 73 73 olds the address
15c0: 20 6f 66 0d 0a 20 20 20 27 63 70 27 20 61 6e 64 of.. 'cp' and
15d0: 20 74 68 65 20 6c 61 73 74 20 6f 6e 65 20 69 73 the last one is
15e0: 20 73 65 74 20 74 6f 20 30 20 74 6f 20 73 69 6d set to 0 to sim
15f0: 70 6c 69 66 79 20 6c 6f 6f 70 69 6e 67 20 6f 76 plify looping ov
1600: 65 72 20 74 68 65 0d 0a 20 20 20 61 72 72 61 79 er the.. array
1610: 2e 20 2a 2f 0d 0a 20 20 2a 6f 75 74 20 3d 20 63 . */.. *out = c
1620: 6f 75 6e 74 3b 0d 0a 20 20 72 65 74 5b 30 5d 20 ount;.. ret[0]
1630: 3d 20 63 70 3b 0d 0a 20 20 2b 2b 72 65 74 3b 0d = cp;.. ++ret;.
1640: 0a 20 20 2f 2a 2a 0d 0a 20 20 20 20 20 57 65 27 . /**.. We'
1650: 72 65 20 67 6f 69 6e 67 20 74 6f 20 68 69 64 65 re going to hide
1660: 20 74 68 61 74 20 5b 30 5d 20 65 6e 74 72 79 20 that [0] entry
1670: 66 72 6f 6d 20 74 68 65 20 63 61 6c 6c 65 72 2e from the caller.
1680: 20 49 6e 73 74 65 61 64 2c 20 77 65 0d 0a 20 20 Instead, we..
1690: 20 20 20 75 73 65 20 74 68 61 74 20 74 6f 20 68 use that to h
16a0: 6f 6c 64 20 74 68 65 20 61 64 64 72 65 73 73 20 old the address
16b0: 6f 66 20 27 63 70 27 2e 20 49 6e 20 74 6f 6b 65 of 'cp'. In toke
16c0: 6e 69 7a 65 5f 70 61 74 68 5f 66 72 65 65 28 29 nize_path_free()
16d0: 0d 0a 20 20 20 20 20 77 65 20 72 65 6c 65 61 73 .. we releas
16e0: 65 20 62 6f 74 68 20 74 68 61 74 20 73 74 72 69 e both that stri
16f0: 6e 67 20 61 6e 64 20 28 72 65 74 2d 31 29 2e 0d ng and (ret-1)..
1700: 0a 20 20 2a 2f 0d 0a 20 20 66 6f 72 28 20 69 20 . */.. for( i
1710: 3d 20 30 3b 20 69 20 3c 20 63 6f 75 6e 74 3b 20 = 0; i < count;
1720: 2b 2b 69 20 29 0d 0a 20 20 7b 0d 0a 20 20 20 20 ++i ).. {..
1730: 72 65 74 5b 69 5d 20 3d 20 73 74 61 72 74 73 5b ret[i] = starts[
1740: 69 5d 3b 0d 0a 20 20 7d 0d 0a 20 20 72 65 74 5b i];.. }.. ret[
1750: 63 6f 75 6e 74 5d 20 3d 20 30 3b 0d 0a 20 20 72 count] = 0;.. r
1760: 65 74 75 72 6e 20 72 65 74 3b 0d 0a 7d 0d 0a 0d eturn ret;..}...
1770: 0a 65 78 74 65 72 6e 20 76 6f 69 64 20 63 67 69 .extern void cgi
1780: 5f 70 72 69 6e 74 66 28 63 6f 6e 73 74 20 63 68 _printf(const ch
1790: 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 2e 2e 2e 29 ar *zFormat,...)
17a0: 3b 0d 0a 2f 2a 2a 0d 0a 72 65 6e 64 65 72 5f 6c ;../**..render_l
17b0: 69 6e 6b 65 64 5f 70 61 74 68 28 29 20 74 61 6b inked_path() tak
17c0: 65 73 20 61 20 72 6f 6f 74 20 70 61 74 68 20 61 es a root path a
17d0: 6e 64 20 61 20 2f 75 6e 69 78 2f 73 74 79 6c 65 nd a /unix/style
17e0: 2f 70 61 74 68 20 61 6e 64 0d 0a 72 65 6e 64 65 /path and..rende
17f0: 72 73 20 28 75 73 69 6e 67 20 63 67 69 5f 70 72 rs (using cgi_pr
1800: 69 6e 74 66 28 29 29 20 61 20 63 6c 69 63 6b 61 intf()) a clicka
1810: 62 6c 65 20 6c 69 73 74 20 6f 66 20 74 68 65 20 ble list of the
1820: 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 0d 0a entries in the..
1830: 70 61 74 68 2e 20 49 66 20 70 61 74 68 20 69 73 path. If path is
1840: 20 6e 75 6c 6c 20 69 74 20 64 6f 65 73 20 6e 6f null it does no
1850: 74 68 69 6e 67 2e 20 49 66 20 72 6f 6f 74 20 69 thing. If root i
1860: 73 20 6e 75 6c 6c 20 69 74 20 69 73 20 74 72 65 s null it is tre
1870: 61 74 65 64 0d 0a 61 73 20 61 6e 20 65 6d 70 74 ated..as an empt
1880: 79 20 73 74 72 69 6e 67 2e 0d 0a 0d 0a 45 78 61 y string.....Exa
1890: 6d 70 6c 65 3a 0d 0a 0d 0a 72 65 6e 64 65 72 5f mple:....render_
18a0: 6c 69 6e 6b 65 64 5f 70 61 74 68 28 20 22 2f 41 linked_path( "/A
18b0: 41 41 22 2c 20 22 62 2f 63 2f 64 22 20 29 3b 0d AA", "b/c/d" );.
18c0: 0a 0d 0a 49 74 20 77 6f 75 6c 64 20 72 65 6e 64 ...It would rend
18d0: 65 72 20 61 20 6c 69 73 74 20 73 69 6d 69 6c 61 er a list simila
18e0: 72 20 74 6f 20 74 68 65 20 66 6f 6c 6c 6f 77 69 r to the followi
18f0: 6e 67 2c 0d 0a 62 75 74 20 74 68 69 6e 6b 20 6f ng,..but think o
1900: 66 20 74 68 65 20 74 65 78 74 20 69 6e 20 5b 62 f the text in [b
1910: 72 61 63 6b 65 74 73 5d 20 61 73 20 68 79 70 65 rackets] as hype
1920: 72 6c 69 6e 6b 65 64 3a 0d 0a 0d 0a 20 20 5b 62 rlinked:.... [b
1930: 5d 2f 5b 63 5d 2f 5b 64 5d 0d 0a 0d 0a 20 20 45 ]/[c]/[d].... E
1940: 61 63 68 20 65 6c 65 6d 65 6e 74 20 69 73 20 6c ach element is l
1950: 69 6e 6b 65 64 20 74 6f 20 61 20 70 61 74 68 20 inked to a path
1960: 6c 69 6b 65 20 73 6f 3a 0d 0a 0d 0a 20 20 62 3a like so:.... b:
1970: 20 72 6f 6f 74 2f 62 0d 0a 20 20 63 3a 20 72 6f root/b.. c: ro
1980: 6f 74 2f 62 2f 63 0d 0a 20 20 64 3a 20 72 6f 6f ot/b/c.. d: roo
1990: 74 2f 62 2f 63 2f 64 0d 0a 0d 0a 49 66 20 72 6f t/b/c/d....If ro
19a0: 6f 74 20 69 73 20 6e 75 6c 6c 20 74 68 65 6e 20 ot is null then
19b0: 74 68 65 20 27 72 6f 6f 74 2f 27 20 70 61 72 74 the 'root/' part
19c0: 20 69 73 20 6e 6f 74 20 61 70 70 6c 69 65 64 2e is not applied.
19d0: 0d 0a 0d 0a 2a 2f 0d 0a 76 6f 69 64 20 72 65 6e ....*/..void ren
19e0: 64 65 72 5f 6c 69 6e 6b 65 64 5f 70 61 74 68 28 der_linked_path(
19f0: 20 63 68 61 72 20 63 6f 6e 73 74 20 2a 20 72 6f char const * ro
1a00: 6f 74 2c 0d 0a 20 20 20 20 20 20 20 20 20 20 20 ot,..
1a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63 68 ch
1a20: 61 72 20 63 6f 6e 73 74 20 2a 20 70 61 74 68 20 ar const * path
1a30: 29 0d 0a 7b 0d 0a 20 20 69 6e 74 20 63 6f 75 6e )..{.. int coun
1a40: 74 20 3d 20 30 3b 0d 0a 20 20 63 68 61 72 20 2a t = 0;.. char *
1a50: 2a 20 74 6f 6b 73 20 3d 20 74 6f 6b 65 6e 69 7a * toks = tokeniz
1a60: 65 5f 70 61 74 68 28 20 70 61 74 68 2c 20 26 63 e_path( path, &c
1a70: 6f 75 6e 74 2c 20 30 20 29 3b 0d 0a 20 20 69 66 ount, 0 );.. if
1a80: 28 20 21 20 74 6f 6b 73 20 29 20 72 65 74 75 72 ( ! toks ) retur
1a90: 6e 3b 0d 0a 20 20 63 68 61 72 20 63 6f 6e 73 74 n;.. char const
1aa0: 20 2a 20 74 20 3d 20 30 3b 0d 0a 20 20 69 6e 74 * t = 0;.. int
1ab0: 20 70 6f 73 20 3d 20 30 3b 0d 0a 20 20 66 6f 72 pos = 0;.. for
1ac0: 28 20 74 20 3d 20 74 6f 6b 73 5b 70 6f 73 5d 3b ( t = toks[pos];
1ad0: 20 74 3b 20 74 20 3d 20 74 6f 6b 73 5b 2b 2b 70 t; t = toks[++p
1ae0: 6f 73 5d 20 29 0d 0a 20 20 7b 0d 0a 20 20 20 20 os] ).. {..
1af0: 63 67 69 5f 70 72 69 6e 74 66 28 20 22 3c 61 20 cgi_printf( "<a
1b00: 68 72 65 66 3d 27 22 20 29 3b 0d 0a 20 20 20 20 href='" );..
1b10: 69 66 28 20 72 6f 6f 74 20 29 0d 0a 20 20 20 20 if( root )..
1b20: 7b 0d 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 {.. cgi_pri
1b30: 6e 74 66 28 20 22 25 73 2f 22 2c 20 72 6f 6f 74 ntf( "%s/", root
1b40: 20 29 3b 0d 0a 20 20 20 20 7d 0d 0a 20 20 20 20 );.. }..
1b50: 69 6e 74 20 62 70 6f 73 20 3d 20 30 3b 0d 0a 20 int bpos = 0;..
1b60: 20 20 20 66 6f 72 28 20 3b 20 62 70 6f 73 20 3c for( ; bpos <
1b70: 20 70 6f 73 3b 20 2b 2b 62 70 6f 73 20 29 0d 0a pos; ++bpos )..
1b80: 20 20 20 20 7b 0d 0a 20 20 20 20 20 20 63 67 69 {.. cgi
1b90: 5f 70 72 69 6e 74 66 28 22 25 73 2f 22 2c 20 74 _printf("%s/", t
1ba0: 6f 6b 73 5b 62 70 6f 73 5d 20 29 3b 0d 0a 20 20 oks[bpos] );..
1bb0: 20 20 7d 0d 0a 20 20 20 20 63 67 69 5f 70 72 69 }.. cgi_pri
1bc0: 6e 74 66 28 22 25 73 27 3e 25 73 3c 2f 61 3e 22 ntf("%s'>%s</a>"
1bd0: 2c 20 74 2c 20 74 20 29 3b 0d 0a 20 20 20 20 69 , t, t );.. i
1be0: 66 28 20 70 6f 73 20 21 3d 20 28 63 6f 75 6e 74 f( pos != (count
1bf0: 2d 31 29 20 29 0d 0a 20 20 20 20 7b 0d 0a 20 20 -1) ).. {..
1c00: 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 cgi_printf("
1c10: 2f 22 29 3b 0d 0a 20 20 20 20 7d 0d 0a 20 20 7d /");.. }.. }
1c20: 0d 0a 20 20 74 6f 6b 65 6e 69 7a 65 5f 70 61 74 .. tokenize_pat
1c30: 68 5f 66 72 65 65 28 20 74 6f 6b 73 20 29 3b 0d h_free( toks );.
1c40: 0a 7d 0d 0a 0d 0a 23 69 66 20 30 20 2f 2a 20 73 .}....#if 0 /* s
1c50: 65 74 20 74 6f 20 31 20 74 6f 20 63 6f 6d 70 69 et to 1 to compi
1c60: 6c 65 20 61 20 74 65 73 74 20 61 70 70 2e 20 2a le a test app. *
1c70: 2f 20 0d 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 / ..#include <st
1c80: 64 69 6f 2e 68 3e 0d 0a 0d 0a 73 74 61 74 69 63 dio.h>....static
1c90: 20 69 6e 74 20 73 65 70 5f 63 68 61 72 20 3d 20 int sep_char =
1ca0: 27 3f 27 3b 0d 0a 73 74 61 74 69 63 20 69 6e 74 '?';..static int
1cb0: 20 69 73 5f 73 65 70 5f 63 68 61 72 28 20 69 6e is_sep_char( in
1cc0: 74 20 63 20 29 0d 0a 7b 0d 0a 20 20 72 65 74 75 t c )..{.. retu
1cd0: 72 6e 20 63 20 3d 3d 20 73 65 70 5f 63 68 61 72 rn c == sep_char
1ce0: 3b 0d 0a 7d 0d 0a 69 6e 74 20 6d 61 69 6e 28 20 ;..}..int main(
1cf0: 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a int argc, char *
1d00: 2a 20 61 72 67 76 20 29 0d 0a 7b 0d 0a 0d 0a 20 * argv )..{....
1d10: 20 69 6e 74 20 63 6f 75 6e 74 20 3d 20 30 3b 0d int count = 0;.
1d20: 0a 20 20 73 65 70 5f 63 68 61 72 20 3d 20 28 20 . sep_char = (
1d30: 28 61 72 67 63 3e 32 29 20 3f 20 28 61 72 67 76 (argc>2) ? (argv
1d40: 5b 32 5d 29 5b 30 5d 20 3a 20 27 2f 27 29 3b 0d [2])[0] : '/');.
1d50: 0a 20 20 70 72 69 6e 74 66 28 20 22 73 65 70 5f . printf( "sep_
1d60: 63 68 61 72 3d 3d 25 63 5c 6e 22 2c 73 65 70 5f char==%c\n",sep_
1d70: 63 68 61 72 29 3b 0d 0a 20 20 63 68 61 72 20 2a char);.. char *
1d80: 2a 20 6c 20 3d 20 74 6f 6b 65 6e 69 7a 65 5f 70 * l = tokenize_p
1d90: 61 74 68 28 20 61 72 67 63 3d 3d 31 20 3f 20 30 ath( argc==1 ? 0
1da0: 20 3a 20 61 72 67 76 5b 31 5d 2c 0d 0a 20 20 20 : argv[1],..
1db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1dc0: 20 20 20 20 20 20 20 20 20 20 26 63 6f 75 6e 74 &count
1dd0: 2c 0d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 ,..
1de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1df0: 69 73 5f 73 65 70 5f 63 68 61 72 20 29 3b 0d 0a is_sep_char );..
1e00: 20 20 70 72 69 6e 74 66 28 20 22 70 61 72 73 65 printf( "parse
1e10: 64 20 70 61 74 68 3a 20 63 6f 75 6e 74 3d 25 64 d path: count=%d
1e20: 5c 6e 22 2c 20 63 6f 75 6e 74 20 29 3b 0d 0a 20 \n", count );..
1e30: 20 69 66 28 20 21 20 63 6f 75 6e 74 20 29 0d 0a if( ! count )..
1e40: 20 20 7b 0d 0a 20 20 20 20 70 72 69 6e 74 66 28 {.. printf(
1e50: 22 65 72 72 6f 72 3a 20 70 61 74 68 20 64 69 64 "error: path did
1e60: 6e 27 74 20 70 61 72 73 65 20 3a 28 5c 6e 22 29 n't parse :(\n")
1e70: 3b 0d 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b ;.. return 1;
1e80: 0d 0a 20 20 7d 0d 0a 20 20 63 68 61 72 20 2a 20 .. }.. char *
1e90: 78 3b 0d 0a 20 20 69 6e 74 20 69 20 3d 20 30 3b x;.. int i = 0;
1ea0: 0d 0a 20 20 66 6f 72 28 20 78 20 3d 20 6c 5b 30 .. for( x = l[0
1eb0: 5d 3b 20 78 3b 20 78 20 3d 20 6c 5b 2b 2b 69 5d ]; x; x = l[++i]
1ec0: 20 29 0d 0a 20 20 7b 0d 0a 20 20 20 20 70 72 69 ).. {.. pri
1ed0: 6e 74 66 28 20 22 5c 74 25 73 5c 6e 22 2c 20 78 ntf( "\t%s\n", x
1ee0: 20 29 3b 0d 0a 20 20 7d 0d 0a 20 20 74 6f 6b 65 );.. }.. toke
1ef0: 6e 69 7a 65 5f 70 61 74 68 5f 66 72 65 65 28 20 nize_path_free(
1f00: 6c 20 29 3b 0d 0a 20 20 70 72 69 6e 74 66 28 20 l );.. printf(
1f10: 22 42 79 65 21 5c 6e 22 29 3b 0d 0a 20 20 72 65 "Bye!\n");.. re
1f20: 74 75 72 6e 20 30 3b 0d 0a 7d 0d 0a 23 65 6e 64 turn 0;..}..#end
1f30: 69 66 0d 0a if..