program SimplifyUnixPath;
const
MAX_PARTS = 100; { Maximum number of path components }
MAX_LEN = 255; { Maximum length of each component }
type
TString = string[MAX_LEN];
TStack = record
items: array[1..MAX_PARTS] of TString;
top: integer;
end;
{ Initialize the stack }
procedure InitStack(var st: TStack);
begin
st.top := 0;
end;
{ Push a string onto the stack }
procedure Push(var st: TStack; s: TString);
begin
if st.top < MAX_PARTS then
begin
inc(st.top);
st.items[st.top] := s;
end;
end;
{ Check if the stack is empty }
function IsEmpty(st: TStack): boolean;
begin
IsEmpty := st.top = 0;
end;
{ Simplify the given Unix-style path }
function SimplifyPath(path: TString): TString;
var
st: TStack;
resultPath: TString;
i, j: integer;
pathpart: TString;
begin
InitStack(st);
i := 1;
{ Iterate through each character in the path }
while i <= length(path) do
begin
{ Skip redundant slashes }
while (i <= length(path)) and (path[i] = '/') do
inc(i);
pathpart := '';
{ Extract the next pathpart until the next slash }
while (i <= length(path)) and (path[i] <> '/') do
begin
pathpart := pathpart + path[i];
inc(i);
end;
{ Ignore current pathpart references }
if pathpart = '.' then
continue;
{ Ignore ".." instead of popping }
if pathpart = '..' then
continue;
{ Valid pathpart, push to stack }
if pathpart <> '' then
Push(st, pathpart);
end;
{ Reconstruct the simplified path from the stack }
resultPath := '';
for j := 1 to st.top do
resultPath := resultPath + '/' + st.items[j];
{ If the stack was empty, return root directory }
if resultPath = '' then
SimplifyPath := '/'
else
SimplifyPath := resultPath;
end;
var
inputPath, simplified: TString;
begin
{ Input path to be simplified }
inputPath := '/home//foo/../bar/./unix/';
{ Call the SimplifyPath function }
simplified := SimplifyPath(inputPath);
{ Output the result }
writeln('Simplified path: ', simplified);
end.
(*
run:
Simplified path: /home/foo/bar/unix
*)